analytica-frontend-lib 1.2.7 → 1.2.9
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/Table/index.d.mts +51 -3
- package/dist/Table/index.d.ts +51 -3
- package/dist/Table/index.js +125 -22
- package/dist/Table/index.js.map +1 -1
- package/dist/Table/index.mjs +129 -22
- package/dist/Table/index.mjs.map +1 -1
- package/dist/index.css +55 -16
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +189 -86
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +237 -130
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +55 -16
- package/dist/styles.css.map +1 -1
- package/package.json +1 -1
package/dist/Table/index.d.mts
CHANGED
|
@@ -1,8 +1,47 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import { HTMLAttributes, TdHTMLAttributes } from 'react';
|
|
2
|
+
import { HTMLAttributes, ThHTMLAttributes, TdHTMLAttributes } from 'react';
|
|
3
3
|
|
|
4
4
|
type TableVariant = 'default' | 'borderless';
|
|
5
5
|
type TableRowState = 'default' | 'selected' | 'invalid' | 'disabled';
|
|
6
|
+
type SortDirection = 'asc' | 'desc' | null;
|
|
7
|
+
interface UseTableSortOptions {
|
|
8
|
+
/** Se true, sincroniza o estado de ordenação com os parâmetros da URL */
|
|
9
|
+
syncWithUrl?: boolean;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Hook para gerenciar ordenação de dados da tabela
|
|
13
|
+
*
|
|
14
|
+
* @param data - Array de dados a serem ordenados
|
|
15
|
+
* @param options - Opções de configuração do hook
|
|
16
|
+
* @returns Objeto com dados ordenados, coluna/direção atual e função de sort
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```tsx
|
|
20
|
+
* const activities = [
|
|
21
|
+
* { id: 1, name: 'Task A', date: '2024-01-01' },
|
|
22
|
+
* { id: 2, name: 'Task B', date: '2024-01-02' },
|
|
23
|
+
* ];
|
|
24
|
+
*
|
|
25
|
+
* // Sem sincronização com URL
|
|
26
|
+
* const { sortedData, sortColumn, sortDirection, handleSort } = useTableSort(activities);
|
|
27
|
+
*
|
|
28
|
+
* // Com sincronização com URL
|
|
29
|
+
* const { sortedData, sortColumn, sortDirection, handleSort } = useTableSort(activities, { syncWithUrl: true });
|
|
30
|
+
*
|
|
31
|
+
* <TableHead
|
|
32
|
+
* sortDirection={sortColumn === 'name' ? sortDirection : null}
|
|
33
|
+
* onSort={() => handleSort('name')}
|
|
34
|
+
* >
|
|
35
|
+
* Name
|
|
36
|
+
* </TableHead>
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
declare function useTableSort<T extends Record<string, unknown>>(data: T[], options?: UseTableSortOptions): {
|
|
40
|
+
sortedData: T[];
|
|
41
|
+
sortColumn: string | null;
|
|
42
|
+
sortDirection: SortDirection;
|
|
43
|
+
handleSort: (column: string) => void;
|
|
44
|
+
};
|
|
6
45
|
interface TableProps extends HTMLAttributes<HTMLTableElement> {
|
|
7
46
|
variant?: TableVariant;
|
|
8
47
|
}
|
|
@@ -21,10 +60,19 @@ interface TableFooterProps extends HTMLAttributes<HTMLTableSectionElement> {
|
|
|
21
60
|
declare const TableFooter: react.ForwardRefExoticComponent<TableFooterProps & react.RefAttributes<HTMLTableSectionElement>>;
|
|
22
61
|
interface TableRowPropsExtended extends TableRowProps {
|
|
23
62
|
variant?: TableVariant;
|
|
63
|
+
clickable?: boolean;
|
|
24
64
|
}
|
|
25
65
|
declare const TableRow: react.ForwardRefExoticComponent<TableRowPropsExtended & react.RefAttributes<HTMLTableRowElement>>;
|
|
26
|
-
|
|
66
|
+
interface TableHeadProps extends ThHTMLAttributes<HTMLTableCellElement> {
|
|
67
|
+
/** Enable sorting on this column (default: true) */
|
|
68
|
+
sortable?: boolean;
|
|
69
|
+
/** Current sort direction for this column */
|
|
70
|
+
sortDirection?: SortDirection;
|
|
71
|
+
/** Callback when column header is clicked */
|
|
72
|
+
onSort?: () => void;
|
|
73
|
+
}
|
|
74
|
+
declare const TableHead: react.ForwardRefExoticComponent<TableHeadProps & react.RefAttributes<HTMLTableCellElement>>;
|
|
27
75
|
declare const TableCell: react.ForwardRefExoticComponent<TdHTMLAttributes<HTMLTableCellElement> & react.RefAttributes<HTMLTableCellElement>>;
|
|
28
76
|
declare const TableCaption: react.ForwardRefExoticComponent<HTMLAttributes<HTMLTableCaptionElement> & react.RefAttributes<HTMLTableCaptionElement>>;
|
|
29
77
|
|
|
30
|
-
export { TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Table as default };
|
|
78
|
+
export { type SortDirection, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Table as default, useTableSort };
|
package/dist/Table/index.d.ts
CHANGED
|
@@ -1,8 +1,47 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import { HTMLAttributes, TdHTMLAttributes } from 'react';
|
|
2
|
+
import { HTMLAttributes, ThHTMLAttributes, TdHTMLAttributes } from 'react';
|
|
3
3
|
|
|
4
4
|
type TableVariant = 'default' | 'borderless';
|
|
5
5
|
type TableRowState = 'default' | 'selected' | 'invalid' | 'disabled';
|
|
6
|
+
type SortDirection = 'asc' | 'desc' | null;
|
|
7
|
+
interface UseTableSortOptions {
|
|
8
|
+
/** Se true, sincroniza o estado de ordenação com os parâmetros da URL */
|
|
9
|
+
syncWithUrl?: boolean;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Hook para gerenciar ordenação de dados da tabela
|
|
13
|
+
*
|
|
14
|
+
* @param data - Array de dados a serem ordenados
|
|
15
|
+
* @param options - Opções de configuração do hook
|
|
16
|
+
* @returns Objeto com dados ordenados, coluna/direção atual e função de sort
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```tsx
|
|
20
|
+
* const activities = [
|
|
21
|
+
* { id: 1, name: 'Task A', date: '2024-01-01' },
|
|
22
|
+
* { id: 2, name: 'Task B', date: '2024-01-02' },
|
|
23
|
+
* ];
|
|
24
|
+
*
|
|
25
|
+
* // Sem sincronização com URL
|
|
26
|
+
* const { sortedData, sortColumn, sortDirection, handleSort } = useTableSort(activities);
|
|
27
|
+
*
|
|
28
|
+
* // Com sincronização com URL
|
|
29
|
+
* const { sortedData, sortColumn, sortDirection, handleSort } = useTableSort(activities, { syncWithUrl: true });
|
|
30
|
+
*
|
|
31
|
+
* <TableHead
|
|
32
|
+
* sortDirection={sortColumn === 'name' ? sortDirection : null}
|
|
33
|
+
* onSort={() => handleSort('name')}
|
|
34
|
+
* >
|
|
35
|
+
* Name
|
|
36
|
+
* </TableHead>
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
declare function useTableSort<T extends Record<string, unknown>>(data: T[], options?: UseTableSortOptions): {
|
|
40
|
+
sortedData: T[];
|
|
41
|
+
sortColumn: string | null;
|
|
42
|
+
sortDirection: SortDirection;
|
|
43
|
+
handleSort: (column: string) => void;
|
|
44
|
+
};
|
|
6
45
|
interface TableProps extends HTMLAttributes<HTMLTableElement> {
|
|
7
46
|
variant?: TableVariant;
|
|
8
47
|
}
|
|
@@ -21,10 +60,19 @@ interface TableFooterProps extends HTMLAttributes<HTMLTableSectionElement> {
|
|
|
21
60
|
declare const TableFooter: react.ForwardRefExoticComponent<TableFooterProps & react.RefAttributes<HTMLTableSectionElement>>;
|
|
22
61
|
interface TableRowPropsExtended extends TableRowProps {
|
|
23
62
|
variant?: TableVariant;
|
|
63
|
+
clickable?: boolean;
|
|
24
64
|
}
|
|
25
65
|
declare const TableRow: react.ForwardRefExoticComponent<TableRowPropsExtended & react.RefAttributes<HTMLTableRowElement>>;
|
|
26
|
-
|
|
66
|
+
interface TableHeadProps extends ThHTMLAttributes<HTMLTableCellElement> {
|
|
67
|
+
/** Enable sorting on this column (default: true) */
|
|
68
|
+
sortable?: boolean;
|
|
69
|
+
/** Current sort direction for this column */
|
|
70
|
+
sortDirection?: SortDirection;
|
|
71
|
+
/** Callback when column header is clicked */
|
|
72
|
+
onSort?: () => void;
|
|
73
|
+
}
|
|
74
|
+
declare const TableHead: react.ForwardRefExoticComponent<TableHeadProps & react.RefAttributes<HTMLTableCellElement>>;
|
|
27
75
|
declare const TableCell: react.ForwardRefExoticComponent<TdHTMLAttributes<HTMLTableCellElement> & react.RefAttributes<HTMLTableCellElement>>;
|
|
28
76
|
declare const TableCaption: react.ForwardRefExoticComponent<HTMLAttributes<HTMLTableCaptionElement> & react.RefAttributes<HTMLTableCaptionElement>>;
|
|
29
77
|
|
|
30
|
-
export { TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Table as default };
|
|
78
|
+
export { type SortDirection, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Table as default, useTableSort };
|
package/dist/Table/index.js
CHANGED
|
@@ -27,7 +27,8 @@ __export(Table_exports, {
|
|
|
27
27
|
TableHead: () => TableHead,
|
|
28
28
|
TableHeader: () => TableHeader,
|
|
29
29
|
TableRow: () => TableRow,
|
|
30
|
-
default: () => Table_default
|
|
30
|
+
default: () => Table_default,
|
|
31
|
+
useTableSort: () => useTableSort
|
|
31
32
|
});
|
|
32
33
|
module.exports = __toCommonJS(Table_exports);
|
|
33
34
|
var import_react = require("react");
|
|
@@ -40,20 +41,93 @@ function cn(...inputs) {
|
|
|
40
41
|
}
|
|
41
42
|
|
|
42
43
|
// src/components/Table/Table.tsx
|
|
44
|
+
var import_phosphor_react = require("phosphor-react");
|
|
43
45
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
46
|
+
function useTableSort(data, options = {}) {
|
|
47
|
+
const { syncWithUrl = false } = options;
|
|
48
|
+
const getInitialState = () => {
|
|
49
|
+
if (!syncWithUrl || globalThis.window === void 0) {
|
|
50
|
+
return { column: null, direction: null };
|
|
51
|
+
}
|
|
52
|
+
const params = new URLSearchParams(globalThis.location.search);
|
|
53
|
+
const sortBy = params.get("sortBy");
|
|
54
|
+
const sort = params.get("sort");
|
|
55
|
+
if (sortBy && sort && (sort === "ASC" || sort === "DESC")) {
|
|
56
|
+
return {
|
|
57
|
+
column: sortBy,
|
|
58
|
+
direction: sort.toLowerCase()
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
return { column: null, direction: null };
|
|
62
|
+
};
|
|
63
|
+
const initialState = getInitialState();
|
|
64
|
+
const [sortColumn, setSortColumn] = (0, import_react.useState)(
|
|
65
|
+
initialState.column
|
|
66
|
+
);
|
|
67
|
+
const [sortDirection, setSortDirection] = (0, import_react.useState)(
|
|
68
|
+
initialState.direction
|
|
69
|
+
);
|
|
70
|
+
(0, import_react.useEffect)(() => {
|
|
71
|
+
if (!syncWithUrl || globalThis.window === void 0) return;
|
|
72
|
+
const url = new URL(globalThis.location.href);
|
|
73
|
+
const params = url.searchParams;
|
|
74
|
+
if (sortColumn && sortDirection) {
|
|
75
|
+
params.set("sortBy", sortColumn);
|
|
76
|
+
params.set("sort", sortDirection.toUpperCase());
|
|
77
|
+
} else {
|
|
78
|
+
params.delete("sortBy");
|
|
79
|
+
params.delete("sort");
|
|
80
|
+
}
|
|
81
|
+
globalThis.history.replaceState({}, "", url.toString());
|
|
82
|
+
}, [sortColumn, sortDirection, syncWithUrl]);
|
|
83
|
+
const handleSort = (column) => {
|
|
84
|
+
if (sortColumn === column) {
|
|
85
|
+
if (sortDirection === "asc") {
|
|
86
|
+
setSortDirection("desc");
|
|
87
|
+
} else if (sortDirection === "desc") {
|
|
88
|
+
setSortColumn(null);
|
|
89
|
+
setSortDirection(null);
|
|
90
|
+
}
|
|
91
|
+
} else {
|
|
92
|
+
setSortColumn(column);
|
|
93
|
+
setSortDirection("asc");
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
const sortedData = (0, import_react.useMemo)(() => {
|
|
97
|
+
if (!sortColumn || !sortDirection) {
|
|
98
|
+
return data;
|
|
99
|
+
}
|
|
100
|
+
return [...data].sort((a, b) => {
|
|
101
|
+
const aValue = a[sortColumn];
|
|
102
|
+
const bValue = b[sortColumn];
|
|
103
|
+
if (typeof aValue === "string" && typeof bValue === "string") {
|
|
104
|
+
const comparison = aValue.localeCompare(bValue);
|
|
105
|
+
return sortDirection === "asc" ? comparison : -comparison;
|
|
106
|
+
}
|
|
107
|
+
if (typeof aValue === "number" && typeof bValue === "number") {
|
|
108
|
+
return sortDirection === "asc" ? aValue - bValue : bValue - aValue;
|
|
109
|
+
}
|
|
110
|
+
return 0;
|
|
111
|
+
});
|
|
112
|
+
}, [data, sortColumn, sortDirection]);
|
|
113
|
+
return { sortedData, sortColumn, sortDirection, handleSort };
|
|
114
|
+
}
|
|
44
115
|
var Table = (0, import_react.forwardRef)(
|
|
45
116
|
({ variant = "default", className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
46
117
|
"div",
|
|
47
118
|
{
|
|
48
119
|
className: cn(
|
|
49
|
-
"relative w-full overflow-
|
|
120
|
+
"relative w-full overflow-x-auto",
|
|
50
121
|
variant === "default" && "border border-border-200 rounded-xl"
|
|
51
122
|
),
|
|
52
123
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
53
124
|
"table",
|
|
54
125
|
{
|
|
55
126
|
ref,
|
|
56
|
-
className: cn(
|
|
127
|
+
className: cn(
|
|
128
|
+
"analytica-table w-full caption-bottom text-sm border-separate border-spacing-0",
|
|
129
|
+
className
|
|
130
|
+
),
|
|
57
131
|
...props,
|
|
58
132
|
children: [
|
|
59
133
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("caption", { className: "sr-only", children: "My Table" }),
|
|
@@ -75,15 +149,11 @@ var TableHeader = (0, import_react.forwardRef)(({ className, ...props }, ref) =>
|
|
|
75
149
|
));
|
|
76
150
|
TableHeader.displayName = "TableHeader";
|
|
77
151
|
var TableBody = (0, import_react.forwardRef)(
|
|
78
|
-
({
|
|
152
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
79
153
|
"tbody",
|
|
80
154
|
{
|
|
81
155
|
ref,
|
|
82
|
-
className: cn(
|
|
83
|
-
"[&_tr:last-child]:border-0",
|
|
84
|
-
variant === "default" && "border-t border-border-200",
|
|
85
|
-
className
|
|
86
|
-
),
|
|
156
|
+
className: cn("[&_tr:last-child]:border-border-200", className),
|
|
87
157
|
...props
|
|
88
158
|
}
|
|
89
159
|
)
|
|
@@ -106,7 +176,7 @@ var TableFooter = (0, import_react.forwardRef)(
|
|
|
106
176
|
TableFooter.displayName = "TableFooter";
|
|
107
177
|
var VARIANT_STATES_ROW = {
|
|
108
178
|
default: {
|
|
109
|
-
default: "border
|
|
179
|
+
default: "border border-border-200",
|
|
110
180
|
borderless: ""
|
|
111
181
|
},
|
|
112
182
|
selected: {
|
|
@@ -123,7 +193,13 @@ var VARIANT_STATES_ROW = {
|
|
|
123
193
|
}
|
|
124
194
|
};
|
|
125
195
|
var TableRow = (0, import_react.forwardRef)(
|
|
126
|
-
({
|
|
196
|
+
({
|
|
197
|
+
variant = "default",
|
|
198
|
+
state = "default",
|
|
199
|
+
clickable = false,
|
|
200
|
+
className,
|
|
201
|
+
...props
|
|
202
|
+
}, ref) => {
|
|
127
203
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
128
204
|
"tr",
|
|
129
205
|
{
|
|
@@ -131,6 +207,7 @@ var TableRow = (0, import_react.forwardRef)(
|
|
|
131
207
|
className: cn(
|
|
132
208
|
"transition-colors",
|
|
133
209
|
state !== "disabled" ? "hover:bg-muted/50" : "",
|
|
210
|
+
clickable && state !== "disabled" ? "cursor-pointer" : "",
|
|
134
211
|
VARIANT_STATES_ROW[state][variant],
|
|
135
212
|
className
|
|
136
213
|
),
|
|
@@ -141,24 +218,49 @@ var TableRow = (0, import_react.forwardRef)(
|
|
|
141
218
|
}
|
|
142
219
|
);
|
|
143
220
|
TableRow.displayName = "TableRow";
|
|
144
|
-
var TableHead = (0, import_react.forwardRef)(
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
),
|
|
221
|
+
var TableHead = (0, import_react.forwardRef)(
|
|
222
|
+
({
|
|
223
|
+
className,
|
|
224
|
+
sortable = true,
|
|
225
|
+
sortDirection = null,
|
|
226
|
+
onSort,
|
|
227
|
+
children,
|
|
152
228
|
...props
|
|
229
|
+
}, ref) => {
|
|
230
|
+
const handleClick = () => {
|
|
231
|
+
if (sortable && onSort) {
|
|
232
|
+
onSort();
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
236
|
+
"th",
|
|
237
|
+
{
|
|
238
|
+
ref,
|
|
239
|
+
className: cn(
|
|
240
|
+
"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",
|
|
241
|
+
sortable && "cursor-pointer select-none hover:bg-muted/30",
|
|
242
|
+
className
|
|
243
|
+
),
|
|
244
|
+
onClick: handleClick,
|
|
245
|
+
...props,
|
|
246
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
247
|
+
children,
|
|
248
|
+
sortable && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col", children: [
|
|
249
|
+
sortDirection === "asc" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_phosphor_react.CaretUp, { size: 16, weight: "fill", className: "text-text-800" }),
|
|
250
|
+
sortDirection === "desc" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_phosphor_react.CaretDown, { size: 16, weight: "fill", className: "text-text-800" })
|
|
251
|
+
] })
|
|
252
|
+
] })
|
|
253
|
+
}
|
|
254
|
+
);
|
|
153
255
|
}
|
|
154
|
-
)
|
|
256
|
+
);
|
|
155
257
|
TableHead.displayName = "TableHead";
|
|
156
258
|
var TableCell = (0, import_react.forwardRef)(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
157
259
|
"td",
|
|
158
260
|
{
|
|
159
261
|
ref,
|
|
160
262
|
className: cn(
|
|
161
|
-
"p-2 align-middle [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px] text-
|
|
263
|
+
"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",
|
|
162
264
|
className
|
|
163
265
|
),
|
|
164
266
|
...props
|
|
@@ -186,6 +288,7 @@ var Table_default = Table;
|
|
|
186
288
|
TableFooter,
|
|
187
289
|
TableHead,
|
|
188
290
|
TableHeader,
|
|
189
|
-
TableRow
|
|
291
|
+
TableRow,
|
|
292
|
+
useTableSort
|
|
190
293
|
});
|
|
191
294
|
//# sourceMappingURL=index.js.map
|
package/dist/Table/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/Table/Table.tsx","../../src/utils/utils.ts"],"sourcesContent":["import { forwardRef, HTMLAttributes, TdHTMLAttributes } from 'react';\nimport { cn } from '../../utils/utils';\n\ntype TableVariant = 'default' | 'borderless';\ntype TableRowState = 'default' | 'selected' | 'invalid' | 'disabled';\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-hidden',\n variant === 'default' && 'border border-border-200 rounded-xl'\n )}\n >\n <table\n ref={ref}\n className={cn('w-full caption-bottom text-sm', className)}\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 ({ variant = 'default', className, ...props }, ref) => (\n <tbody\n ref={ref}\n className={cn(\n '[&_tr:last-child]:border-0',\n variant === 'default' && 'border-t border-border-200',\n className\n )}\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-b 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}\n\nconst TableRow = forwardRef<HTMLTableRowElement, TableRowPropsExtended>(\n ({ variant = 'default', state = 'default', className, ...props }, ref) => {\n return (\n <tr\n ref={ref}\n className={cn(\n 'transition-colors',\n state !== 'disabled' ? 'hover:bg-muted/50' : '',\n VARIANT_STATES_ROW[state][variant],\n className\n )}\n aria-disabled={state === 'disabled'}\n {...props}\n />\n );\n }\n);\nTableRow.displayName = 'TableRow';\n\nconst TableHead = forwardRef<\n HTMLTableCellElement,\n TdHTMLAttributes<HTMLTableCellElement>\n>(({ className, ...props }, ref) => (\n <th\n ref={ref}\n className={cn(\n 'h-10 px-6 py-3.5 bg-muted/50 text-left align-middle font-bold text-text-800 [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]',\n className\n )}\n {...props}\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-md text-text-800 px-6 py-3.5',\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\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":[]}
|
package/dist/Table/index.mjs
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
// src/components/Table/Table.tsx
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
forwardRef,
|
|
4
|
+
useState,
|
|
5
|
+
useMemo,
|
|
6
|
+
useEffect
|
|
7
|
+
} from "react";
|
|
3
8
|
|
|
4
9
|
// src/utils/utils.ts
|
|
5
10
|
import { clsx } from "clsx";
|
|
@@ -9,20 +14,93 @@ function cn(...inputs) {
|
|
|
9
14
|
}
|
|
10
15
|
|
|
11
16
|
// src/components/Table/Table.tsx
|
|
17
|
+
import { CaretUp, CaretDown } from "phosphor-react";
|
|
12
18
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
19
|
+
function useTableSort(data, options = {}) {
|
|
20
|
+
const { syncWithUrl = false } = options;
|
|
21
|
+
const getInitialState = () => {
|
|
22
|
+
if (!syncWithUrl || globalThis.window === void 0) {
|
|
23
|
+
return { column: null, direction: null };
|
|
24
|
+
}
|
|
25
|
+
const params = new URLSearchParams(globalThis.location.search);
|
|
26
|
+
const sortBy = params.get("sortBy");
|
|
27
|
+
const sort = params.get("sort");
|
|
28
|
+
if (sortBy && sort && (sort === "ASC" || sort === "DESC")) {
|
|
29
|
+
return {
|
|
30
|
+
column: sortBy,
|
|
31
|
+
direction: sort.toLowerCase()
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
return { column: null, direction: null };
|
|
35
|
+
};
|
|
36
|
+
const initialState = getInitialState();
|
|
37
|
+
const [sortColumn, setSortColumn] = useState(
|
|
38
|
+
initialState.column
|
|
39
|
+
);
|
|
40
|
+
const [sortDirection, setSortDirection] = useState(
|
|
41
|
+
initialState.direction
|
|
42
|
+
);
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
if (!syncWithUrl || globalThis.window === void 0) return;
|
|
45
|
+
const url = new URL(globalThis.location.href);
|
|
46
|
+
const params = url.searchParams;
|
|
47
|
+
if (sortColumn && sortDirection) {
|
|
48
|
+
params.set("sortBy", sortColumn);
|
|
49
|
+
params.set("sort", sortDirection.toUpperCase());
|
|
50
|
+
} else {
|
|
51
|
+
params.delete("sortBy");
|
|
52
|
+
params.delete("sort");
|
|
53
|
+
}
|
|
54
|
+
globalThis.history.replaceState({}, "", url.toString());
|
|
55
|
+
}, [sortColumn, sortDirection, syncWithUrl]);
|
|
56
|
+
const handleSort = (column) => {
|
|
57
|
+
if (sortColumn === column) {
|
|
58
|
+
if (sortDirection === "asc") {
|
|
59
|
+
setSortDirection("desc");
|
|
60
|
+
} else if (sortDirection === "desc") {
|
|
61
|
+
setSortColumn(null);
|
|
62
|
+
setSortDirection(null);
|
|
63
|
+
}
|
|
64
|
+
} else {
|
|
65
|
+
setSortColumn(column);
|
|
66
|
+
setSortDirection("asc");
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
const sortedData = useMemo(() => {
|
|
70
|
+
if (!sortColumn || !sortDirection) {
|
|
71
|
+
return data;
|
|
72
|
+
}
|
|
73
|
+
return [...data].sort((a, b) => {
|
|
74
|
+
const aValue = a[sortColumn];
|
|
75
|
+
const bValue = b[sortColumn];
|
|
76
|
+
if (typeof aValue === "string" && typeof bValue === "string") {
|
|
77
|
+
const comparison = aValue.localeCompare(bValue);
|
|
78
|
+
return sortDirection === "asc" ? comparison : -comparison;
|
|
79
|
+
}
|
|
80
|
+
if (typeof aValue === "number" && typeof bValue === "number") {
|
|
81
|
+
return sortDirection === "asc" ? aValue - bValue : bValue - aValue;
|
|
82
|
+
}
|
|
83
|
+
return 0;
|
|
84
|
+
});
|
|
85
|
+
}, [data, sortColumn, sortDirection]);
|
|
86
|
+
return { sortedData, sortColumn, sortDirection, handleSort };
|
|
87
|
+
}
|
|
13
88
|
var Table = forwardRef(
|
|
14
89
|
({ variant = "default", className, children, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
15
90
|
"div",
|
|
16
91
|
{
|
|
17
92
|
className: cn(
|
|
18
|
-
"relative w-full overflow-
|
|
93
|
+
"relative w-full overflow-x-auto",
|
|
19
94
|
variant === "default" && "border border-border-200 rounded-xl"
|
|
20
95
|
),
|
|
21
96
|
children: /* @__PURE__ */ jsxs(
|
|
22
97
|
"table",
|
|
23
98
|
{
|
|
24
99
|
ref,
|
|
25
|
-
className: cn(
|
|
100
|
+
className: cn(
|
|
101
|
+
"analytica-table w-full caption-bottom text-sm border-separate border-spacing-0",
|
|
102
|
+
className
|
|
103
|
+
),
|
|
26
104
|
...props,
|
|
27
105
|
children: [
|
|
28
106
|
/* @__PURE__ */ jsx("caption", { className: "sr-only", children: "My Table" }),
|
|
@@ -44,15 +122,11 @@ var TableHeader = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ j
|
|
|
44
122
|
));
|
|
45
123
|
TableHeader.displayName = "TableHeader";
|
|
46
124
|
var TableBody = forwardRef(
|
|
47
|
-
({
|
|
125
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
48
126
|
"tbody",
|
|
49
127
|
{
|
|
50
128
|
ref,
|
|
51
|
-
className: cn(
|
|
52
|
-
"[&_tr:last-child]:border-0",
|
|
53
|
-
variant === "default" && "border-t border-border-200",
|
|
54
|
-
className
|
|
55
|
-
),
|
|
129
|
+
className: cn("[&_tr:last-child]:border-border-200", className),
|
|
56
130
|
...props
|
|
57
131
|
}
|
|
58
132
|
)
|
|
@@ -75,7 +149,7 @@ var TableFooter = forwardRef(
|
|
|
75
149
|
TableFooter.displayName = "TableFooter";
|
|
76
150
|
var VARIANT_STATES_ROW = {
|
|
77
151
|
default: {
|
|
78
|
-
default: "border
|
|
152
|
+
default: "border border-border-200",
|
|
79
153
|
borderless: ""
|
|
80
154
|
},
|
|
81
155
|
selected: {
|
|
@@ -92,7 +166,13 @@ var VARIANT_STATES_ROW = {
|
|
|
92
166
|
}
|
|
93
167
|
};
|
|
94
168
|
var TableRow = forwardRef(
|
|
95
|
-
({
|
|
169
|
+
({
|
|
170
|
+
variant = "default",
|
|
171
|
+
state = "default",
|
|
172
|
+
clickable = false,
|
|
173
|
+
className,
|
|
174
|
+
...props
|
|
175
|
+
}, ref) => {
|
|
96
176
|
return /* @__PURE__ */ jsx(
|
|
97
177
|
"tr",
|
|
98
178
|
{
|
|
@@ -100,6 +180,7 @@ var TableRow = forwardRef(
|
|
|
100
180
|
className: cn(
|
|
101
181
|
"transition-colors",
|
|
102
182
|
state !== "disabled" ? "hover:bg-muted/50" : "",
|
|
183
|
+
clickable && state !== "disabled" ? "cursor-pointer" : "",
|
|
103
184
|
VARIANT_STATES_ROW[state][variant],
|
|
104
185
|
className
|
|
105
186
|
),
|
|
@@ -110,24 +191,49 @@ var TableRow = forwardRef(
|
|
|
110
191
|
}
|
|
111
192
|
);
|
|
112
193
|
TableRow.displayName = "TableRow";
|
|
113
|
-
var TableHead = forwardRef(
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
),
|
|
194
|
+
var TableHead = forwardRef(
|
|
195
|
+
({
|
|
196
|
+
className,
|
|
197
|
+
sortable = true,
|
|
198
|
+
sortDirection = null,
|
|
199
|
+
onSort,
|
|
200
|
+
children,
|
|
121
201
|
...props
|
|
202
|
+
}, ref) => {
|
|
203
|
+
const handleClick = () => {
|
|
204
|
+
if (sortable && onSort) {
|
|
205
|
+
onSort();
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
return /* @__PURE__ */ jsx(
|
|
209
|
+
"th",
|
|
210
|
+
{
|
|
211
|
+
ref,
|
|
212
|
+
className: cn(
|
|
213
|
+
"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",
|
|
214
|
+
sortable && "cursor-pointer select-none hover:bg-muted/30",
|
|
215
|
+
className
|
|
216
|
+
),
|
|
217
|
+
onClick: handleClick,
|
|
218
|
+
...props,
|
|
219
|
+
children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
220
|
+
children,
|
|
221
|
+
sortable && /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
|
|
222
|
+
sortDirection === "asc" && /* @__PURE__ */ jsx(CaretUp, { size: 16, weight: "fill", className: "text-text-800" }),
|
|
223
|
+
sortDirection === "desc" && /* @__PURE__ */ jsx(CaretDown, { size: 16, weight: "fill", className: "text-text-800" })
|
|
224
|
+
] })
|
|
225
|
+
] })
|
|
226
|
+
}
|
|
227
|
+
);
|
|
122
228
|
}
|
|
123
|
-
)
|
|
229
|
+
);
|
|
124
230
|
TableHead.displayName = "TableHead";
|
|
125
231
|
var TableCell = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
126
232
|
"td",
|
|
127
233
|
{
|
|
128
234
|
ref,
|
|
129
235
|
className: cn(
|
|
130
|
-
"p-2 align-middle [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px] text-
|
|
236
|
+
"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",
|
|
131
237
|
className
|
|
132
238
|
),
|
|
133
239
|
...props
|
|
@@ -155,6 +261,7 @@ export {
|
|
|
155
261
|
TableHead,
|
|
156
262
|
TableHeader,
|
|
157
263
|
TableRow,
|
|
158
|
-
Table_default as default
|
|
264
|
+
Table_default as default,
|
|
265
|
+
useTableSort
|
|
159
266
|
};
|
|
160
267
|
//# sourceMappingURL=index.mjs.map
|