{"version":3,"file":"Table.cjs","names":[],"sources":["../../../src/components/Table/Table.tsx"],"sourcesContent":["/**\n * @tempest-limits props-count — columns, data and rowKey are the model; onRowClick\n * and emptyMessage the interaction and the empty state; stackOnMobile and\n * scrollLabel are the two ways a table survives a phone, and the label is required\n * because a scroll region needs an accessible name.\n */\nimport { useRef } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport { useScrollOverflow } from \"@/hooks/use-scroll-overflow\";\nimport styles from \"./Table.module.css\";\n\nexport type TableAlign = \"left\" | \"right\" | \"center\";\nexport type TablePriority = \"always\" | \"tablet\" | \"desktop\";\n\nexport interface TableColumn<T> {\n    key: string;\n    header: ReactNode;\n    /** Render the cell content. Defaults to `row[key]` if not provided. */\n    render?: (row: T, index: number) => ReactNode;\n    align?: TableAlign;\n    width?: string | number;\n    className?: string;\n    /**\n     * Visibility priority: `always` (default) shows on every viewport,\n     * `tablet` hides below md (< 768px), `desktop` hides below lg (< 1024px).\n     */\n    priority?: TablePriority;\n}\n\nexport interface TableProps<T> {\n    columns: TableColumn<T>[];\n    data: T[];\n    rowKey: (row: T, index: number) => string | number;\n    onRowClick?: (row: T) => void;\n    emptyMessage?: ReactNode;\n    className?: string;\n    /**\n     * Stack mode — render rows as label/value cards on mobile (< md).\n     * Better than horizontal scroll when each row has 3+ columns of dense data.\n     */\n    stackOnMobile?: boolean;\n    /**\n     * Accessible name for the scrollable region, used only while the table is\n     * actually wider than its box. A focus stop that announces nothing is worse\n     * than no focus stop, so name the table when the page holds several.\n     */\n    scrollLabel?: string;\n}\n\nfunction priorityClass(priority: TablePriority | undefined): string | undefined {\n    if (priority === \"tablet\") return styles.priorityTablet;\n    if (priority === \"desktop\") return styles.priorityDesktop;\n    return undefined;\n}\n\n/**\n * Lightweight table with declarative columns + mobile niceties.\n *\n * - `priority` per column lets less-important data hide on narrow viewports.\n * - `stackOnMobile` re-renders each row as a label/value card on mobile,\n *   avoiding horizontal scroll for dense data.\n */\nexport function Table<T>({\n    columns,\n    data,\n    rowKey,\n    onRowClick,\n    emptyMessage = \"Nenhum registro encontrado.\",\n    className,\n    stackOnMobile = false,\n    scrollLabel = \"Tabela rolável horizontalmente\",\n}: TableProps<T>) {\n    const scrollRef = useRef<HTMLDivElement>(null);\n    const scrollable = useScrollOverflow(scrollRef, \"horizontal\");\n\n    return (\n        <div\n            ref={scrollRef}\n            className={cn(styles.scroll, stackOnMobile && styles.stackable, className)}\n            tabIndex={scrollable ? 0 : undefined}\n            role={scrollable ? \"group\" : undefined}\n            aria-label={scrollable ? scrollLabel : undefined}\n        >\n            <table className={styles.table}>\n                <thead className={cn(stackOnMobile && styles.stackableHead)}>\n                    <tr>\n                        {columns.map((column) => (\n                            <th\n                                key={column.key}\n                                className={cn(\n                                    styles.th,\n                                    column.align === \"right\" && styles.alignRight,\n                                    column.align === \"center\" && styles.alignCenter,\n                                    priorityClass(column.priority),\n                                )}\n                                style={{ width: column.width }}\n                            >\n                                {column.header}\n                            </th>\n                        ))}\n                    </tr>\n                </thead>\n                <tbody>\n                    {data.length === 0 ? (\n                        <tr>\n                            <td className={styles.emptyRow} colSpan={columns.length}>\n                                {emptyMessage}\n                            </td>\n                        </tr>\n                    ) : (\n                        data.map((row, index) => (\n                            <tr\n                                key={rowKey(row, index)}\n                                className={cn(\n                                    styles.tr,\n                                    onRowClick && styles.clickable,\n                                    stackOnMobile && styles.stackableRow,\n                                )}\n                                onClick={onRowClick ? () => onRowClick(row) : undefined}\n                            >\n                                {columns.map((column) => {\n                                    const content = column.render\n                                        ? column.render(row, index)\n                                        : (row as Record<string, ReactNode>)[column.key];\n                                    return (\n                                        <td\n                                            key={column.key}\n                                            className={cn(\n                                                styles.td,\n                                                column.align === \"right\" && styles.alignRight,\n                                                column.align === \"center\" && styles.alignCenter,\n                                                priorityClass(column.priority),\n                                                column.className,\n                                            )}\n                                            data-label={\n                                                typeof column.header === \"string\"\n                                                    ? column.header\n                                                    : undefined\n                                            }\n                                        >\n                                            {content}\n                                        </td>\n                                    );\n                                })}\n                            </tr>\n                        ))\n                    )}\n                </tbody>\n            </table>\n        </div>\n    );\n}\n"],"mappings":"6KAkDA,SAAS,EAAc,EAAyD,CAC5E,GAAI,IAAa,SAAU,OAAO,EAAA,QAAO,eACzC,GAAI,IAAa,UAAW,OAAO,EAAA,QAAO,eAE9C,CASA,SAAgB,EAAS,CACrB,UACA,OACA,SACA,aACA,eAAe,8BACf,YACA,gBAAgB,GAChB,cAAc,kCACA,CACd,IAAM,GAAA,EAAY,EAAA,OAAA,CAAuB,IAAI,EACvC,EAAa,EAAA,kBAAkB,EAAW,YAAY,EAE5D,OACI,EAAA,EAAA,IAAA,CAAC,MAAD,CACI,IAAK,EACL,UAAW,EAAA,GAAG,EAAA,QAAO,OAAQ,GAAiB,EAAA,QAAO,UAAW,CAAS,EACzE,SAAU,EAAa,EAAI,IAAA,GAC3B,KAAM,EAAa,QAAU,IAAA,GAC7B,aAAY,EAAa,EAAc,IAAA,GAEvC,UAAA,EAAA,EAAA,KAAA,CAAC,QAAD,CAAO,UAAW,EAAA,QAAO,MAAzB,SAAA,EACI,EAAA,EAAA,IAAA,CAAC,QAAD,CAAO,UAAW,EAAA,GAAG,GAAiB,EAAA,QAAO,aAAa,EACtD,UAAA,EAAA,EAAA,IAAA,CAAC,KAAD,CAAA,SACK,EAAQ,IAAK,IACV,EAAA,EAAA,IAAA,CAAC,KAAD,CAEI,UAAW,EAAA,GACP,EAAA,QAAO,GACP,EAAO,QAAU,SAAW,EAAA,QAAO,WACnC,EAAO,QAAU,UAAY,EAAA,QAAO,YACpC,EAAc,EAAO,QAAQ,CACjC,EACA,MAAO,CAAE,MAAO,EAAO,KAAM,EAE5B,SAAA,EAAO,MACR,EAVK,EAAO,GAUZ,CACP,CACD,CAAA,CACD,CAAA,GACP,EAAA,EAAA,IAAA,CAAC,QAAD,CAAA,SACK,EAAK,SAAW,GACb,EAAA,EAAA,IAAA,CAAC,KAAD,CAAA,UACI,EAAA,EAAA,IAAA,CAAC,KAAD,CAAI,UAAW,EAAA,QAAO,SAAU,QAAS,EAAQ,OAC5C,SAAA,CACD,CAAA,CACJ,CAAA,EAEJ,EAAK,KAAK,EAAK,KACX,EAAA,EAAA,IAAA,CAAC,KAAD,CAEI,UAAW,EAAA,GACP,EAAA,QAAO,GACP,GAAc,EAAA,QAAO,UACrB,GAAiB,EAAA,QAAO,YAC5B,EACA,QAAS,MAAmB,EAAW,CAAG,EAAI,IAAA,GAE7C,SAAA,EAAQ,IAAK,GAAW,CACrB,IAAM,EAAU,EAAO,OACjB,EAAO,OAAO,EAAK,CAAK,EACvB,EAAkC,EAAO,KAChD,OACI,EAAA,EAAA,IAAA,CAAC,KAAD,CAEI,UAAW,EAAA,GACP,EAAA,QAAO,GACP,EAAO,QAAU,SAAW,EAAA,QAAO,WACnC,EAAO,QAAU,UAAY,EAAA,QAAO,YACpC,EAAc,EAAO,QAAQ,EAC7B,EAAO,SACX,EACA,aACI,OAAO,EAAO,QAAW,SACnB,EAAO,OACP,IAAA,GAGT,SAAA,CACD,EAfK,EAAO,GAeZ,CAEZ,CAAC,CACD,EAhCK,EAAO,EAAK,CAAK,CAgCtB,CACP,CAEF,CAAA,CACJ,GACN,CAAA,CAEb"}