analytica-frontend-lib 1.2.11 → 1.2.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/CheckBox/index.d.mts +1 -1
- package/dist/CheckBox/index.d.ts +1 -1
- package/dist/Radio/index.d.mts +2 -2
- package/dist/Radio/index.d.ts +2 -2
- package/dist/Search/index.d.mts +1 -1
- package/dist/Search/index.d.ts +1 -1
- package/dist/Table/index.d.mts +1 -1
- package/dist/Table/index.d.ts +1 -1
- package/dist/Table/index.js.map +1 -1
- package/dist/Table/index.mjs.map +1 -1
- package/dist/index.css +3 -0
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +116 -3
- package/dist/index.d.ts +116 -3
- package/dist/index.js +1057 -788
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +978 -711
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +3 -0
- package/dist/styles.css.map +1 -1
- package/package.json +1 -1
|
@@ -69,6 +69,6 @@ declare const CheckBox: react.ForwardRefExoticComponent<{
|
|
|
69
69
|
className?: string;
|
|
70
70
|
/** Label CSS classes */
|
|
71
71
|
labelClassName?: string;
|
|
72
|
-
} & Omit<InputHTMLAttributes<HTMLInputElement>, "
|
|
72
|
+
} & Omit<InputHTMLAttributes<HTMLInputElement>, "type" | "size"> & react.RefAttributes<HTMLInputElement>>;
|
|
73
73
|
|
|
74
74
|
export { type CheckBoxProps, CheckBox as default };
|
package/dist/CheckBox/index.d.ts
CHANGED
|
@@ -69,6 +69,6 @@ declare const CheckBox: react.ForwardRefExoticComponent<{
|
|
|
69
69
|
className?: string;
|
|
70
70
|
/** Label CSS classes */
|
|
71
71
|
labelClassName?: string;
|
|
72
|
-
} & Omit<InputHTMLAttributes<HTMLInputElement>, "
|
|
72
|
+
} & Omit<InputHTMLAttributes<HTMLInputElement>, "type" | "size"> & react.RefAttributes<HTMLInputElement>>;
|
|
73
73
|
|
|
74
74
|
export { type CheckBoxProps, CheckBox as default };
|
package/dist/Radio/index.d.mts
CHANGED
|
@@ -81,7 +81,7 @@ declare const Radio: react.ForwardRefExoticComponent<{
|
|
|
81
81
|
value?: string;
|
|
82
82
|
/** Default checked state for uncontrolled radios */
|
|
83
83
|
defaultChecked?: boolean;
|
|
84
|
-
} & Omit<InputHTMLAttributes<HTMLInputElement>, "
|
|
84
|
+
} & Omit<InputHTMLAttributes<HTMLInputElement>, "defaultChecked" | "type" | "size"> & react.RefAttributes<HTMLInputElement>>;
|
|
85
85
|
/**
|
|
86
86
|
* RadioGroup store interface
|
|
87
87
|
*/
|
|
@@ -198,6 +198,6 @@ declare const RadioGroupItem: react.ForwardRefExoticComponent<{
|
|
|
198
198
|
state?: RadioState;
|
|
199
199
|
/** Additional CSS classes */
|
|
200
200
|
className?: string;
|
|
201
|
-
} & Omit<InputHTMLAttributes<HTMLInputElement>, "
|
|
201
|
+
} & Omit<InputHTMLAttributes<HTMLInputElement>, "onChange" | "name" | "type" | "size" | "value" | "checked"> & react.RefAttributes<HTMLInputElement>>;
|
|
202
202
|
|
|
203
203
|
export { RadioGroup, RadioGroupItem, type RadioGroupItemProps, type RadioGroupProps, type RadioProps, Radio as default, useRadioGroupStore };
|
package/dist/Radio/index.d.ts
CHANGED
|
@@ -81,7 +81,7 @@ declare const Radio: react.ForwardRefExoticComponent<{
|
|
|
81
81
|
value?: string;
|
|
82
82
|
/** Default checked state for uncontrolled radios */
|
|
83
83
|
defaultChecked?: boolean;
|
|
84
|
-
} & Omit<InputHTMLAttributes<HTMLInputElement>, "
|
|
84
|
+
} & Omit<InputHTMLAttributes<HTMLInputElement>, "defaultChecked" | "type" | "size"> & react.RefAttributes<HTMLInputElement>>;
|
|
85
85
|
/**
|
|
86
86
|
* RadioGroup store interface
|
|
87
87
|
*/
|
|
@@ -198,6 +198,6 @@ declare const RadioGroupItem: react.ForwardRefExoticComponent<{
|
|
|
198
198
|
state?: RadioState;
|
|
199
199
|
/** Additional CSS classes */
|
|
200
200
|
className?: string;
|
|
201
|
-
} & Omit<InputHTMLAttributes<HTMLInputElement>, "
|
|
201
|
+
} & Omit<InputHTMLAttributes<HTMLInputElement>, "onChange" | "name" | "type" | "size" | "value" | "checked"> & react.RefAttributes<HTMLInputElement>>;
|
|
202
202
|
|
|
203
203
|
export { RadioGroup, RadioGroupItem, type RadioGroupItemProps, type RadioGroupProps, type RadioProps, Radio as default, useRadioGroupStore };
|
package/dist/Search/index.d.mts
CHANGED
|
@@ -22,6 +22,6 @@ declare const Search: react.ForwardRefExoticComponent<{
|
|
|
22
22
|
containerClassName?: string;
|
|
23
23
|
/** Callback when clear button is clicked */
|
|
24
24
|
onClear?: () => void;
|
|
25
|
-
} & Omit<InputHTMLAttributes<HTMLInputElement>, "
|
|
25
|
+
} & Omit<InputHTMLAttributes<HTMLInputElement>, "onSelect" | "size"> & react.RefAttributes<HTMLInputElement>>;
|
|
26
26
|
|
|
27
27
|
export { Search as default };
|
package/dist/Search/index.d.ts
CHANGED
|
@@ -22,6 +22,6 @@ declare const Search: react.ForwardRefExoticComponent<{
|
|
|
22
22
|
containerClassName?: string;
|
|
23
23
|
/** Callback when clear button is clicked */
|
|
24
24
|
onClear?: () => void;
|
|
25
|
-
} & Omit<InputHTMLAttributes<HTMLInputElement>, "
|
|
25
|
+
} & Omit<InputHTMLAttributes<HTMLInputElement>, "onSelect" | "size"> & react.RefAttributes<HTMLInputElement>>;
|
|
26
26
|
|
|
27
27
|
export { Search as default };
|
package/dist/Table/index.d.mts
CHANGED
|
@@ -75,4 +75,4 @@ declare const TableHead: react.ForwardRefExoticComponent<TableHeadProps & react.
|
|
|
75
75
|
declare const TableCell: react.ForwardRefExoticComponent<TdHTMLAttributes<HTMLTableCellElement> & react.RefAttributes<HTMLTableCellElement>>;
|
|
76
76
|
declare const TableCaption: react.ForwardRefExoticComponent<HTMLAttributes<HTMLTableCaptionElement> & react.RefAttributes<HTMLTableCaptionElement>>;
|
|
77
77
|
|
|
78
|
-
export { type SortDirection, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Table as default, useTableSort };
|
|
78
|
+
export { type SortDirection, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, type UseTableSortOptions, Table as default, useTableSort };
|
package/dist/Table/index.d.ts
CHANGED
|
@@ -75,4 +75,4 @@ declare const TableHead: react.ForwardRefExoticComponent<TableHeadProps & react.
|
|
|
75
75
|
declare const TableCell: react.ForwardRefExoticComponent<TdHTMLAttributes<HTMLTableCellElement> & react.RefAttributes<HTMLTableCellElement>>;
|
|
76
76
|
declare const TableCaption: react.ForwardRefExoticComponent<HTMLAttributes<HTMLTableCaptionElement> & react.RefAttributes<HTMLTableCaptionElement>>;
|
|
77
77
|
|
|
78
|
-
export { type SortDirection, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Table as default, useTableSort };
|
|
78
|
+
export { type SortDirection, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, type UseTableSortOptions, Table as default, useTableSort };
|
package/dist/Table/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/Table/Table.tsx","../../src/utils/utils.ts"],"sourcesContent":["import {\n forwardRef,\n HTMLAttributes,\n TdHTMLAttributes,\n ThHTMLAttributes,\n useState,\n useMemo,\n useEffect,\n} from 'react';\nimport { cn } from '../../utils/utils';\nimport { CaretUp, CaretDown } from 'phosphor-react';\n\ntype TableVariant = 'default' | 'borderless';\ntype TableRowState = 'default' | 'selected' | 'invalid' | 'disabled';\nexport type SortDirection = 'asc' | 'desc' | null;\n\ninterface UseTableSortOptions {\n /** Se true, sincroniza o estado de ordenação com os parâmetros da URL */\n syncWithUrl?: boolean;\n}\n\n/**\n * Hook para gerenciar ordenação de dados da tabela\n *\n * @param data - Array de dados a serem ordenados\n * @param options - Opções de configuração do hook\n * @returns Objeto com dados ordenados, coluna/direção atual e função de sort\n *\n * @example\n * ```tsx\n * const activities = [\n * { id: 1, name: 'Task A', date: '2024-01-01' },\n * { id: 2, name: 'Task B', date: '2024-01-02' },\n * ];\n *\n * // Sem sincronização com URL\n * const { sortedData, sortColumn, sortDirection, handleSort } = useTableSort(activities);\n *\n * // Com sincronização com URL\n * const { sortedData, sortColumn, sortDirection, handleSort } = useTableSort(activities, { syncWithUrl: true });\n *\n * <TableHead\n * sortDirection={sortColumn === 'name' ? sortDirection : null}\n * onSort={() => handleSort('name')}\n * >\n * Name\n * </TableHead>\n * ```\n */\nexport function useTableSort<T extends Record<string, unknown>>(\n data: T[],\n options: UseTableSortOptions = {}\n) {\n const { syncWithUrl = false } = options;\n\n // Inicializar estado a partir da URL se syncWithUrl estiver habilitado\n const getInitialState = () => {\n if (!syncWithUrl || globalThis.window === undefined) {\n return { column: null, direction: null };\n }\n\n const params = new URLSearchParams(globalThis.location.search);\n const sortBy = params.get('sortBy');\n const sort = params.get('sort');\n\n if (sortBy && sort && (sort === 'ASC' || sort === 'DESC')) {\n return {\n column: sortBy,\n direction: sort.toLowerCase() as SortDirection,\n };\n }\n\n return { column: null, direction: null };\n };\n\n const initialState = getInitialState();\n const [sortColumn, setSortColumn] = useState<string | null>(\n initialState.column\n );\n const [sortDirection, setSortDirection] = useState<SortDirection>(\n initialState.direction\n );\n\n // Atualizar URL quando o estado de ordenação mudar\n useEffect(() => {\n if (!syncWithUrl || globalThis.window === undefined) return;\n\n const url = new URL(globalThis.location.href);\n const params = url.searchParams;\n\n if (sortColumn && sortDirection) {\n params.set('sortBy', sortColumn);\n params.set('sort', sortDirection.toUpperCase());\n } else {\n params.delete('sortBy');\n params.delete('sort');\n }\n\n // Atualizar URL sem recarregar a página\n globalThis.history.replaceState({}, '', url.toString());\n }, [sortColumn, sortDirection, syncWithUrl]);\n\n const handleSort = (column: string) => {\n if (sortColumn === column) {\n if (sortDirection === 'asc') {\n setSortDirection('desc');\n } else if (sortDirection === 'desc') {\n setSortColumn(null);\n setSortDirection(null);\n }\n } else {\n setSortColumn(column);\n setSortDirection('asc');\n }\n };\n\n const sortedData = useMemo(() => {\n if (!sortColumn || !sortDirection) {\n return data;\n }\n\n return [...data].sort((a, b) => {\n const aValue = a[sortColumn as keyof T];\n const bValue = b[sortColumn as keyof T];\n\n if (typeof aValue === 'string' && typeof bValue === 'string') {\n const comparison = aValue.localeCompare(bValue);\n return sortDirection === 'asc' ? comparison : -comparison;\n }\n\n if (typeof aValue === 'number' && typeof bValue === 'number') {\n return sortDirection === 'asc' ? aValue - bValue : bValue - aValue;\n }\n\n return 0;\n });\n }, [data, sortColumn, sortDirection]);\n\n return { sortedData, sortColumn, sortDirection, handleSort };\n}\n\ninterface TableProps extends HTMLAttributes<HTMLTableElement> {\n variant?: TableVariant;\n}\n\ninterface TableRowProps extends HTMLAttributes<HTMLTableRowElement> {\n state?: TableRowState;\n}\n\nconst Table = forwardRef<HTMLTableElement, TableProps>(\n ({ variant = 'default', className, children, ...props }, ref) => (\n <div\n className={cn(\n 'relative w-full overflow-x-auto',\n variant === 'default' && 'border border-border-200 rounded-xl'\n )}\n >\n <table\n ref={ref}\n className={cn(\n 'analytica-table w-full caption-bottom text-sm border-separate border-spacing-0',\n className\n )}\n {...props}\n >\n {/* Fix Sonnar */}\n <caption className=\"sr-only\">My Table</caption>\n {children}\n </table>\n </div>\n )\n);\n\nTable.displayName = 'Table';\n\nconst TableHeader = forwardRef<\n HTMLTableSectionElement,\n HTMLAttributes<HTMLTableSectionElement>\n>(({ className, ...props }, ref) => (\n <thead\n ref={ref}\n className={cn('[&_tr:first-child]:border-0', className)}\n {...props}\n />\n));\nTableHeader.displayName = 'TableHeader';\n\ninterface TableBodyProps extends HTMLAttributes<HTMLTableSectionElement> {\n variant?: TableVariant;\n}\n\nconst TableBody = forwardRef<HTMLTableSectionElement, TableBodyProps>(\n ({ className, ...props }, ref) => (\n <tbody\n ref={ref}\n className={cn('[&_tr:last-child]:border-border-200', className)}\n {...props}\n />\n )\n);\nTableBody.displayName = 'TableBody';\n\ninterface TableFooterProps extends HTMLAttributes<HTMLTableSectionElement> {\n variant?: TableVariant;\n}\n\nconst TableFooter = forwardRef<HTMLTableSectionElement, TableFooterProps>(\n ({ variant = 'default', className, ...props }, ref) => (\n <tfoot\n ref={ref}\n className={cn(\n 'bg-background-50 font-medium [&>tr]:last:border-b-0 px-6 py-3.5',\n variant === 'default' && 'border-t border-border-200',\n className\n )}\n {...props}\n />\n )\n);\nTableFooter.displayName = 'TableFooter';\n\nconst VARIANT_STATES_ROW = {\n default: {\n default: 'border border-border-200',\n borderless: '',\n },\n selected: {\n default: 'border-b-2 border-indicator-primary',\n borderless: 'bg-indicator-primary/10',\n },\n invalid: {\n default: 'border-b-2 border-indicator-error',\n borderless: 'bg-indicator-error/10',\n },\n disabled: {\n default:\n 'border-b border-border-100 bg-background-50 opacity-50 cursor-not-allowed',\n borderless: 'bg-background-50 opacity-50 cursor-not-allowed',\n },\n} as const;\n\ninterface TableRowPropsExtended extends TableRowProps {\n variant?: TableVariant;\n clickable?: boolean;\n}\n\nconst TableRow = forwardRef<HTMLTableRowElement, TableRowPropsExtended>(\n (\n {\n variant = 'default',\n state = 'default',\n clickable = false,\n className,\n ...props\n },\n ref\n ) => {\n return (\n <tr\n ref={ref}\n className={cn(\n 'transition-colors',\n state !== 'disabled' ? 'hover:bg-muted/50' : '',\n clickable && state !== 'disabled' ? 'cursor-pointer' : '',\n VARIANT_STATES_ROW[state][variant],\n className\n )}\n aria-disabled={state === 'disabled'}\n {...props}\n />\n );\n }\n);\nTableRow.displayName = 'TableRow';\n\ninterface TableHeadProps extends ThHTMLAttributes<HTMLTableCellElement> {\n /** Enable sorting on this column (default: true) */\n sortable?: boolean;\n /** Current sort direction for this column */\n sortDirection?: SortDirection;\n /** Callback when column header is clicked */\n onSort?: () => void;\n}\n\nconst TableHead = forwardRef<HTMLTableCellElement, TableHeadProps>(\n (\n {\n className,\n sortable = true,\n sortDirection = null,\n onSort,\n children,\n ...props\n },\n ref\n ) => {\n const handleClick = () => {\n if (sortable && onSort) {\n onSort();\n }\n };\n\n return (\n <th\n ref={ref}\n className={cn(\n 'h-10 px-6 py-3.5 text-left align-middle font-bold text-base text-text-800 tracking-[0.2px] leading-none [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px] whitespace-nowrap',\n sortable && 'cursor-pointer select-none hover:bg-muted/30',\n className\n )}\n onClick={handleClick}\n {...props}\n >\n <div className=\"flex items-center gap-2\">\n {children}\n {sortable && (\n <div className=\"flex flex-col\">\n {sortDirection === 'asc' && (\n <CaretUp size={16} weight=\"fill\" className=\"text-text-800\" />\n )}\n {sortDirection === 'desc' && (\n <CaretDown size={16} weight=\"fill\" className=\"text-text-800\" />\n )}\n </div>\n )}\n </div>\n </th>\n );\n }\n);\nTableHead.displayName = 'TableHead';\n\nconst TableCell = forwardRef<\n HTMLTableCellElement,\n TdHTMLAttributes<HTMLTableCellElement>\n>(({ className, ...props }, ref) => (\n <td\n ref={ref}\n className={cn(\n 'p-2 align-middle [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px] text-base font-normal text-text-800 leading-[150%] tracking-normal px-6 py-3.5 whitespace-nowrap',\n className\n )}\n {...props}\n />\n));\nTableCell.displayName = 'TableCell';\n\nconst TableCaption = forwardRef<\n HTMLTableCaptionElement,\n HTMLAttributes<HTMLTableCaptionElement>\n>(({ className, ...props }, ref) => (\n <caption\n ref={ref}\n className={cn(\n 'border-t border-border-200 text-sm text-text-800 px-6 py-3.5',\n className\n )}\n {...props}\n />\n));\nTableCaption.displayName = 'TableCaption';\n\nexport default Table;\nexport {\n TableHeader,\n TableBody,\n TableFooter,\n TableHead,\n TableRow,\n TableCell,\n TableCaption,\n};\n","import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n\nexport { syncDropdownState } from './dropdown';\n\n/**\n * Retorna a cor hexadecimal com opacidade 0.3 (4d) se não estiver em dark mode.\n * Se estiver em dark mode, retorna a cor original.\n *\n * @param hexColor - Cor hexadecimal (ex: \"#0066b8\" ou \"0066b8\")\n * @param isDark - booleano indicando se está em dark mode\n * @returns string - cor hexadecimal com opacidade se necessário\n */\nexport function getSubjectColorWithOpacity(\n hexColor: string | undefined,\n isDark: boolean\n): string | undefined {\n if (!hexColor) return undefined;\n // Remove o '#' se existir\n let color = hexColor.replace(/^#/, '').toLowerCase();\n\n if (isDark) {\n // Se está em dark mode, sempre remove opacidade se existir\n if (color.length === 8) {\n color = color.slice(0, 6);\n }\n return `#${color}`;\n } else {\n // Se não está em dark mode (light mode)\n let resultColor: string;\n if (color.length === 6) {\n // Adiciona opacidade 0.3 (4D) para cores de 6 dígitos\n resultColor = `#${color}4d`;\n } else if (color.length === 8) {\n // Já tem opacidade, retorna como está\n resultColor = `#${color}`;\n } else {\n // Para outros tamanhos (3, 4, 5 dígitos), retorna como está\n resultColor = `#${color}`;\n }\n return resultColor;\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/Table/Table.tsx","../../src/utils/utils.ts"],"sourcesContent":["import {\n forwardRef,\n HTMLAttributes,\n TdHTMLAttributes,\n ThHTMLAttributes,\n useState,\n useMemo,\n useEffect,\n} from 'react';\nimport { cn } from '../../utils/utils';\nimport { CaretUp, CaretDown } from 'phosphor-react';\n\ntype TableVariant = 'default' | 'borderless';\ntype TableRowState = 'default' | 'selected' | 'invalid' | 'disabled';\nexport type SortDirection = 'asc' | 'desc' | null;\n\nexport interface UseTableSortOptions {\n /** Se true, sincroniza o estado de ordenação com os parâmetros da URL */\n syncWithUrl?: boolean;\n}\n\n/**\n * Hook para gerenciar ordenação de dados da tabela\n *\n * @param data - Array de dados a serem ordenados\n * @param options - Opções de configuração do hook\n * @returns Objeto com dados ordenados, coluna/direção atual e função de sort\n *\n * @example\n * ```tsx\n * const activities = [\n * { id: 1, name: 'Task A', date: '2024-01-01' },\n * { id: 2, name: 'Task B', date: '2024-01-02' },\n * ];\n *\n * // Sem sincronização com URL\n * const { sortedData, sortColumn, sortDirection, handleSort } = useTableSort(activities);\n *\n * // Com sincronização com URL\n * const { sortedData, sortColumn, sortDirection, handleSort } = useTableSort(activities, { syncWithUrl: true });\n *\n * <TableHead\n * sortDirection={sortColumn === 'name' ? sortDirection : null}\n * onSort={() => handleSort('name')}\n * >\n * Name\n * </TableHead>\n * ```\n */\nexport function useTableSort<T extends Record<string, unknown>>(\n data: T[],\n options: UseTableSortOptions = {}\n) {\n const { syncWithUrl = false } = options;\n\n // Inicializar estado a partir da URL se syncWithUrl estiver habilitado\n const getInitialState = () => {\n if (!syncWithUrl || globalThis.window === undefined) {\n return { column: null, direction: null };\n }\n\n const params = new URLSearchParams(globalThis.location.search);\n const sortBy = params.get('sortBy');\n const sort = params.get('sort');\n\n if (sortBy && sort && (sort === 'ASC' || sort === 'DESC')) {\n return {\n column: sortBy,\n direction: sort.toLowerCase() as SortDirection,\n };\n }\n\n return { column: null, direction: null };\n };\n\n const initialState = getInitialState();\n const [sortColumn, setSortColumn] = useState<string | null>(\n initialState.column\n );\n const [sortDirection, setSortDirection] = useState<SortDirection>(\n initialState.direction\n );\n\n // Atualizar URL quando o estado de ordenação mudar\n useEffect(() => {\n if (!syncWithUrl || globalThis.window === undefined) return;\n\n const url = new URL(globalThis.location.href);\n const params = url.searchParams;\n\n if (sortColumn && sortDirection) {\n params.set('sortBy', sortColumn);\n params.set('sort', sortDirection.toUpperCase());\n } else {\n params.delete('sortBy');\n params.delete('sort');\n }\n\n // Atualizar URL sem recarregar a página\n globalThis.history.replaceState({}, '', url.toString());\n }, [sortColumn, sortDirection, syncWithUrl]);\n\n const handleSort = (column: string) => {\n if (sortColumn === column) {\n if (sortDirection === 'asc') {\n setSortDirection('desc');\n } else if (sortDirection === 'desc') {\n setSortColumn(null);\n setSortDirection(null);\n }\n } else {\n setSortColumn(column);\n setSortDirection('asc');\n }\n };\n\n const sortedData = useMemo(() => {\n if (!sortColumn || !sortDirection) {\n return data;\n }\n\n return [...data].sort((a, b) => {\n const aValue = a[sortColumn as keyof T];\n const bValue = b[sortColumn as keyof T];\n\n if (typeof aValue === 'string' && typeof bValue === 'string') {\n const comparison = aValue.localeCompare(bValue);\n return sortDirection === 'asc' ? comparison : -comparison;\n }\n\n if (typeof aValue === 'number' && typeof bValue === 'number') {\n return sortDirection === 'asc' ? aValue - bValue : bValue - aValue;\n }\n\n return 0;\n });\n }, [data, sortColumn, sortDirection]);\n\n return { sortedData, sortColumn, sortDirection, handleSort };\n}\n\ninterface TableProps extends HTMLAttributes<HTMLTableElement> {\n variant?: TableVariant;\n}\n\ninterface TableRowProps extends HTMLAttributes<HTMLTableRowElement> {\n state?: TableRowState;\n}\n\nconst Table = forwardRef<HTMLTableElement, TableProps>(\n ({ variant = 'default', className, children, ...props }, ref) => (\n <div\n className={cn(\n 'relative w-full overflow-x-auto',\n variant === 'default' && 'border border-border-200 rounded-xl'\n )}\n >\n <table\n ref={ref}\n className={cn(\n 'analytica-table w-full caption-bottom text-sm border-separate border-spacing-0',\n className\n )}\n {...props}\n >\n {/* Fix Sonnar */}\n <caption className=\"sr-only\">My Table</caption>\n {children}\n </table>\n </div>\n )\n);\n\nTable.displayName = 'Table';\n\nconst TableHeader = forwardRef<\n HTMLTableSectionElement,\n HTMLAttributes<HTMLTableSectionElement>\n>(({ className, ...props }, ref) => (\n <thead\n ref={ref}\n className={cn('[&_tr:first-child]:border-0', className)}\n {...props}\n />\n));\nTableHeader.displayName = 'TableHeader';\n\ninterface TableBodyProps extends HTMLAttributes<HTMLTableSectionElement> {\n variant?: TableVariant;\n}\n\nconst TableBody = forwardRef<HTMLTableSectionElement, TableBodyProps>(\n ({ className, ...props }, ref) => (\n <tbody\n ref={ref}\n className={cn('[&_tr:last-child]:border-border-200', className)}\n {...props}\n />\n )\n);\nTableBody.displayName = 'TableBody';\n\ninterface TableFooterProps extends HTMLAttributes<HTMLTableSectionElement> {\n variant?: TableVariant;\n}\n\nconst TableFooter = forwardRef<HTMLTableSectionElement, TableFooterProps>(\n ({ variant = 'default', className, ...props }, ref) => (\n <tfoot\n ref={ref}\n className={cn(\n 'bg-background-50 font-medium [&>tr]:last:border-b-0 px-6 py-3.5',\n variant === 'default' && 'border-t border-border-200',\n className\n )}\n {...props}\n />\n )\n);\nTableFooter.displayName = 'TableFooter';\n\nconst VARIANT_STATES_ROW = {\n default: {\n default: 'border border-border-200',\n borderless: '',\n },\n selected: {\n default: 'border-b-2 border-indicator-primary',\n borderless: 'bg-indicator-primary/10',\n },\n invalid: {\n default: 'border-b-2 border-indicator-error',\n borderless: 'bg-indicator-error/10',\n },\n disabled: {\n default:\n 'border-b border-border-100 bg-background-50 opacity-50 cursor-not-allowed',\n borderless: 'bg-background-50 opacity-50 cursor-not-allowed',\n },\n} as const;\n\ninterface TableRowPropsExtended extends TableRowProps {\n variant?: TableVariant;\n clickable?: boolean;\n}\n\nconst TableRow = forwardRef<HTMLTableRowElement, TableRowPropsExtended>(\n (\n {\n variant = 'default',\n state = 'default',\n clickable = false,\n className,\n ...props\n },\n ref\n ) => {\n return (\n <tr\n ref={ref}\n className={cn(\n 'transition-colors',\n state !== 'disabled' ? 'hover:bg-muted/50' : '',\n clickable && state !== 'disabled' ? 'cursor-pointer' : '',\n VARIANT_STATES_ROW[state][variant],\n className\n )}\n aria-disabled={state === 'disabled'}\n {...props}\n />\n );\n }\n);\nTableRow.displayName = 'TableRow';\n\ninterface TableHeadProps extends ThHTMLAttributes<HTMLTableCellElement> {\n /** Enable sorting on this column (default: true) */\n sortable?: boolean;\n /** Current sort direction for this column */\n sortDirection?: SortDirection;\n /** Callback when column header is clicked */\n onSort?: () => void;\n}\n\nconst TableHead = forwardRef<HTMLTableCellElement, TableHeadProps>(\n (\n {\n className,\n sortable = true,\n sortDirection = null,\n onSort,\n children,\n ...props\n },\n ref\n ) => {\n const handleClick = () => {\n if (sortable && onSort) {\n onSort();\n }\n };\n\n return (\n <th\n ref={ref}\n className={cn(\n 'h-10 px-6 py-3.5 text-left align-middle font-bold text-base text-text-800 tracking-[0.2px] leading-none [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px] whitespace-nowrap',\n sortable && 'cursor-pointer select-none hover:bg-muted/30',\n className\n )}\n onClick={handleClick}\n {...props}\n >\n <div className=\"flex items-center gap-2\">\n {children}\n {sortable && (\n <div className=\"flex flex-col\">\n {sortDirection === 'asc' && (\n <CaretUp size={16} weight=\"fill\" className=\"text-text-800\" />\n )}\n {sortDirection === 'desc' && (\n <CaretDown size={16} weight=\"fill\" className=\"text-text-800\" />\n )}\n </div>\n )}\n </div>\n </th>\n );\n }\n);\nTableHead.displayName = 'TableHead';\n\nconst TableCell = forwardRef<\n HTMLTableCellElement,\n TdHTMLAttributes<HTMLTableCellElement>\n>(({ className, ...props }, ref) => (\n <td\n ref={ref}\n className={cn(\n 'p-2 align-middle [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px] text-base font-normal text-text-800 leading-[150%] tracking-normal px-6 py-3.5 whitespace-nowrap',\n className\n )}\n {...props}\n />\n));\nTableCell.displayName = 'TableCell';\n\nconst TableCaption = forwardRef<\n HTMLTableCaptionElement,\n HTMLAttributes<HTMLTableCaptionElement>\n>(({ className, ...props }, ref) => (\n <caption\n ref={ref}\n className={cn(\n 'border-t border-border-200 text-sm text-text-800 px-6 py-3.5',\n className\n )}\n {...props}\n />\n));\nTableCaption.displayName = 'TableCaption';\n\nexport default Table;\nexport {\n TableHeader,\n TableBody,\n TableFooter,\n TableHead,\n TableRow,\n TableCell,\n TableCaption,\n};\n","import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n\nexport { syncDropdownState } from './dropdown';\n\n/**\n * Retorna a cor hexadecimal com opacidade 0.3 (4d) se não estiver em dark mode.\n * Se estiver em dark mode, retorna a cor original.\n *\n * @param hexColor - Cor hexadecimal (ex: \"#0066b8\" ou \"0066b8\")\n * @param isDark - booleano indicando se está em dark mode\n * @returns string - cor hexadecimal com opacidade se necessário\n */\nexport function getSubjectColorWithOpacity(\n hexColor: string | undefined,\n isDark: boolean\n): string | undefined {\n if (!hexColor) return undefined;\n // Remove o '#' se existir\n let color = hexColor.replace(/^#/, '').toLowerCase();\n\n if (isDark) {\n // Se está em dark mode, sempre remove opacidade se existir\n if (color.length === 8) {\n color = color.slice(0, 6);\n }\n return `#${color}`;\n } else {\n // Se não está em dark mode (light mode)\n let resultColor: string;\n if (color.length === 6) {\n // Adiciona opacidade 0.3 (4D) para cores de 6 dígitos\n resultColor = `#${color}4d`;\n } else if (color.length === 8) {\n // Já tem opacidade, retorna como está\n resultColor = `#${color}`;\n } else {\n // Para outros tamanhos (3, 4, 5 dígitos), retorna como está\n resultColor = `#${color}`;\n }\n return resultColor;\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/Table/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/Table/Table.tsx","../../src/utils/utils.ts"],"sourcesContent":["import {\n forwardRef,\n HTMLAttributes,\n TdHTMLAttributes,\n ThHTMLAttributes,\n useState,\n useMemo,\n useEffect,\n} from 'react';\nimport { cn } from '../../utils/utils';\nimport { CaretUp, CaretDown } from 'phosphor-react';\n\ntype TableVariant = 'default' | 'borderless';\ntype TableRowState = 'default' | 'selected' | 'invalid' | 'disabled';\nexport type SortDirection = 'asc' | 'desc' | null;\n\ninterface UseTableSortOptions {\n /** Se true, sincroniza o estado de ordenação com os parâmetros da URL */\n syncWithUrl?: boolean;\n}\n\n/**\n * Hook para gerenciar ordenação de dados da tabela\n *\n * @param data - Array de dados a serem ordenados\n * @param options - Opções de configuração do hook\n * @returns Objeto com dados ordenados, coluna/direção atual e função de sort\n *\n * @example\n * ```tsx\n * const activities = [\n * { id: 1, name: 'Task A', date: '2024-01-01' },\n * { id: 2, name: 'Task B', date: '2024-01-02' },\n * ];\n *\n * // Sem sincronização com URL\n * const { sortedData, sortColumn, sortDirection, handleSort } = useTableSort(activities);\n *\n * // Com sincronização com URL\n * const { sortedData, sortColumn, sortDirection, handleSort } = useTableSort(activities, { syncWithUrl: true });\n *\n * <TableHead\n * sortDirection={sortColumn === 'name' ? sortDirection : null}\n * onSort={() => handleSort('name')}\n * >\n * Name\n * </TableHead>\n * ```\n */\nexport function useTableSort<T extends Record<string, unknown>>(\n data: T[],\n options: UseTableSortOptions = {}\n) {\n const { syncWithUrl = false } = options;\n\n // Inicializar estado a partir da URL se syncWithUrl estiver habilitado\n const getInitialState = () => {\n if (!syncWithUrl || globalThis.window === undefined) {\n return { column: null, direction: null };\n }\n\n const params = new URLSearchParams(globalThis.location.search);\n const sortBy = params.get('sortBy');\n const sort = params.get('sort');\n\n if (sortBy && sort && (sort === 'ASC' || sort === 'DESC')) {\n return {\n column: sortBy,\n direction: sort.toLowerCase() as SortDirection,\n };\n }\n\n return { column: null, direction: null };\n };\n\n const initialState = getInitialState();\n const [sortColumn, setSortColumn] = useState<string | null>(\n initialState.column\n );\n const [sortDirection, setSortDirection] = useState<SortDirection>(\n initialState.direction\n );\n\n // Atualizar URL quando o estado de ordenação mudar\n useEffect(() => {\n if (!syncWithUrl || globalThis.window === undefined) return;\n\n const url = new URL(globalThis.location.href);\n const params = url.searchParams;\n\n if (sortColumn && sortDirection) {\n params.set('sortBy', sortColumn);\n params.set('sort', sortDirection.toUpperCase());\n } else {\n params.delete('sortBy');\n params.delete('sort');\n }\n\n // Atualizar URL sem recarregar a página\n globalThis.history.replaceState({}, '', url.toString());\n }, [sortColumn, sortDirection, syncWithUrl]);\n\n const handleSort = (column: string) => {\n if (sortColumn === column) {\n if (sortDirection === 'asc') {\n setSortDirection('desc');\n } else if (sortDirection === 'desc') {\n setSortColumn(null);\n setSortDirection(null);\n }\n } else {\n setSortColumn(column);\n setSortDirection('asc');\n }\n };\n\n const sortedData = useMemo(() => {\n if (!sortColumn || !sortDirection) {\n return data;\n }\n\n return [...data].sort((a, b) => {\n const aValue = a[sortColumn as keyof T];\n const bValue = b[sortColumn as keyof T];\n\n if (typeof aValue === 'string' && typeof bValue === 'string') {\n const comparison = aValue.localeCompare(bValue);\n return sortDirection === 'asc' ? comparison : -comparison;\n }\n\n if (typeof aValue === 'number' && typeof bValue === 'number') {\n return sortDirection === 'asc' ? aValue - bValue : bValue - aValue;\n }\n\n return 0;\n });\n }, [data, sortColumn, sortDirection]);\n\n return { sortedData, sortColumn, sortDirection, handleSort };\n}\n\ninterface TableProps extends HTMLAttributes<HTMLTableElement> {\n variant?: TableVariant;\n}\n\ninterface TableRowProps extends HTMLAttributes<HTMLTableRowElement> {\n state?: TableRowState;\n}\n\nconst Table = forwardRef<HTMLTableElement, TableProps>(\n ({ variant = 'default', className, children, ...props }, ref) => (\n <div\n className={cn(\n 'relative w-full overflow-x-auto',\n variant === 'default' && 'border border-border-200 rounded-xl'\n )}\n >\n <table\n ref={ref}\n className={cn(\n 'analytica-table w-full caption-bottom text-sm border-separate border-spacing-0',\n className\n )}\n {...props}\n >\n {/* Fix Sonnar */}\n <caption className=\"sr-only\">My Table</caption>\n {children}\n </table>\n </div>\n )\n);\n\nTable.displayName = 'Table';\n\nconst TableHeader = forwardRef<\n HTMLTableSectionElement,\n HTMLAttributes<HTMLTableSectionElement>\n>(({ className, ...props }, ref) => (\n <thead\n ref={ref}\n className={cn('[&_tr:first-child]:border-0', className)}\n {...props}\n />\n));\nTableHeader.displayName = 'TableHeader';\n\ninterface TableBodyProps extends HTMLAttributes<HTMLTableSectionElement> {\n variant?: TableVariant;\n}\n\nconst TableBody = forwardRef<HTMLTableSectionElement, TableBodyProps>(\n ({ className, ...props }, ref) => (\n <tbody\n ref={ref}\n className={cn('[&_tr:last-child]:border-border-200', className)}\n {...props}\n />\n )\n);\nTableBody.displayName = 'TableBody';\n\ninterface TableFooterProps extends HTMLAttributes<HTMLTableSectionElement> {\n variant?: TableVariant;\n}\n\nconst TableFooter = forwardRef<HTMLTableSectionElement, TableFooterProps>(\n ({ variant = 'default', className, ...props }, ref) => (\n <tfoot\n ref={ref}\n className={cn(\n 'bg-background-50 font-medium [&>tr]:last:border-b-0 px-6 py-3.5',\n variant === 'default' && 'border-t border-border-200',\n className\n )}\n {...props}\n />\n )\n);\nTableFooter.displayName = 'TableFooter';\n\nconst VARIANT_STATES_ROW = {\n default: {\n default: 'border border-border-200',\n borderless: '',\n },\n selected: {\n default: 'border-b-2 border-indicator-primary',\n borderless: 'bg-indicator-primary/10',\n },\n invalid: {\n default: 'border-b-2 border-indicator-error',\n borderless: 'bg-indicator-error/10',\n },\n disabled: {\n default:\n 'border-b border-border-100 bg-background-50 opacity-50 cursor-not-allowed',\n borderless: 'bg-background-50 opacity-50 cursor-not-allowed',\n },\n} as const;\n\ninterface TableRowPropsExtended extends TableRowProps {\n variant?: TableVariant;\n clickable?: boolean;\n}\n\nconst TableRow = forwardRef<HTMLTableRowElement, TableRowPropsExtended>(\n (\n {\n variant = 'default',\n state = 'default',\n clickable = false,\n className,\n ...props\n },\n ref\n ) => {\n return (\n <tr\n ref={ref}\n className={cn(\n 'transition-colors',\n state !== 'disabled' ? 'hover:bg-muted/50' : '',\n clickable && state !== 'disabled' ? 'cursor-pointer' : '',\n VARIANT_STATES_ROW[state][variant],\n className\n )}\n aria-disabled={state === 'disabled'}\n {...props}\n />\n );\n }\n);\nTableRow.displayName = 'TableRow';\n\ninterface TableHeadProps extends ThHTMLAttributes<HTMLTableCellElement> {\n /** Enable sorting on this column (default: true) */\n sortable?: boolean;\n /** Current sort direction for this column */\n sortDirection?: SortDirection;\n /** Callback when column header is clicked */\n onSort?: () => void;\n}\n\nconst TableHead = forwardRef<HTMLTableCellElement, TableHeadProps>(\n (\n {\n className,\n sortable = true,\n sortDirection = null,\n onSort,\n children,\n ...props\n },\n ref\n ) => {\n const handleClick = () => {\n if (sortable && onSort) {\n onSort();\n }\n };\n\n return (\n <th\n ref={ref}\n className={cn(\n 'h-10 px-6 py-3.5 text-left align-middle font-bold text-base text-text-800 tracking-[0.2px] leading-none [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px] whitespace-nowrap',\n sortable && 'cursor-pointer select-none hover:bg-muted/30',\n className\n )}\n onClick={handleClick}\n {...props}\n >\n <div className=\"flex items-center gap-2\">\n {children}\n {sortable && (\n <div className=\"flex flex-col\">\n {sortDirection === 'asc' && (\n <CaretUp size={16} weight=\"fill\" className=\"text-text-800\" />\n )}\n {sortDirection === 'desc' && (\n <CaretDown size={16} weight=\"fill\" className=\"text-text-800\" />\n )}\n </div>\n )}\n </div>\n </th>\n );\n }\n);\nTableHead.displayName = 'TableHead';\n\nconst TableCell = forwardRef<\n HTMLTableCellElement,\n TdHTMLAttributes<HTMLTableCellElement>\n>(({ className, ...props }, ref) => (\n <td\n ref={ref}\n className={cn(\n 'p-2 align-middle [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px] text-base font-normal text-text-800 leading-[150%] tracking-normal px-6 py-3.5 whitespace-nowrap',\n className\n )}\n {...props}\n />\n));\nTableCell.displayName = 'TableCell';\n\nconst TableCaption = forwardRef<\n HTMLTableCaptionElement,\n HTMLAttributes<HTMLTableCaptionElement>\n>(({ className, ...props }, ref) => (\n <caption\n ref={ref}\n className={cn(\n 'border-t border-border-200 text-sm text-text-800 px-6 py-3.5',\n className\n )}\n {...props}\n />\n));\nTableCaption.displayName = 'TableCaption';\n\nexport default Table;\nexport {\n TableHeader,\n TableBody,\n TableFooter,\n TableHead,\n TableRow,\n TableCell,\n TableCaption,\n};\n","import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n\nexport { syncDropdownState } from './dropdown';\n\n/**\n * Retorna a cor hexadecimal com opacidade 0.3 (4d) se não estiver em dark mode.\n * Se estiver em dark mode, retorna a cor original.\n *\n * @param hexColor - Cor hexadecimal (ex: \"#0066b8\" ou \"0066b8\")\n * @param isDark - booleano indicando se está em dark mode\n * @returns string - cor hexadecimal com opacidade se necessário\n */\nexport function getSubjectColorWithOpacity(\n hexColor: string | undefined,\n isDark: boolean\n): string | undefined {\n if (!hexColor) return undefined;\n // Remove o '#' se existir\n let color = hexColor.replace(/^#/, '').toLowerCase();\n\n if (isDark) {\n // Se está em dark mode, sempre remove opacidade se existir\n if (color.length === 8) {\n color = color.slice(0, 6);\n }\n return `#${color}`;\n } else {\n // Se não está em dark mode (light mode)\n let resultColor: string;\n if (color.length === 6) {\n // Adiciona opacidade 0.3 (4D) para cores de 6 dígitos\n resultColor = `#${color}4d`;\n } else if (color.length === 8) {\n // Já tem opacidade, retorna como está\n resultColor = `#${color}`;\n } else {\n // Para outros tamanhos (3, 4, 5 dígitos), retorna como está\n resultColor = `#${color}`;\n }\n return resultColor;\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/Table/Table.tsx","../../src/utils/utils.ts"],"sourcesContent":["import {\n forwardRef,\n HTMLAttributes,\n TdHTMLAttributes,\n ThHTMLAttributes,\n useState,\n useMemo,\n useEffect,\n} from 'react';\nimport { cn } from '../../utils/utils';\nimport { CaretUp, CaretDown } from 'phosphor-react';\n\ntype TableVariant = 'default' | 'borderless';\ntype TableRowState = 'default' | 'selected' | 'invalid' | 'disabled';\nexport type SortDirection = 'asc' | 'desc' | null;\n\nexport interface UseTableSortOptions {\n /** Se true, sincroniza o estado de ordenação com os parâmetros da URL */\n syncWithUrl?: boolean;\n}\n\n/**\n * Hook para gerenciar ordenação de dados da tabela\n *\n * @param data - Array de dados a serem ordenados\n * @param options - Opções de configuração do hook\n * @returns Objeto com dados ordenados, coluna/direção atual e função de sort\n *\n * @example\n * ```tsx\n * const activities = [\n * { id: 1, name: 'Task A', date: '2024-01-01' },\n * { id: 2, name: 'Task B', date: '2024-01-02' },\n * ];\n *\n * // Sem sincronização com URL\n * const { sortedData, sortColumn, sortDirection, handleSort } = useTableSort(activities);\n *\n * // Com sincronização com URL\n * const { sortedData, sortColumn, sortDirection, handleSort } = useTableSort(activities, { syncWithUrl: true });\n *\n * <TableHead\n * sortDirection={sortColumn === 'name' ? sortDirection : null}\n * onSort={() => handleSort('name')}\n * >\n * Name\n * </TableHead>\n * ```\n */\nexport function useTableSort<T extends Record<string, unknown>>(\n data: T[],\n options: UseTableSortOptions = {}\n) {\n const { syncWithUrl = false } = options;\n\n // Inicializar estado a partir da URL se syncWithUrl estiver habilitado\n const getInitialState = () => {\n if (!syncWithUrl || globalThis.window === undefined) {\n return { column: null, direction: null };\n }\n\n const params = new URLSearchParams(globalThis.location.search);\n const sortBy = params.get('sortBy');\n const sort = params.get('sort');\n\n if (sortBy && sort && (sort === 'ASC' || sort === 'DESC')) {\n return {\n column: sortBy,\n direction: sort.toLowerCase() as SortDirection,\n };\n }\n\n return { column: null, direction: null };\n };\n\n const initialState = getInitialState();\n const [sortColumn, setSortColumn] = useState<string | null>(\n initialState.column\n );\n const [sortDirection, setSortDirection] = useState<SortDirection>(\n initialState.direction\n );\n\n // Atualizar URL quando o estado de ordenação mudar\n useEffect(() => {\n if (!syncWithUrl || globalThis.window === undefined) return;\n\n const url = new URL(globalThis.location.href);\n const params = url.searchParams;\n\n if (sortColumn && sortDirection) {\n params.set('sortBy', sortColumn);\n params.set('sort', sortDirection.toUpperCase());\n } else {\n params.delete('sortBy');\n params.delete('sort');\n }\n\n // Atualizar URL sem recarregar a página\n globalThis.history.replaceState({}, '', url.toString());\n }, [sortColumn, sortDirection, syncWithUrl]);\n\n const handleSort = (column: string) => {\n if (sortColumn === column) {\n if (sortDirection === 'asc') {\n setSortDirection('desc');\n } else if (sortDirection === 'desc') {\n setSortColumn(null);\n setSortDirection(null);\n }\n } else {\n setSortColumn(column);\n setSortDirection('asc');\n }\n };\n\n const sortedData = useMemo(() => {\n if (!sortColumn || !sortDirection) {\n return data;\n }\n\n return [...data].sort((a, b) => {\n const aValue = a[sortColumn as keyof T];\n const bValue = b[sortColumn as keyof T];\n\n if (typeof aValue === 'string' && typeof bValue === 'string') {\n const comparison = aValue.localeCompare(bValue);\n return sortDirection === 'asc' ? comparison : -comparison;\n }\n\n if (typeof aValue === 'number' && typeof bValue === 'number') {\n return sortDirection === 'asc' ? aValue - bValue : bValue - aValue;\n }\n\n return 0;\n });\n }, [data, sortColumn, sortDirection]);\n\n return { sortedData, sortColumn, sortDirection, handleSort };\n}\n\ninterface TableProps extends HTMLAttributes<HTMLTableElement> {\n variant?: TableVariant;\n}\n\ninterface TableRowProps extends HTMLAttributes<HTMLTableRowElement> {\n state?: TableRowState;\n}\n\nconst Table = forwardRef<HTMLTableElement, TableProps>(\n ({ variant = 'default', className, children, ...props }, ref) => (\n <div\n className={cn(\n 'relative w-full overflow-x-auto',\n variant === 'default' && 'border border-border-200 rounded-xl'\n )}\n >\n <table\n ref={ref}\n className={cn(\n 'analytica-table w-full caption-bottom text-sm border-separate border-spacing-0',\n className\n )}\n {...props}\n >\n {/* Fix Sonnar */}\n <caption className=\"sr-only\">My Table</caption>\n {children}\n </table>\n </div>\n )\n);\n\nTable.displayName = 'Table';\n\nconst TableHeader = forwardRef<\n HTMLTableSectionElement,\n HTMLAttributes<HTMLTableSectionElement>\n>(({ className, ...props }, ref) => (\n <thead\n ref={ref}\n className={cn('[&_tr:first-child]:border-0', className)}\n {...props}\n />\n));\nTableHeader.displayName = 'TableHeader';\n\ninterface TableBodyProps extends HTMLAttributes<HTMLTableSectionElement> {\n variant?: TableVariant;\n}\n\nconst TableBody = forwardRef<HTMLTableSectionElement, TableBodyProps>(\n ({ className, ...props }, ref) => (\n <tbody\n ref={ref}\n className={cn('[&_tr:last-child]:border-border-200', className)}\n {...props}\n />\n )\n);\nTableBody.displayName = 'TableBody';\n\ninterface TableFooterProps extends HTMLAttributes<HTMLTableSectionElement> {\n variant?: TableVariant;\n}\n\nconst TableFooter = forwardRef<HTMLTableSectionElement, TableFooterProps>(\n ({ variant = 'default', className, ...props }, ref) => (\n <tfoot\n ref={ref}\n className={cn(\n 'bg-background-50 font-medium [&>tr]:last:border-b-0 px-6 py-3.5',\n variant === 'default' && 'border-t border-border-200',\n className\n )}\n {...props}\n />\n )\n);\nTableFooter.displayName = 'TableFooter';\n\nconst VARIANT_STATES_ROW = {\n default: {\n default: 'border border-border-200',\n borderless: '',\n },\n selected: {\n default: 'border-b-2 border-indicator-primary',\n borderless: 'bg-indicator-primary/10',\n },\n invalid: {\n default: 'border-b-2 border-indicator-error',\n borderless: 'bg-indicator-error/10',\n },\n disabled: {\n default:\n 'border-b border-border-100 bg-background-50 opacity-50 cursor-not-allowed',\n borderless: 'bg-background-50 opacity-50 cursor-not-allowed',\n },\n} as const;\n\ninterface TableRowPropsExtended extends TableRowProps {\n variant?: TableVariant;\n clickable?: boolean;\n}\n\nconst TableRow = forwardRef<HTMLTableRowElement, TableRowPropsExtended>(\n (\n {\n variant = 'default',\n state = 'default',\n clickable = false,\n className,\n ...props\n },\n ref\n ) => {\n return (\n <tr\n ref={ref}\n className={cn(\n 'transition-colors',\n state !== 'disabled' ? 'hover:bg-muted/50' : '',\n clickable && state !== 'disabled' ? 'cursor-pointer' : '',\n VARIANT_STATES_ROW[state][variant],\n className\n )}\n aria-disabled={state === 'disabled'}\n {...props}\n />\n );\n }\n);\nTableRow.displayName = 'TableRow';\n\ninterface TableHeadProps extends ThHTMLAttributes<HTMLTableCellElement> {\n /** Enable sorting on this column (default: true) */\n sortable?: boolean;\n /** Current sort direction for this column */\n sortDirection?: SortDirection;\n /** Callback when column header is clicked */\n onSort?: () => void;\n}\n\nconst TableHead = forwardRef<HTMLTableCellElement, TableHeadProps>(\n (\n {\n className,\n sortable = true,\n sortDirection = null,\n onSort,\n children,\n ...props\n },\n ref\n ) => {\n const handleClick = () => {\n if (sortable && onSort) {\n onSort();\n }\n };\n\n return (\n <th\n ref={ref}\n className={cn(\n 'h-10 px-6 py-3.5 text-left align-middle font-bold text-base text-text-800 tracking-[0.2px] leading-none [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px] whitespace-nowrap',\n sortable && 'cursor-pointer select-none hover:bg-muted/30',\n className\n )}\n onClick={handleClick}\n {...props}\n >\n <div className=\"flex items-center gap-2\">\n {children}\n {sortable && (\n <div className=\"flex flex-col\">\n {sortDirection === 'asc' && (\n <CaretUp size={16} weight=\"fill\" className=\"text-text-800\" />\n )}\n {sortDirection === 'desc' && (\n <CaretDown size={16} weight=\"fill\" className=\"text-text-800\" />\n )}\n </div>\n )}\n </div>\n </th>\n );\n }\n);\nTableHead.displayName = 'TableHead';\n\nconst TableCell = forwardRef<\n HTMLTableCellElement,\n TdHTMLAttributes<HTMLTableCellElement>\n>(({ className, ...props }, ref) => (\n <td\n ref={ref}\n className={cn(\n 'p-2 align-middle [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px] text-base font-normal text-text-800 leading-[150%] tracking-normal px-6 py-3.5 whitespace-nowrap',\n className\n )}\n {...props}\n />\n));\nTableCell.displayName = 'TableCell';\n\nconst TableCaption = forwardRef<\n HTMLTableCaptionElement,\n HTMLAttributes<HTMLTableCaptionElement>\n>(({ className, ...props }, ref) => (\n <caption\n ref={ref}\n className={cn(\n 'border-t border-border-200 text-sm text-text-800 px-6 py-3.5',\n className\n )}\n {...props}\n />\n));\nTableCaption.displayName = 'TableCaption';\n\nexport default Table;\nexport {\n TableHeader,\n TableBody,\n TableFooter,\n TableHead,\n TableRow,\n TableCell,\n TableCaption,\n};\n","import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n\nexport { syncDropdownState } from './dropdown';\n\n/**\n * Retorna a cor hexadecimal com opacidade 0.3 (4d) se não estiver em dark mode.\n * Se estiver em dark mode, retorna a cor original.\n *\n * @param hexColor - Cor hexadecimal (ex: \"#0066b8\" ou \"0066b8\")\n * @param isDark - booleano indicando se está em dark mode\n * @returns string - cor hexadecimal com opacidade se necessário\n */\nexport function getSubjectColorWithOpacity(\n hexColor: string | undefined,\n isDark: boolean\n): string | undefined {\n if (!hexColor) return undefined;\n // Remove o '#' se existir\n let color = hexColor.replace(/^#/, '').toLowerCase();\n\n if (isDark) {\n // Se está em dark mode, sempre remove opacidade se existir\n if (color.length === 8) {\n color = color.slice(0, 6);\n }\n return `#${color}`;\n } else {\n // Se não está em dark mode (light mode)\n let resultColor: string;\n if (color.length === 6) {\n // Adiciona opacidade 0.3 (4D) para cores de 6 dígitos\n resultColor = `#${color}4d`;\n } else if (color.length === 8) {\n // Já tem opacidade, retorna como está\n resultColor = `#${color}`;\n } else {\n // Para outros tamanhos (3, 4, 5 dígitos), retorna como está\n resultColor = `#${color}`;\n }\n return resultColor;\n }\n}\n"],"mappings":";AAAA;AAAA,EACE;AAAA,EAIA;AAAA,EACA;AAAA,EACA;AAAA,OACK;;;ACRP,SAAS,YAA6B;AACtC,SAAS,eAAe;AAEjB,SAAS,MAAM,QAAsB;AAC1C,SAAO,QAAQ,KAAK,MAAM,CAAC;AAC7B;;;ADKA,SAAS,SAAS,iBAAiB;AAmJ7B,SASE,KATF;AA5GC,SAAS,aACd,MACA,UAA+B,CAAC,GAChC;AACA,QAAM,EAAE,cAAc,MAAM,IAAI;AAGhC,QAAM,kBAAkB,MAAM;AAC5B,QAAI,CAAC,eAAe,WAAW,WAAW,QAAW;AACnD,aAAO,EAAE,QAAQ,MAAM,WAAW,KAAK;AAAA,IACzC;AAEA,UAAM,SAAS,IAAI,gBAAgB,WAAW,SAAS,MAAM;AAC7D,UAAM,SAAS,OAAO,IAAI,QAAQ;AAClC,UAAM,OAAO,OAAO,IAAI,MAAM;AAE9B,QAAI,UAAU,SAAS,SAAS,SAAS,SAAS,SAAS;AACzD,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,WAAW,KAAK,YAAY;AAAA,MAC9B;AAAA,IACF;AAEA,WAAO,EAAE,QAAQ,MAAM,WAAW,KAAK;AAAA,EACzC;AAEA,QAAM,eAAe,gBAAgB;AACrC,QAAM,CAAC,YAAY,aAAa,IAAI;AAAA,IAClC,aAAa;AAAA,EACf;AACA,QAAM,CAAC,eAAe,gBAAgB,IAAI;AAAA,IACxC,aAAa;AAAA,EACf;AAGA,YAAU,MAAM;AACd,QAAI,CAAC,eAAe,WAAW,WAAW,OAAW;AAErD,UAAM,MAAM,IAAI,IAAI,WAAW,SAAS,IAAI;AAC5C,UAAM,SAAS,IAAI;AAEnB,QAAI,cAAc,eAAe;AAC/B,aAAO,IAAI,UAAU,UAAU;AAC/B,aAAO,IAAI,QAAQ,cAAc,YAAY,CAAC;AAAA,IAChD,OAAO;AACL,aAAO,OAAO,QAAQ;AACtB,aAAO,OAAO,MAAM;AAAA,IACtB;AAGA,eAAW,QAAQ,aAAa,CAAC,GAAG,IAAI,IAAI,SAAS,CAAC;AAAA,EACxD,GAAG,CAAC,YAAY,eAAe,WAAW,CAAC;AAE3C,QAAM,aAAa,CAAC,WAAmB;AACrC,QAAI,eAAe,QAAQ;AACzB,UAAI,kBAAkB,OAAO;AAC3B,yBAAiB,MAAM;AAAA,MACzB,WAAW,kBAAkB,QAAQ;AACnC,sBAAc,IAAI;AAClB,yBAAiB,IAAI;AAAA,MACvB;AAAA,IACF,OAAO;AACL,oBAAc,MAAM;AACpB,uBAAiB,KAAK;AAAA,IACxB;AAAA,EACF;AAEA,QAAM,aAAa,QAAQ,MAAM;AAC/B,QAAI,CAAC,cAAc,CAAC,eAAe;AACjC,aAAO;AAAA,IACT;AAEA,WAAO,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,MAAM;AAC9B,YAAM,SAAS,EAAE,UAAqB;AACtC,YAAM,SAAS,EAAE,UAAqB;AAEtC,UAAI,OAAO,WAAW,YAAY,OAAO,WAAW,UAAU;AAC5D,cAAM,aAAa,OAAO,cAAc,MAAM;AAC9C,eAAO,kBAAkB,QAAQ,aAAa,CAAC;AAAA,MACjD;AAEA,UAAI,OAAO,WAAW,YAAY,OAAO,WAAW,UAAU;AAC5D,eAAO,kBAAkB,QAAQ,SAAS,SAAS,SAAS;AAAA,MAC9D;AAEA,aAAO;AAAA,IACT,CAAC;AAAA,EACH,GAAG,CAAC,MAAM,YAAY,aAAa,CAAC;AAEpC,SAAO,EAAE,YAAY,YAAY,eAAe,WAAW;AAC7D;AAUA,IAAM,QAAQ;AAAA,EACZ,CAAC,EAAE,UAAU,WAAW,WAAW,UAAU,GAAG,MAAM,GAAG,QACvD;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA,YAAY,aAAa;AAAA,MAC3B;AAAA,MAEA;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA,WAAW;AAAA,YACT;AAAA,YACA;AAAA,UACF;AAAA,UACC,GAAG;AAAA,UAGJ;AAAA,gCAAC,aAAQ,WAAU,WAAU,sBAAQ;AAAA,YACpC;AAAA;AAAA;AAAA,MACH;AAAA;AAAA,EACF;AAEJ;AAEA,MAAM,cAAc;AAEpB,IAAM,cAAc,WAGlB,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,QAC1B;AAAA,EAAC;AAAA;AAAA,IACC;AAAA,IACA,WAAW,GAAG,+BAA+B,SAAS;AAAA,IACrD,GAAG;AAAA;AACN,CACD;AACD,YAAY,cAAc;AAM1B,IAAM,YAAY;AAAA,EAChB,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,QACxB;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,WAAW,GAAG,uCAAuC,SAAS;AAAA,MAC7D,GAAG;AAAA;AAAA,EACN;AAEJ;AACA,UAAU,cAAc;AAMxB,IAAM,cAAc;AAAA,EAClB,CAAC,EAAE,UAAU,WAAW,WAAW,GAAG,MAAM,GAAG,QAC7C;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,WAAW;AAAA,QACT;AAAA,QACA,YAAY,aAAa;AAAA,QACzB;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AACA,YAAY,cAAc;AAE1B,IAAM,qBAAqB;AAAA,EACzB,SAAS;AAAA,IACP,SAAS;AAAA,IACT,YAAY;AAAA,EACd;AAAA,EACA,UAAU;AAAA,IACR,SAAS;AAAA,IACT,YAAY;AAAA,EACd;AAAA,EACA,SAAS;AAAA,IACP,SAAS;AAAA,IACT,YAAY;AAAA,EACd;AAAA,EACA,UAAU;AAAA,IACR,SACE;AAAA,IACF,YAAY;AAAA,EACd;AACF;AAOA,IAAM,WAAW;AAAA,EACf,CACE;AAAA,IACE,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AACH,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,WAAW;AAAA,UACT;AAAA,UACA,UAAU,aAAa,sBAAsB;AAAA,UAC7C,aAAa,UAAU,aAAa,mBAAmB;AAAA,UACvD,mBAAmB,KAAK,EAAE,OAAO;AAAA,UACjC;AAAA,QACF;AAAA,QACA,iBAAe,UAAU;AAAA,QACxB,GAAG;AAAA;AAAA,IACN;AAAA,EAEJ;AACF;AACA,SAAS,cAAc;AAWvB,IAAM,YAAY;AAAA,EAChB,CACE;AAAA,IACE;AAAA,IACA,WAAW;AAAA,IACX,gBAAgB;AAAA,IAChB;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,cAAc,MAAM;AACxB,UAAI,YAAY,QAAQ;AACtB,eAAO;AAAA,MACT;AAAA,IACF;AAEA,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,WAAW;AAAA,UACT;AAAA,UACA,YAAY;AAAA,UACZ;AAAA,QACF;AAAA,QACA,SAAS;AAAA,QACR,GAAG;AAAA,QAEJ,+BAAC,SAAI,WAAU,2BACZ;AAAA;AAAA,UACA,YACC,qBAAC,SAAI,WAAU,iBACZ;AAAA,8BAAkB,SACjB,oBAAC,WAAQ,MAAM,IAAI,QAAO,QAAO,WAAU,iBAAgB;AAAA,YAE5D,kBAAkB,UACjB,oBAAC,aAAU,MAAM,IAAI,QAAO,QAAO,WAAU,iBAAgB;AAAA,aAEjE;AAAA,WAEJ;AAAA;AAAA,IACF;AAAA,EAEJ;AACF;AACA,UAAU,cAAc;AAExB,IAAM,YAAY,WAGhB,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,QAC1B;AAAA,EAAC;AAAA;AAAA,IACC;AAAA,IACA,WAAW;AAAA,MACT;AAAA,MACA;AAAA,IACF;AAAA,IACC,GAAG;AAAA;AACN,CACD;AACD,UAAU,cAAc;AAExB,IAAM,eAAe,WAGnB,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,QAC1B;AAAA,EAAC;AAAA;AAAA,IACC;AAAA,IACA,WAAW;AAAA,MACT;AAAA,MACA;AAAA,IACF;AAAA,IACC,GAAG;AAAA;AACN,CACD;AACD,aAAa,cAAc;AAE3B,IAAO,gBAAQ;","names":[]}
|