@itilite/lumina-ui 1.0.6-alpha → 1.0.7-alpha
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-DNvoh2P8.d.mts +127 -0
- package/dist/Table-DNvoh2P8.d.ts +127 -0
- package/dist/atom/Table/Table.d.mts +1 -1
- package/dist/atom/Table/Table.d.ts +1 -1
- package/dist/atom/Table/Table.js +15 -20
- package/dist/atom/Table/Table.mjs +1 -1
- package/dist/chunk-DXPVJNGY.mjs +284 -0
- package/dist/chunk-G4P6XGQX.mjs +278 -0
- package/dist/chunk-I6GLPWHS.mjs +278 -0
- package/dist/chunk-J5JDQ4R6.mjs +278 -0
- package/dist/chunk-X3NDICAU.mjs +284 -0
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +15 -20
- package/dist/index.mjs +13 -13
- package/dist/styles.css +297 -304
- package/package.json +1 -1
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { TableProps as TableProps$1, TablePaginationConfig } from 'antd';
|
|
3
|
+
|
|
4
|
+
type SortOrder = "ascend" | "descend" | undefined;
|
|
5
|
+
type AntColumnType<RecordType> = NonNullable<TableProps$1<RecordType>["columns"]>[number];
|
|
6
|
+
/**
|
|
7
|
+
* Header icon configuration added to any column definition.
|
|
8
|
+
* The Table component reads these props and renders sort/filter icons automatically.
|
|
9
|
+
*/
|
|
10
|
+
interface LuminaColumnHeaderProps {
|
|
11
|
+
/** Show sort icon. Clicking cycles: undefined (↑↓) → ascend (↑) → descend (↓) → undefined */
|
|
12
|
+
sortable?: boolean;
|
|
13
|
+
/** Current sort direction. Provide to make sort controlled. */
|
|
14
|
+
sortOrder?: SortOrder;
|
|
15
|
+
/** Called when the user clicks the sort icon. */
|
|
16
|
+
onSortChange?: (order: SortOrder) => void;
|
|
17
|
+
/**
|
|
18
|
+
* Custom sort icon. This MUST be provided if sortable is true.
|
|
19
|
+
* If omitted, no icon will be rendered.
|
|
20
|
+
*/
|
|
21
|
+
sortIcon?: React.ReactNode;
|
|
22
|
+
/** > 0 turns the filter icon red and shows a count badge. */
|
|
23
|
+
filterCount?: number;
|
|
24
|
+
/**
|
|
25
|
+
* Custom filter icon. This MUST be provided if filterContent is present.
|
|
26
|
+
* If omitted, no icon will be rendered.
|
|
27
|
+
*/
|
|
28
|
+
filterIcon?: React.ReactNode;
|
|
29
|
+
/**
|
|
30
|
+
* Filter dropdown content from the consumer.
|
|
31
|
+
* Providing this prop renders the filter icon button.
|
|
32
|
+
* Clicking the icon toggles visibility of this content.
|
|
33
|
+
*/
|
|
34
|
+
filterContent?: React.ReactNode;
|
|
35
|
+
/** Optional class name to apply to the header label. */
|
|
36
|
+
className?: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* AntD ColumnType extended with optional `headerProps` for Lumina sort/filter icons.
|
|
40
|
+
*/
|
|
41
|
+
type LuminaColumnType<RecordType = any> = AntColumnType<RecordType> & {
|
|
42
|
+
headerProps?: LuminaColumnHeaderProps;
|
|
43
|
+
};
|
|
44
|
+
type LuminaColumnsType<RecordType = any> = LuminaColumnType<RecordType>[];
|
|
45
|
+
interface TableProps<RecordType = any> extends Omit<TableProps$1<RecordType>, "size" | "bordered" | "pagination" | "columns"> {
|
|
46
|
+
/**
|
|
47
|
+
* Lumina UI table variant.
|
|
48
|
+
* - `default` – standard table
|
|
49
|
+
* - `selectable` – checkbox rows; clicking any row toggles its checkbox
|
|
50
|
+
*/
|
|
51
|
+
variant?: "default" | "selectable";
|
|
52
|
+
/** If true, strips outer card chrome to fit inside an Accordion parent. */
|
|
53
|
+
isAccordion?: boolean;
|
|
54
|
+
/** If true, strips outer card chrome to fit inside a Toolbar/Container parent. */
|
|
55
|
+
isToolbar?: boolean;
|
|
56
|
+
/** Table size. Defaults to 'middle'. */
|
|
57
|
+
size?: "small" | "middle" | "large";
|
|
58
|
+
/** Extra class applied on the outermost wrapper div. */
|
|
59
|
+
className?: string;
|
|
60
|
+
/** AntD pagination config. Pass `false` to hide pagination. */
|
|
61
|
+
pagination?: TablePaginationConfig | boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Column definitions. Add `headerProps` to any column to get sort/filter icons
|
|
64
|
+
* rendered automatically in the column header.
|
|
65
|
+
*/
|
|
66
|
+
columns?: LuminaColumnsType<RecordType>;
|
|
67
|
+
/** Total number of items in the dataset (for server-side pagination). */
|
|
68
|
+
total?: number;
|
|
69
|
+
/** Current page number (1-indexed). */
|
|
70
|
+
current?: number;
|
|
71
|
+
/** Number of rows per page. */
|
|
72
|
+
pageSize?: number;
|
|
73
|
+
/** Called when the page or page size changes. */
|
|
74
|
+
onPaginationChange?: TablePaginationConfig["onChange"];
|
|
75
|
+
/**
|
|
76
|
+
* Custom content to show when the table has no data.
|
|
77
|
+
* If provided, it overrides the default Ant Design "No Data" view.
|
|
78
|
+
*/
|
|
79
|
+
emptyState?: React.ReactNode;
|
|
80
|
+
/**
|
|
81
|
+
* If true, the table header (the row with column labels) will be hidden.
|
|
82
|
+
* Useful during loading or for specific visual variants.
|
|
83
|
+
*/
|
|
84
|
+
hideHeader?: boolean;
|
|
85
|
+
/**
|
|
86
|
+
* Custom loading indicator (e.g. a spinner or skeleton).
|
|
87
|
+
* If provided, this will be rendered when the table is in a loading state.
|
|
88
|
+
*/
|
|
89
|
+
loadingIndicator?: React.ReactElement;
|
|
90
|
+
/** Extra class applied to header cells (th). */
|
|
91
|
+
headerCellClassName?: string;
|
|
92
|
+
/** Extra class applied to body cells (td). */
|
|
93
|
+
bodyCellClassName?: string;
|
|
94
|
+
/** Custom class name for rows. Can be a string or function. */
|
|
95
|
+
rowClassName?: string | ((record: RecordType, index: number) => string);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Lumina Table component.
|
|
100
|
+
*
|
|
101
|
+
* Variants:
|
|
102
|
+
* - `default` – standalone table card with rounded border
|
|
103
|
+
* - `hover` – row highlight on mouse-over
|
|
104
|
+
* - `selectable` – use with `rowSelection`; clicking any row toggles its checkbox
|
|
105
|
+
* - `accordion-child` – strips outer card chrome; place inside your own accordion wrapper
|
|
106
|
+
* - `toolbar-child` – strips outer card chrome; place inside your own toolbar/container wrapper
|
|
107
|
+
*
|
|
108
|
+
* Column header icons — add `headerProps` to any column definition:
|
|
109
|
+
* ```tsx
|
|
110
|
+
* columns={[{
|
|
111
|
+
* key: "name", dataIndex: "name", title: "Name",
|
|
112
|
+
* headerProps: {
|
|
113
|
+
* sortable: true,
|
|
114
|
+
* sortOrder: sortOrders.name,
|
|
115
|
+
* onSortChange: (order) => setSortOrders(prev => ({ ...prev, name: order })),
|
|
116
|
+
* filterCount: activeFilters.name ?? 0,
|
|
117
|
+
* filterContent: <MyFilterPanel />,
|
|
118
|
+
* },
|
|
119
|
+
* }]}
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
122
|
+
declare function Table<RecordType extends object = any>(props: TableProps<RecordType>): React.JSX.Element;
|
|
123
|
+
declare namespace Table {
|
|
124
|
+
var displayName: string;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export { type LuminaColumnHeaderProps as L, type SortOrder as S, Table as T, type LuminaColumnType as a, type LuminaColumnsType as b, type TableProps as c };
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { TableProps as TableProps$1, TablePaginationConfig } from 'antd';
|
|
3
|
+
|
|
4
|
+
type SortOrder = "ascend" | "descend" | undefined;
|
|
5
|
+
type AntColumnType<RecordType> = NonNullable<TableProps$1<RecordType>["columns"]>[number];
|
|
6
|
+
/**
|
|
7
|
+
* Header icon configuration added to any column definition.
|
|
8
|
+
* The Table component reads these props and renders sort/filter icons automatically.
|
|
9
|
+
*/
|
|
10
|
+
interface LuminaColumnHeaderProps {
|
|
11
|
+
/** Show sort icon. Clicking cycles: undefined (↑↓) → ascend (↑) → descend (↓) → undefined */
|
|
12
|
+
sortable?: boolean;
|
|
13
|
+
/** Current sort direction. Provide to make sort controlled. */
|
|
14
|
+
sortOrder?: SortOrder;
|
|
15
|
+
/** Called when the user clicks the sort icon. */
|
|
16
|
+
onSortChange?: (order: SortOrder) => void;
|
|
17
|
+
/**
|
|
18
|
+
* Custom sort icon. This MUST be provided if sortable is true.
|
|
19
|
+
* If omitted, no icon will be rendered.
|
|
20
|
+
*/
|
|
21
|
+
sortIcon?: React.ReactNode;
|
|
22
|
+
/** > 0 turns the filter icon red and shows a count badge. */
|
|
23
|
+
filterCount?: number;
|
|
24
|
+
/**
|
|
25
|
+
* Custom filter icon. This MUST be provided if filterContent is present.
|
|
26
|
+
* If omitted, no icon will be rendered.
|
|
27
|
+
*/
|
|
28
|
+
filterIcon?: React.ReactNode;
|
|
29
|
+
/**
|
|
30
|
+
* Filter dropdown content from the consumer.
|
|
31
|
+
* Providing this prop renders the filter icon button.
|
|
32
|
+
* Clicking the icon toggles visibility of this content.
|
|
33
|
+
*/
|
|
34
|
+
filterContent?: React.ReactNode;
|
|
35
|
+
/** Optional class name to apply to the header label. */
|
|
36
|
+
className?: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* AntD ColumnType extended with optional `headerProps` for Lumina sort/filter icons.
|
|
40
|
+
*/
|
|
41
|
+
type LuminaColumnType<RecordType = any> = AntColumnType<RecordType> & {
|
|
42
|
+
headerProps?: LuminaColumnHeaderProps;
|
|
43
|
+
};
|
|
44
|
+
type LuminaColumnsType<RecordType = any> = LuminaColumnType<RecordType>[];
|
|
45
|
+
interface TableProps<RecordType = any> extends Omit<TableProps$1<RecordType>, "size" | "bordered" | "pagination" | "columns"> {
|
|
46
|
+
/**
|
|
47
|
+
* Lumina UI table variant.
|
|
48
|
+
* - `default` – standard table
|
|
49
|
+
* - `selectable` – checkbox rows; clicking any row toggles its checkbox
|
|
50
|
+
*/
|
|
51
|
+
variant?: "default" | "selectable";
|
|
52
|
+
/** If true, strips outer card chrome to fit inside an Accordion parent. */
|
|
53
|
+
isAccordion?: boolean;
|
|
54
|
+
/** If true, strips outer card chrome to fit inside a Toolbar/Container parent. */
|
|
55
|
+
isToolbar?: boolean;
|
|
56
|
+
/** Table size. Defaults to 'middle'. */
|
|
57
|
+
size?: "small" | "middle" | "large";
|
|
58
|
+
/** Extra class applied on the outermost wrapper div. */
|
|
59
|
+
className?: string;
|
|
60
|
+
/** AntD pagination config. Pass `false` to hide pagination. */
|
|
61
|
+
pagination?: TablePaginationConfig | boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Column definitions. Add `headerProps` to any column to get sort/filter icons
|
|
64
|
+
* rendered automatically in the column header.
|
|
65
|
+
*/
|
|
66
|
+
columns?: LuminaColumnsType<RecordType>;
|
|
67
|
+
/** Total number of items in the dataset (for server-side pagination). */
|
|
68
|
+
total?: number;
|
|
69
|
+
/** Current page number (1-indexed). */
|
|
70
|
+
current?: number;
|
|
71
|
+
/** Number of rows per page. */
|
|
72
|
+
pageSize?: number;
|
|
73
|
+
/** Called when the page or page size changes. */
|
|
74
|
+
onPaginationChange?: TablePaginationConfig["onChange"];
|
|
75
|
+
/**
|
|
76
|
+
* Custom content to show when the table has no data.
|
|
77
|
+
* If provided, it overrides the default Ant Design "No Data" view.
|
|
78
|
+
*/
|
|
79
|
+
emptyState?: React.ReactNode;
|
|
80
|
+
/**
|
|
81
|
+
* If true, the table header (the row with column labels) will be hidden.
|
|
82
|
+
* Useful during loading or for specific visual variants.
|
|
83
|
+
*/
|
|
84
|
+
hideHeader?: boolean;
|
|
85
|
+
/**
|
|
86
|
+
* Custom loading indicator (e.g. a spinner or skeleton).
|
|
87
|
+
* If provided, this will be rendered when the table is in a loading state.
|
|
88
|
+
*/
|
|
89
|
+
loadingIndicator?: React.ReactElement;
|
|
90
|
+
/** Extra class applied to header cells (th). */
|
|
91
|
+
headerCellClassName?: string;
|
|
92
|
+
/** Extra class applied to body cells (td). */
|
|
93
|
+
bodyCellClassName?: string;
|
|
94
|
+
/** Custom class name for rows. Can be a string or function. */
|
|
95
|
+
rowClassName?: string | ((record: RecordType, index: number) => string);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Lumina Table component.
|
|
100
|
+
*
|
|
101
|
+
* Variants:
|
|
102
|
+
* - `default` – standalone table card with rounded border
|
|
103
|
+
* - `hover` – row highlight on mouse-over
|
|
104
|
+
* - `selectable` – use with `rowSelection`; clicking any row toggles its checkbox
|
|
105
|
+
* - `accordion-child` – strips outer card chrome; place inside your own accordion wrapper
|
|
106
|
+
* - `toolbar-child` – strips outer card chrome; place inside your own toolbar/container wrapper
|
|
107
|
+
*
|
|
108
|
+
* Column header icons — add `headerProps` to any column definition:
|
|
109
|
+
* ```tsx
|
|
110
|
+
* columns={[{
|
|
111
|
+
* key: "name", dataIndex: "name", title: "Name",
|
|
112
|
+
* headerProps: {
|
|
113
|
+
* sortable: true,
|
|
114
|
+
* sortOrder: sortOrders.name,
|
|
115
|
+
* onSortChange: (order) => setSortOrders(prev => ({ ...prev, name: order })),
|
|
116
|
+
* filterCount: activeFilters.name ?? 0,
|
|
117
|
+
* filterContent: <MyFilterPanel />,
|
|
118
|
+
* },
|
|
119
|
+
* }]}
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
122
|
+
declare function Table<RecordType extends object = any>(props: TableProps<RecordType>): React.JSX.Element;
|
|
123
|
+
declare namespace Table {
|
|
124
|
+
var displayName: string;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export { type LuminaColumnHeaderProps as L, type SortOrder as S, Table as T, type LuminaColumnType as a, type LuminaColumnsType as b, type TableProps as c };
|
package/dist/atom/Table/Table.js
CHANGED
|
@@ -68,7 +68,7 @@ var import_antd = require("antd");
|
|
|
68
68
|
var import_clsx = __toESM(require("clsx"));
|
|
69
69
|
|
|
70
70
|
// src/atom/Table/Table.module.scss
|
|
71
|
-
var Table_module_default = { "tableWrapper": "Table-module__tableWrapper___3cqiD", "isAccordion": "Table-module__isAccordion___-uIs6", "isToolbar": "Table-module__isToolbar___LdS-m", "hasCustomHeaderCell": "Table-module__hasCustomHeaderCell___AtCk8", "table": "Table-module__table___5d7g0", "
|
|
71
|
+
var Table_module_default = { "tableWrapper": "Table-module__tableWrapper___3cqiD", "isAccordion": "Table-module__isAccordion___-uIs6", "isToolbar": "Table-module__isToolbar___LdS-m", "hasCustomHeaderCell": "Table-module__hasCustomHeaderCell___AtCk8", "table": "Table-module__table___5d7g0", "ant-table-selection-column": "Table-module__ant-table-selection-column___H9vtu", "hasCustomBodyCell": "Table-module__hasCustomBodyCell___sf8j8", "firstRow": "Table-module__firstRow___Xq-Hi", "lastRow": "Table-module__lastRow___ahv4g", "showHoverEffect": "Table-module__showHoverEffect___IyKyO", "columnHeader": "Table-module__columnHeader___Unr6d", "columnHeaderLeft": "Table-module__columnHeaderLeft___mp7pK", "columnHeaderSortArea": "Table-module__columnHeaderSortArea___jrIYo", "columnHeaderLabel": "Table-module__columnHeaderLabel___A-mRu", "columnHeaderSortIcon": "Table-module__columnHeaderSortIcon___mWVZN", "columnHeaderSortIconActive": "Table-module__columnHeaderSortIconActive___wHAqC", "columnHeaderFilterWrapper": "Table-module__columnHeaderFilterWrapper___DnSve", "columnHeaderFilterBtn": "Table-module__columnHeaderFilterBtn___NR7DY", "columnHeaderFilterBtnActive": "Table-module__columnHeaderFilterBtnActive___JdO11", "columnHeaderFilterBadge": "Table-module__columnHeaderFilterBadge___-Q2T2", "columnHeaderFilterDropdown": "Table-module__columnHeaderFilterDropdown___M-fD4" };
|
|
72
72
|
|
|
73
73
|
// src/atom/Table/Table.tsx
|
|
74
74
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
@@ -218,8 +218,7 @@ function Table(props) {
|
|
|
218
218
|
style,
|
|
219
219
|
headerCellClassName,
|
|
220
220
|
bodyCellClassName,
|
|
221
|
-
rowClassName
|
|
222
|
-
rowSpacing
|
|
221
|
+
rowClassName
|
|
223
222
|
} = _a, rest = __objRest(_a, [
|
|
224
223
|
"size",
|
|
225
224
|
"variant",
|
|
@@ -243,8 +242,7 @@ function Table(props) {
|
|
|
243
242
|
"style",
|
|
244
243
|
"headerCellClassName",
|
|
245
244
|
"bodyCellClassName",
|
|
246
|
-
"rowClassName"
|
|
247
|
-
"rowSpacing"
|
|
245
|
+
"rowClassName"
|
|
248
246
|
]);
|
|
249
247
|
const isChildVariant = isAccordion || isToolbar;
|
|
250
248
|
const resolvedPagination = buildPagination(pagination, {
|
|
@@ -257,8 +255,14 @@ function Table(props) {
|
|
|
257
255
|
() => processColumns(columns, headerCellClassName, bodyCellClassName),
|
|
258
256
|
[columns, headerCellClassName, bodyCellClassName]
|
|
259
257
|
);
|
|
258
|
+
const resolvedRowSelection = React.useMemo(() => {
|
|
259
|
+
if (!rowSelection) return void 0;
|
|
260
|
+
return __spreadValues({
|
|
261
|
+
columnWidth: 48
|
|
262
|
+
}, rowSelection);
|
|
263
|
+
}, [rowSelection]);
|
|
260
264
|
const resolvedOnRow = React.useMemo(() => {
|
|
261
|
-
const onChange =
|
|
265
|
+
const onChange = resolvedRowSelection == null ? void 0 : resolvedRowSelection.onChange;
|
|
262
266
|
if (variant !== "selectable" || !onChange) return onRow;
|
|
263
267
|
return (record, index) => {
|
|
264
268
|
var _a2;
|
|
@@ -270,7 +274,7 @@ function Table(props) {
|
|
|
270
274
|
var _a3, _b2;
|
|
271
275
|
(_a3 = base.onClick) == null ? void 0 : _a3.call(base, e);
|
|
272
276
|
const key = getKey(record, index);
|
|
273
|
-
const current2 = (_b2 =
|
|
277
|
+
const current2 = (_b2 = resolvedRowSelection.selectedRowKeys) != null ? _b2 : [];
|
|
274
278
|
const isSelected = current2.some((k) => k === key);
|
|
275
279
|
const newKeys = isSelected ? current2.filter((k) => k !== key) : [...current2, key];
|
|
276
280
|
const newRows = (dataSource != null ? dataSource : []).filter(
|
|
@@ -280,15 +284,7 @@ function Table(props) {
|
|
|
280
284
|
}
|
|
281
285
|
});
|
|
282
286
|
};
|
|
283
|
-
}, [variant,
|
|
284
|
-
const hasRowSpacing = rowSpacing !== void 0;
|
|
285
|
-
const rowSpacingValue = typeof rowSpacing === "number" ? `${rowSpacing}px` : rowSpacing;
|
|
286
|
-
const wrapperStyle = React.useMemo(() => {
|
|
287
|
-
if (!hasRowSpacing) return style;
|
|
288
|
-
return __spreadProps(__spreadValues({}, style), {
|
|
289
|
-
"--lumina-table-row-spacing": rowSpacingValue
|
|
290
|
-
});
|
|
291
|
-
}, [style, hasRowSpacing, rowSpacingValue]);
|
|
287
|
+
}, [variant, resolvedRowSelection, rowKey, onRow, dataSource]);
|
|
292
288
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
293
289
|
"div",
|
|
294
290
|
{
|
|
@@ -299,12 +295,11 @@ function Table(props) {
|
|
|
299
295
|
[Table_module_default.isAccordion]: isAccordion,
|
|
300
296
|
[Table_module_default.isToolbar]: isToolbar,
|
|
301
297
|
[Table_module_default.hasCustomHeaderCell]: !!headerCellClassName,
|
|
302
|
-
[Table_module_default.hasCustomBodyCell]: !!bodyCellClassName
|
|
303
|
-
[Table_module_default.hasRowSpacing]: hasRowSpacing
|
|
298
|
+
[Table_module_default.hasCustomBodyCell]: !!bodyCellClassName
|
|
304
299
|
},
|
|
305
300
|
className
|
|
306
301
|
),
|
|
307
|
-
style
|
|
302
|
+
style,
|
|
308
303
|
"data-testid": "lumina-table",
|
|
309
304
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
310
305
|
import_antd.Table,
|
|
@@ -313,7 +308,7 @@ function Table(props) {
|
|
|
313
308
|
size,
|
|
314
309
|
pagination: resolvedPagination,
|
|
315
310
|
columns: processedColumns,
|
|
316
|
-
rowSelection,
|
|
311
|
+
rowSelection: resolvedRowSelection,
|
|
317
312
|
rowKey,
|
|
318
313
|
onRow: resolvedOnRow,
|
|
319
314
|
dataSource,
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__objRest,
|
|
3
|
+
__spreadProps,
|
|
4
|
+
__spreadValues
|
|
5
|
+
} from "./chunk-FWCSY2DS.mjs";
|
|
6
|
+
|
|
7
|
+
// src/atom/Table/Table.tsx
|
|
8
|
+
import * as React from "react";
|
|
9
|
+
import { Table as AntTable } from "antd";
|
|
10
|
+
import clsx from "clsx";
|
|
11
|
+
|
|
12
|
+
// src/atom/Table/Table.module.scss
|
|
13
|
+
var Table_module_default = { "tableWrapper": "Table-module__tableWrapper___3cqiD", "isAccordion": "Table-module__isAccordion___-uIs6", "isToolbar": "Table-module__isToolbar___LdS-m", "hasCustomHeaderCell": "Table-module__hasCustomHeaderCell___AtCk8", "table": "Table-module__table___5d7g0", "ant-table-selection-column": "Table-module__ant-table-selection-column___H9vtu", "hasCustomBodyCell": "Table-module__hasCustomBodyCell___sf8j8", "firstRow": "Table-module__firstRow___Xq-Hi", "lastRow": "Table-module__lastRow___ahv4g", "showHoverEffect": "Table-module__showHoverEffect___IyKyO", "columnHeader": "Table-module__columnHeader___Unr6d", "columnHeaderLeft": "Table-module__columnHeaderLeft___mp7pK", "columnHeaderSortArea": "Table-module__columnHeaderSortArea___jrIYo", "columnHeaderLabel": "Table-module__columnHeaderLabel___A-mRu", "columnHeaderSortIcon": "Table-module__columnHeaderSortIcon___mWVZN", "columnHeaderSortIconActive": "Table-module__columnHeaderSortIconActive___wHAqC", "columnHeaderFilterWrapper": "Table-module__columnHeaderFilterWrapper___DnSve", "columnHeaderFilterBtn": "Table-module__columnHeaderFilterBtn___NR7DY", "columnHeaderFilterBtnActive": "Table-module__columnHeaderFilterBtnActive___JdO11", "columnHeaderFilterBadge": "Table-module__columnHeaderFilterBadge___-Q2T2", "columnHeaderFilterDropdown": "Table-module__columnHeaderFilterDropdown___M-fD4" };
|
|
14
|
+
|
|
15
|
+
// src/atom/Table/Table.tsx
|
|
16
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
17
|
+
function buildPagination(pagination, overrides = {}) {
|
|
18
|
+
var _a, _b, _c, _d;
|
|
19
|
+
if (pagination === false) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
const defaults = {
|
|
23
|
+
showSizeChanger: true,
|
|
24
|
+
pageSizeOptions: ["10", "25", "50"],
|
|
25
|
+
locale: { items_per_page: "" },
|
|
26
|
+
// Removes "/ page" text
|
|
27
|
+
showTotal: (total, range) => `${range[0]}\u2013${range[1]} of ${total} items`
|
|
28
|
+
};
|
|
29
|
+
const baseConfig = pagination === true || pagination === void 0 ? defaults : __spreadValues(__spreadValues({}, defaults), pagination);
|
|
30
|
+
return __spreadProps(__spreadValues({}, baseConfig), {
|
|
31
|
+
total: (_a = overrides.total) != null ? _a : baseConfig.total,
|
|
32
|
+
current: (_b = overrides.current) != null ? _b : baseConfig.current,
|
|
33
|
+
pageSize: (_c = overrides.pageSize) != null ? _c : baseConfig.pageSize,
|
|
34
|
+
onChange: (_d = overrides.onChange) != null ? _d : baseConfig.onChange
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
function nextSortOrder(current) {
|
|
38
|
+
if (current === void 0) return "ascend";
|
|
39
|
+
if (current === "ascend") return "descend";
|
|
40
|
+
return void 0;
|
|
41
|
+
}
|
|
42
|
+
function ColumnHeader({
|
|
43
|
+
label,
|
|
44
|
+
sortable = false,
|
|
45
|
+
sortOrder,
|
|
46
|
+
onSortChange,
|
|
47
|
+
sortIcon,
|
|
48
|
+
filterCount = 0,
|
|
49
|
+
filterIcon,
|
|
50
|
+
filterContent,
|
|
51
|
+
className = ""
|
|
52
|
+
}) {
|
|
53
|
+
const [filterOpen, setFilterOpen] = React.useState(false);
|
|
54
|
+
const wrapperRef = React.useRef(null);
|
|
55
|
+
const filterActive = filterCount > 0;
|
|
56
|
+
const hasFilter = filterContent !== void 0 && filterIcon !== void 0;
|
|
57
|
+
const hasSort = sortable && sortIcon !== void 0;
|
|
58
|
+
React.useEffect(() => {
|
|
59
|
+
if (!filterOpen) return;
|
|
60
|
+
const onOutside = (e) => {
|
|
61
|
+
if (wrapperRef.current && !wrapperRef.current.contains(e.target)) {
|
|
62
|
+
setFilterOpen(false);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
document.addEventListener("mousedown", onOutside);
|
|
66
|
+
return () => document.removeEventListener("mousedown", onOutside);
|
|
67
|
+
}, [filterOpen]);
|
|
68
|
+
return /* @__PURE__ */ jsxs("div", { className: Table_module_default.columnHeader, ref: wrapperRef, children: [
|
|
69
|
+
/* @__PURE__ */ jsx("div", { className: Table_module_default.columnHeaderLeft, children: hasSort ? /* @__PURE__ */ jsxs(
|
|
70
|
+
"button",
|
|
71
|
+
{
|
|
72
|
+
type: "button",
|
|
73
|
+
className: Table_module_default.columnHeaderSortArea,
|
|
74
|
+
onClick: () => onSortChange == null ? void 0 : onSortChange(nextSortOrder(sortOrder)),
|
|
75
|
+
"aria-label": typeof label === "string" ? `Sort by ${label}` : "Sort",
|
|
76
|
+
children: [
|
|
77
|
+
/* @__PURE__ */ jsx("span", { className: clsx(Table_module_default.columnHeaderLabel, "tw-typography-caption2Bold tw-text-color-text-weak", className), children: label }),
|
|
78
|
+
/* @__PURE__ */ jsx(
|
|
79
|
+
"span",
|
|
80
|
+
{
|
|
81
|
+
className: clsx(Table_module_default.columnHeaderSortIcon, {
|
|
82
|
+
[Table_module_default.columnHeaderSortIconActive]: sortOrder !== void 0
|
|
83
|
+
}),
|
|
84
|
+
children: sortIcon
|
|
85
|
+
}
|
|
86
|
+
)
|
|
87
|
+
]
|
|
88
|
+
}
|
|
89
|
+
) : /* @__PURE__ */ jsx("span", { className: clsx(Table_module_default.columnHeaderLabel, "tw-typography-caption2Bold tw-text-color-text-weak", className), children: label }) }),
|
|
90
|
+
hasFilter && /* @__PURE__ */ jsxs("div", { className: Table_module_default.columnHeaderFilterWrapper, children: [
|
|
91
|
+
/* @__PURE__ */ jsxs(
|
|
92
|
+
"button",
|
|
93
|
+
{
|
|
94
|
+
type: "button",
|
|
95
|
+
className: clsx(Table_module_default.columnHeaderFilterBtn, {
|
|
96
|
+
[Table_module_default.columnHeaderFilterBtnActive]: filterActive
|
|
97
|
+
}),
|
|
98
|
+
onClick: () => setFilterOpen((v) => !v),
|
|
99
|
+
"aria-label": typeof label === "string" ? `Filter ${label}` : "Filter",
|
|
100
|
+
"aria-expanded": filterOpen,
|
|
101
|
+
"aria-haspopup": "dialog",
|
|
102
|
+
children: [
|
|
103
|
+
filterIcon,
|
|
104
|
+
filterActive && /* @__PURE__ */ jsx("span", { className: Table_module_default.columnHeaderFilterBadge, children: filterCount })
|
|
105
|
+
]
|
|
106
|
+
}
|
|
107
|
+
),
|
|
108
|
+
filterOpen && /* @__PURE__ */ jsx("div", { className: Table_module_default.columnHeaderFilterDropdown, role: "dialog", children: filterContent })
|
|
109
|
+
] })
|
|
110
|
+
] });
|
|
111
|
+
}
|
|
112
|
+
function processColumns(columns, headerCellClassName, bodyCellClassName) {
|
|
113
|
+
if (!columns) return void 0;
|
|
114
|
+
return columns.map((col) => {
|
|
115
|
+
const _a = col, { headerProps, title, onHeaderCell, onCell } = _a, rest = __objRest(_a, ["headerProps", "title", "onHeaderCell", "onCell"]);
|
|
116
|
+
const resolvedOnHeaderCell = (column) => {
|
|
117
|
+
var _a2;
|
|
118
|
+
const base = (_a2 = onHeaderCell == null ? void 0 : onHeaderCell(column)) != null ? _a2 : {};
|
|
119
|
+
return __spreadProps(__spreadValues({}, base), {
|
|
120
|
+
className: clsx(base.className, headerCellClassName)
|
|
121
|
+
});
|
|
122
|
+
};
|
|
123
|
+
const resolvedOnCell = (record, rowIndex) => {
|
|
124
|
+
var _a2;
|
|
125
|
+
const base = (_a2 = onCell == null ? void 0 : onCell(record, rowIndex)) != null ? _a2 : {};
|
|
126
|
+
return __spreadProps(__spreadValues({}, base), {
|
|
127
|
+
className: clsx(base.className, bodyCellClassName)
|
|
128
|
+
});
|
|
129
|
+
};
|
|
130
|
+
const processedTitle = headerProps ? /* @__PURE__ */ jsx(ColumnHeader, __spreadValues({ label: title }, headerProps)) : title;
|
|
131
|
+
return __spreadProps(__spreadValues({}, rest), {
|
|
132
|
+
title: processedTitle,
|
|
133
|
+
onHeaderCell: resolvedOnHeaderCell,
|
|
134
|
+
onCell: resolvedOnCell
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
function Table(props) {
|
|
139
|
+
var _b;
|
|
140
|
+
const _a = props, {
|
|
141
|
+
size = "middle",
|
|
142
|
+
variant = "default",
|
|
143
|
+
isAccordion = false,
|
|
144
|
+
isToolbar = false,
|
|
145
|
+
className = "",
|
|
146
|
+
pagination,
|
|
147
|
+
loading,
|
|
148
|
+
total,
|
|
149
|
+
current,
|
|
150
|
+
pageSize,
|
|
151
|
+
onPaginationChange,
|
|
152
|
+
columns,
|
|
153
|
+
rowSelection,
|
|
154
|
+
rowKey = "key",
|
|
155
|
+
onRow,
|
|
156
|
+
dataSource,
|
|
157
|
+
emptyState,
|
|
158
|
+
hideHeader,
|
|
159
|
+
loadingIndicator,
|
|
160
|
+
style,
|
|
161
|
+
headerCellClassName,
|
|
162
|
+
bodyCellClassName,
|
|
163
|
+
rowClassName
|
|
164
|
+
} = _a, rest = __objRest(_a, [
|
|
165
|
+
"size",
|
|
166
|
+
"variant",
|
|
167
|
+
"isAccordion",
|
|
168
|
+
"isToolbar",
|
|
169
|
+
"className",
|
|
170
|
+
"pagination",
|
|
171
|
+
"loading",
|
|
172
|
+
"total",
|
|
173
|
+
"current",
|
|
174
|
+
"pageSize",
|
|
175
|
+
"onPaginationChange",
|
|
176
|
+
"columns",
|
|
177
|
+
"rowSelection",
|
|
178
|
+
"rowKey",
|
|
179
|
+
"onRow",
|
|
180
|
+
"dataSource",
|
|
181
|
+
"emptyState",
|
|
182
|
+
"hideHeader",
|
|
183
|
+
"loadingIndicator",
|
|
184
|
+
"style",
|
|
185
|
+
"headerCellClassName",
|
|
186
|
+
"bodyCellClassName",
|
|
187
|
+
"rowClassName"
|
|
188
|
+
]);
|
|
189
|
+
const isChildVariant = isAccordion || isToolbar;
|
|
190
|
+
const resolvedPagination = buildPagination(pagination, {
|
|
191
|
+
total,
|
|
192
|
+
current,
|
|
193
|
+
pageSize,
|
|
194
|
+
onChange: onPaginationChange
|
|
195
|
+
});
|
|
196
|
+
const processedColumns = React.useMemo(
|
|
197
|
+
() => processColumns(columns, headerCellClassName, bodyCellClassName),
|
|
198
|
+
[columns, headerCellClassName, bodyCellClassName]
|
|
199
|
+
);
|
|
200
|
+
const resolvedRowSelection = React.useMemo(() => {
|
|
201
|
+
if (!rowSelection) return void 0;
|
|
202
|
+
return __spreadValues({
|
|
203
|
+
columnWidth: 48
|
|
204
|
+
}, rowSelection);
|
|
205
|
+
}, [rowSelection]);
|
|
206
|
+
const resolvedOnRow = React.useMemo(() => {
|
|
207
|
+
const onChange = resolvedRowSelection == null ? void 0 : resolvedRowSelection.onChange;
|
|
208
|
+
if (variant !== "selectable" || !onChange) return onRow;
|
|
209
|
+
return (record, index) => {
|
|
210
|
+
var _a2;
|
|
211
|
+
const base = (_a2 = onRow == null ? void 0 : onRow(record, index)) != null ? _a2 : {};
|
|
212
|
+
const getKey = (r, i) => typeof rowKey === "function" ? rowKey(r, i) : r[rowKey];
|
|
213
|
+
return __spreadProps(__spreadValues({}, base), {
|
|
214
|
+
style: __spreadValues({ cursor: "pointer" }, base.style),
|
|
215
|
+
onClick: (e) => {
|
|
216
|
+
var _a3, _b2;
|
|
217
|
+
(_a3 = base.onClick) == null ? void 0 : _a3.call(base, e);
|
|
218
|
+
const key = getKey(record, index);
|
|
219
|
+
const current2 = (_b2 = resolvedRowSelection.selectedRowKeys) != null ? _b2 : [];
|
|
220
|
+
const isSelected = current2.some((k) => k === key);
|
|
221
|
+
const newKeys = isSelected ? current2.filter((k) => k !== key) : [...current2, key];
|
|
222
|
+
const newRows = (dataSource != null ? dataSource : []).filter(
|
|
223
|
+
(r) => newKeys.some((k) => k === getKey(r))
|
|
224
|
+
);
|
|
225
|
+
onChange(newKeys, newRows, { type: "single" });
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
};
|
|
229
|
+
}, [variant, resolvedRowSelection, rowKey, onRow, dataSource]);
|
|
230
|
+
return /* @__PURE__ */ jsx(
|
|
231
|
+
"div",
|
|
232
|
+
{
|
|
233
|
+
className: clsx(
|
|
234
|
+
Table_module_default.tableWrapper,
|
|
235
|
+
Table_module_default.showHoverEffect,
|
|
236
|
+
{
|
|
237
|
+
[Table_module_default.isAccordion]: isAccordion,
|
|
238
|
+
[Table_module_default.isToolbar]: isToolbar,
|
|
239
|
+
[Table_module_default.hasCustomHeaderCell]: !!headerCellClassName,
|
|
240
|
+
[Table_module_default.hasCustomBodyCell]: !!bodyCellClassName
|
|
241
|
+
},
|
|
242
|
+
className
|
|
243
|
+
),
|
|
244
|
+
style,
|
|
245
|
+
"data-testid": "lumina-table",
|
|
246
|
+
children: /* @__PURE__ */ jsx(
|
|
247
|
+
AntTable,
|
|
248
|
+
__spreadProps(__spreadValues({
|
|
249
|
+
className: Table_module_default.table,
|
|
250
|
+
size,
|
|
251
|
+
pagination: resolvedPagination,
|
|
252
|
+
columns: processedColumns,
|
|
253
|
+
rowSelection,
|
|
254
|
+
rowKey,
|
|
255
|
+
onRow: resolvedOnRow,
|
|
256
|
+
dataSource,
|
|
257
|
+
showHeader: !hideHeader,
|
|
258
|
+
locale: {
|
|
259
|
+
emptyText: loading && loadingIndicator ? loadingIndicator : loading ? " " : emptyState
|
|
260
|
+
}
|
|
261
|
+
}, rest), {
|
|
262
|
+
loading: loadingIndicator ? { spinning: !!loading && ((_b = dataSource == null ? void 0 : dataSource.length) != null ? _b : 0) > 0, indicator: loadingIndicator } : loading,
|
|
263
|
+
rowClassName: (record, index) => {
|
|
264
|
+
var _a2;
|
|
265
|
+
return clsx(
|
|
266
|
+
{
|
|
267
|
+
[Table_module_default.firstRow]: index === 0,
|
|
268
|
+
[Table_module_default.lastRow]: index === ((_a2 = dataSource == null ? void 0 : dataSource.length) != null ? _a2 : 0) - 1
|
|
269
|
+
},
|
|
270
|
+
typeof rowClassName === "function" ? rowClassName(record, index) : rowClassName
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
})
|
|
274
|
+
)
|
|
275
|
+
}
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
Table.displayName = "Table";
|
|
279
|
+
var Table_default = Table;
|
|
280
|
+
|
|
281
|
+
export {
|
|
282
|
+
Table,
|
|
283
|
+
Table_default
|
|
284
|
+
};
|