@bsol-oss/react-datatable5 12.0.0-beta.77 → 12.0.0-beta.78
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/index.d.ts +8 -4
- package/dist/index.js +82 -28
- package/dist/index.mjs +83 -29
- package/dist/types/components/DataTable/DataTable.d.ts +3 -0
- package/dist/types/components/DataTable/DefaultTable.d.ts +9 -8
- package/dist/types/components/DataTable/DefaultTableServer.d.ts +23 -0
- package/dist/types/components/DataTable/display/Table.d.ts +1 -1
- package/dist/types/components/DataTable/display/TableBodySkeleton.d.ts +5 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -112,6 +112,9 @@ interface DataTableProps<TData = unknown> {
|
|
|
112
112
|
* Data array for the table.
|
|
113
113
|
*
|
|
114
114
|
* It will pass into as the data in `@tanstack/react-table`
|
|
115
|
+
* Do not toggle the data array, it will cause the table to re-render in infinite loop.
|
|
116
|
+
*
|
|
117
|
+
* @default []
|
|
115
118
|
*
|
|
116
119
|
*/
|
|
117
120
|
data: TData[];
|
|
@@ -386,7 +389,7 @@ interface TableProps extends TableRootProps {
|
|
|
386
389
|
canResize?: boolean;
|
|
387
390
|
children: ReactNode;
|
|
388
391
|
}
|
|
389
|
-
declare const Table: ({ children, emptyComponent, canResize, ...props }: TableProps) => string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | react.ReactPortal | react.ReactElement<unknown, string | react.JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | react_jsx_runtime.JSX.Element | null;
|
|
392
|
+
declare const Table: ({ children, emptyComponent, canResize, showLoading, ...props }: TableProps) => string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | react.ReactPortal | react.ReactElement<unknown, string | react.JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | react_jsx_runtime.JSX.Element | null;
|
|
390
393
|
|
|
391
394
|
interface TableBodyProps {
|
|
392
395
|
pinnedBgColor?: {
|
|
@@ -467,14 +470,15 @@ declare const TableHeader: ({ canResize, showSelector, isSticky, tableHeaderProp
|
|
|
467
470
|
|
|
468
471
|
interface DefaultTableProps {
|
|
469
472
|
showFooter?: boolean;
|
|
470
|
-
tableProps?: Omit<TableProps,
|
|
473
|
+
tableProps?: Omit<TableProps, 'children'>;
|
|
471
474
|
tableHeaderProps?: TableHeaderProps;
|
|
472
475
|
tableBodyProps?: TableBodyProps;
|
|
473
476
|
tableFooterProps?: TableFooterProps;
|
|
474
477
|
controlProps?: TableControlsProps;
|
|
475
|
-
variant?:
|
|
478
|
+
variant?: '' | 'greedy';
|
|
479
|
+
isLoading?: boolean;
|
|
476
480
|
}
|
|
477
|
-
declare const DefaultTable: ({ showFooter, tableProps, tableHeaderProps, tableBodyProps, tableFooterProps, controlProps, variant, }: DefaultTableProps) => react_jsx_runtime.JSX.Element;
|
|
481
|
+
declare const DefaultTable: ({ showFooter, tableProps, tableHeaderProps, tableBodyProps, tableFooterProps, controlProps, variant, isLoading, }: DefaultTableProps) => react_jsx_runtime.JSX.Element;
|
|
478
482
|
|
|
479
483
|
interface ReloadButtonProps {
|
|
480
484
|
variant?: string;
|
package/dist/index.js
CHANGED
|
@@ -3114,9 +3114,10 @@ const EmptyState = React__namespace.forwardRef(function EmptyState(props, ref) {
|
|
|
3114
3114
|
});
|
|
3115
3115
|
|
|
3116
3116
|
const EmptyResult = (jsxRuntime.jsx(EmptyState, { icon: jsxRuntime.jsx(hi.HiColorSwatch, {}), title: "No results found", description: "Try adjusting your search", children: jsxRuntime.jsxs(react.List.Root, { variant: "marker", children: [jsxRuntime.jsx(react.List.Item, { children: "Try removing filters" }), jsxRuntime.jsx(react.List.Item, { children: "Try different keywords" })] }) }));
|
|
3117
|
-
const Table = ({ children, emptyComponent = EmptyResult, canResize = true, ...props }) => {
|
|
3117
|
+
const Table = ({ children, emptyComponent = EmptyResult, canResize = true, showLoading = false, ...props }) => {
|
|
3118
3118
|
const { table } = useDataTableContext();
|
|
3119
|
-
|
|
3119
|
+
// Skip empty check when loading to allow skeleton to render
|
|
3120
|
+
if (!showLoading && table.getRowModel().rows.length <= 0) {
|
|
3120
3121
|
return emptyComponent;
|
|
3121
3122
|
}
|
|
3122
3123
|
return (jsxRuntime.jsx(react.Table.Root, { stickyHeader: true, variant: "outline", width: canResize ? table.getCenterTotalSize() : undefined, display: "grid", alignContent: "start", overflowY: "auto", bg: { base: "colorPalette.50", _dark: "colorPalette.950" }, ...props, children: children }));
|
|
@@ -3185,6 +3186,65 @@ const TableRowSelector = ({ row, }) => {
|
|
|
3185
3186
|
onCheckedChange: row.getToggleSelectedHandler() }) }));
|
|
3186
3187
|
};
|
|
3187
3188
|
|
|
3189
|
+
const TableBodySkeleton = ({ showSelector = false, canResize = true, }) => {
|
|
3190
|
+
"use no memo";
|
|
3191
|
+
const { table } = useDataTableContext();
|
|
3192
|
+
const SELECTION_BOX_WIDTH = 20;
|
|
3193
|
+
const [hoveredRow, setHoveredRow] = React.useState(-1);
|
|
3194
|
+
const handleRowHover = (index) => {
|
|
3195
|
+
setHoveredRow(index);
|
|
3196
|
+
};
|
|
3197
|
+
const getTdProps = (column) => {
|
|
3198
|
+
const tdProps = column.getIsPinned()
|
|
3199
|
+
? {
|
|
3200
|
+
left: showSelector
|
|
3201
|
+
? `${column.getStart("left") + SELECTION_BOX_WIDTH + table.getDensityValue() * 2}px`
|
|
3202
|
+
: `${column.getStart("left")}px`,
|
|
3203
|
+
position: "relative",
|
|
3204
|
+
}
|
|
3205
|
+
: {};
|
|
3206
|
+
return tdProps;
|
|
3207
|
+
};
|
|
3208
|
+
const getTrProps = ({ hoveredRow, index, }) => {
|
|
3209
|
+
if (hoveredRow === -1) {
|
|
3210
|
+
return {};
|
|
3211
|
+
}
|
|
3212
|
+
if (hoveredRow === index) {
|
|
3213
|
+
return {
|
|
3214
|
+
opacity: "1",
|
|
3215
|
+
};
|
|
3216
|
+
}
|
|
3217
|
+
return {
|
|
3218
|
+
opacity: "0.8",
|
|
3219
|
+
};
|
|
3220
|
+
};
|
|
3221
|
+
// Get the number of skeleton rows based on current pageSize
|
|
3222
|
+
const pageSize = table.getState().pagination.pageSize;
|
|
3223
|
+
const visibleColumns = table.getVisibleLeafColumns();
|
|
3224
|
+
return (jsxRuntime.jsx(react.Table.Body, { children: Array.from({ length: pageSize }).map((_, rowIndex) => {
|
|
3225
|
+
return (jsxRuntime.jsxs(react.Table.Row, { display: "flex", zIndex: 1, onMouseEnter: () => handleRowHover(rowIndex), onMouseLeave: () => handleRowHover(-1), ...getTrProps({ hoveredRow, index: rowIndex }), children: [showSelector && (jsxRuntime.jsx(TableRowSelectorSkeleton, {})), visibleColumns.map((column, colIndex) => {
|
|
3226
|
+
return (jsxRuntime.jsx(react.Table.Cell, { padding: `${table.getDensityValue()}px`,
|
|
3227
|
+
// styling resize and pinning start
|
|
3228
|
+
flex: `${canResize ? "0" : "1"} 0 ${column.getSize()}px`,
|
|
3229
|
+
// this is to avoid the cell from being too wide
|
|
3230
|
+
minWidth: `0`, color: {
|
|
3231
|
+
base: "colorPalette.900",
|
|
3232
|
+
_dark: "colorPalette.100",
|
|
3233
|
+
},
|
|
3234
|
+
bg: { base: "colorPalette.50", _dark: "colorPalette.950" }, ...getTdProps(column), children: jsxRuntime.jsx(react.Skeleton, { height: "20px", width: "80%" }) }, `chakra-table-skeleton-cell-${rowIndex}-${colIndex}`));
|
|
3235
|
+
})] }, `chakra-table-skeleton-row-${rowIndex}`));
|
|
3236
|
+
}) }));
|
|
3237
|
+
};
|
|
3238
|
+
const TableRowSelectorSkeleton = () => {
|
|
3239
|
+
const { table } = useDataTableContext();
|
|
3240
|
+
const SELECTION_BOX_WIDTH = 20;
|
|
3241
|
+
return (jsxRuntime.jsx(react.Table.Cell, { padding: `${table.getDensityValue()}px`, display: "grid", color: {
|
|
3242
|
+
base: "colorPalette.900",
|
|
3243
|
+
_dark: "colorPalette.100",
|
|
3244
|
+
},
|
|
3245
|
+
bg: { base: "colorPalette.50", _dark: "colorPalette.950" }, justifyItems: "center", alignItems: "center", children: jsxRuntime.jsx(react.Skeleton, { width: `${SELECTION_BOX_WIDTH}px`, height: `${SELECTION_BOX_WIDTH}px` }) }));
|
|
3246
|
+
};
|
|
3247
|
+
|
|
3188
3248
|
const TableFooter = ({ showSelector = false, alwaysShowSelector = true, }) => {
|
|
3189
3249
|
const table = useDataTableContext().table;
|
|
3190
3250
|
const SELECTION_BOX_WIDTH = 20;
|
|
@@ -3346,11 +3406,12 @@ const TableHeader = ({ canResize = true, showSelector = false, isSticky = true,
|
|
|
3346
3406
|
})] }, `chakra-table-headergroup-${headerGroup.id}`))) }));
|
|
3347
3407
|
};
|
|
3348
3408
|
|
|
3349
|
-
const DefaultTable = ({ showFooter = false, tableProps = {}, tableHeaderProps = {}, tableBodyProps = {}, tableFooterProps = {}, controlProps = {}, variant =
|
|
3350
|
-
|
|
3351
|
-
|
|
3409
|
+
const DefaultTable = ({ showFooter = false, tableProps = {}, tableHeaderProps = {}, tableBodyProps = {}, tableFooterProps = {}, controlProps = {}, variant = '', isLoading = false, }) => {
|
|
3410
|
+
const bodyComponent = isLoading ? (jsxRuntime.jsx(TableBodySkeleton, { showSelector: tableBodyProps.showSelector, canResize: tableBodyProps.canResize })) : (jsxRuntime.jsx(TableBody, { ...tableBodyProps }));
|
|
3411
|
+
if (variant === 'greedy') {
|
|
3412
|
+
return (jsxRuntime.jsx(TableControls, { ...controlProps, children: jsxRuntime.jsxs(Table, { canResize: false, showLoading: isLoading, ...tableProps, children: [jsxRuntime.jsx(TableHeader, { canResize: false, ...tableHeaderProps }), bodyComponent, showFooter && (jsxRuntime.jsx(TableFooter, { canResize: false, ...tableFooterProps }))] }) }));
|
|
3352
3413
|
}
|
|
3353
|
-
return (jsxRuntime.jsx(TableControls, { ...controlProps, children: jsxRuntime.jsxs(Table, { ...tableProps, children: [jsxRuntime.jsx(TableHeader, { ...tableHeaderProps }),
|
|
3414
|
+
return (jsxRuntime.jsx(TableControls, { ...controlProps, children: jsxRuntime.jsxs(Table, { showLoading: isLoading, ...tableProps, children: [jsxRuntime.jsx(TableHeader, { ...tableHeaderProps }), bodyComponent, showFooter && jsxRuntime.jsx(TableFooter, { ...tableFooterProps })] }) }));
|
|
3354
3415
|
};
|
|
3355
3416
|
|
|
3356
3417
|
const TableCardContainer = ({ children, variant = "", gap = "1rem", gridTemplateColumns = "repeat(auto-fit, minmax(20rem, 1fr))", direction = "row", ...props }) => {
|
|
@@ -4469,7 +4530,8 @@ function filterArray(array, searchTerm) {
|
|
|
4469
4530
|
|
|
4470
4531
|
const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLimit = false, }) => {
|
|
4471
4532
|
const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
|
|
4472
|
-
const {
|
|
4533
|
+
const { enumPickerLabels } = useSchemaContext();
|
|
4534
|
+
const formI18n = useFormI18n(column, prefix);
|
|
4473
4535
|
const { required, variant } = schema;
|
|
4474
4536
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4475
4537
|
const { gridColumn = 'span 12', gridRow = 'span 1', renderDisplay } = schema;
|
|
@@ -4477,7 +4539,7 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLi
|
|
|
4477
4539
|
const [limit, setLimit] = React.useState(10);
|
|
4478
4540
|
const [openSearchResult, setOpenSearchResult] = React.useState();
|
|
4479
4541
|
const ref = React.useRef(null);
|
|
4480
|
-
const colLabel =
|
|
4542
|
+
const colLabel = formI18n.colLabel;
|
|
4481
4543
|
const watchEnum = watch(colLabel);
|
|
4482
4544
|
const watchEnums = (watch(colLabel) ?? []);
|
|
4483
4545
|
const dataList = schema.enum ?? [];
|
|
@@ -4488,10 +4550,8 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLi
|
|
|
4488
4550
|
setLimit(10);
|
|
4489
4551
|
};
|
|
4490
4552
|
if (variant === 'radio') {
|
|
4491
|
-
return (jsxRuntime.jsx(Field, { label:
|
|
4492
|
-
gridRow, errorText: errors[`${colLabel}`]
|
|
4493
|
-
? translate.t(removeIndex(`${colLabel}.field_required`))
|
|
4494
|
-
: undefined, invalid: !!errors[colLabel], children: jsxRuntime.jsx(react.RadioGroup.Root, { defaultValue: "1", children: jsxRuntime.jsx(react.HStack, { gap: "6", children: filterArray(dataList, searchText ?? '').map((item) => {
|
|
4553
|
+
return (jsxRuntime.jsx(Field, { label: formI18n.label(), required: isRequired, alignItems: 'stretch', gridColumn,
|
|
4554
|
+
gridRow, errorText: errors[`${colLabel}`] ? formI18n.required() : undefined, invalid: !!errors[colLabel], children: jsxRuntime.jsx(react.RadioGroup.Root, { defaultValue: "1", children: jsxRuntime.jsx(react.HStack, { gap: "6", children: filterArray(dataList, searchText ?? '').map((item) => {
|
|
4495
4555
|
return (jsxRuntime.jsxs(react.RadioGroup.Item, { onClick: () => {
|
|
4496
4556
|
if (!isMultiple) {
|
|
4497
4557
|
setOpenSearchResult(false);
|
|
@@ -4502,13 +4562,11 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLi
|
|
|
4502
4562
|
setValue(colLabel, [...newSet]);
|
|
4503
4563
|
}, value: item, children: [jsxRuntime.jsx(react.RadioGroup.ItemHiddenInput, {}), jsxRuntime.jsx(react.RadioGroup.ItemIndicator, {}), jsxRuntime.jsx(react.RadioGroup.ItemText, { children: !!renderDisplay === true
|
|
4504
4564
|
? renderDisplay(item)
|
|
4505
|
-
:
|
|
4565
|
+
: formI18n.t(item) })] }, `${colLabel}-${item}`));
|
|
4506
4566
|
}) }) }) }));
|
|
4507
4567
|
}
|
|
4508
|
-
return (jsxRuntime.jsxs(Field, { label:
|
|
4509
|
-
gridRow, errorText: errors[`${colLabel}`]
|
|
4510
|
-
? translate.t(removeIndex(`${colLabel}.field_required`))
|
|
4511
|
-
: undefined, invalid: !!errors[colLabel], children: [isMultiple && (jsxRuntime.jsxs(react.Flex, { flexFlow: 'wrap', gap: 1, children: [watchEnums.map((enumValue) => {
|
|
4568
|
+
return (jsxRuntime.jsxs(Field, { label: formI18n.label(), required: isRequired, alignItems: 'stretch', gridColumn,
|
|
4569
|
+
gridRow, errorText: errors[`${colLabel}`] ? formI18n.required() : undefined, invalid: !!errors[colLabel], children: [isMultiple && (jsxRuntime.jsxs(react.Flex, { flexFlow: 'wrap', gap: 1, children: [watchEnums.map((enumValue) => {
|
|
4512
4570
|
const item = enumValue;
|
|
4513
4571
|
if (!!item === false) {
|
|
4514
4572
|
return jsxRuntime.jsx(jsxRuntime.Fragment, {});
|
|
@@ -4517,19 +4575,15 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLi
|
|
|
4517
4575
|
setValue(column, watchEnums.filter((id) => id != item));
|
|
4518
4576
|
}, children: !!renderDisplay === true
|
|
4519
4577
|
? renderDisplay(item)
|
|
4520
|
-
:
|
|
4578
|
+
: formI18n.t(item) }, item));
|
|
4521
4579
|
}), jsxRuntime.jsx(Tag, { size: "lg", cursor: 'pointer', onClick: () => {
|
|
4522
4580
|
setOpenSearchResult(true);
|
|
4523
|
-
}, children: enumPickerLabels?.addMore ??
|
|
4524
|
-
translate.t(removeIndex(`${colLabel}.add_more`)) }, `${colLabel}-add-more-tag`)] })), !isMultiple && (jsxRuntime.jsx(Button, { variant: 'outline', onClick: () => {
|
|
4581
|
+
}, children: enumPickerLabels?.addMore ?? formI18n.t('add_more') }, `${colLabel}-add-more-tag`)] })), !isMultiple && (jsxRuntime.jsx(Button, { variant: 'outline', onClick: () => {
|
|
4525
4582
|
setOpenSearchResult(true);
|
|
4526
|
-
}, justifyContent: 'start', children: !!watchEnum === false
|
|
4527
|
-
? ''
|
|
4528
|
-
: translate.t(removeIndex(`${colLabel}.${watchEnum ?? 'null'}`)) })), jsxRuntime.jsxs(PopoverRoot, { open: openSearchResult, onOpenChange: (e) => setOpenSearchResult(e.open), closeOnInteractOutside: true, initialFocusEl: () => ref.current, positioning: { placement: 'bottom-start' }, children: [jsxRuntime.jsx(PopoverTrigger, {}), jsxRuntime.jsx(PopoverContent, { portalled: false, children: jsxRuntime.jsxs(PopoverBody, { display: 'grid', gap: 1, children: [jsxRuntime.jsx(react.Input, { placeholder: enumPickerLabels?.typeToSearch ??
|
|
4529
|
-
translate.t(`${colLabel}.type_to_search`), onChange: (event) => {
|
|
4583
|
+
}, justifyContent: 'start', children: !!watchEnum === false ? '' : formI18n.t(watchEnum ?? 'null') })), jsxRuntime.jsxs(PopoverRoot, { open: openSearchResult, onOpenChange: (e) => setOpenSearchResult(e.open), closeOnInteractOutside: true, initialFocusEl: () => ref.current, positioning: { placement: 'bottom-start' }, children: [jsxRuntime.jsx(PopoverTrigger, {}), jsxRuntime.jsx(PopoverContent, { portalled: false, children: jsxRuntime.jsxs(PopoverBody, { display: 'grid', gap: 1, children: [jsxRuntime.jsx(react.Input, { placeholder: enumPickerLabels?.typeToSearch ?? formI18n.t('type_to_search'), onChange: (event) => {
|
|
4530
4584
|
onSearchChange(event);
|
|
4531
4585
|
setOpenSearchResult(true);
|
|
4532
|
-
}, autoComplete: "off", ref: ref }), jsxRuntime.jsx(PopoverTitle, {}), showTotalAndLimit && (jsxRuntime.jsx(react.Text, { children: `${enumPickerLabels?.total ??
|
|
4586
|
+
}, autoComplete: "off", ref: ref }), jsxRuntime.jsx(PopoverTitle, {}), showTotalAndLimit && (jsxRuntime.jsx(react.Text, { children: `${enumPickerLabels?.total ?? formI18n.t('total')}: ${count}, ${enumPickerLabels?.showing ?? formI18n.t('showing')} ${limit}` })), jsxRuntime.jsxs(react.Grid, { overflow: 'auto', maxHeight: '20rem', children: [jsxRuntime.jsx(react.Flex, { flexFlow: 'column wrap', children: dataList
|
|
4533
4587
|
.filter((item) => {
|
|
4534
4588
|
const searchTerm = (searchText || '').toLowerCase();
|
|
4535
4589
|
if (!searchTerm)
|
|
@@ -4541,7 +4595,7 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLi
|
|
|
4541
4595
|
// Check if the display value (translation) contains the search text
|
|
4542
4596
|
const displayValue = !!renderDisplay === true
|
|
4543
4597
|
? renderDisplay(item)
|
|
4544
|
-
:
|
|
4598
|
+
: formI18n.t(item);
|
|
4545
4599
|
// Convert to string and check if it includes the search term
|
|
4546
4600
|
const displayValueString = String(displayValue).toLowerCase();
|
|
4547
4601
|
const displayValueMatch = displayValueString.includes(searchTerm);
|
|
@@ -4561,9 +4615,9 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLi
|
|
|
4561
4615
|
setValue(colLabel, [...newSet]);
|
|
4562
4616
|
}, ...(selected ? { color: 'colorPalette.400/50' } : {}), children: !!renderDisplay === true
|
|
4563
4617
|
? renderDisplay(item)
|
|
4564
|
-
:
|
|
4618
|
+
: formI18n.t(item) }, `${colLabel}-${item}`));
|
|
4565
4619
|
}) }), isDirty && (jsxRuntime.jsx(jsxRuntime.Fragment, { children: dataList.length <= 0 && (jsxRuntime.jsx(jsxRuntime.Fragment, { children: enumPickerLabels?.emptySearchResult ??
|
|
4566
|
-
|
|
4620
|
+
formI18n.t('empty_search_result') })) }))] })] }) })] })] }));
|
|
4567
4621
|
};
|
|
4568
4622
|
|
|
4569
4623
|
function isEnteringWindow(_ref) {
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
|
-
import { Button as Button$1, AbsoluteCenter, Spinner, Span, IconButton, Portal, Dialog, Flex, Text, useDisclosure, DialogBackdrop, RadioGroup as RadioGroup$1, Grid, Box, Slider as Slider$1, HStack, For, Tag as Tag$1, Input, Menu, createRecipeContext, createContext as createContext$1, Pagination as Pagination$1, usePaginationContext, CheckboxCard as CheckboxCard$1, Image, EmptyState as EmptyState$2, VStack, Alert, Card, Group, InputElement, Tooltip as Tooltip$1, Icon, List, Table as Table$1, Checkbox as Checkbox$1, MenuRoot as MenuRoot$1, MenuTrigger as MenuTrigger$1, Field as Field$1, Popover, NumberInput, Show, RadioCard, CheckboxGroup, Center, Heading } from '@chakra-ui/react';
|
|
2
|
+
import { Button as Button$1, AbsoluteCenter, Spinner, Span, IconButton, Portal, Dialog, Flex, Text, useDisclosure, DialogBackdrop, RadioGroup as RadioGroup$1, Grid, Box, Slider as Slider$1, HStack, For, Tag as Tag$1, Input, Menu, createRecipeContext, createContext as createContext$1, Pagination as Pagination$1, usePaginationContext, CheckboxCard as CheckboxCard$1, Image, EmptyState as EmptyState$2, VStack, Alert, Card, Group, InputElement, Tooltip as Tooltip$1, Icon, List, Table as Table$1, Checkbox as Checkbox$1, Skeleton, MenuRoot as MenuRoot$1, MenuTrigger as MenuTrigger$1, Field as Field$1, Popover, NumberInput, Show, RadioCard, CheckboxGroup, Center, Heading } from '@chakra-ui/react';
|
|
3
3
|
import { AiOutlineColumnWidth } from 'react-icons/ai';
|
|
4
4
|
import * as React from 'react';
|
|
5
5
|
import React__default, { createContext, useContext, useState, useEffect, useRef, forwardRef } from 'react';
|
|
@@ -3094,9 +3094,10 @@ const EmptyState = React.forwardRef(function EmptyState(props, ref) {
|
|
|
3094
3094
|
});
|
|
3095
3095
|
|
|
3096
3096
|
const EmptyResult = (jsx(EmptyState, { icon: jsx(HiColorSwatch, {}), title: "No results found", description: "Try adjusting your search", children: jsxs(List.Root, { variant: "marker", children: [jsx(List.Item, { children: "Try removing filters" }), jsx(List.Item, { children: "Try different keywords" })] }) }));
|
|
3097
|
-
const Table = ({ children, emptyComponent = EmptyResult, canResize = true, ...props }) => {
|
|
3097
|
+
const Table = ({ children, emptyComponent = EmptyResult, canResize = true, showLoading = false, ...props }) => {
|
|
3098
3098
|
const { table } = useDataTableContext();
|
|
3099
|
-
|
|
3099
|
+
// Skip empty check when loading to allow skeleton to render
|
|
3100
|
+
if (!showLoading && table.getRowModel().rows.length <= 0) {
|
|
3100
3101
|
return emptyComponent;
|
|
3101
3102
|
}
|
|
3102
3103
|
return (jsx(Table$1.Root, { stickyHeader: true, variant: "outline", width: canResize ? table.getCenterTotalSize() : undefined, display: "grid", alignContent: "start", overflowY: "auto", bg: { base: "colorPalette.50", _dark: "colorPalette.950" }, ...props, children: children }));
|
|
@@ -3165,6 +3166,65 @@ const TableRowSelector = ({ row, }) => {
|
|
|
3165
3166
|
onCheckedChange: row.getToggleSelectedHandler() }) }));
|
|
3166
3167
|
};
|
|
3167
3168
|
|
|
3169
|
+
const TableBodySkeleton = ({ showSelector = false, canResize = true, }) => {
|
|
3170
|
+
"use no memo";
|
|
3171
|
+
const { table } = useDataTableContext();
|
|
3172
|
+
const SELECTION_BOX_WIDTH = 20;
|
|
3173
|
+
const [hoveredRow, setHoveredRow] = useState(-1);
|
|
3174
|
+
const handleRowHover = (index) => {
|
|
3175
|
+
setHoveredRow(index);
|
|
3176
|
+
};
|
|
3177
|
+
const getTdProps = (column) => {
|
|
3178
|
+
const tdProps = column.getIsPinned()
|
|
3179
|
+
? {
|
|
3180
|
+
left: showSelector
|
|
3181
|
+
? `${column.getStart("left") + SELECTION_BOX_WIDTH + table.getDensityValue() * 2}px`
|
|
3182
|
+
: `${column.getStart("left")}px`,
|
|
3183
|
+
position: "relative",
|
|
3184
|
+
}
|
|
3185
|
+
: {};
|
|
3186
|
+
return tdProps;
|
|
3187
|
+
};
|
|
3188
|
+
const getTrProps = ({ hoveredRow, index, }) => {
|
|
3189
|
+
if (hoveredRow === -1) {
|
|
3190
|
+
return {};
|
|
3191
|
+
}
|
|
3192
|
+
if (hoveredRow === index) {
|
|
3193
|
+
return {
|
|
3194
|
+
opacity: "1",
|
|
3195
|
+
};
|
|
3196
|
+
}
|
|
3197
|
+
return {
|
|
3198
|
+
opacity: "0.8",
|
|
3199
|
+
};
|
|
3200
|
+
};
|
|
3201
|
+
// Get the number of skeleton rows based on current pageSize
|
|
3202
|
+
const pageSize = table.getState().pagination.pageSize;
|
|
3203
|
+
const visibleColumns = table.getVisibleLeafColumns();
|
|
3204
|
+
return (jsx(Table$1.Body, { children: Array.from({ length: pageSize }).map((_, rowIndex) => {
|
|
3205
|
+
return (jsxs(Table$1.Row, { display: "flex", zIndex: 1, onMouseEnter: () => handleRowHover(rowIndex), onMouseLeave: () => handleRowHover(-1), ...getTrProps({ hoveredRow, index: rowIndex }), children: [showSelector && (jsx(TableRowSelectorSkeleton, {})), visibleColumns.map((column, colIndex) => {
|
|
3206
|
+
return (jsx(Table$1.Cell, { padding: `${table.getDensityValue()}px`,
|
|
3207
|
+
// styling resize and pinning start
|
|
3208
|
+
flex: `${canResize ? "0" : "1"} 0 ${column.getSize()}px`,
|
|
3209
|
+
// this is to avoid the cell from being too wide
|
|
3210
|
+
minWidth: `0`, color: {
|
|
3211
|
+
base: "colorPalette.900",
|
|
3212
|
+
_dark: "colorPalette.100",
|
|
3213
|
+
},
|
|
3214
|
+
bg: { base: "colorPalette.50", _dark: "colorPalette.950" }, ...getTdProps(column), children: jsx(Skeleton, { height: "20px", width: "80%" }) }, `chakra-table-skeleton-cell-${rowIndex}-${colIndex}`));
|
|
3215
|
+
})] }, `chakra-table-skeleton-row-${rowIndex}`));
|
|
3216
|
+
}) }));
|
|
3217
|
+
};
|
|
3218
|
+
const TableRowSelectorSkeleton = () => {
|
|
3219
|
+
const { table } = useDataTableContext();
|
|
3220
|
+
const SELECTION_BOX_WIDTH = 20;
|
|
3221
|
+
return (jsx(Table$1.Cell, { padding: `${table.getDensityValue()}px`, display: "grid", color: {
|
|
3222
|
+
base: "colorPalette.900",
|
|
3223
|
+
_dark: "colorPalette.100",
|
|
3224
|
+
},
|
|
3225
|
+
bg: { base: "colorPalette.50", _dark: "colorPalette.950" }, justifyItems: "center", alignItems: "center", children: jsx(Skeleton, { width: `${SELECTION_BOX_WIDTH}px`, height: `${SELECTION_BOX_WIDTH}px` }) }));
|
|
3226
|
+
};
|
|
3227
|
+
|
|
3168
3228
|
const TableFooter = ({ showSelector = false, alwaysShowSelector = true, }) => {
|
|
3169
3229
|
const table = useDataTableContext().table;
|
|
3170
3230
|
const SELECTION_BOX_WIDTH = 20;
|
|
@@ -3326,11 +3386,12 @@ const TableHeader = ({ canResize = true, showSelector = false, isSticky = true,
|
|
|
3326
3386
|
})] }, `chakra-table-headergroup-${headerGroup.id}`))) }));
|
|
3327
3387
|
};
|
|
3328
3388
|
|
|
3329
|
-
const DefaultTable = ({ showFooter = false, tableProps = {}, tableHeaderProps = {}, tableBodyProps = {}, tableFooterProps = {}, controlProps = {}, variant =
|
|
3330
|
-
|
|
3331
|
-
|
|
3389
|
+
const DefaultTable = ({ showFooter = false, tableProps = {}, tableHeaderProps = {}, tableBodyProps = {}, tableFooterProps = {}, controlProps = {}, variant = '', isLoading = false, }) => {
|
|
3390
|
+
const bodyComponent = isLoading ? (jsx(TableBodySkeleton, { showSelector: tableBodyProps.showSelector, canResize: tableBodyProps.canResize })) : (jsx(TableBody, { ...tableBodyProps }));
|
|
3391
|
+
if (variant === 'greedy') {
|
|
3392
|
+
return (jsx(TableControls, { ...controlProps, children: jsxs(Table, { canResize: false, showLoading: isLoading, ...tableProps, children: [jsx(TableHeader, { canResize: false, ...tableHeaderProps }), bodyComponent, showFooter && (jsx(TableFooter, { canResize: false, ...tableFooterProps }))] }) }));
|
|
3332
3393
|
}
|
|
3333
|
-
return (jsx(TableControls, { ...controlProps, children: jsxs(Table, { ...tableProps, children: [jsx(TableHeader, { ...tableHeaderProps }),
|
|
3394
|
+
return (jsx(TableControls, { ...controlProps, children: jsxs(Table, { showLoading: isLoading, ...tableProps, children: [jsx(TableHeader, { ...tableHeaderProps }), bodyComponent, showFooter && jsx(TableFooter, { ...tableFooterProps })] }) }));
|
|
3334
3395
|
};
|
|
3335
3396
|
|
|
3336
3397
|
const TableCardContainer = ({ children, variant = "", gap = "1rem", gridTemplateColumns = "repeat(auto-fit, minmax(20rem, 1fr))", direction = "row", ...props }) => {
|
|
@@ -4449,7 +4510,8 @@ function filterArray(array, searchTerm) {
|
|
|
4449
4510
|
|
|
4450
4511
|
const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLimit = false, }) => {
|
|
4451
4512
|
const { watch, formState: { errors }, setValue, } = useFormContext();
|
|
4452
|
-
const {
|
|
4513
|
+
const { enumPickerLabels } = useSchemaContext();
|
|
4514
|
+
const formI18n = useFormI18n(column, prefix);
|
|
4453
4515
|
const { required, variant } = schema;
|
|
4454
4516
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4455
4517
|
const { gridColumn = 'span 12', gridRow = 'span 1', renderDisplay } = schema;
|
|
@@ -4457,7 +4519,7 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLi
|
|
|
4457
4519
|
const [limit, setLimit] = useState(10);
|
|
4458
4520
|
const [openSearchResult, setOpenSearchResult] = useState();
|
|
4459
4521
|
const ref = useRef(null);
|
|
4460
|
-
const colLabel =
|
|
4522
|
+
const colLabel = formI18n.colLabel;
|
|
4461
4523
|
const watchEnum = watch(colLabel);
|
|
4462
4524
|
const watchEnums = (watch(colLabel) ?? []);
|
|
4463
4525
|
const dataList = schema.enum ?? [];
|
|
@@ -4468,10 +4530,8 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLi
|
|
|
4468
4530
|
setLimit(10);
|
|
4469
4531
|
};
|
|
4470
4532
|
if (variant === 'radio') {
|
|
4471
|
-
return (jsx(Field, { label:
|
|
4472
|
-
gridRow, errorText: errors[`${colLabel}`]
|
|
4473
|
-
? translate.t(removeIndex(`${colLabel}.field_required`))
|
|
4474
|
-
: undefined, invalid: !!errors[colLabel], children: jsx(RadioGroup$1.Root, { defaultValue: "1", children: jsx(HStack, { gap: "6", children: filterArray(dataList, searchText ?? '').map((item) => {
|
|
4533
|
+
return (jsx(Field, { label: formI18n.label(), required: isRequired, alignItems: 'stretch', gridColumn,
|
|
4534
|
+
gridRow, errorText: errors[`${colLabel}`] ? formI18n.required() : undefined, invalid: !!errors[colLabel], children: jsx(RadioGroup$1.Root, { defaultValue: "1", children: jsx(HStack, { gap: "6", children: filterArray(dataList, searchText ?? '').map((item) => {
|
|
4475
4535
|
return (jsxs(RadioGroup$1.Item, { onClick: () => {
|
|
4476
4536
|
if (!isMultiple) {
|
|
4477
4537
|
setOpenSearchResult(false);
|
|
@@ -4482,13 +4542,11 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLi
|
|
|
4482
4542
|
setValue(colLabel, [...newSet]);
|
|
4483
4543
|
}, value: item, children: [jsx(RadioGroup$1.ItemHiddenInput, {}), jsx(RadioGroup$1.ItemIndicator, {}), jsx(RadioGroup$1.ItemText, { children: !!renderDisplay === true
|
|
4484
4544
|
? renderDisplay(item)
|
|
4485
|
-
:
|
|
4545
|
+
: formI18n.t(item) })] }, `${colLabel}-${item}`));
|
|
4486
4546
|
}) }) }) }));
|
|
4487
4547
|
}
|
|
4488
|
-
return (jsxs(Field, { label:
|
|
4489
|
-
gridRow, errorText: errors[`${colLabel}`]
|
|
4490
|
-
? translate.t(removeIndex(`${colLabel}.field_required`))
|
|
4491
|
-
: undefined, invalid: !!errors[colLabel], children: [isMultiple && (jsxs(Flex, { flexFlow: 'wrap', gap: 1, children: [watchEnums.map((enumValue) => {
|
|
4548
|
+
return (jsxs(Field, { label: formI18n.label(), required: isRequired, alignItems: 'stretch', gridColumn,
|
|
4549
|
+
gridRow, errorText: errors[`${colLabel}`] ? formI18n.required() : undefined, invalid: !!errors[colLabel], children: [isMultiple && (jsxs(Flex, { flexFlow: 'wrap', gap: 1, children: [watchEnums.map((enumValue) => {
|
|
4492
4550
|
const item = enumValue;
|
|
4493
4551
|
if (!!item === false) {
|
|
4494
4552
|
return jsx(Fragment, {});
|
|
@@ -4497,19 +4555,15 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLi
|
|
|
4497
4555
|
setValue(column, watchEnums.filter((id) => id != item));
|
|
4498
4556
|
}, children: !!renderDisplay === true
|
|
4499
4557
|
? renderDisplay(item)
|
|
4500
|
-
:
|
|
4558
|
+
: formI18n.t(item) }, item));
|
|
4501
4559
|
}), jsx(Tag, { size: "lg", cursor: 'pointer', onClick: () => {
|
|
4502
4560
|
setOpenSearchResult(true);
|
|
4503
|
-
}, children: enumPickerLabels?.addMore ??
|
|
4504
|
-
translate.t(removeIndex(`${colLabel}.add_more`)) }, `${colLabel}-add-more-tag`)] })), !isMultiple && (jsx(Button, { variant: 'outline', onClick: () => {
|
|
4561
|
+
}, children: enumPickerLabels?.addMore ?? formI18n.t('add_more') }, `${colLabel}-add-more-tag`)] })), !isMultiple && (jsx(Button, { variant: 'outline', onClick: () => {
|
|
4505
4562
|
setOpenSearchResult(true);
|
|
4506
|
-
}, justifyContent: 'start', children: !!watchEnum === false
|
|
4507
|
-
? ''
|
|
4508
|
-
: translate.t(removeIndex(`${colLabel}.${watchEnum ?? 'null'}`)) })), jsxs(PopoverRoot, { open: openSearchResult, onOpenChange: (e) => setOpenSearchResult(e.open), closeOnInteractOutside: true, initialFocusEl: () => ref.current, positioning: { placement: 'bottom-start' }, children: [jsx(PopoverTrigger, {}), jsx(PopoverContent, { portalled: false, children: jsxs(PopoverBody, { display: 'grid', gap: 1, children: [jsx(Input, { placeholder: enumPickerLabels?.typeToSearch ??
|
|
4509
|
-
translate.t(`${colLabel}.type_to_search`), onChange: (event) => {
|
|
4563
|
+
}, justifyContent: 'start', children: !!watchEnum === false ? '' : formI18n.t(watchEnum ?? 'null') })), jsxs(PopoverRoot, { open: openSearchResult, onOpenChange: (e) => setOpenSearchResult(e.open), closeOnInteractOutside: true, initialFocusEl: () => ref.current, positioning: { placement: 'bottom-start' }, children: [jsx(PopoverTrigger, {}), jsx(PopoverContent, { portalled: false, children: jsxs(PopoverBody, { display: 'grid', gap: 1, children: [jsx(Input, { placeholder: enumPickerLabels?.typeToSearch ?? formI18n.t('type_to_search'), onChange: (event) => {
|
|
4510
4564
|
onSearchChange(event);
|
|
4511
4565
|
setOpenSearchResult(true);
|
|
4512
|
-
}, autoComplete: "off", ref: ref }), jsx(PopoverTitle, {}), showTotalAndLimit && (jsx(Text, { children: `${enumPickerLabels?.total ??
|
|
4566
|
+
}, autoComplete: "off", ref: ref }), jsx(PopoverTitle, {}), showTotalAndLimit && (jsx(Text, { children: `${enumPickerLabels?.total ?? formI18n.t('total')}: ${count}, ${enumPickerLabels?.showing ?? formI18n.t('showing')} ${limit}` })), jsxs(Grid, { overflow: 'auto', maxHeight: '20rem', children: [jsx(Flex, { flexFlow: 'column wrap', children: dataList
|
|
4513
4567
|
.filter((item) => {
|
|
4514
4568
|
const searchTerm = (searchText || '').toLowerCase();
|
|
4515
4569
|
if (!searchTerm)
|
|
@@ -4521,7 +4575,7 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLi
|
|
|
4521
4575
|
// Check if the display value (translation) contains the search text
|
|
4522
4576
|
const displayValue = !!renderDisplay === true
|
|
4523
4577
|
? renderDisplay(item)
|
|
4524
|
-
:
|
|
4578
|
+
: formI18n.t(item);
|
|
4525
4579
|
// Convert to string and check if it includes the search term
|
|
4526
4580
|
const displayValueString = String(displayValue).toLowerCase();
|
|
4527
4581
|
const displayValueMatch = displayValueString.includes(searchTerm);
|
|
@@ -4541,9 +4595,9 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLi
|
|
|
4541
4595
|
setValue(colLabel, [...newSet]);
|
|
4542
4596
|
}, ...(selected ? { color: 'colorPalette.400/50' } : {}), children: !!renderDisplay === true
|
|
4543
4597
|
? renderDisplay(item)
|
|
4544
|
-
:
|
|
4598
|
+
: formI18n.t(item) }, `${colLabel}-${item}`));
|
|
4545
4599
|
}) }), isDirty && (jsx(Fragment, { children: dataList.length <= 0 && (jsx(Fragment, { children: enumPickerLabels?.emptySearchResult ??
|
|
4546
|
-
|
|
4600
|
+
formI18n.t('empty_search_result') })) }))] })] }) })] })] }));
|
|
4547
4601
|
};
|
|
4548
4602
|
|
|
4549
4603
|
function isEnteringWindow(_ref) {
|
|
@@ -18,6 +18,9 @@ export interface DataTableProps<TData = unknown> {
|
|
|
18
18
|
* Data array for the table.
|
|
19
19
|
*
|
|
20
20
|
* It will pass into as the data in `@tanstack/react-table`
|
|
21
|
+
* Do not toggle the data array, it will cause the table to re-render in infinite loop.
|
|
22
|
+
*
|
|
23
|
+
* @default []
|
|
21
24
|
*
|
|
22
25
|
*/
|
|
23
26
|
data: TData[];
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import { TableControlsProps } from
|
|
2
|
-
import { TableProps } from
|
|
3
|
-
import { TableBodyProps } from
|
|
4
|
-
import { TableFooterProps } from
|
|
5
|
-
import { TableHeaderProps } from
|
|
1
|
+
import { TableControlsProps } from './controls/TableControls';
|
|
2
|
+
import { TableProps } from './display/Table';
|
|
3
|
+
import { TableBodyProps } from './display/TableBody';
|
|
4
|
+
import { TableFooterProps } from './display/TableFooter';
|
|
5
|
+
import { TableHeaderProps } from './display/TableHeader';
|
|
6
6
|
export interface DefaultTableProps {
|
|
7
7
|
showFooter?: boolean;
|
|
8
|
-
tableProps?: Omit<TableProps,
|
|
8
|
+
tableProps?: Omit<TableProps, 'children'>;
|
|
9
9
|
tableHeaderProps?: TableHeaderProps;
|
|
10
10
|
tableBodyProps?: TableBodyProps;
|
|
11
11
|
tableFooterProps?: TableFooterProps;
|
|
12
12
|
controlProps?: TableControlsProps;
|
|
13
|
-
variant?:
|
|
13
|
+
variant?: '' | 'greedy';
|
|
14
|
+
isLoading?: boolean;
|
|
14
15
|
}
|
|
15
|
-
export declare const DefaultTable: ({ showFooter, tableProps, tableHeaderProps, tableBodyProps, tableFooterProps, controlProps, variant, }: DefaultTableProps) => import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
export declare const DefaultTable: ({ showFooter, tableProps, tableHeaderProps, tableBodyProps, tableFooterProps, controlProps, variant, isLoading, }: DefaultTableProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { DefaultTableProps } from './DefaultTable';
|
|
2
|
+
export interface DefaultTableServerProps extends DefaultTableProps {
|
|
3
|
+
/**
|
|
4
|
+
* Optional isLoading prop to override auto-detected loading state.
|
|
5
|
+
* If not provided, will automatically detect from DataTableServerContext.
|
|
6
|
+
*/
|
|
7
|
+
isLoading?: boolean;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* DefaultTableServer is a wrapper around DefaultTable that automatically
|
|
11
|
+
* detects server-side loading state from DataTableServerContext.
|
|
12
|
+
*
|
|
13
|
+
* Use this component when working with DataTableServer to automatically
|
|
14
|
+
* show skeleton loading state during data fetching.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```tsx
|
|
18
|
+
* <DataTableServer columns={columns} {...datatableServer}>
|
|
19
|
+
* <DefaultTableServer />
|
|
20
|
+
* </DataTableServer>
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export declare const DefaultTableServer: ({ isLoading: isLoadingOverride, ...props }: DefaultTableServerProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -7,4 +7,4 @@ export interface TableProps extends TableRootProps {
|
|
|
7
7
|
canResize?: boolean;
|
|
8
8
|
children: ReactNode;
|
|
9
9
|
}
|
|
10
|
-
export declare const Table: ({ children, emptyComponent, canResize, ...props }: TableProps) => string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | import("react/jsx-runtime").JSX.Element | null;
|
|
10
|
+
export declare const Table: ({ children, emptyComponent, canResize, showLoading, ...props }: TableProps) => string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | import("react/jsx-runtime").JSX.Element | null;
|