@bsol-oss/react-datatable5 12.0.0-beta.7 → 12.0.0-beta.70

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.
Files changed (52) hide show
  1. package/README.md +192 -0
  2. package/dist/index.d.ts +277 -83
  3. package/dist/index.js +1577 -469
  4. package/dist/index.mjs +1585 -477
  5. package/dist/types/components/DataTable/DataTable.d.ts +3 -1
  6. package/dist/types/components/DataTable/DataTableServer.d.ts +6 -4
  7. package/dist/types/components/DataTable/DefaultTable.d.ts +6 -9
  8. package/dist/types/components/DataTable/context/DataTableContext.d.ts +21 -3
  9. package/dist/types/components/DataTable/context/useDataTableContext.d.ts +2 -2
  10. package/dist/types/components/DataTable/controls/ReloadButton.d.ts +1 -2
  11. package/dist/types/components/DataTable/controls/ResetFilteringButton.d.ts +1 -4
  12. package/dist/types/components/DataTable/controls/ResetSelectionButton.d.ts +1 -4
  13. package/dist/types/components/DataTable/controls/ResetSortingButton.d.ts +1 -4
  14. package/dist/types/components/DataTable/controls/TableControls.d.ts +10 -2
  15. package/dist/types/components/DataTable/display/TableBody.d.ts +1 -2
  16. package/dist/types/components/DataTable/display/TableCardContainer.d.ts +6 -3
  17. package/dist/types/components/DataTable/display/TableDataDisplay.d.ts +6 -1
  18. package/dist/types/components/DataTable/display/TableFooter.d.ts +1 -5
  19. package/dist/types/components/DataTable/display/TableHeader.d.ts +46 -8
  20. package/dist/types/components/DataTable/useDataTableServer.d.ts +55 -3
  21. package/dist/types/components/DatePicker/DatePicker.d.ts +23 -0
  22. package/dist/types/components/DatePicker/DateTimePicker.d.ts +11 -0
  23. package/dist/types/components/DatePicker/DurationPicker.d.ts +12 -0
  24. package/dist/types/components/DatePicker/IsoTimePicker.d.ts +16 -0
  25. package/dist/types/components/DatePicker/PickerDemo.d.ts +1 -0
  26. package/dist/types/components/DatePicker/UniversalPicker.d.ts +9 -0
  27. package/dist/types/components/DatePicker/index.d.ts +7 -0
  28. package/dist/types/components/Filter/TagFilter.d.ts +5 -1
  29. package/dist/types/components/Form/SchemaFormContext.d.ts +8 -1
  30. package/dist/types/components/Form/components/core/DefaultForm.d.ts +1 -0
  31. package/dist/types/components/Form/components/core/FormRoot.d.ts +9 -2
  32. package/dist/types/components/Form/components/fields/CustomInput.d.ts +8 -0
  33. package/dist/types/components/Form/components/fields/DatePicker.d.ts +2 -7
  34. package/dist/types/components/Form/components/fields/DateTimePicker.d.ts +2 -0
  35. package/dist/types/components/Form/components/fields/EnumPicker.d.ts +2 -1
  36. package/dist/types/components/Form/components/fields/FilePicker.d.ts +2 -5
  37. package/dist/types/components/Form/components/fields/StringInputField.d.ts +19 -5
  38. package/dist/types/components/Form/components/fields/TextAreaInput.d.ts +12 -0
  39. package/dist/types/components/Form/components/fields/TimePicker.d.ts +7 -0
  40. package/dist/types/components/Form/components/fields/types.d.ts +6 -0
  41. package/dist/types/components/Form/components/types/CustomJSONSchema7.d.ts +19 -1
  42. package/dist/types/components/Form/components/viewers/CustomViewer.d.ts +8 -0
  43. package/dist/types/components/Form/components/viewers/DateTimeViewer.d.ts +7 -0
  44. package/dist/types/components/Form/components/viewers/TextAreaViewer.d.ts +12 -0
  45. package/dist/types/components/Form/components/viewers/TimeViewer.d.ts +7 -0
  46. package/dist/types/components/Form/utils/translateWrapper.d.ts +6 -0
  47. package/dist/types/components/Form/utils/validateData.d.ts +9 -0
  48. package/dist/types/components/Form/utils/validation.d.ts +104 -0
  49. package/dist/types/components/TextArea/TextArea.d.ts +22 -0
  50. package/dist/types/components/TimePicker/TimePicker.d.ts +21 -0
  51. package/dist/types/index.d.ts +17 -2
  52. package/package.json +9 -2
package/dist/index.mjs CHANGED
@@ -1,26 +1,26 @@
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, Checkbox as Checkbox$1, Table as Table$1, Tooltip as Tooltip$1, Group, InputElement, Icon, MenuRoot as MenuRoot$1, MenuTrigger as MenuTrigger$1, List, Accordion, 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, MenuRoot as MenuRoot$1, MenuTrigger as MenuTrigger$1, Accordion, 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
- import React__default, { createContext, useContext, useState, useEffect, useRef } from 'react';
5
+ import React__default, { createContext, useContext, useState, useEffect, useRef, forwardRef } from 'react';
6
6
  import { LuX, LuCheck, LuChevronRight, LuChevronDown } from 'react-icons/lu';
7
- import { MdOutlineSort, MdFilterAlt, MdSearch, MdClose, MdOutlineViewColumn, MdFilterListAlt, MdPushPin, MdCancel, MdClear, MdOutlineChecklist } from 'react-icons/md';
8
- import { FaUpDown, FaGripLinesVertical } from 'react-icons/fa6';
7
+ import { MdOutlineSort, MdFilterAlt, MdSearch, MdOutlineViewColumn, MdFilterListAlt, MdPushPin, MdCancel, MdClear, MdOutlineChecklist, MdDateRange } from 'react-icons/md';
8
+ import { FaUpDown, FaGripLinesVertical, FaTrash } from 'react-icons/fa6';
9
9
  import { BiDownArrow, BiUpArrow, BiError } from 'react-icons/bi';
10
- import { CgClose } from 'react-icons/cg';
10
+ import { CgClose, CgTrash } from 'react-icons/cg';
11
11
  import Dayzed from '@bsol-oss/dayzed-react19';
12
12
  import { HiMiniEllipsisHorizontal, HiChevronLeft, HiChevronRight } from 'react-icons/hi2';
13
- import { IoMdEye, IoMdCheckbox } from 'react-icons/io';
13
+ import { IoMdEye, IoMdCheckbox, IoMdClock } from 'react-icons/io';
14
14
  import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
15
15
  import { bind, bindAll } from 'bind-event-listener';
16
16
  import _defineProperty from '@babel/runtime/helpers/defineProperty';
17
17
  import _toConsumableArray from '@babel/runtime/helpers/toConsumableArray';
18
18
  import rafSchd from 'raf-schd';
19
19
  import invariant from 'tiny-invariant';
20
- import { HiColorSwatch } from 'react-icons/hi';
20
+ import { HiColorSwatch, HiOutlineInformationCircle } from 'react-icons/hi';
21
21
  import { flexRender, makeStateUpdater, functionalUpdate, useReactTable, getCoreRowModel, getFilteredRowModel, getSortedRowModel, getPaginationRowModel, createColumnHelper } from '@tanstack/react-table';
22
22
  import { rankItem } from '@tanstack/match-sorter-utils';
23
- import { BsExclamationCircleFill } from 'react-icons/bs';
23
+ import { BsExclamationCircleFill, BsClock } from 'react-icons/bs';
24
24
  import { useDebounce } from '@uidotdev/usehooks';
25
25
  import { useQueryClient, useQuery } from '@tanstack/react-query';
26
26
  import { IoReload } from 'react-icons/io5';
@@ -28,7 +28,12 @@ import { GrAscend, GrDescend } from 'react-icons/gr';
28
28
  import { useTranslation } from 'react-i18next';
29
29
  import axios from 'axios';
30
30
  import { FormProvider, useFormContext, useForm as useForm$1 } from 'react-hook-form';
31
+ import Ajv from 'ajv';
32
+ import addFormats from 'ajv-formats';
33
+ import addErrors from 'ajv-errors';
31
34
  import dayjs from 'dayjs';
35
+ import utc from 'dayjs/plugin/utc';
36
+ import timezone from 'dayjs/plugin/timezone';
32
37
  import { TiDeleteOutline } from 'react-icons/ti';
33
38
 
34
39
  const DataTableContext = createContext({
@@ -37,6 +42,56 @@ const DataTableContext = createContext({
37
42
  setGlobalFilter: () => { },
38
43
  type: "client",
39
44
  translate: {},
45
+ data: [],
46
+ columns: [],
47
+ columnOrder: [],
48
+ columnFilters: [],
49
+ density: "sm",
50
+ sorting: [],
51
+ setPagination: function () {
52
+ throw new Error("Function not implemented.");
53
+ },
54
+ setSorting: function () {
55
+ throw new Error("Function not implemented.");
56
+ },
57
+ setColumnFilters: function () {
58
+ throw new Error("Function not implemented.");
59
+ },
60
+ setRowSelection: function () {
61
+ throw new Error("Function not implemented.");
62
+ },
63
+ setColumnOrder: function () {
64
+ throw new Error("Function not implemented.");
65
+ },
66
+ setDensity: function () {
67
+ throw new Error("Function not implemented.");
68
+ },
69
+ setColumnVisibility: function () {
70
+ throw new Error("Function not implemented.");
71
+ },
72
+ pagination: {
73
+ pageIndex: 0,
74
+ pageSize: 10,
75
+ },
76
+ rowSelection: {},
77
+ columnVisibility: {},
78
+ tableLabel: {
79
+ view: "View",
80
+ edit: "Edit",
81
+ filterButtonText: "Filter",
82
+ filterTitle: "Filter",
83
+ filterReset: "Reset",
84
+ filterClose: "Close",
85
+ reloadTooltip: "Reload",
86
+ reloadButtonText: "Reload",
87
+ resetSelection: "Reset Selection",
88
+ resetSorting: "Reset Sorting",
89
+ rowCountText: "Row Count",
90
+ hasErrorText: "Has Error",
91
+ globalFilterPlaceholder: "Search",
92
+ trueLabel: "True",
93
+ falseLabel: "False",
94
+ },
40
95
  });
41
96
 
42
97
  const useDataTableContext = () => {
@@ -92,11 +147,13 @@ const TableSorter = () => {
92
147
  }) }))) }));
93
148
  };
94
149
 
95
- const ResetSortingButton = ({ text = "Reset Sorting", }) => {
150
+ const ResetSortingButton = () => {
96
151
  const { table } = useDataTableContext();
152
+ const { tableLabel } = useDataTableContext();
153
+ const { resetSorting } = tableLabel;
97
154
  return (jsx(Button$1, { onClick: () => {
98
155
  table.resetSorting();
99
- }, children: text }));
156
+ }, children: resetSorting }));
100
157
  };
101
158
 
102
159
  const EditSortingButton = ({ text, icon = jsx(MdOutlineSort, {}), title = "Edit Sorting", }) => {
@@ -124,7 +181,7 @@ const monthNamesFull = [
124
181
  "November",
125
182
  "December",
126
183
  ];
127
- const weekdayNamesShort$1 = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
184
+ const weekdayNamesShort = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
128
185
  function Calendar$1({ calendars, getBackProps, getForwardProps, getDateProps, selected = [], firstDayOfWeek = 0, }) {
129
186
  const [hoveredDate, setHoveredDate] = useState();
130
187
  const onMouseLeave = () => {
@@ -159,7 +216,7 @@ function Calendar$1({ calendars, getBackProps, getForwardProps, getDateProps, se
159
216
  offset: 12,
160
217
  }), children: ">>" })] }), jsx(Grid, { templateColumns: "repeat(2, auto)", justifyContent: "center", gap: 4, children: calendars.map((calendar) => (jsxs(Grid, { gap: 4, children: [jsxs(Grid, { justifyContent: "center", children: [monthNamesFull[calendar.month], " ", calendar.year] }), jsx(Grid, { templateColumns: "repeat(7, auto)", justifyContent: "center", children: [0, 1, 2, 3, 4, 5, 6].map((weekdayNum) => {
161
218
  const weekday = (weekdayNum + firstDayOfWeek) % 7;
162
- return (jsx(Box, { minWidth: "48px", textAlign: "center", children: weekdayNamesShort$1[weekday] }, `${calendar.month}${calendar.year}${weekday}`));
219
+ return (jsx(Box, { minWidth: "48px", textAlign: "center", children: weekdayNamesShort[weekday] }, `${calendar.month}${calendar.year}${weekday}`));
163
220
  }) }), jsx(Grid, { templateColumns: "repeat(7, auto)", justifyContent: "center", children: calendar.weeks.map((week, windex) => week.map((dateObj, index) => {
164
221
  const key = `${calendar.month}${calendar.year}${windex}${index}`;
165
222
  if (!dateObj) {
@@ -280,8 +337,17 @@ const Tag = React.forwardRef(function Tag(props, ref) {
280
337
  return (jsxs(Tag$1.Root, { ref: ref, ...rest, children: [startElement && (jsx(Tag$1.StartElement, { children: startElement })), jsx(Tag$1.Label, { children: children }), endElement && (jsx(Tag$1.EndElement, { children: endElement })), closable && (jsx(Tag$1.EndElement, { children: jsx(Tag$1.CloseTrigger, { onClick: onClose }) }))] }));
281
338
  });
282
339
 
283
- const TagFilter = ({ availableTags, selectedTags, onTagChange, }) => {
340
+ const TagFilter = ({ availableTags, selectedTags, onTagChange, selectOne = false, }) => {
284
341
  const toggleTag = (tag) => {
342
+ if (selectOne) {
343
+ if (selectedTags.includes(tag)) {
344
+ onTagChange([]);
345
+ }
346
+ else {
347
+ onTagChange([tag]);
348
+ }
349
+ return;
350
+ }
285
351
  if (selectedTags.includes(tag)) {
286
352
  onTagChange(selectedTags.filter((t) => t !== tag));
287
353
  }
@@ -289,10 +355,14 @@ const TagFilter = ({ availableTags, selectedTags, onTagChange, }) => {
289
355
  onTagChange([...selectedTags, tag]);
290
356
  }
291
357
  };
292
- return (jsx(Flex, { flexFlow: "wrap", p: "0.5rem", gap: "0.5rem", children: availableTags.map((tag) => (jsx(Tag, { variant: selectedTags.includes(tag) ? "solid" : "outline", cursor: "pointer", closable: selectedTags.includes(tag) ? true : undefined, onClick: () => toggleTag(tag), children: tag }))) }));
358
+ return (jsx(Flex, { flexFlow: "wrap", p: "0.5rem", gap: "0.5rem", children: availableTags.map((tag) => {
359
+ const { label, value } = tag;
360
+ return (jsx(Tag, { variant: selectedTags.includes(value) ? "solid" : "outline", cursor: "pointer", closable: selectedTags.includes(value) ? true : undefined, onClick: () => toggleTag(value), children: label ?? value }));
361
+ }) }));
293
362
  };
294
363
 
295
364
  const Filter = ({ column }) => {
365
+ const { tableLabel } = useDataTableContext();
296
366
  const { filterVariant } = column.columnDef.meta ?? {};
297
367
  const displayName = column.columnDef.meta?.displayName ?? column.id;
298
368
  const filterOptions = column.columnDef.meta?.filterOptions ?? [];
@@ -307,10 +377,14 @@ const Filter = ({ column }) => {
307
377
  if (filterVariant === "select") {
308
378
  return (jsxs(Flex, { flexFlow: "column", gap: "0.25rem", children: [jsx(Text, { children: displayName }), jsx(RadioGroup, { value: column.getFilterValue() ? String(column.getFilterValue()) : "", onValueChange: (details) => {
309
379
  column.setFilterValue(details.value);
310
- }, children: jsx(Flex, { flexFlow: "wrap", gap: "0.5rem", children: filterOptions.map((item) => (jsx(Radio, { value: item, children: item }, item))) }) })] }, column.id));
380
+ }, children: jsxs(Flex, { flexFlow: "wrap", gap: "0.5rem", children: [filterOptions.length === 0 && jsx(Text, { children: "No filter options" }), filterOptions.length > 0 &&
381
+ filterOptions.map((item) => (jsx(Radio, { value: item.value, children: item.label }, item.value)))] }) })] }, column.id));
311
382
  }
312
383
  if (filterVariant === "tag") {
313
- return (jsxs(Flex, { flexFlow: "column", gap: "0.25rem", children: [jsx(Text, { children: displayName }), jsx(TagFilter, { availableTags: filterOptions, selectedTags: (column.getFilterValue() ?? []), onTagChange: (tags) => {
384
+ return (jsxs(Flex, { flexFlow: "column", gap: "0.25rem", children: [jsx(Text, { children: displayName }), jsx(TagFilter, { availableTags: filterOptions.map((item) => ({
385
+ label: item.label,
386
+ value: item.value,
387
+ })), selectedTags: (column.getFilterValue() ?? []), onTagChange: (tags) => {
314
388
  if (tags.length === 0) {
315
389
  return column.setFilterValue(undefined);
316
390
  }
@@ -318,7 +392,11 @@ const Filter = ({ column }) => {
318
392
  } })] }, column.id));
319
393
  }
320
394
  if (filterVariant === "boolean") {
321
- return (jsxs(Flex, { flexFlow: "column", gap: "0.25rem", children: [jsx(Text, { children: displayName }), jsx(TagFilter, { availableTags: ["true", "false"], selectedTags: (column.getFilterValue() ?? []), onTagChange: (tags) => {
395
+ const { trueLabel, falseLabel } = tableLabel;
396
+ return (jsxs(Flex, { flexFlow: "column", gap: "0.25rem", children: [jsx(Text, { children: displayName }), jsx(TagFilter, { availableTags: [
397
+ { label: trueLabel, value: "true" },
398
+ { label: falseLabel, value: "false" },
399
+ ], selectedTags: (column.getFilterValue() ?? []), onTagChange: (tags) => {
322
400
  if (tags.length === 0) {
323
401
  return column.setFilterValue(undefined);
324
402
  }
@@ -373,17 +451,20 @@ const TableFilter = () => {
373
451
  }) }));
374
452
  };
375
453
 
376
- const ResetFilteringButton = ({ text = "Reset Filtering", }) => {
454
+ const ResetFilteringButton = () => {
377
455
  const { table } = useDataTableContext();
456
+ const { tableLabel } = useDataTableContext();
457
+ const { filterReset } = tableLabel;
378
458
  return (jsx(Button$1, { onClick: () => {
379
459
  table.resetColumnFilters();
380
- }, children: text }));
460
+ }, children: filterReset }));
381
461
  };
382
462
 
383
463
  const FilterDialog = ({ icon = jsx(MdFilterAlt, {}), }) => {
384
464
  const filterModal = useDisclosure();
385
- const { translate } = useDataTableContext();
386
- return (jsxs(DialogRoot, { size: ["full", "full", "md", "md"], open: filterModal.open, children: [jsx(DialogTrigger, { asChild: true, children: jsxs(Button$1, { as: Box, variant: "ghost", onClick: filterModal.onOpen, children: [icon, " ", translate.t("filterDialog.buttonText")] }) }), jsxs(DialogContent, { children: [jsx(DialogHeader, { children: jsx(DialogTitle, { children: translate.t("filterDialog.title") }) }), jsx(DialogBody, { display: "flex", flexFlow: "column", children: jsx(TableFilter, {}) }), jsxs(DialogFooter, { children: [jsx(ResetFilteringButton, { text: translate.t("filterDialog.reset") }), jsx(Button$1, { onClick: filterModal.onClose, variant: "subtle", children: translate.t("filterDialog.close") })] }), jsx(DialogCloseTrigger, { onClick: filterModal.onClose })] })] }));
465
+ const { tableLabel } = useDataTableContext();
466
+ const { filterButtonText, filterTitle, filterClose } = tableLabel;
467
+ return (jsxs(DialogRoot, { size: ["full", "full", "md", "md"], open: filterModal.open, children: [jsx(DialogTrigger, { asChild: true, children: jsxs(Button$1, { as: Box, variant: "ghost", onClick: filterModal.onOpen, children: [icon, " ", filterButtonText] }) }), jsxs(DialogContent, { children: [jsx(DialogHeader, { children: jsx(DialogTitle, { children: filterTitle }) }), jsx(DialogBody, { display: "flex", flexFlow: "column", children: jsx(TableFilter, {}) }), jsxs(DialogFooter, { children: [jsx(ResetFilteringButton, {}), jsx(Button$1, { onClick: filterModal.onClose, variant: "subtle", children: filterClose })] }), jsx(DialogCloseTrigger, { onClick: filterModal.onClose })] })] }));
387
468
  };
388
469
 
389
470
  const MenuContent = React.forwardRef(function MenuContent(props, ref) {
@@ -502,11 +583,13 @@ const Pagination = () => {
502
583
  }, children: jsxs(HStack, { children: [jsx(PaginationPrevTrigger, {}), jsx(PaginationItems, {}), jsx(PaginationNextTrigger, {})] }) }));
503
584
  };
504
585
 
505
- const ResetSelectionButton = ({ text = "Reset Selection", }) => {
586
+ const ResetSelectionButton = () => {
506
587
  const { table } = useDataTableContext();
588
+ const { tableLabel } = useDataTableContext();
589
+ const { resetSelection } = tableLabel;
507
590
  return (jsx(Button$1, { onClick: () => {
508
591
  table.resetRowSelection();
509
- }, children: text }));
592
+ }, children: resetSelection }));
510
593
  };
511
594
 
512
595
  const RowCountText = () => {
@@ -2421,8 +2504,8 @@ CheckboxCard$1.Indicator;
2421
2504
  function ColumnCard({ columnId }) {
2422
2505
  const ref = useRef(null);
2423
2506
  const [dragging, setDragging] = useState(false); // NEW
2424
- const { table } = useDataTableContext();
2425
- const displayName = columnId;
2507
+ const { table, translate } = useDataTableContext();
2508
+ const displayName = translate.t(columnId);
2426
2509
  const column = table.getColumn(columnId);
2427
2510
  invariant(column);
2428
2511
  useEffect(() => {
@@ -2437,7 +2520,7 @@ function ColumnCard({ columnId }) {
2437
2520
  onDrop: () => setDragging(false), // NEW
2438
2521
  });
2439
2522
  }, [columnId, table]);
2440
- return (jsxs(Grid, { ref: ref, templateColumns: "auto 1fr", gap: "0.5rem", alignItems: "center", style: dragging ? { opacity: 0.4 } : {}, children: [jsx(Flex, { alignItems: "center", padding: "0", cursor: "grab", children: jsx(FaGripLinesVertical, { color: "gray.400" }) }), jsx(Flex, { justifyContent: "space-between", alignItems: "center", children: jsx(CheckboxCard, { variant: "surface", label: displayName, checked: column.getIsVisible(), onChange: column.getToggleVisibilityHandler() }) })] }));
2523
+ return (jsxs(Grid, { ref: ref, templateColumns: "auto 1fr", gap: "0.5rem", alignItems: "center", style: dragging ? { opacity: 0.4 } : {}, children: [jsx(Flex, { alignItems: "center", padding: "0", cursor: "grab", children: jsx(FaGripLinesVertical, { color: "colorPalette.400" }) }), jsx(Flex, { justifyContent: "space-between", alignItems: "center", children: jsx(CheckboxCard, { variant: "surface", label: displayName, checked: column.getIsVisible(), onChange: column.getToggleVisibilityHandler() }) })] }));
2441
2524
  }
2442
2525
  function CardContainer({ location, children }) {
2443
2526
  const ref = useRef(null);
@@ -2456,7 +2539,6 @@ function CardContainer({ location, children }) {
2456
2539
  onDrop: () => setIsDraggedOver(false),
2457
2540
  });
2458
2541
  }, [location]);
2459
- // const isDark = (location + location) % 2 === 1;
2460
2542
  function getColor(isDraggedOver) {
2461
2543
  if (isDraggedOver) {
2462
2544
  return {
@@ -2466,7 +2548,6 @@ function CardContainer({ location, children }) {
2466
2548
  },
2467
2549
  };
2468
2550
  }
2469
- // return isDark ? "lightgrey" : "white";
2470
2551
  return {
2471
2552
  backgroundColor: undefined,
2472
2553
  _dark: {
@@ -2517,8 +2598,9 @@ const TableViewer = () => {
2517
2598
 
2518
2599
  const ViewDialog = ({ icon = jsx(IoMdEye, {}) }) => {
2519
2600
  const viewModel = useDisclosure();
2520
- const { translate } = useDataTableContext();
2521
- return (jsxs(DialogRoot, { children: [jsx(DialogBackdrop, {}), jsx(DialogTrigger, { asChild: true, children: jsxs(Button$1, { as: Box, variant: "ghost", onClick: viewModel.onOpen, children: [icon, " ", translate.t("viewDialog.buttonText")] }) }), jsxs(DialogContent, { children: [jsx(DialogCloseTrigger, {}), jsx(DialogHeader, { children: jsx(DialogTitle, { children: translate.t("viewDialog.title") }) }), jsx(DialogBody, { children: jsx(TableViewer, {}) }), jsx(DialogFooter, {})] })] }));
2601
+ const { tableLabel } = useDataTableContext();
2602
+ const { view } = tableLabel;
2603
+ return (jsxs(DialogRoot, { children: [jsx(DialogBackdrop, {}), jsx(DialogTrigger, { asChild: true, children: jsxs(Button$1, { as: Box, variant: "ghost", onClick: viewModel.onOpen, children: [icon, " ", view] }) }), jsxs(DialogContent, { children: [jsx(DialogCloseTrigger, {}), jsx(DialogHeader, { children: jsx(DialogTitle, { children: view }) }), jsx(DialogBody, { children: jsx(TableViewer, {}) }), jsx(DialogFooter, {})] })] }));
2522
2604
  };
2523
2605
 
2524
2606
  const CardHeader = ({ row, imageColumnId = undefined, titleColumnId = undefined, tagColumnId = undefined, tagIcon = undefined, showTag = true, imageProps = {}, }) => {
@@ -2569,7 +2651,7 @@ const RecordDisplay = ({ object, boxProps, translate, prefix = "", }) => {
2569
2651
  return jsx(Fragment, { children: "null" });
2570
2652
  }
2571
2653
  return (jsx(Grid, { rowGap: 1, padding: 1, overflow: "auto", ...boxProps, children: Object.entries(object).map(([field, value]) => {
2572
- return (jsxs(Grid, { columnGap: 2, gridTemplateColumns: "auto 1fr", children: [jsx(Text, { color: "gray.400", children: getColumn({ field }) }), typeof value === "object" ? (jsx(RecordDisplay, { object: value, prefix: `${prefix}${field}.`, translate: translate })) : (jsx(Text, { children: JSON.stringify(value) }))] }, field));
2654
+ return (jsxs(Grid, { columnGap: 2, gridTemplateColumns: "auto 1fr", children: [jsx(Text, { color: "colorPalette.400", children: getColumn({ field }) }), typeof value === "object" ? (jsx(RecordDisplay, { object: value, prefix: `${prefix}${field}.`, translate: translate })) : (jsx(Text, { children: JSON.stringify(value) }))] }, field));
2573
2655
  }) }));
2574
2656
  };
2575
2657
 
@@ -2619,7 +2701,7 @@ const CellRenderer = ({ cell }) => {
2619
2701
  paddingY: 2,
2620
2702
  }, object: value })] }, cell.id));
2621
2703
  }
2622
- return (jsxs(Box, { gridColumn, gridRow, children: [jsx(Box, { color: 'gray.400', children: getLabel({ columnId: cell.column.id }) }), jsx(Box, { wordBreak: "break-word", textOverflow: "ellipsis", overflow: "hidden", children: `${formatValue(cell.getValue())}` })] }, cell.id));
2704
+ return (jsxs(Box, { gridColumn, gridRow, children: [jsx(Box, { color: "colorPalette.400", children: getLabel({ columnId: cell.column.id }) }), jsx(Box, { wordBreak: "break-word", textOverflow: "ellipsis", overflow: "hidden", children: `${formatValue(cell.getValue())}` })] }, cell.id));
2623
2705
  };
2624
2706
  const DataDisplay = ({ variant = "" }) => {
2625
2707
  const { table, translate } = useDataTableContext();
@@ -2741,7 +2823,23 @@ const fuzzyFilter = (row, columnId, value, addMeta) => {
2741
2823
  *
2742
2824
  * @link https://tanstack.com/table/latest/docs/guide/column-defs
2743
2825
  */
2744
- function DataTable({ columns, data, enableRowSelection = true, enableMultiRowSelection = true, enableSubRowSelection = true, columnOrder, columnFilters, columnVisibility, density, globalFilter, pagination, sorting, rowSelection, setPagination, setSorting, setColumnFilters, setRowSelection, setGlobalFilter, setColumnOrder, setDensity, setColumnVisibility, translate, children, }) {
2826
+ function DataTable({ columns, data, enableRowSelection = true, enableMultiRowSelection = true, enableSubRowSelection = true, columnOrder, columnFilters, columnVisibility, density, globalFilter, pagination, sorting, rowSelection, setPagination, setSorting, setColumnFilters, setRowSelection, setGlobalFilter, setColumnOrder, setDensity, setColumnVisibility, translate, children, tableLabel = {
2827
+ view: "View",
2828
+ edit: "Edit",
2829
+ filterButtonText: "Filter",
2830
+ filterTitle: "Filter",
2831
+ filterReset: "Reset",
2832
+ filterClose: "Close",
2833
+ reloadTooltip: "Reload",
2834
+ reloadButtonText: "Reload",
2835
+ resetSelection: "Reset Selection",
2836
+ resetSorting: "Reset Sorting",
2837
+ rowCountText: "Row Count",
2838
+ hasErrorText: "Has Error",
2839
+ globalFilterPlaceholder: "Search",
2840
+ trueLabel: "True",
2841
+ falseLabel: "False",
2842
+ }, }) {
2745
2843
  const table = useReactTable({
2746
2844
  _features: [DensityFeature],
2747
2845
  data: data,
@@ -2794,7 +2892,7 @@ function DataTable({ columns, data, enableRowSelection = true, enableMultiRowSel
2794
2892
  setGlobalFilter,
2795
2893
  type: "client",
2796
2894
  translate,
2797
- columns,
2895
+ columns: columns,
2798
2896
  sorting,
2799
2897
  setSorting,
2800
2898
  columnFilters,
@@ -2809,6 +2907,8 @@ function DataTable({ columns, data, enableRowSelection = true, enableMultiRowSel
2809
2907
  setDensity,
2810
2908
  columnVisibility,
2811
2909
  setColumnVisibility,
2910
+ data,
2911
+ tableLabel,
2812
2912
  }, children: children }));
2813
2913
  }
2814
2914
 
@@ -2823,10 +2923,26 @@ function DataTable({ columns, data, enableRowSelection = true, enableMultiRowSel
2823
2923
  *
2824
2924
  * @link https://tanstack.com/table/latest/docs/guide/column-defs
2825
2925
  */
2826
- function DataTableServer({ columns, enableRowSelection = true, enableMultiRowSelection = true, enableSubRowSelection = true, columnOrder, columnFilters, columnVisibility, density, globalFilter, pagination, sorting, rowSelection, setPagination, setSorting, setColumnFilters, setRowSelection, setGlobalFilter, setColumnOrder, setDensity, setColumnVisibility, query, url, translate, children, }) {
2926
+ function DataTableServer({ columns, enableRowSelection = true, enableMultiRowSelection = true, enableSubRowSelection = true, columnOrder, columnFilters, columnVisibility, density, globalFilter, pagination, sorting, rowSelection, setPagination, setSorting, setColumnFilters, setRowSelection, setGlobalFilter, setColumnOrder, setDensity, setColumnVisibility, query, url, translate, children, tableLabel = {
2927
+ view: "View",
2928
+ edit: "Edit",
2929
+ filterButtonText: "Filter",
2930
+ filterTitle: "Filter",
2931
+ filterReset: "Reset",
2932
+ filterClose: "Close",
2933
+ reloadTooltip: "Reload",
2934
+ reloadButtonText: "Reload",
2935
+ resetSelection: "Reset Selection",
2936
+ resetSorting: "Reset Sorting",
2937
+ rowCountText: "Row Count",
2938
+ hasErrorText: "Has Error",
2939
+ globalFilterPlaceholder: "Search",
2940
+ trueLabel: "True",
2941
+ falseLabel: "False",
2942
+ }, }) {
2827
2943
  const table = useReactTable({
2828
2944
  _features: [DensityFeature],
2829
- data: query.data?.data ?? [],
2945
+ data: (query.data?.data ?? []),
2830
2946
  rowCount: query.data?.count ?? 0,
2831
2947
  columns: columns,
2832
2948
  getCoreRowModel: getCoreRowModel(),
@@ -2872,12 +2988,12 @@ function DataTableServer({ columns, enableRowSelection = true, enableMultiRowSel
2872
2988
  // for tanstack-table ts bug end
2873
2989
  });
2874
2990
  return (jsx(DataTableContext.Provider, { value: {
2875
- table: { ...table },
2991
+ table: table,
2876
2992
  globalFilter,
2877
2993
  setGlobalFilter,
2878
2994
  type: "server",
2879
2995
  translate,
2880
- columns,
2996
+ columns: columns,
2881
2997
  sorting,
2882
2998
  setSorting,
2883
2999
  columnFilters,
@@ -2892,98 +3008,11 @@ function DataTableServer({ columns, enableRowSelection = true, enableMultiRowSel
2892
3008
  setDensity,
2893
3009
  columnVisibility,
2894
3010
  setColumnVisibility,
3011
+ data: query.data?.data ?? [],
3012
+ tableLabel,
2895
3013
  }, children: jsx(DataTableServerContext.Provider, { value: { url, query }, children: children }) }));
2896
3014
  }
2897
3015
 
2898
- const Checkbox = React.forwardRef(function Checkbox(props, ref) {
2899
- const { icon, children, inputProps, rootRef, ...rest } = props;
2900
- return (jsxs(Checkbox$1.Root, { ref: rootRef, ...rest, children: [jsx(Checkbox$1.HiddenInput, { ref: ref, ...inputProps }), jsx(Checkbox$1.Control, { children: icon || jsx(Checkbox$1.Indicator, {}) }), children != null && (jsx(Checkbox$1.Label, { children: children }))] }));
2901
- });
2902
-
2903
- const TableBody = ({ pinnedBgColor = { light: "gray.50", dark: "gray.700" }, showSelector = false, alwaysShowSelector = true, canResize = true, }) => {
2904
- "use no memo";
2905
- const { table } = useDataTableContext();
2906
- const SELECTION_BOX_WIDTH = 20;
2907
- const [hoveredRow, setHoveredRow] = useState(-1);
2908
- const handleRowHover = (index) => {
2909
- setHoveredRow(index);
2910
- };
2911
- const getTdProps = (cell) => {
2912
- const tdProps = cell.column.getIsPinned()
2913
- ? {
2914
- left: showSelector
2915
- ? `${cell.column.getStart("left") + SELECTION_BOX_WIDTH + table.getDensityValue() * 2}px`
2916
- : `${cell.column.getStart("left")}px`,
2917
- background: pinnedBgColor.light,
2918
- position: "sticky",
2919
- zIndex: -1,
2920
- _dark: {
2921
- backgroundColor: pinnedBgColor.dark,
2922
- },
2923
- }
2924
- : {};
2925
- return tdProps;
2926
- };
2927
- const getTrProps = ({ hoveredRow, index, }) => {
2928
- if (hoveredRow === -1) {
2929
- return {};
2930
- }
2931
- if (hoveredRow === index) {
2932
- return {
2933
- opacity: "1",
2934
- };
2935
- }
2936
- return {
2937
- opacity: "0.8",
2938
- };
2939
- };
2940
- return (jsx(Table$1.Body, { children: table.getRowModel().rows.map((row, index) => {
2941
- return (jsxs(Table$1.Row, { display: "flex", zIndex: 1, onMouseEnter: () => handleRowHover(index), onMouseLeave: () => handleRowHover(-1), ...getTrProps({ hoveredRow, index }), children: [showSelector && (jsx(TableRowSelector, { index: index, row: row, hoveredRow: hoveredRow, alwaysShowSelector: alwaysShowSelector })), row.getVisibleCells().map((cell, index) => {
2942
- return (jsx(Table$1.Cell, { padding: `${table.getDensityValue()}px`,
2943
- // styling resize and pinning start
2944
- flex: `${canResize ? "0" : "1"} 0 ${cell.column.getSize()}px`, backgroundColor: "white", ...getTdProps(cell), _dark: {
2945
- backgroundColor: "gray.950",
2946
- }, children: flexRender(cell.column.columnDef.cell, cell.getContext()) }, `chakra-table-rowcell-${cell.id}-${index}`));
2947
- })] }, `chakra-table-row-${row.id}`));
2948
- }) }));
2949
- };
2950
- const TableRowSelector = ({ index, row, hoveredRow, pinnedBgColor = { light: "gray.50", dark: "gray.700" }, alwaysShowSelector = true, }) => {
2951
- const { table } = useDataTableContext();
2952
- const SELECTION_BOX_WIDTH = 20;
2953
- const isCheckBoxVisible = (current_index, current_row) => {
2954
- if (alwaysShowSelector) {
2955
- return true;
2956
- }
2957
- if (current_row.getIsSelected()) {
2958
- return true;
2959
- }
2960
- if (hoveredRow == current_index) {
2961
- return true;
2962
- }
2963
- return false;
2964
- };
2965
- return (jsxs(Table$1.Cell, { padding: `${table.getDensityValue()}px`, ...(table.getIsSomeColumnsPinned("left")
2966
- ? {
2967
- left: `0px`,
2968
- backgroundColor: pinnedBgColor.light,
2969
- position: "sticky",
2970
- zIndex: 1,
2971
- _dark: { backgroundColor: pinnedBgColor.dark },
2972
- }
2973
- : {}),
2974
- // styling resize and pinning end
2975
- display: "grid", children: [!isCheckBoxVisible(index, row) && (jsx(Box, { as: "span", margin: "0rem", display: "grid", justifyItems: "center", alignItems: "center", width: `${SELECTION_BOX_WIDTH}px`, height: `${SELECTION_BOX_WIDTH}px` })), isCheckBoxVisible(index, row) && (jsx(Box, { margin: "0rem", display: "grid", justifyItems: "center", alignItems: "center", children: jsx(Checkbox, { width: `${SELECTION_BOX_WIDTH}px`, height: `${SELECTION_BOX_WIDTH}px`, isChecked: row.getIsSelected(),
2976
- disabled: !row.getCanSelect(),
2977
- onChange: row.getToggleSelectedHandler() }) }))] }));
2978
- };
2979
-
2980
- const Tooltip = React.forwardRef(function Tooltip(props, ref) {
2981
- const { showArrow, children, disabled, portalled, content, contentProps, portalRef, ...rest } = props;
2982
- if (disabled)
2983
- return children;
2984
- return (jsxs(Tooltip$1.Root, { ...rest, children: [jsx(Tooltip$1.Trigger, { asChild: true, children: children }), jsx(Portal, { disabled: !portalled, container: portalRef, children: jsx(Tooltip$1.Positioner, { children: jsxs(Tooltip$1.Content, { ref: ref, ...contentProps, children: [showArrow && (jsx(Tooltip$1.Arrow, { children: jsx(Tooltip$1.ArrowTip, {}) })), content] }) }) })] }));
2985
- });
2986
-
2987
3016
  const InputGroup = React.forwardRef(function InputGroup(props, ref) {
2988
3017
  const { startElement, startElementProps, endElement, endElementProps, children, startOffset = "6px", endOffset = "6px", ...rest } = props;
2989
3018
  return (jsxs(Group, { ref: ref, ...rest, children: [startElement && (jsx(InputElement, { pointerEvents: "none", ...startElementProps, children: startElement })), React.cloneElement(children, {
@@ -2997,7 +3026,8 @@ const InputGroup = React.forwardRef(function InputGroup(props, ref) {
2997
3026
  });
2998
3027
 
2999
3028
  const GlobalFilter = () => {
3000
- const { table } = useDataTableContext();
3029
+ const { table, tableLabel } = useDataTableContext();
3030
+ const { globalFilterPlaceholder } = tableLabel;
3001
3031
  const [searchTerm, setSearchTerm] = useState("");
3002
3032
  const debouncedSearchTerm = useDebounce(searchTerm, 500);
3003
3033
  useEffect(() => {
@@ -3006,42 +3036,31 @@ const GlobalFilter = () => {
3006
3036
  };
3007
3037
  searchHN();
3008
3038
  }, [debouncedSearchTerm]);
3009
- return (jsx(Fragment, { children: jsx(InputGroup, { flex: "1", startElement: jsx(MdSearch, {}), children: jsx(Input, { placeholder: "Outline", variant: "outline", onChange: (e) => {
3039
+ return (jsx(Fragment, { children: jsx(InputGroup, { flex: "1", startElement: jsx(MdSearch, {}), children: jsx(Input, { placeholder: globalFilterPlaceholder, variant: "outline", onChange: (e) => {
3010
3040
  setSearchTerm(e.target.value);
3011
3041
  } }) }) }));
3012
3042
  };
3013
3043
 
3014
- const ReloadButton = ({ text = "Reload", variant = "icon", }) => {
3044
+ const Tooltip = React.forwardRef(function Tooltip(props, ref) {
3045
+ const { showArrow, children, disabled, portalled, content, contentProps, portalRef, ...rest } = props;
3046
+ if (disabled)
3047
+ return children;
3048
+ return (jsxs(Tooltip$1.Root, { ...rest, children: [jsx(Tooltip$1.Trigger, { asChild: true, children: children }), jsx(Portal, { disabled: !portalled, container: portalRef, children: jsx(Tooltip$1.Positioner, { children: jsxs(Tooltip$1.Content, { ref: ref, ...contentProps, children: [showArrow && (jsx(Tooltip$1.Arrow, { children: jsx(Tooltip$1.ArrowTip, {}) })), content] }) }) })] }));
3049
+ });
3050
+
3051
+ const ReloadButton = ({ variant = "icon", }) => {
3015
3052
  const { url } = useDataTableServerContext();
3016
3053
  const queryClient = useQueryClient();
3054
+ const { tableLabel } = useDataTableContext();
3055
+ const { reloadTooltip, reloadButtonText } = tableLabel;
3017
3056
  if (variant === "icon") {
3018
- return (jsx(Tooltip, { showArrow: true, content: "This is the tooltip content", children: jsx(Button, { variant: "ghost", onClick: () => {
3057
+ return (jsx(Tooltip, { showArrow: true, content: reloadTooltip, children: jsx(Button, { variant: "ghost", onClick: () => {
3019
3058
  queryClient.invalidateQueries({ queryKey: [url] });
3020
3059
  }, "aria-label": "refresh", children: jsx(IoReload, {}) }) }));
3021
3060
  }
3022
3061
  return (jsxs(Button, { variant: "ghost", onClick: () => {
3023
3062
  queryClient.invalidateQueries({ queryKey: [url] });
3024
- }, children: [jsx(IoReload, {}), " ", text] }));
3025
- };
3026
-
3027
- const FilterOptions = ({ column }) => {
3028
- const { table } = useDataTableContext();
3029
- const tableColumn = table.getColumn(column);
3030
- const options = tableColumn?.columnDef.meta?.filterOptions ?? [];
3031
- return (jsx(Fragment, { children: options.map((option) => {
3032
- const selected = table.getColumn(column)?.getFilterValue() === option;
3033
- return (jsxs(Button$1, { size: "sm", onClick: () => {
3034
- if (selected) {
3035
- table.setColumnFilters((state) => {
3036
- return state.filter((filter) => {
3037
- return filter.id !== column;
3038
- });
3039
- });
3040
- return;
3041
- }
3042
- table.getColumn(column)?.setFilterValue(option);
3043
- }, variant: selected ? "solid" : "outline", display: "flex", gap: "0.25rem", children: [option, selected && jsx(MdClose, {})] }, option));
3044
- }) }));
3063
+ }, children: [jsx(IoReload, {}), " ", reloadButtonText] }));
3045
3064
  };
3046
3065
 
3047
3066
  const TableFilterTags = () => {
@@ -3055,16 +3074,99 @@ const TableFilterTags = () => {
3055
3074
  }) }));
3056
3075
  };
3057
3076
 
3058
- const TableControls = ({ fitTableWidth = false, fitTableHeight = false, children = jsx(Fragment, {}), showGlobalFilter = false, showFilter = false, showFilterName = false, showFilterTags = false, showReload = false, showPagination = true, showPageSizeControl = true, showPageCountText = true, showView = true, filterOptions = [], extraItems = jsx(Fragment, {}), loading = false, hasError = false, }) => {
3059
- const { translate } = useDataTableContext();
3060
- return (jsxs(Grid, { templateRows: "auto 1fr auto", width: fitTableWidth ? "fit-content" : "100%", height: fitTableHeight ? "fit-content" : "100%", gap: "0.5rem", children: [jsxs(Flex, { flexFlow: "column", gap: 2, children: [jsxs(Flex, { justifyContent: "space-between", children: [jsx(Box, { children: showView && jsx(ViewDialog, { icon: jsx(MdOutlineViewColumn, {}) }) }), jsxs(Flex, { gap: "0.5rem", alignItems: "center", justifySelf: "end", children: [loading && jsx(Spinner, { size: "sm" }), hasError && (jsx(Tooltip, { content: translate.t("hasError"), children: jsx(Icon, { as: BsExclamationCircleFill, color: "red.400" }) })), showGlobalFilter && jsx(GlobalFilter, {}), showFilter && jsx(FilterDialog, {}), showReload && jsx(ReloadButton, {}), extraItems] })] }), filterOptions.length > 0 && (jsx(Flex, { flexFlow: "column", gap: "0.5rem", children: filterOptions.map((column) => {
3061
- return (jsxs(Flex, { alignItems: "center", flexFlow: "wrap", gap: "0.5rem", children: [showFilterName && jsxs(Text, { children: [column, ":"] }), jsx(FilterOptions, { column: column })] }, column));
3062
- }) })), showFilterTags && (jsx(Flex, { children: jsx(TableFilterTags, {}) }))] }), jsx(Grid, { overflow: "auto", backgroundColor: "gray.50", _dark: {
3063
- backgroundColor: "gray.900",
3064
- }, children: children }), jsxs(Flex, { justifyContent: "space-between", children: [jsxs(Flex, { gap: "1rem", alignItems: "center", children: [showPageSizeControl && jsx(PageSizeControl, {}), showPageCountText && (jsxs(Flex, { children: [jsx(Text, { paddingRight: "0.5rem", children: translate.t("rowcount.total") }), jsx(RowCountText, {})] }))] }), jsx(Box, { justifySelf: "end", children: showPagination && jsx(Pagination, {}) })] })] }));
3077
+ const TableControls = ({ fitTableWidth = false, fitTableHeight = false, children = jsx(Fragment, {}), showGlobalFilter = false, showFilter = false, showFilterName = false, showFilterTags = false, showReload = false, showPagination = true, showPageSizeControl = true, showPageCountText = true, showView = true, filterTagsOptions = [], extraItems = jsx(Fragment, {}), loading = false, hasError = false, gridProps = {}, }) => {
3078
+ const { tableLabel, table } = useDataTableContext();
3079
+ const { rowCountText, hasErrorText } = tableLabel;
3080
+ return (jsxs(Grid, { templateRows: "auto 1fr", width: fitTableWidth ? "fit-content" : "100%", height: fitTableHeight ? "fit-content" : "100%", gap: "0.5rem", ...gridProps, children: [jsxs(Flex, { flexFlow: "column", gap: 2, children: [jsxs(Flex, { justifyContent: "space-between", children: [jsx(Box, { children: showView && jsx(ViewDialog, { icon: jsx(MdOutlineViewColumn, {}) }) }), jsxs(Flex, { gap: "0.5rem", alignItems: "center", justifySelf: "end", children: [loading && jsx(Spinner, { size: "sm" }), hasError && (jsx(Tooltip, { content: hasErrorText, children: jsx(Icon, { as: BsExclamationCircleFill, color: "red.400" }) })), showGlobalFilter && jsx(GlobalFilter, {}), showFilter && jsx(FilterDialog, {}), showReload && jsx(ReloadButton, {}), extraItems] })] }), filterTagsOptions.length > 0 && (jsx(Flex, { flexFlow: "column", gap: "0.5rem", children: filterTagsOptions.map((option) => {
3081
+ const { column, options } = option;
3082
+ const tableColumn = table.getColumn(column);
3083
+ return (jsxs(Flex, { alignItems: "center", flexFlow: "wrap", gap: "0.5rem", children: [tableColumn?.columnDef.meta?.displayName && (jsx(Text, { children: tableColumn?.columnDef.meta?.displayName })), jsx(TagFilter, { availableTags: options, selectedTags: tableColumn?.getFilterValue() ?? [], selectOne: true, onTagChange: (tags) => {
3084
+ if (tags.length === 0) {
3085
+ return tableColumn?.setFilterValue(undefined);
3086
+ }
3087
+ tableColumn?.setFilterValue(tags);
3088
+ } })] }, column));
3089
+ }) })), showFilterTags && (jsx(Flex, { children: jsx(TableFilterTags, {}) }))] }), jsx(Grid, { overflow: "auto", bg: { base: "colorPalette.50", _dark: "colorPalette.950" }, children: children }), (showPageSizeControl || showPageCountText || showPagination) && (jsxs(Flex, { justifyContent: "space-between", children: [jsxs(Flex, { gap: "1rem", alignItems: "center", children: [showPageSizeControl && jsx(PageSizeControl, {}), showPageCountText && (jsxs(Flex, { children: [jsx(Text, { paddingRight: "0.5rem", children: rowCountText }), jsx(RowCountText, {})] }))] }), jsx(Box, { justifySelf: "end", children: showPagination && jsx(Pagination, {}) })] }))] }));
3090
+ };
3091
+
3092
+ const EmptyState = React.forwardRef(function EmptyState(props, ref) {
3093
+ const { title, description, icon, children, ...rest } = props;
3094
+ return (jsx(EmptyState$2.Root, { ref: ref, ...rest, children: jsxs(EmptyState$2.Content, { children: [icon && (jsx(EmptyState$2.Indicator, { children: icon })), description ? (jsxs(VStack, { textAlign: "center", children: [jsx(EmptyState$2.Title, { children: title }), jsx(EmptyState$2.Description, { children: description })] })) : (jsx(EmptyState$2.Title, { children: title })), children] }) }));
3095
+ });
3096
+
3097
+ 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" })] }) }));
3098
+ const Table = ({ children, emptyComponent = EmptyResult, canResize = true, ...props }) => {
3099
+ const { table } = useDataTableContext();
3100
+ if (table.getRowModel().rows.length <= 0) {
3101
+ return emptyComponent;
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 }));
3104
+ };
3105
+
3106
+ const Checkbox = React.forwardRef(function Checkbox(props, ref) {
3107
+ const { icon, children, inputProps, rootRef, ...rest } = props;
3108
+ return (jsxs(Checkbox$1.Root, { ref: rootRef, ...rest, children: [jsx(Checkbox$1.HiddenInput, { ref: ref, ...inputProps }), jsx(Checkbox$1.Control, { children: icon || jsx(Checkbox$1.Indicator, {}) }), children != null && (jsx(Checkbox$1.Label, { children: children }))] }));
3109
+ });
3110
+
3111
+ const TableBody = ({ showSelector = false, canResize = true, }) => {
3112
+ "use no memo";
3113
+ const { table } = useDataTableContext();
3114
+ const SELECTION_BOX_WIDTH = 20;
3115
+ const [hoveredRow, setHoveredRow] = useState(-1);
3116
+ const handleRowHover = (index) => {
3117
+ setHoveredRow(index);
3118
+ };
3119
+ const getTdProps = (cell) => {
3120
+ const tdProps = cell.column.getIsPinned()
3121
+ ? {
3122
+ left: showSelector
3123
+ ? `${cell.column.getStart("left") + SELECTION_BOX_WIDTH + table.getDensityValue() * 2}px`
3124
+ : `${cell.column.getStart("left")}px`,
3125
+ position: "relative",
3126
+ }
3127
+ : {};
3128
+ return tdProps;
3129
+ };
3130
+ const getTrProps = ({ hoveredRow, index, }) => {
3131
+ if (hoveredRow === -1) {
3132
+ return {};
3133
+ }
3134
+ if (hoveredRow === index) {
3135
+ return {
3136
+ opacity: "1",
3137
+ };
3138
+ }
3139
+ return {
3140
+ opacity: "0.8",
3141
+ };
3142
+ };
3143
+ return (jsx(Table$1.Body, { children: table.getRowModel().rows.map((row, index) => {
3144
+ return (jsxs(Table$1.Row, { display: "flex", zIndex: 1, onMouseEnter: () => handleRowHover(index), onMouseLeave: () => handleRowHover(-1), ...getTrProps({ hoveredRow, index }), children: [showSelector && (jsx(TableRowSelector, { index: index, row: row, hoveredRow: hoveredRow })), row.getVisibleCells().map((cell, index) => {
3145
+ return (jsx(Table$1.Cell, { padding: `${table.getDensityValue()}px`,
3146
+ // styling resize and pinning start
3147
+ flex: `${canResize ? "0" : "1"} 0 ${cell.column.getSize()}px`,
3148
+ // this is to avoid the cell from being too wide
3149
+ minWidth: `0`, color: {
3150
+ base: "colorPalette.900",
3151
+ _dark: "colorPalette.100",
3152
+ },
3153
+ bg: { base: "colorPalette.50", _dark: "colorPalette.950" }, ...getTdProps(cell), children: flexRender(cell.column.columnDef.cell, cell.getContext()) }, `chakra-table-rowcell-${cell.id}-${index}`));
3154
+ })] }, `chakra-table-row-${row.id}`));
3155
+ }) }));
3156
+ };
3157
+ const TableRowSelector = ({ row, }) => {
3158
+ const { table } = useDataTableContext();
3159
+ const SELECTION_BOX_WIDTH = 20;
3160
+ return (jsx(Table$1.Cell, { padding: `${table.getDensityValue()}px`, display: "grid", color: {
3161
+ base: "colorPalette.900",
3162
+ _dark: "colorPalette.100",
3163
+ },
3164
+ bg: { base: "colorPalette.50", _dark: "colorPalette.950" }, justifyItems: "center", alignItems: "center", children: jsx(Checkbox, { width: `${SELECTION_BOX_WIDTH}px`, height: `${SELECTION_BOX_WIDTH}px`, checked: row.getIsSelected(),
3165
+ disabled: !row.getCanSelect(),
3166
+ onCheckedChange: row.getToggleSelectedHandler() }) }));
3065
3167
  };
3066
3168
 
3067
- const TableFooter = ({ pinnedBgColor = { light: "gray.50", dark: "gray.700" }, showSelector = false, alwaysShowSelector = true, }) => {
3169
+ const TableFooter = ({ showSelector = false, alwaysShowSelector = true, }) => {
3068
3170
  const table = useDataTableContext().table;
3069
3171
  const SELECTION_BOX_WIDTH = 20;
3070
3172
  const [hoveredCheckBox, setHoveredCheckBox] = useState(false);
@@ -3083,65 +3185,62 @@ const TableFooter = ({ pinnedBgColor = { light: "gray.50", dark: "gray.700" }, s
3083
3185
  }
3084
3186
  return false;
3085
3187
  };
3086
- const getThProps = (header) => {
3087
- const thProps = header.column.getIsPinned()
3088
- ? {
3089
- left: showSelector
3090
- ? `${header.getStart("left") + SELECTION_BOX_WIDTH + table.getDensityValue() * 2}px`
3091
- : `${header.getStart("left") + table.getDensityValue() * 2}px`,
3092
- background: pinnedBgColor.light,
3093
- position: "sticky",
3094
- zIndex: 1,
3095
- _dark: {
3096
- backgroundColor: pinnedBgColor.dark,
3097
- },
3098
- }
3099
- : {};
3100
- return thProps;
3101
- };
3102
- return (jsx(Table$1.Footer, { children: table.getFooterGroups().map((footerGroup) => (jsxs(Table$1.Row, { display: "flex", children: [showSelector && (jsxs(Table$1.Header
3103
- // styling resize and pinning start
3104
- , {
3105
- // styling resize and pinning start
3106
- padding: `${table.getDensityValue()}px`, ...(table.getIsSomeColumnsPinned("left")
3107
- ? {
3108
- left: `0px`,
3109
- backgroundColor: pinnedBgColor.light,
3110
- position: "sticky",
3111
- zIndex: 1,
3112
- _dark: { backgroundColor: pinnedBgColor.dark },
3113
- }
3114
- : {}),
3115
- // styling resize and pinning end
3116
- onMouseEnter: () => handleRowHover(true), onMouseLeave: () => handleRowHover(false), display: "grid", children: [isCheckBoxVisible() && (jsx(Box, { margin: "0rem", display: "grid", justifyItems: "center", alignItems: "center", children: jsx(Checkbox, { width: `${SELECTION_BOX_WIDTH}px`, height: `${SELECTION_BOX_WIDTH}px`, isChecked: table.getIsAllRowsSelected(),
3188
+ return (jsx(Table$1.Footer, { children: table.getFooterGroups().map((footerGroup) => (jsxs(Table$1.Row, { display: "flex", children: [showSelector && (jsxs(Table$1.Header, { padding: `${table.getDensityValue()}px`, onMouseEnter: () => handleRowHover(true), onMouseLeave: () => handleRowHover(false), display: "grid", children: [isCheckBoxVisible() && (jsx(Box, { margin: "0rem", display: "grid", justifyItems: "center", alignItems: "center", children: jsx(Checkbox, { width: `${SELECTION_BOX_WIDTH}px`, height: `${SELECTION_BOX_WIDTH}px`, isChecked: table.getIsAllRowsSelected(),
3117
3189
  // indeterminate: table.getIsSomeRowsSelected(),
3118
3190
  onChange: table.getToggleAllRowsSelectedHandler() }) })), !isCheckBoxVisible() && (jsx(Box, { as: "span", margin: "0rem", display: "grid", justifyItems: "center", alignItems: "center", width: `${SELECTION_BOX_WIDTH}px`, height: `${SELECTION_BOX_WIDTH}px` }))] })), footerGroup.headers.map((header) => (jsx(Table$1.Cell, { padding: "0", columnSpan: `${header.colSpan}`,
3119
3191
  // styling resize and pinning start
3120
- maxWidth: `${header.getSize()}px`, width: `${header.getSize()}px`, display: "grid", ...getThProps(header), children: jsx(MenuRoot$1, { children: jsx(MenuTrigger$1, { asChild: true, children: jsx(Box, { padding: `${table.getDensityValue()}px`, display: "flex", alignItems: "center", justifyContent: "start", borderRadius: "0rem", _hover: { backgroundColor: "gray.100" }, children: jsxs(Flex, { gap: "0.5rem", alignItems: "center", children: [header.isPlaceholder
3192
+ maxWidth: `${header.getSize()}px`, width: `${header.getSize()}px`, display: "grid", children: jsx(MenuRoot$1, { children: jsx(MenuTrigger$1, { asChild: true, children: jsx(Box, { padding: `${table.getDensityValue()}px`, display: "flex", alignItems: "center", justifyContent: "start", borderRadius: "0rem", children: jsxs(Flex, { gap: "0.5rem", alignItems: "center", children: [header.isPlaceholder
3121
3193
  ? null
3122
- : flexRender(header.column.columnDef.footer, header.getContext()), jsx(Box, { children: header.column.getCanSort() && (jsxs(Fragment, { children: [header.column.getIsSorted() === false && (
3123
- // <UpDownIcon />
3124
- jsx(Fragment, {})), header.column.getIsSorted() === "asc" && (jsx(BiUpArrow, {})), header.column.getIsSorted() === "desc" && (jsx(BiDownArrow, {}))] })) })] }) }) }) }) }, `chakra-table-footer-${header.column.id}-${footerGroup.id}`)))] }, `chakra-table-footergroup-${footerGroup.id}`))) }));
3194
+ : flexRender(header.column.columnDef.footer, header.getContext()), jsx(Box, { children: header.column.getCanSort() && (jsxs(Fragment, { children: [header.column.getIsSorted() === false && jsx(Fragment, {}), header.column.getIsSorted() === "asc" && (jsx(BiUpArrow, {})), header.column.getIsSorted() === "desc" && (jsx(BiDownArrow, {}))] })) })] }) }) }) }) }, `chakra-table-footer-${header.column.id}-${footerGroup.id}`)))] }, `chakra-table-footergroup-${footerGroup.id}`))) }));
3125
3195
  };
3126
3196
 
3127
- const TableHeader = ({ canResize = true, pinnedBgColor = { light: "gray.50", dark: "gray.700" }, showSelector = false, isSticky = true, alwaysShowSelector = true, tHeadProps = {}, }) => {
3197
+ // Default text values
3198
+ const DEFAULT_HEADER_TEXTS = {
3199
+ pinColumn: "Pin Column",
3200
+ cancelPin: "Cancel Pin",
3201
+ sortAscending: "Sort Ascending",
3202
+ sortDescending: "Sort Descending",
3203
+ clearSorting: "Clear Sorting",
3204
+ };
3205
+ /**
3206
+ * TableHeader component with configurable text strings.
3207
+ *
3208
+ * @example
3209
+ * // Using default texts
3210
+ * <TableHeader />
3211
+ *
3212
+ * @example
3213
+ * // Customizing default texts for all columns
3214
+ * <TableHeader
3215
+ * defaultTexts={{
3216
+ * pinColumn: "Pin This Column",
3217
+ * sortAscending: "Sort A-Z"
3218
+ * }}
3219
+ * />
3220
+ *
3221
+ * @example
3222
+ * // Customizing texts per column via meta
3223
+ * const columns = [
3224
+ * columnHelper.accessor("name", {
3225
+ * header: "Name",
3226
+ * meta: {
3227
+ * headerTexts: {
3228
+ * pinColumn: "Pin Name Column",
3229
+ * sortAscending: "Sort Names A-Z"
3230
+ * }
3231
+ * }
3232
+ * })
3233
+ * ];
3234
+ */
3235
+ const TableHeader = ({ canResize = true, showSelector = false, isSticky = true, tableHeaderProps = {}, tableRowProps = {}, defaultTexts = {}, }) => {
3128
3236
  const { table } = useDataTableContext();
3129
3237
  const SELECTION_BOX_WIDTH = 20;
3130
- const [hoveredCheckBox, setHoveredCheckBox] = useState(false);
3131
- const handleRowHover = (isHovered) => {
3132
- setHoveredCheckBox(isHovered);
3133
- };
3134
- const isCheckBoxVisible = () => {
3135
- if (alwaysShowSelector) {
3136
- return true;
3137
- }
3138
- if (table.getIsAllRowsSelected()) {
3139
- return true;
3140
- }
3141
- if (hoveredCheckBox) {
3142
- return true;
3143
- }
3144
- return false;
3238
+ // Merge default texts with provided defaults
3239
+ const mergedDefaultTexts = { ...DEFAULT_HEADER_TEXTS, ...defaultTexts };
3240
+ // Helper function to get text for a specific header
3241
+ const getHeaderText = (header, key) => {
3242
+ const columnMeta = header.column.columnDef.meta;
3243
+ return columnMeta?.headerTexts?.[key] || mergedDefaultTexts[key];
3145
3244
  };
3146
3245
  const getThProps = (header) => {
3147
3246
  const thProps = header.column.getIsPinned()
@@ -3149,12 +3248,8 @@ const TableHeader = ({ canResize = true, pinnedBgColor = { light: "gray.50", dar
3149
3248
  left: showSelector
3150
3249
  ? `${header.getStart("left") + SELECTION_BOX_WIDTH + table.getDensityValue() * 2}px`
3151
3250
  : `${header.getStart("left")}px`,
3152
- background: pinnedBgColor.light,
3153
3251
  position: "sticky",
3154
3252
  zIndex: 100 + 1,
3155
- _dark: {
3156
- backgroundColor: pinnedBgColor.dark,
3157
- },
3158
3253
  }
3159
3254
  : {};
3160
3255
  return thProps;
@@ -3163,21 +3258,13 @@ const TableHeader = ({ canResize = true, pinnedBgColor = { light: "gray.50", dar
3163
3258
  position: "sticky",
3164
3259
  top: 0,
3165
3260
  };
3166
- return (jsx(Table$1.Header, { ...(isSticky ? stickyProps : {}), ...tHeadProps, children: table.getHeaderGroups().map((headerGroup) => (jsxs(Table$1.Row, { display: "flex", children: [showSelector && (jsxs(Table$1.ColumnHeader
3167
- // styling resize and pinning start
3168
- , { ...(table.getIsSomeColumnsPinned("left")
3169
- ? {
3170
- left: `0px`,
3171
- backgroundColor: pinnedBgColor.light,
3172
- position: "sticky",
3173
- zIndex: 1,
3174
- _dark: { backgroundColor: pinnedBgColor.dark },
3175
- }
3176
- : {}),
3177
- // styling resize and pinning end
3178
- padding: `${table.getDensityValue()}px`, onMouseEnter: () => handleRowHover(true), onMouseLeave: () => handleRowHover(false), display: "grid", children: [isCheckBoxVisible() && (jsx(Box, { margin: "0rem", display: "grid", justifyItems: "center", alignItems: "center", children: jsx(Checkbox, { width: `${SELECTION_BOX_WIDTH}px`, height: `${SELECTION_BOX_WIDTH}px`, isChecked: table.getIsAllRowsSelected(),
3179
- // indeterminate: table.getIsSomeRowsSelected(),
3180
- onChange: table.getToggleAllRowsSelectedHandler() }) })), !isCheckBoxVisible() && (jsx(Box, { as: "span", margin: "0rem", display: "grid", justifyItems: "center", alignItems: "center", width: `${SELECTION_BOX_WIDTH}px`, height: `${SELECTION_BOX_WIDTH}px` }))] })), headerGroup.headers.map((header) => {
3261
+ return (jsx(Table$1.Header, { ...(isSticky ? stickyProps : {}), bgColor: "transparent", ...tableHeaderProps, children: table.getHeaderGroups().map((headerGroup) => (jsxs(Table$1.Row, { display: "flex", bgColor: "transparent", ...tableRowProps, children: [showSelector && (jsx(Table$1.ColumnHeader, { padding: `${table.getDensityValue()}px`, display: "grid", color: {
3262
+ base: "colorPalette.900",
3263
+ _dark: "colorPalette.100",
3264
+ },
3265
+ bg: { base: "colorPalette.50", _dark: "colorPalette.950" }, justifyItems: "center", alignItems: "center", children: jsx(Checkbox, { width: `${SELECTION_BOX_WIDTH}px`, height: `${SELECTION_BOX_WIDTH}px`, checked: table.getIsAllRowsSelected(),
3266
+ // indeterminate: table.getIsSomeRowsSelected(),
3267
+ onChange: table.getToggleAllRowsSelectedHandler() }) })), headerGroup.headers.map((header) => {
3181
3268
  const resizeProps = {
3182
3269
  onMouseDown: header.getResizeHandler(),
3183
3270
  onTouchStart: header.getResizeHandler(),
@@ -3185,18 +3272,32 @@ const TableHeader = ({ canResize = true, pinnedBgColor = { light: "gray.50", dar
3185
3272
  };
3186
3273
  return (jsxs(Table$1.ColumnHeader, { padding: 0, columnSpan: `${header.colSpan}`,
3187
3274
  // styling resize and pinning start
3188
- flex: `${canResize ? "0" : "1"} 0 ${header.column.getSize()}px`, display: "grid", gridTemplateColumns: "1fr auto", zIndex: 1500 + header.index, ...getThProps(header), children: [jsxs(MenuRoot, { children: [jsx(MenuTrigger, { asChild: true, children: jsx(Flex, { padding: `${table.getDensityValue()}px`, alignItems: "center", justifyContent: "start", borderRadius: "0rem", overflow: "auto", _hover: {
3189
- backgroundColor: "gray.100",
3190
- _dark: {
3191
- backgroundColor: "gray.700",
3275
+ flex: `${canResize ? "0" : "1"} 0 ${header.column.getSize()}px`, display: "grid", gridTemplateColumns: "1fr auto", zIndex: 1500 + header.index, color: {
3276
+ base: "colorPalette.800",
3277
+ _dark: "colorPalette.200",
3278
+ },
3279
+ bg: { base: "colorPalette.100", _dark: "colorPalette.900" }, ...getThProps(header), children: [jsxs(MenuRoot, { children: [jsx(MenuTrigger, { asChild: true, children: jsx(Flex, { padding: `${table.getDensityValue()}px`, alignItems: "center", justifyContent: "start", borderRadius: "0rem", overflow: "auto", color: {
3280
+ base: "colorPalette.800",
3281
+ _dark: "colorPalette.200",
3282
+ _hover: {
3283
+ base: "colorPalette.700",
3284
+ _dark: "colorPalette.300",
3285
+ },
3286
+ },
3287
+ bg: {
3288
+ base: "colorPalette.100",
3289
+ _dark: "colorPalette.900",
3290
+ _hover: {
3291
+ base: "colorPalette.200",
3292
+ _dark: "colorPalette.800",
3192
3293
  },
3193
3294
  }, children: jsxs(Flex, { gap: "0.5rem", alignItems: "center", children: [header.isPlaceholder
3194
3295
  ? null
3195
3296
  : flexRender(header.column.columnDef.header, header.getContext()), jsx(Box, { children: header.column.getCanSort() && (jsxs(Fragment, { children: [header.column.getIsSorted() === false && jsx(Fragment, {}), header.column.getIsSorted() === "asc" && (jsx(BiUpArrow, {})), header.column.getIsSorted() === "desc" && (jsx(BiDownArrow, {}))] })) }), jsx(Box, { children: header.column.getIsFiltered() && jsx(MdFilterListAlt, {}) })] }) }) }), jsxs(MenuContent, { children: [!header.column.getIsPinned() && (jsx(MenuItem, { asChild: true, value: "pin-column", children: jsxs(Button, { variant: "ghost", onClick: () => {
3196
3297
  header.column.pin("left");
3197
- }, children: [jsx(MdPushPin, {}), "Pin Column"] }) })), header.column.getIsPinned() && (jsx(MenuItem, { asChild: true, value: "cancel-pin", children: jsxs(Button, { variant: "ghost", onClick: () => {
3298
+ }, children: [jsx(MdPushPin, {}), getHeaderText(header, "pinColumn")] }) })), header.column.getIsPinned() && (jsx(MenuItem, { asChild: true, value: "cancel-pin", children: jsxs(Button, { variant: "ghost", onClick: () => {
3198
3299
  header.column.pin(false);
3199
- }, children: [jsx(MdCancel, {}), "Cancel Pin"] }) })), header.column.getCanSort() && (jsxs(Fragment, { children: [jsx(MenuItem, { asChild: true, value: "sort-ascend", children: jsxs(Button, { variant: "ghost", onClick: () => {
3300
+ }, children: [jsx(MdCancel, {}), getHeaderText(header, "cancelPin")] }) })), header.column.getCanSort() && (jsxs(Fragment, { children: [jsx(MenuItem, { asChild: true, value: "sort-ascend", children: jsxs(Button, { variant: "ghost", onClick: () => {
3200
3301
  table.setSorting((state) => {
3201
3302
  return [
3202
3303
  ...state.filter((column) => {
@@ -3205,7 +3306,7 @@ const TableHeader = ({ canResize = true, pinnedBgColor = { light: "gray.50", dar
3205
3306
  { id: header.id, desc: false },
3206
3307
  ];
3207
3308
  });
3208
- }, children: [jsx(GrAscend, {}), "Sort Ascending"] }) }), jsx(MenuItem, { asChild: true, value: "sort-descend", children: jsxs(Button, { variant: "ghost", onClick: () => {
3309
+ }, children: [jsx(GrAscend, {}), getHeaderText(header, "sortAscending")] }) }), jsx(MenuItem, { asChild: true, value: "sort-descend", children: jsxs(Button, { variant: "ghost", onClick: () => {
3209
3310
  table.setSorting((state) => {
3210
3311
  return [
3211
3312
  ...state.filter((column) => {
@@ -3214,42 +3315,30 @@ const TableHeader = ({ canResize = true, pinnedBgColor = { light: "gray.50", dar
3214
3315
  { id: header.id, desc: true },
3215
3316
  ];
3216
3317
  });
3217
- }, children: [jsx(GrDescend, {}), "Sort Descending"] }) }), header.column.getIsSorted() && (jsx(MenuItem, { asChild: true, value: "sort-descend", children: jsxs(Button, { variant: "ghost", onClick: () => {
3318
+ }, children: [jsx(GrDescend, {}), getHeaderText(header, "sortDescending")] }) }), header.column.getIsSorted() && (jsx(MenuItem, { asChild: true, value: "clear-sorting", children: jsxs(Button, { variant: "ghost", onClick: () => {
3218
3319
  header.column.clearSorting();
3219
- }, children: [jsx(MdClear, {}), "Clear Sorting"] }) }))] }))] })] }), canResize && (jsx(Box, { borderRight: "0.2rem solid", borderRightColor: header.column.getIsResizing() ? "gray.700" : "transparent", position: "relative", right: "0.1rem", width: "2px", height: "100%", userSelect: "none", style: { touchAction: "none" }, _hover: {
3320
+ }, children: [jsx(MdClear, {}), getHeaderText(header, "clearSorting")] }) }))] }))] })] }), canResize && (jsx(Box, { borderRight: "0.2rem solid", borderRightColor: header.column.getIsResizing()
3321
+ ? "colorPalette.700"
3322
+ : "transparent", position: "relative", right: "0.1rem", width: "2px", height: "100%", userSelect: "none", style: { touchAction: "none" }, _hover: {
3220
3323
  borderRightColor: header.column.getIsResizing()
3221
- ? "gray.700"
3222
- : "gray.400",
3324
+ ? "colorPalette.700"
3325
+ : "colorPalette.400",
3223
3326
  }, ...resizeProps }))] }, `chakra-table-header-${header.id}`));
3224
3327
  })] }, `chakra-table-headergroup-${headerGroup.id}`))) }));
3225
3328
  };
3226
3329
 
3227
- const EmptyState = React.forwardRef(function EmptyState(props, ref) {
3228
- const { title, description, icon, children, ...rest } = props;
3229
- return (jsx(EmptyState$2.Root, { ref: ref, ...rest, children: jsxs(EmptyState$2.Content, { children: [icon && (jsx(EmptyState$2.Indicator, { children: icon })), description ? (jsxs(VStack, { textAlign: "center", children: [jsx(EmptyState$2.Title, { children: title }), jsx(EmptyState$2.Description, { children: description })] })) : (jsx(EmptyState$2.Title, { children: title })), children] }) }));
3230
- });
3231
-
3232
- 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" })] }) }));
3233
- const Table = ({ children, emptyComponent = EmptyResult, canResize = true, ...props }) => {
3234
- const { table } = useDataTableContext();
3235
- if (table.getRowModel().rows.length <= 0) {
3236
- return emptyComponent;
3237
- }
3238
- return (jsx(Table$1.Root, { stickyHeader: true, variant: "outline", width: canResize ? table.getCenterTotalSize() : undefined, display: "grid", alignContent: "start", overflowY: "auto", ...props, children: children }));
3239
- };
3240
-
3241
- const DefaultTable = ({ showFooter = false, tableProps = {}, tableHeaderProps = {}, tableBodyProps = {}, controlProps = {}, tableFooterProps = {}, variant = "", }) => {
3330
+ const DefaultTable = ({ showFooter = false, tableProps = {}, tableHeaderProps = {}, tableBodyProps = {}, tableFooterProps = {}, controlProps = {}, variant = "", }) => {
3242
3331
  if (variant === "greedy") {
3243
3332
  return (jsx(TableControls, { ...controlProps, children: jsxs(Table, { canResize: false, ...{ ...tableProps }, children: [jsx(TableHeader, { canResize: false, ...tableHeaderProps }), jsx(TableBody, { canResize: false, ...tableBodyProps }), showFooter && (jsx(TableFooter, { canResize: false, ...tableFooterProps }))] }) }));
3244
3333
  }
3245
3334
  return (jsx(TableControls, { ...controlProps, children: jsxs(Table, { ...tableProps, children: [jsx(TableHeader, { ...tableHeaderProps }), jsx(TableBody, { ...tableBodyProps }), showFooter && jsx(TableFooter, { ...tableFooterProps })] }) }));
3246
3335
  };
3247
3336
 
3248
- const TableCardContainer = ({ children, variant = "", ...props }) => {
3337
+ const TableCardContainer = ({ children, variant = "", gap = "1rem", gridTemplateColumns = "repeat(auto-fit, minmax(20rem, 1fr))", direction = "row", ...props }) => {
3249
3338
  if (variant === "carousel") {
3250
- return (jsx(Flex, { overflow: "scroll", gap: "1rem", children: children }));
3339
+ return (jsx(Flex, { overflow: "auto", gap: gap, direction: direction, ...props, children: children }));
3251
3340
  }
3252
- return (jsx(Grid, { gridTemplateColumns: "repeat(auto-fit, minmax(20rem, 1fr))", gap: "0.5rem", ...props, children: children }));
3341
+ return (jsx(Grid, { gridTemplateColumns: gridTemplateColumns, gap: gap, ...props, children: children }));
3253
3342
  };
3254
3343
 
3255
3344
  const DefaultCardTitle = () => {
@@ -3278,8 +3367,8 @@ const TableComponent = ({ render = () => {
3278
3367
  };
3279
3368
 
3280
3369
  const TableLoadingComponent = ({ render, }) => {
3281
- const { loading } = useDataTableContext();
3282
- return jsx(Fragment, { children: render(loading) });
3370
+ const { query } = useDataTableServerContext();
3371
+ return jsx(Fragment, { children: render(query.isLoading) });
3283
3372
  };
3284
3373
 
3285
3374
  const SelectAllRowsToggle = ({ selectAllIcon = jsx(MdOutlineChecklist, {}), clearAllIcon = jsx(MdClear, {}), selectAllText = "", clearAllText = "", }) => {
@@ -3365,50 +3454,43 @@ const useDataTable = ({ default: { sorting: defaultSorting = [], pagination: def
3365
3454
  };
3366
3455
  };
3367
3456
 
3368
- const useDataTableServer = ({ url, default: { sorting: defaultSorting = [], pagination: defaultPagination = {
3369
- pageIndex: 0, //initial page index
3370
- pageSize: 10, //default page size
3371
- }, rowSelection: defaultRowSelection = {}, columnFilters: defaultColumnFilters = [], columnOrder: defaultColumnOrder = [], columnVisibility: defaultColumnVisibility = {}, globalFilter: defaultGlobalFilter = "", density: defaultDensity = "sm", } = {
3372
- sorting: [],
3373
- pagination: {
3457
+ const useDataTableServer = (props) => {
3458
+ const { url, default: defaultProps, keyPrefix, placeholderData, queryFn: customQueryFn, } = props;
3459
+ const { sorting: defaultSorting, pagination: defaultPagination, rowSelection: defaultRowSelection, columnFilters: defaultColumnFilters, columnOrder: defaultColumnOrder, columnVisibility: defaultColumnVisibility, globalFilter: defaultGlobalFilter, density: defaultDensity, } = defaultProps || {};
3460
+ const [sorting, setSorting] = useState(defaultSorting || []);
3461
+ const [columnFilters, setColumnFilters] = useState(defaultColumnFilters || []); // can set initial column filter state here
3462
+ const [pagination, setPagination] = useState(defaultPagination || {
3374
3463
  pageIndex: 0, //initial page index
3375
- pageSize: 10, //age size
3376
- },
3377
- rowSelection: {},
3378
- columnFilters: [],
3379
- columnOrder: [],
3380
- columnVisibility: {},
3381
- globalFilter: "",
3382
- density: "sm",
3383
- }, keyPrefix, }) => {
3384
- const [sorting, setSorting] = useState(defaultSorting);
3385
- const [columnFilters, setColumnFilters] = useState(defaultColumnFilters); // can set initial column filter state here
3386
- const [pagination, setPagination] = useState(defaultPagination);
3387
- const [rowSelection, setRowSelection] = useState(defaultRowSelection);
3388
- const [columnOrder, setColumnOrder] = useState(defaultColumnOrder);
3389
- const [globalFilter, setGlobalFilter] = useState(defaultGlobalFilter);
3390
- const [density, setDensity] = useState(defaultDensity);
3391
- const [columnVisibility, setColumnVisibility] = useState(defaultColumnVisibility);
3464
+ pageSize: 10, //default page size
3465
+ });
3466
+ const [rowSelection, setRowSelection] = useState(defaultRowSelection || {});
3467
+ const [columnOrder, setColumnOrder] = useState(defaultColumnOrder || []);
3468
+ const [globalFilter, setGlobalFilter] = useState(defaultGlobalFilter || "");
3469
+ const [density, setDensity] = useState(defaultDensity || "sm");
3470
+ const [columnVisibility, setColumnVisibility] = useState(defaultColumnVisibility || {});
3471
+ const { pageSize, pageIndex } = pagination;
3392
3472
  const params = {
3393
- offset: pagination.pageIndex * pagination.pageSize,
3394
- limit: pagination.pageSize,
3473
+ offset: pageIndex * pageSize,
3474
+ limit: pageSize,
3395
3475
  sorting,
3396
3476
  where: columnFilters,
3397
3477
  searching: globalFilter,
3398
3478
  };
3479
+ const defaultQueryFn = async () => {
3480
+ if (!url) {
3481
+ throw new Error("url is required");
3482
+ }
3483
+ const response = await axios.get(url, {
3484
+ params,
3485
+ });
3486
+ return response.data;
3487
+ };
3399
3488
  const query = useQuery({
3400
3489
  queryKey: [url, JSON.stringify(params)],
3401
- queryFn: () => {
3402
- return axios
3403
- .get(url, {
3404
- params,
3405
- })
3406
- .then((res) => res.data);
3407
- },
3408
- placeholderData: {
3409
- count: 0,
3410
- data: [],
3411
- },
3490
+ queryFn: customQueryFn !== undefined
3491
+ ? () => customQueryFn(params)
3492
+ : defaultQueryFn,
3493
+ placeholderData,
3412
3494
  });
3413
3495
  const translate = useTranslation("", { keyPrefix });
3414
3496
  return {
@@ -3498,7 +3580,71 @@ const getColumns = ({ schema, include = [], ignore = [], width = [], meta = {},
3498
3580
  return columns;
3499
3581
  };
3500
3582
 
3501
- const AccordionItemTrigger = React.forwardRef(function AccordionItemTrigger(props, ref) {
3583
+ const TableDataDisplay = ({ colorPalette, emptyComponent, }) => {
3584
+ const { columns, translate, data } = useDataTableContext();
3585
+ const columnsMap = Object.fromEntries(columns.map((def) => {
3586
+ const { accessorKey, id } = def;
3587
+ if (accessorKey) {
3588
+ return [accessorKey, def];
3589
+ }
3590
+ return [id, def];
3591
+ }));
3592
+ const columnHeaders = Object.keys(columnsMap);
3593
+ const totalWidths = columns
3594
+ .map(({ size }) => {
3595
+ if (!!size === false) {
3596
+ return 0;
3597
+ }
3598
+ if (typeof size === "number") {
3599
+ return size;
3600
+ }
3601
+ return 0;
3602
+ })
3603
+ .reduce((previous, current) => previous + current, 0);
3604
+ const columnWidths = columns
3605
+ .map(({ size }) => {
3606
+ if (!!size === false) {
3607
+ return "1fr";
3608
+ }
3609
+ return `minmax(${size}px, ${(size / totalWidths) * 100}%)`;
3610
+ })
3611
+ .join(" ");
3612
+ console.log({ columnWidths }, "hadfg");
3613
+ const cellProps = {
3614
+ flex: "1 0 0%",
3615
+ overflow: "auto",
3616
+ paddingX: "2",
3617
+ py: "1",
3618
+ color: { base: "colorPalette.900", _dark: "colorPalette.100" },
3619
+ bgColor: { base: "colorPalette.50", _dark: "colorPalette.950" },
3620
+ borderBottomColor: { base: "colorPalette.200", _dark: "colorPalette.800" },
3621
+ borderBottomWidth: "1px",
3622
+ ...{ colorPalette },
3623
+ };
3624
+ if (data.length <= 0) {
3625
+ return jsx(Fragment, { children: emptyComponent });
3626
+ }
3627
+ return (jsxs(Grid, { templateColumns: `${columnWidths}`, overflow: "auto", borderWidth: "1px", color: { base: "colorPalette.900", _dark: "colorPalette.100" }, borderColor: { base: "colorPalette.200", _dark: "colorPalette.800" }, colorPalette, children: [jsx(Grid, { templateColumns: `${columnWidths}`, column: `1/span ${columns.length}`, bg: { base: "colorPalette.200", _dark: "colorPalette.800" }, colorPalette, children: columnHeaders.map((header) => {
3628
+ return (jsx(Box, { flex: "1 0 0%", paddingX: "2", py: "1", overflow: "auto", textOverflow: "ellipsis", children: translate.t(`column_header.${header}`) }));
3629
+ }) }), data.map((record) => {
3630
+ return (jsx(Fragment, { children: columnHeaders.map((header) => {
3631
+ const { cell } = columnsMap[header];
3632
+ const value = record[header];
3633
+ if (!!record === false) {
3634
+ return (jsx(Box, { ...cellProps, children: translate.t(`column_cell.placeholder`) }));
3635
+ }
3636
+ if (cell) {
3637
+ return (jsx(Box, { ...cellProps, children: cell({ row: { original: record } }) }));
3638
+ }
3639
+ if (typeof value === "object") {
3640
+ return (jsx(Box, { ...cellProps, children: jsx(RecordDisplay, { object: value }) }));
3641
+ }
3642
+ return jsx(Box, { ...cellProps, children: value });
3643
+ }) }));
3644
+ })] }));
3645
+ };
3646
+
3647
+ const AccordionItemTrigger = React.forwardRef(function AccordionItemTrigger(props, ref) {
3502
3648
  const { children, indicatorPlacement = "end", ...rest } = props;
3503
3649
  return (jsxs(Accordion.ItemTrigger, { ...rest, ref: ref, children: [indicatorPlacement === "start" && (jsx(Accordion.ItemIndicator, { rotate: { base: "-90deg", _open: "0deg" }, children: jsx(LuChevronDown, {}) })), jsx(HStack, { gap: "4", flex: "1", textAlign: "start", width: "full", children: children }), indicatorPlacement === "end" && (jsx(Accordion.ItemIndicator, { children: jsx(LuChevronDown, {}) }))] }));
3504
3650
  });
@@ -3519,6 +3665,12 @@ const SchemaFormContext = createContext({
3519
3665
  onSubmit: async () => { },
3520
3666
  rowNumber: 0,
3521
3667
  requestOptions: {},
3668
+ timezone: 'Asia/Hong_Kong',
3669
+ displayConfig: {
3670
+ showSubmitButton: true,
3671
+ showResetButton: true,
3672
+ showTitle: true,
3673
+ },
3522
3674
  });
3523
3675
 
3524
3676
  const useSchemaContext = () => {
@@ -3529,6 +3681,24 @@ const clearEmptyString = (object) => {
3529
3681
  return Object.fromEntries(Object.entries(object).filter(([, value]) => value !== ""));
3530
3682
  };
3531
3683
 
3684
+ const validateData = (data, schema) => {
3685
+ const ajv = new Ajv({
3686
+ strict: false,
3687
+ allErrors: true,
3688
+ });
3689
+ addFormats(ajv);
3690
+ addErrors(ajv);
3691
+ const validate = ajv.compile(schema);
3692
+ const validationResult = validate(data);
3693
+ const errors = validate.errors;
3694
+ console.log(errors, data);
3695
+ return {
3696
+ isValid: validationResult,
3697
+ validate,
3698
+ errors,
3699
+ };
3700
+ };
3701
+
3532
3702
  const idPickerSanityCheck = (column, foreign_key) => {
3533
3703
  if (!!foreign_key == false) {
3534
3704
  throw new Error(`The key foreign_key does not exist in properties of column ${column} when using id-picker.`);
@@ -3544,7 +3714,11 @@ const idPickerSanityCheck = (column, foreign_key) => {
3544
3714
  throw new Error(`The key column does not exist in properties of column ${column} when using id-picker.`);
3545
3715
  }
3546
3716
  };
3547
- const FormRoot = ({ schema, idMap, setIdMap, form, serverUrl, translate, children, order = [], ignore = [], include = [], onSubmit = undefined, rowNumber = undefined, requestOptions = {}, getUpdatedData = () => { }, }) => {
3717
+ const FormRoot = ({ schema, idMap, setIdMap, form, serverUrl, translate, children, order = [], ignore = [], include = [], onSubmit = undefined, rowNumber = undefined, requestOptions = {}, getUpdatedData = () => { }, customErrorRenderer, displayConfig = {
3718
+ showSubmitButton: true,
3719
+ showResetButton: true,
3720
+ showTitle: true,
3721
+ }, }) => {
3548
3722
  const [isSuccess, setIsSuccess] = useState(false);
3549
3723
  const [isError, setIsError] = useState(false);
3550
3724
  const [isSubmiting, setIsSubmiting] = useState(false);
@@ -3577,11 +3751,13 @@ const FormRoot = ({ schema, idMap, setIdMap, form, serverUrl, translate, childre
3577
3751
  error,
3578
3752
  setError,
3579
3753
  getUpdatedData,
3754
+ customErrorRenderer,
3755
+ displayConfig,
3580
3756
  }, children: jsx(FormProvider, { ...form, children: children }) }));
3581
3757
  };
3582
3758
 
3583
3759
  function removeIndex(str) {
3584
- return str.replace(/\.\d+\./g, '.');
3760
+ return str.replace(/\.\d+\./g, ".");
3585
3761
  }
3586
3762
 
3587
3763
  const ArrayRenderer = ({ schema, column, prefix, }) => {
@@ -3593,13 +3769,17 @@ const ArrayRenderer = ({ schema, column, prefix, }) => {
3593
3769
  const isRequired = required?.some((columnId) => columnId === column);
3594
3770
  const { formState: { errors }, setValue, watch, } = useFormContext();
3595
3771
  const fields = (watch(colLabel) ?? []);
3596
- return (jsxs(Box, { gridRow, gridColumn, children: [jsxs(Box, { as: "label", gridColumn: "1/span12", children: [`${translate.t(removeIndex(`${colLabel}.fieldLabel`))}`, isRequired && jsx("span", { children: "*" })] }), fields.map((field, index) => (jsxs(Flex, { flexFlow: "column", children: [jsx(Grid, { gap: "4", padding: "4", gridTemplateColumns: "repeat(12, 1fr)", gridTemplateRows: `repeat("auto-fit", auto)`, children: jsx(SchemaRenderer, { column: `${index}`,
3597
- prefix: `${colLabel}.`,
3598
- schema: items }) }), jsx(Flex, { justifyContent: "end", children: jsx(Button$1, { variant: "ghost", onClick: () => {
3599
- setValue(colLabel, fields.filter((_, curIndex) => {
3600
- return curIndex === index;
3601
- }));
3602
- }, children: translate.t(removeIndex(`${colLabel}.remove`)) }) })] }, `${colLabel}.${index}`))), jsx(Flex, { children: jsx(Button$1, { onClick: () => {
3772
+ return (jsxs(Flex, { gridRow, gridColumn, flexFlow: "column", gap: 2, children: [jsxs(Box, { as: "label", children: [`${translate.t(removeIndex(`${colLabel}.field_label`))}`, isRequired && jsx("span", { children: "*" })] }), jsx(Flex, { flexFlow: "column", gap: 2, children: fields.map((field, index) => (jsxs(Grid, { gridTemplateColumns: '1fr auto', gap: 2, bgColor: { base: "colorPalette.100", _dark: "colorPalette.900" }, p: 2, borderRadius: 4, borderWidth: 1, borderColor: {
3773
+ base: "colorPalette.200",
3774
+ _dark: "colorPalette.800",
3775
+ }, children: [jsx(Grid, { gridTemplateColumns: "repeat(12, 1fr)", autoFlow: "row", children: jsx(SchemaRenderer, { column: `${index}`,
3776
+ prefix: `${colLabel}.`,
3777
+ // @ts-expect-error find suitable types
3778
+ schema: { showLabel: false, ...(items ?? {}) } }) }), jsx(Flex, { justifyContent: "end", children: jsx(Button$1, { variant: "ghost", onClick: () => {
3779
+ setValue(colLabel, fields.filter((_, curIndex) => {
3780
+ return curIndex !== index;
3781
+ }));
3782
+ }, children: jsx(Icon, { children: jsx(CgTrash, {}) }) }) })] }, `${colLabel}.${index}`))) }), jsx(Flex, { children: jsx(Button$1, { onClick: () => {
3603
3783
  if (type === "number") {
3604
3784
  setValue(colLabel, [...fields, 0]);
3605
3785
  return;
@@ -3613,7 +3793,7 @@ const ArrayRenderer = ({ schema, column, prefix, }) => {
3613
3793
  return;
3614
3794
  }
3615
3795
  setValue(colLabel, [...fields, {}]);
3616
- }, children: translate.t(removeIndex(`${colLabel}.add`)) }) }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.fieldRequired`)) }))] }));
3796
+ }, children: translate.t(removeIndex(`${colLabel}.add`)) }) }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
3617
3797
  };
3618
3798
 
3619
3799
  const Field = React.forwardRef(function Field(props, ref) {
@@ -3624,37 +3804,36 @@ const Field = React.forwardRef(function Field(props, ref) {
3624
3804
  const BooleanPicker = ({ schema, column, prefix }) => {
3625
3805
  const { watch, formState: { errors }, setValue, } = useFormContext();
3626
3806
  const { translate } = useSchemaContext();
3627
- const { required, gridColumn, gridRow } = schema;
3807
+ const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
3628
3808
  const isRequired = required?.some((columnId) => columnId === column);
3629
3809
  const colLabel = `${prefix}${column}`;
3630
3810
  const value = watch(colLabel);
3631
- return (jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.fieldLabel`))}`, required: isRequired, alignItems: "stretch", gridColumn,
3811
+ return (jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
3632
3812
  gridRow, children: [jsx(CheckboxCard, { checked: value, variant: "surface", onChange: () => {
3633
3813
  setValue(colLabel, !value);
3634
- } }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.fieldRequired`)) }))] }));
3814
+ } }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
3815
+ };
3816
+
3817
+ const CustomInput = ({ column, schema, prefix }) => {
3818
+ const formContext = useFormContext();
3819
+ const { inputRender } = schema;
3820
+ return (inputRender &&
3821
+ inputRender({
3822
+ column,
3823
+ schema,
3824
+ prefix,
3825
+ formContext,
3826
+ }));
3635
3827
  };
3636
3828
 
3637
- const monthNamesShort = [
3638
- "Jan",
3639
- "Feb",
3640
- "Mar",
3641
- "Apr",
3642
- "May",
3643
- "Jun",
3644
- "Jul",
3645
- "Aug",
3646
- "Sep",
3647
- "Oct",
3648
- "Nov",
3649
- "Dec",
3650
- ];
3651
- const weekdayNamesShort = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
3652
3829
  const Calendar = ({ calendars, getBackProps, getForwardProps, getDateProps, firstDayOfWeek = 0, }) => {
3830
+ const { labels } = useContext(DatePickerContext);
3831
+ const { monthNamesShort, weekdayNamesShort, backButtonLabel, forwardButtonLabel } = labels;
3653
3832
  if (calendars.length) {
3654
3833
  return (jsxs(Grid, { children: [jsxs(Grid, { templateColumns: "repeat(4, auto)", justifyContent: "center", children: [jsx(Button$1, { variant: "ghost", ...getBackProps({
3655
3834
  calendars,
3656
3835
  offset: 12,
3657
- }), children: "<<" }), jsx(Button$1, { variant: "ghost", ...getBackProps({ calendars }), children: "Back" }), jsx(Button$1, { variant: "ghost", ...getForwardProps({ calendars }), children: "Next" }), jsx(Button$1, { variant: "ghost", ...getForwardProps({
3836
+ }), children: "<<" }), jsx(Button$1, { variant: "ghost", ...getBackProps({ calendars }), children: backButtonLabel }), jsx(Button$1, { variant: "ghost", ...getForwardProps({ calendars }), children: forwardButtonLabel }), jsx(Button$1, { variant: "ghost", ...getForwardProps({
3658
3837
  calendars,
3659
3838
  offset: 12,
3660
3839
  }), children: ">>" })] }), jsx(Grid, { templateColumns: "repeat(2, auto)", justifyContent: "center", children: calendars.map((calendar) => (jsxs(Grid, { gap: 4, children: [jsxs(Grid, { justifyContent: "center", children: [monthNamesShort[calendar.month], " ", calendar.year] }), jsxs(Grid, { templateColumns: "repeat(7, auto)", justifyContent: "center", children: [[0, 1, 2, 3, 4, 5, 6].map((weekdayNum) => {
@@ -3697,9 +3876,52 @@ const Calendar = ({ calendars, getBackProps, getForwardProps, getDateProps, firs
3697
3876
  }
3698
3877
  return null;
3699
3878
  };
3879
+ const DatePickerContext = createContext({
3880
+ labels: {
3881
+ monthNamesShort: [
3882
+ "Jan",
3883
+ "Feb",
3884
+ "Mar",
3885
+ "Apr",
3886
+ "May",
3887
+ "Jun",
3888
+ "Jul",
3889
+ "Aug",
3890
+ "Sep",
3891
+ "Oct",
3892
+ "Nov",
3893
+ "Dec",
3894
+ ],
3895
+ weekdayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
3896
+ backButtonLabel: "Back",
3897
+ forwardButtonLabel: "Next",
3898
+ },
3899
+ });
3700
3900
  let DatePicker$1 = class DatePicker extends React__default.Component {
3701
3901
  render() {
3702
- return (jsx(Dayzed, { onDateSelected: this.props.onDateSelected, selected: this.props.selected, firstDayOfWeek: this.props.firstDayOfWeek, showOutsideDays: this.props.showOutsideDays, date: this.props.date, minDate: this.props.minDate, maxDate: this.props.maxDate, monthsToDisplay: this.props.monthsToDisplay, render: (dayzedData) => (jsx(Calendar, { ...dayzedData, firstDayOfWeek: this.props.firstDayOfWeek })) }));
3902
+ const { labels = {
3903
+ monthNamesShort: [
3904
+ "Jan",
3905
+ "Feb",
3906
+ "Mar",
3907
+ "Apr",
3908
+ "May",
3909
+ "Jun",
3910
+ "Jul",
3911
+ "Aug",
3912
+ "Sep",
3913
+ "Oct",
3914
+ "Nov",
3915
+ "Dec",
3916
+ ],
3917
+ weekdayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
3918
+ backButtonLabel: "Back",
3919
+ forwardButtonLabel: "Next",
3920
+ }, } = this.props;
3921
+ return (jsx(DatePickerContext.Provider, { value: { labels }, children: jsx(Dayzed, { onDateSelected: this.props.onDateSelected, selected: this.props.selected, firstDayOfWeek: this.props.firstDayOfWeek, showOutsideDays: this.props.showOutsideDays, date: this.props.date, minDate: this.props.minDate, maxDate: this.props.maxDate, monthsToDisplay: this.props.monthsToDisplay, render:
3922
+ // @ts-expect-error - Dayzed types need to be fixed
3923
+ (dayzedData) => (jsx(Calendar, { ...dayzedData,
3924
+ firstDayOfWeek: this.props.firstDayOfWeek })) }) }));
3703
3925
  }
3704
3926
  };
3705
3927
 
@@ -3721,28 +3943,86 @@ const PopoverRoot = Popover.Root;
3721
3943
  const PopoverBody = Popover.Body;
3722
3944
  const PopoverTrigger = Popover.Trigger;
3723
3945
 
3946
+ function translateWrapper({ prefix, column, label, translate, }) {
3947
+ return translate.t(removeIndex(`${prefix}${column}.${label}`));
3948
+ }
3949
+
3950
+ dayjs.extend(utc);
3951
+ dayjs.extend(timezone);
3724
3952
  const DatePicker = ({ column, schema, prefix }) => {
3725
3953
  const { watch, formState: { errors }, setValue, } = useFormContext();
3726
- const { translate } = useSchemaContext();
3727
- const { required, gridColumn, gridRow } = schema;
3954
+ const { translate, timezone } = useSchemaContext();
3955
+ const { required, gridColumn = "span 4", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD", dateFormat = "YYYY-MM-DD", } = schema;
3728
3956
  const isRequired = required?.some((columnId) => columnId === column);
3729
3957
  const colLabel = `${prefix}${column}`;
3730
3958
  const [open, setOpen] = useState(false);
3731
3959
  const selectedDate = watch(colLabel);
3732
- const formatedDate = dayjs(selectedDate).format("YYYY-MM-DD");
3733
- return (jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.fieldLabel`))}`, required: isRequired, alignItems: "stretch", gridColumn,
3734
- gridRow, children: [jsxs(PopoverRoot, { open: open, onOpenChange: (e) => setOpen(e.open), closeOnInteractOutside: true, children: [jsx(PopoverTrigger, { asChild: true, children: jsx(Button, { size: "sm", variant: "outline", onClick: () => {
3960
+ const displayDate = dayjs(selectedDate).tz(timezone).format(displayDateFormat);
3961
+ useEffect(() => {
3962
+ try {
3963
+ if (selectedDate) {
3964
+ // Parse the selectedDate as UTC or in a specific timezone to avoid +8 hour shift
3965
+ // For example, parse as UTC:
3966
+ const parsedDate = dayjs(selectedDate).tz(timezone);
3967
+ if (!parsedDate.isValid())
3968
+ return;
3969
+ // Format according to dateFormat from schema
3970
+ const formatted = parsedDate.format(dateFormat);
3971
+ // Update the form value only if different to avoid loops
3972
+ if (formatted !== selectedDate) {
3973
+ setValue(colLabel, formatted, {
3974
+ shouldValidate: true,
3975
+ shouldDirty: true,
3976
+ });
3977
+ }
3978
+ }
3979
+ }
3980
+ catch (e) {
3981
+ console.error(e);
3982
+ }
3983
+ }, [selectedDate, dateFormat, colLabel, setValue]);
3984
+ const customTranslate = (label) => {
3985
+ return translateWrapper({ prefix, column, label, translate });
3986
+ };
3987
+ return (jsxs(Field, { label: `${customTranslate(`field_label`)}`, required: isRequired, alignItems: "stretch", gridColumn,
3988
+ gridRow, children: [jsxs(PopoverRoot, { open: open, onOpenChange: (e) => setOpen(e.open), closeOnInteractOutside: true, children: [jsx(PopoverTrigger, { asChild: true, children: jsxs(Button, { size: "sm", variant: "outline", onClick: () => {
3735
3989
  setOpen(true);
3736
- }, children: selectedDate !== undefined ? `${formatedDate}` : "" }) }), jsx(PopoverContent, { children: jsxs(PopoverBody, { children: [jsx(PopoverTitle, {}), jsx(DatePicker$1
3737
- // @ts-expect-error TODO: find appropriate types
3738
- , {
3739
- // @ts-expect-error TODO: find appropriate types
3740
- selected: new Date(selectedDate),
3741
- // @ts-expect-error TODO: find appropriate types
3742
- onDateSelected: ({ date }) => {
3743
- setValue(colLabel, dayjs(date).format("YYYY-MM-DD"));
3990
+ }, justifyContent: "start", children: [jsx(MdDateRange, {}), selectedDate !== undefined ? `${displayDate}` : ""] }) }), jsx(PopoverContent, { children: jsxs(PopoverBody, { children: [jsx(PopoverTitle, {}), jsx(DatePicker$1, { selected: new Date(selectedDate), onDateSelected: ({ date }) => {
3991
+ setValue(colLabel, dayjs(date).format(dateFormat));
3744
3992
  setOpen(false);
3745
- } })] }) })] }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.fieldRequired`)) }))] }));
3993
+ }, labels: {
3994
+ monthNamesShort: [
3995
+ translate.t(`common.month_1`, { defaultValue: "January" }),
3996
+ translate.t(`common.month_2`, { defaultValue: "February" }),
3997
+ translate.t(`common.month_3`, { defaultValue: "March" }),
3998
+ translate.t(`common.month_4`, { defaultValue: "April" }),
3999
+ translate.t(`common.month_5`, { defaultValue: "May" }),
4000
+ translate.t(`common.month_6`, { defaultValue: "June" }),
4001
+ translate.t(`common.month_7`, { defaultValue: "July" }),
4002
+ translate.t(`common.month_8`, { defaultValue: "August" }),
4003
+ translate.t(`common.month_9`, { defaultValue: "September" }),
4004
+ translate.t(`common.month_10`, { defaultValue: "October" }),
4005
+ translate.t(`common.month_11`, { defaultValue: "November" }),
4006
+ translate.t(`common.month_12`, { defaultValue: "December" }),
4007
+ ],
4008
+ weekdayNamesShort: [
4009
+ translate.t(`common.weekday_1`, { defaultValue: "Sun" }),
4010
+ translate.t(`common.weekday_2`, { defaultValue: "Mon" }),
4011
+ translate.t(`common.weekday_3`, { defaultValue: "Tue" }),
4012
+ translate.t(`common.weekday_4`, {
4013
+ defaultValue: "Wed",
4014
+ }),
4015
+ translate.t(`common.weekday_5`, { defaultValue: "Thu" }),
4016
+ translate.t(`common.weekday_6`, { defaultValue: "Fri" }),
4017
+ translate.t(`common.weekday_7`, { defaultValue: "Sat" }),
4018
+ ],
4019
+ backButtonLabel: translate.t(`common.back_button`, {
4020
+ defaultValue: "Back",
4021
+ }),
4022
+ forwardButtonLabel: translate.t(`common.forward_button`, {
4023
+ defaultValue: "Forward",
4024
+ }),
4025
+ } })] }) })] }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: customTranslate(`field_required`) }))] }));
3746
4026
  };
3747
4027
 
3748
4028
  function filterArray(array, searchTerm) {
@@ -3755,12 +4035,12 @@ function filterArray(array, searchTerm) {
3755
4035
  });
3756
4036
  }
3757
4037
 
3758
- const EnumPicker = ({ column, isMultiple = false, schema, prefix, }) => {
4038
+ const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLimit = false, }) => {
3759
4039
  const { watch, formState: { errors }, setValue, } = useFormContext();
3760
4040
  const { translate } = useSchemaContext();
3761
- const { required } = schema;
4041
+ const { required, variant } = schema;
3762
4042
  const isRequired = required?.some((columnId) => columnId === column);
3763
- const { gridColumn, gridRow, renderDisplay } = schema;
4043
+ const { gridColumn = "span 4", gridRow = "span 1", renderDisplay } = schema;
3764
4044
  const [searchText, setSearchText] = useState();
3765
4045
  const [limit, setLimit] = useState(10);
3766
4046
  const [openSearchResult, setOpenSearchResult] = useState();
@@ -3775,28 +4055,61 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, }) => {
3775
4055
  setSearchText(event.target.value);
3776
4056
  setLimit(10);
3777
4057
  };
3778
- return (jsxs(Field, { label: `${translate.t(removeIndex(`${column}.fieldLabel`))}`, required: isRequired, alignItems: "stretch", gridColumn,
4058
+ if (variant === "radio") {
4059
+ return (jsx(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
4060
+ gridRow, children: jsx(RadioGroup$1.Root, { defaultValue: "1", children: jsx(HStack, { gap: "6", children: filterArray(dataList, searchText ?? "").map((item) => {
4061
+ return (jsxs(RadioGroup$1.Item, { onClick: () => {
4062
+ if (!isMultiple) {
4063
+ setOpenSearchResult(false);
4064
+ setValue(colLabel, item);
4065
+ return;
4066
+ }
4067
+ const newSet = new Set([...(watchEnums ?? []), item]);
4068
+ setValue(colLabel, [...newSet]);
4069
+ }, value: item, children: [jsx(RadioGroup$1.ItemHiddenInput, {}), jsx(RadioGroup$1.ItemIndicator, {}), jsx(RadioGroup$1.ItemText, { children: !!renderDisplay === true
4070
+ ? renderDisplay(item)
4071
+ : translate.t(removeIndex(`${colLabel}.${item}`)) })] }, `${colLabel}-${item}`));
4072
+ }) }) }) }));
4073
+ }
4074
+ return (jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
3779
4075
  gridRow, children: [isMultiple && (jsxs(Flex, { flexFlow: "wrap", gap: 1, children: [watchEnums.map((enumValue) => {
3780
4076
  const item = enumValue;
3781
- if (item === undefined) {
3782
- return jsx(Fragment, { children: "undefined" });
4077
+ if (!!item === false) {
4078
+ return jsx(Fragment, {});
3783
4079
  }
3784
- return (jsx(Tag, { closable: true, onClick: () => {
3785
- // setSelectedEnums((state) => state.filter((id) => id != item));
4080
+ return (jsx(Tag, { size: "lg", closable: true, onClick: () => {
3786
4081
  setValue(column, watchEnums.filter((id) => id != item));
3787
4082
  }, children: !!renderDisplay === true
3788
4083
  ? renderDisplay(item)
3789
- : translate.t(removeIndex(`${colLabel}.${item}`)) }));
3790
- }), jsx(Tag, { cursor: "pointer", onClick: () => {
4084
+ : translate.t(removeIndex(`${colLabel}.${item}`)) }, item));
4085
+ }), jsx(Tag, { size: "lg", cursor: "pointer", onClick: () => {
3791
4086
  setOpenSearchResult(true);
3792
- }, children: translate.t(removeIndex(`${colLabel}.addMore`)) })] })), !isMultiple && (jsx(Button, { variant: "outline", onClick: () => {
4087
+ }, children: translate.t(removeIndex(`${colLabel}.add_more`)) }, `${colLabel}-add-more-tag`)] })), !isMultiple && (jsx(Button, { variant: "outline", onClick: () => {
3793
4088
  setOpenSearchResult(true);
3794
- }, children: watchEnum === undefined
4089
+ }, justifyContent: "start", children: !!watchEnum === false
3795
4090
  ? ""
3796
- : translate.t(removeIndex(`${colLabel}.${watchEnum}`)) })), jsxs(PopoverRoot, { open: openSearchResult, onOpenChange: (e) => setOpenSearchResult(e.open), closeOnInteractOutside: true, initialFocusEl: () => ref.current, positioning: { placement: "bottom-start" }, children: [jsx(PopoverTrigger, {}), jsx(PopoverContent, { children: jsxs(PopoverBody, { display: "grid", gap: 1, children: [jsx(Input, { placeholder: translate.t(`${column}.typeToSearch`), onChange: (event) => {
4091
+ : 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: translate.t(`${colLabel}.type_to_search`), onChange: (event) => {
3797
4092
  onSearchChange(event);
3798
4093
  setOpenSearchResult(true);
3799
- }, autoComplete: "off", ref: ref }), jsx(PopoverTitle, {}), jsx(Text, { children: `${translate.t(`${column}.total`)}: ${count}, ${translate.t(`${column}.showing`)} ${limit}` }), jsxs(Grid, { gridTemplateColumns: "repeat(auto-fit, minmax(15rem, 1fr))", overflow: "auto", maxHeight: "50vh", children: [jsx(Flex, { flexFlow: "column wrap", children: filterArray(dataList, searchText ?? "").map((item) => {
4094
+ }, autoComplete: "off", ref: ref }), jsx(PopoverTitle, {}), showTotalAndLimit && (jsx(Text, { children: `${translate.t(removeIndex(`${colLabel}.total`))}: ${count}, ${translate.t(removeIndex(`${colLabel}.showing`))} ${limit}` })), jsxs(Grid, { overflow: "auto", maxHeight: "20rem", children: [jsx(Flex, { flexFlow: "column wrap", children: dataList
4095
+ .filter((item) => {
4096
+ const searchTerm = (searchText || "").toLowerCase();
4097
+ if (!searchTerm)
4098
+ return true;
4099
+ // Check if the original enum value contains the search text
4100
+ const enumValueMatch = item
4101
+ .toLowerCase()
4102
+ .includes(searchTerm);
4103
+ // Check if the display value (translation) contains the search text
4104
+ const displayValue = !!renderDisplay === true
4105
+ ? renderDisplay(item)
4106
+ : translate.t(removeIndex(`${colLabel}.${item}`));
4107
+ // Convert to string and check if it includes the search term
4108
+ const displayValueString = String(displayValue).toLowerCase();
4109
+ const displayValueMatch = displayValueString.includes(searchTerm);
4110
+ return enumValueMatch || displayValueMatch;
4111
+ })
4112
+ .map((item) => {
3800
4113
  const selected = isMultiple
3801
4114
  ? watchEnums.some((enumValue) => item === enumValue)
3802
4115
  : watchEnum == item;
@@ -3808,10 +4121,10 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, }) => {
3808
4121
  }
3809
4122
  const newSet = new Set([...(watchEnums ?? []), item]);
3810
4123
  setValue(colLabel, [...newSet]);
3811
- }, ...(selected ? { color: "gray.400/50" } : {}), children: !!renderDisplay === true
4124
+ }, ...(selected ? { color: "colorPalette.400/50" } : {}), children: !!renderDisplay === true
3812
4125
  ? renderDisplay(item)
3813
4126
  : translate.t(removeIndex(`${colLabel}.${item}`)) }, `${colLabel}-${item}`));
3814
- }) }), isDirty && (jsx(Fragment, { children: dataList.length <= 0 && (jsx(Fragment, { children: translate.t(removeIndex(`${colLabel}.emptySearchResult`)) })) }))] })] }) })] }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.fieldRequired`)) }))] }));
4127
+ }) }), isDirty && (jsx(Fragment, { children: dataList.length <= 0 && (jsx(Fragment, { children: translate.t(removeIndex(`${colLabel}.empty_search_result`)) })) }))] })] }) })] }), errors[`${colLabel}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
3815
4128
  };
3816
4129
 
3817
4130
  function isEnteringWindow(_ref) {
@@ -4163,17 +4476,17 @@ const FileDropzone = ({ children = undefined, gridProps = {}, onDrop = () => { }
4163
4476
  const filesArray = [...event.target.files];
4164
4477
  onDrop({ files: filesArray });
4165
4478
  };
4166
- return (jsxs(Grid, { ...getColor(isDraggedOver), ref: ref, cursor: "pointer", onClick: handleClick, borderStyle: "dashed", borderColor: "gray.400", alignContent: "center", justifyContent: "center", borderWidth: 1, borderRadius: 4, ...gridProps, children: [children, !!children === false && (jsxs(Fragment, { children: [jsx(Flex, { children: placeholder }), jsx(Input, { type: "file", multiple: true, style: { display: "none" }, ref: fileInput, onChange: handleChange })] }))] }));
4479
+ return (jsxs(Grid, { ...getColor(isDraggedOver), ref: ref, cursor: "pointer", onClick: handleClick, borderStyle: "dashed", borderColor: "colorPalette.400", alignContent: "center", justifyContent: "center", borderWidth: 1, borderRadius: 4, ...gridProps, children: [children, !!children === false && (jsxs(Fragment, { children: [jsx(Flex, { children: placeholder }), jsx(Input, { type: "file", multiple: true, style: { display: "none" }, ref: fileInput, onChange: handleChange })] }))] }));
4167
4480
  };
4168
4481
 
4169
4482
  const FilePicker = ({ column, schema, prefix }) => {
4170
4483
  const { setValue, formState: { errors }, watch, } = useFormContext();
4171
4484
  const { translate } = useSchemaContext();
4172
- const { required, gridColumn, gridRow } = schema;
4485
+ const { required, gridColumn = "span 4", gridRow = "span 1", } = schema;
4173
4486
  const isRequired = required?.some((columnId) => columnId === column);
4174
4487
  const currentFiles = (watch(column) ?? []);
4175
4488
  const colLabel = `${prefix}${column}`;
4176
- return (jsxs(Field, { label: `${translate.t(`${colLabel}.fieldLabel`)}`, required: isRequired, gridColumn: gridColumn ?? "span 4", gridRow: gridRow ?? "span 1", display: "grid", gridTemplateRows: "auto 1fr auto", alignItems: "stretch", children: [jsx(FileDropzone, { onDrop: ({ files }) => {
4489
+ return (jsxs(Field, { label: `${translate.t(`${colLabel}.field_label`)}`, required: isRequired, gridColumn: gridColumn ?? "span 4", gridRow: gridRow ?? "span 1", display: "grid", gridTemplateRows: "auto 1fr auto", alignItems: "stretch", children: [jsx(FileDropzone, { onDrop: ({ files }) => {
4177
4490
  const newFiles = files.filter(({ name }) => !currentFiles.some((cur) => cur.name === name));
4178
4491
  setValue(colLabel, [...currentFiles, ...newFiles]);
4179
4492
  }, placeholder: translate.t(removeIndex(`${colLabel}.fileDropzone`)) }), jsx(Flex, { flexFlow: "column", gap: 1, children: currentFiles.map((file) => {
@@ -4181,10 +4494,19 @@ const FilePicker = ({ column, schema, prefix }) => {
4181
4494
  setValue(column, currentFiles.filter(({ name }) => {
4182
4495
  return name !== file.name;
4183
4496
  }));
4184
- }, display: "flex", flexFlow: "row", alignItems: "center", padding: "2", children: [jsx(Box, { children: file.name }), jsx(TiDeleteOutline, {})] }) }, file.name));
4185
- }) }), errors[`${colLabel}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.fieldRequired`)) }))] }));
4497
+ }, display: "flex", flexFlow: "row", alignItems: "center", padding: "2", children: [file.type.startsWith("image/") && (jsx(Image, { src: URL.createObjectURL(file), alt: file.name, boxSize: "50px", objectFit: "cover", borderRadius: "md", marginRight: "2" })), jsx(Box, { children: file.name }), jsx(TiDeleteOutline, {})] }) }, file.name));
4498
+ }) }), errors[`${colLabel}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
4186
4499
  };
4187
4500
 
4501
+ const ToggleTip = React.forwardRef(function ToggleTip(props, ref) {
4502
+ const { showArrow, children, portalled = true, content, portalRef, ...rest } = props;
4503
+ return (jsxs(Popover.Root, { ...rest, positioning: { ...rest.positioning, gutter: 4 }, children: [jsx(Popover.Trigger, { asChild: true, children: children }), jsx(Portal, { disabled: !portalled, container: portalRef, children: jsx(Popover.Positioner, { children: jsxs(Popover.Content, { width: "auto", px: "2", py: "1", textStyle: "xs", rounded: "sm", ref: ref, children: [showArrow && (jsx(Popover.Arrow, { children: jsx(Popover.ArrowTip, {}) })), content] }) }) })] }));
4504
+ });
4505
+ const InfoTip = React.forwardRef(function InfoTip(props, ref) {
4506
+ const { children, ...rest } = props;
4507
+ return (jsx(ToggleTip, { content: children, ...rest, ref: ref, children: jsx(IconButton, { variant: "ghost", "aria-label": "info", size: "2xs", colorPalette: "colorPalette", children: jsx(HiOutlineInformationCircle, {}) }) }));
4508
+ });
4509
+
4188
4510
  const getTableData = async ({ serverUrl, in_table, searching = "", where = [], limit = 10, offset = 0, }) => {
4189
4511
  if (serverUrl === undefined || serverUrl.length == 0) {
4190
4512
  throw new Error("The serverUrl is missing");
@@ -4216,24 +4538,38 @@ const getTableData = async ({ serverUrl, in_table, searching = "", where = [], l
4216
4538
  const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
4217
4539
  const { watch, formState: { errors }, setValue, } = useFormContext();
4218
4540
  const { serverUrl, idMap, setIdMap, translate, schema: parentSchema, } = useSchemaContext();
4219
- const { required, gridColumn, gridRow, renderDisplay, foreign_key } = schema;
4541
+ const { required, gridColumn = "span 4", gridRow = "span 1", renderDisplay, foreign_key, } = schema;
4220
4542
  const isRequired = required?.some((columnId) => columnId === column);
4221
- const { table, column: column_ref, display_column, } = foreign_key;
4222
- const [searchText, setSearchText] = useState();
4543
+ const { table, column: column_ref, display_column, customQueryFn, } = foreign_key;
4544
+ const [searchText, setSearchText] = useState("");
4223
4545
  const [limit, setLimit] = useState(10);
4224
4546
  const [openSearchResult, setOpenSearchResult] = useState();
4225
4547
  const [page, setPage] = useState(0);
4226
4548
  const ref = useRef(null);
4227
4549
  const colLabel = `${prefix}${column}`;
4550
+ const watchId = watch(colLabel);
4551
+ const watchIds = isMultiple ? (watch(colLabel) ?? []) : [];
4552
+ // Query for search results
4228
4553
  const query = useQuery({
4229
4554
  queryKey: [`idpicker`, { column, searchText, limit, page }],
4230
4555
  queryFn: async () => {
4556
+ if (customQueryFn) {
4557
+ const { data, idMap } = await customQueryFn({
4558
+ searching: searchText ?? "",
4559
+ limit: limit,
4560
+ offset: page * limit,
4561
+ });
4562
+ setIdMap((state) => {
4563
+ return { ...state, ...idMap };
4564
+ });
4565
+ return data;
4566
+ }
4231
4567
  const data = await getTableData({
4232
4568
  serverUrl,
4233
4569
  searching: searchText ?? "",
4234
4570
  in_table: table,
4235
4571
  limit: limit,
4236
- offset: page * 10,
4572
+ offset: page * limit,
4237
4573
  });
4238
4574
  const newMap = Object.fromEntries((data ?? { data: [] }).data.map((item) => {
4239
4575
  return [
@@ -4248,27 +4584,38 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
4248
4584
  });
4249
4585
  return data;
4250
4586
  },
4251
- enabled: (searchText ?? "")?.length > 0,
4587
+ enabled: openSearchResult === true,
4252
4588
  staleTime: 300000,
4253
4589
  });
4254
- const { isLoading, isFetching, data, isPending, isError } = query;
4255
- const dataList = data?.data ?? [];
4256
- const count = data?.count ?? 0;
4257
- const isDirty = (searchText?.length ?? 0) > 0;
4258
- const watchId = watch(colLabel);
4259
- const watchIds = (watch(colLabel) ?? []);
4260
- useQuery({
4590
+ // Query for currently selected items (to display them properly)
4591
+ const queryDefault = useQuery({
4261
4592
  queryKey: [
4262
- `idpicker`,
4263
- { form: parentSchema.title, column, searchText, limit, page },
4593
+ `idpicker-default`,
4594
+ { form: parentSchema.title, column, id: isMultiple ? watchIds : watchId },
4264
4595
  ],
4265
4596
  queryFn: async () => {
4597
+ if (customQueryFn) {
4598
+ const { data, idMap } = await customQueryFn({
4599
+ searching: watchIds.join(","),
4600
+ limit: isMultiple ? watchIds.length : 1,
4601
+ offset: 0,
4602
+ });
4603
+ setIdMap((state) => {
4604
+ return { ...state, ...idMap };
4605
+ });
4606
+ return data;
4607
+ }
4608
+ if (!watchId && (!watchIds || watchIds.length === 0)) {
4609
+ return { data: [] };
4610
+ }
4611
+ const searchValue = isMultiple ? watchIds.join(",") : watchId;
4266
4612
  const data = await getTableData({
4267
4613
  serverUrl,
4268
- searching: watchId,
4614
+ searching: searchValue,
4269
4615
  in_table: table,
4270
- limit: limit,
4271
- offset: page * 10,
4616
+ where: [{ id: column_ref, value: isMultiple ? watchIds : watchId }],
4617
+ limit: isMultiple ? watchIds.length : 1,
4618
+ offset: 0,
4272
4619
  });
4273
4620
  const newMap = Object.fromEntries((data ?? { data: [] }).data.map((item) => {
4274
4621
  return [
@@ -4283,12 +4630,45 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
4283
4630
  });
4284
4631
  return data;
4285
4632
  },
4633
+ enabled: isMultiple
4634
+ ? Array.isArray(watchIds) && watchIds.length > 0
4635
+ : !!watchId,
4286
4636
  });
4637
+ // Effect to load selected values when component mounts
4638
+ useEffect(() => {
4639
+ if (isMultiple ? watchIds.length > 0 : !!watchId) {
4640
+ queryDefault.refetch();
4641
+ }
4642
+ // eslint-disable-next-line react-hooks/exhaustive-deps
4643
+ }, []);
4644
+ // Effect to trigger initial data fetch when popover opens
4645
+ useEffect(() => {
4646
+ if (openSearchResult) {
4647
+ // Reset search text when opening the popover
4648
+ setSearchText("");
4649
+ // Reset page to first page
4650
+ setPage(0);
4651
+ // Fetch initial data
4652
+ query.refetch();
4653
+ }
4654
+ // eslint-disable-next-line react-hooks/exhaustive-deps
4655
+ }, [openSearchResult]);
4287
4656
  const onSearchChange = async (event) => {
4288
4657
  setSearchText(event.target.value);
4289
4658
  setPage(0);
4290
- setLimit(10);
4659
+ query.refetch();
4291
4660
  };
4661
+ const handleLimitChange = (event) => {
4662
+ const newLimit = Number(event.target.value);
4663
+ setLimit(newLimit);
4664
+ // Reset to first page when changing limit
4665
+ setPage(0);
4666
+ // Trigger a new search with the updated limit
4667
+ query.refetch();
4668
+ };
4669
+ const { isLoading, isFetching, data, isPending, isError } = query;
4670
+ const dataList = data?.data ?? [];
4671
+ const count = data?.count ?? 0;
4292
4672
  const getPickedValue = () => {
4293
4673
  if (Object.keys(idMap).length <= 0) {
4294
4674
  return "";
@@ -4297,52 +4677,67 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
4297
4677
  if (record === undefined) {
4298
4678
  return "";
4299
4679
  }
4680
+ if (!!renderDisplay === true) {
4681
+ return renderDisplay(record);
4682
+ }
4300
4683
  return record[display_column];
4301
4684
  };
4302
- return (jsxs(Field, { label: `${translate.t(removeIndex(removeIndex(`${column}.fieldLabel`)))}`, required: isRequired, alignItems: "stretch", gridColumn,
4685
+ return (jsxs(Field, { label: `${translate.t(removeIndex(removeIndex(`${column}.field_label`)))}`, required: isRequired, alignItems: "stretch", gridColumn,
4303
4686
  gridRow, children: [isMultiple && (jsxs(Flex, { flexFlow: "wrap", gap: 1, children: [watchIds.map((id) => {
4304
4687
  const item = idMap[id];
4305
4688
  if (item === undefined) {
4306
4689
  return (jsx(Text, { children: translate.t(removeIndex(`${colLabel}.undefined`)) }, id));
4307
4690
  }
4308
4691
  return (jsx(Tag, { closable: true, onClick: () => {
4309
- setValue(column, watchIds.filter((id) => id != item[column_ref]));
4692
+ setValue(colLabel, watchIds.filter((itemId) => itemId !== item[column_ref]));
4310
4693
  }, children: !!renderDisplay === true
4311
4694
  ? renderDisplay(item)
4312
4695
  : item[display_column] }, id));
4313
4696
  }), jsx(Tag, { cursor: "pointer", onClick: () => {
4314
4697
  setOpenSearchResult(true);
4315
- }, children: translate.t(removeIndex(`${colLabel}.addMore`)) })] })), !isMultiple && (jsx(Button, { variant: "outline", onClick: () => {
4698
+ }, children: translate.t(removeIndex(`${colLabel}.add_more`)) })] })), !isMultiple && (jsx(Button, { variant: "outline", onClick: () => {
4316
4699
  setOpenSearchResult(true);
4317
- }, children: getPickedValue() })), jsxs(PopoverRoot, { open: openSearchResult, onOpenChange: (e) => setOpenSearchResult(e.open), closeOnInteractOutside: true, initialFocusEl: () => ref.current, positioning: { placement: "bottom-start", strategy: "fixed" }, children: [jsx(PopoverTrigger, {}), jsx(PopoverContent, { children: jsxs(PopoverBody, { display: "grid", gap: 1, children: [jsx(Input, { placeholder: translate.t(removeIndex(`${colLabel}.typeToSearch`)), onChange: (event) => {
4318
- onSearchChange(event);
4319
- setOpenSearchResult(true);
4320
- }, autoComplete: "off", ref: ref }), jsx(PopoverTitle, {}), (searchText?.length ?? 0) > 0 && (jsxs(Fragment, { children: [isFetching && jsx(Fragment, { children: "isFetching" }), isLoading && jsx(Fragment, { children: "isLoading" }), isPending && jsx(Fragment, { children: "isPending" }), (isFetching || isLoading || isPending) && jsx(Spinner, {}), isError && (jsx(Icon, { color: "red.400", children: jsx(BiError, {}) })), jsx(Text, { justifySelf: "center", children: `${translate.t(removeIndex(`${colLabel}.total`))} ${count}, ${translate.t(removeIndex(`${colLabel}.showing`))} ${limit}` }), jsxs(Grid, { gridTemplateColumns: "repeat(auto-fit, minmax(15rem, 1fr))", overflow: "auto", maxHeight: "50vh", children: [jsx(Flex, { flexFlow: "column wrap", children:
4321
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
4322
- dataList.map((item) => {
4323
- const selected = isMultiple
4324
- ? watchIds.some((id) => item[column_ref] === id)
4325
- : watchId === item[column_ref];
4326
- return (jsx(Box, { cursor: "pointer", onClick: () => {
4327
- if (!isMultiple) {
4328
- setOpenSearchResult(false);
4329
- setValue(colLabel, item[column_ref]);
4330
- return;
4331
- }
4332
- const newSet = new Set([
4333
- ...(watchIds ?? []),
4334
- item[column_ref],
4335
- ]);
4336
- setValue(colLabel, [...newSet]);
4337
- }, opacity: 0.7, _hover: { opacity: 1 }, ...(selected ? { color: "gray.400/50" } : {}), children: !!renderDisplay === true
4338
- ? renderDisplay(item)
4339
- : item[display_column] }, item[column_ref]));
4340
- }) }), isDirty && (jsx(Fragment, { children: dataList.length <= 0 && (jsx(Text, { children: translate.t(removeIndex(`${colLabel}.emptySearchResult`)) })) }))] }), jsx(PaginationRoot, { justifySelf: "center", count: count, pageSize: 10, defaultPage: 1, page: page + 1, onPageChange: (e) => setPage(e.page - 1), children: jsxs(HStack, { gap: "4", children: [jsx(PaginationPrevTrigger, {}), count > 0 && jsx(PaginationPageText, {}), jsx(PaginationNextTrigger, {})] }) })] }))] }) })] }), errors[`${colLabel}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.fieldRequired`)) }))] }));
4700
+ }, justifyContent: "start", children: queryDefault.isLoading ? jsx(Spinner, { size: "sm" }) : getPickedValue() })), jsxs(PopoverRoot, { open: openSearchResult, onOpenChange: (e) => setOpenSearchResult(e.open), closeOnInteractOutside: true, initialFocusEl: () => ref.current, positioning: { placement: "bottom-start", strategy: "fixed" }, children: [jsx(PopoverTrigger, {}), jsx(PopoverContent, { portalled: false, children: jsxs(PopoverBody, { display: "grid", gap: 1, children: [jsx(Input, { placeholder: translate.t(removeIndex(`${colLabel}.type_to_search`)), onChange: onSearchChange, autoComplete: "off", ref: ref, value: searchText }), jsx(PopoverTitle, {}), openSearchResult && (jsxs(Fragment, { children: [(isFetching || isLoading || isPending) && jsx(Spinner, {}), isError && (jsx(Icon, { color: "red.400", children: jsx(BiError, {}) })), jsxs(Flex, { justifyContent: "space-between", alignItems: "center", children: [jsxs(Flex, { alignItems: "center", gap: "2", children: [jsx(InfoTip, { children: `${translate.t(removeIndex(`${colLabel}.total`))} ${count}, ${translate.t(removeIndex(`${colLabel}.showing`))} ${limit} ${translate.t(removeIndex(`${colLabel}.per_page`), "per page")}` }), jsxs(Text, { fontSize: "sm", fontWeight: "bold", children: [count, jsxs(Text, { as: "span", fontSize: "xs", ml: "1", color: "gray.500", children: ["/", " ", count > 0
4701
+ ? `${page * limit + 1}-${Math.min((page + 1) * limit, count)}`
4702
+ : "0"] })] })] }), jsx(Box, { children: jsxs("select", { value: limit, onChange: handleLimitChange, style: {
4703
+ padding: "4px 8px",
4704
+ borderRadius: "4px",
4705
+ border: "1px solid #ccc",
4706
+ fontSize: "14px",
4707
+ }, children: [jsx("option", { value: "5", children: "5" }), jsx("option", { value: "10", children: "10" }), jsx("option", { value: "20", children: "20" }), jsx("option", { value: "30", children: "30" })] }) })] }), jsx(Grid, { overflowY: "auto", children: dataList.length > 0 ? (jsx(Flex, { flexFlow: "column wrap", gap: 1, children: dataList.map((item) => {
4708
+ const selected = isMultiple
4709
+ ? watchIds.some((id) => item[column_ref] === id)
4710
+ : watchId === item[column_ref];
4711
+ return (jsx(Box, { cursor: "pointer", onClick: () => {
4712
+ if (!isMultiple) {
4713
+ setOpenSearchResult(false);
4714
+ setValue(colLabel, item[column_ref]);
4715
+ return;
4716
+ }
4717
+ // For multiple selection, don't add if already selected
4718
+ if (selected)
4719
+ return;
4720
+ const newSet = new Set([
4721
+ ...(watchIds ?? []),
4722
+ item[column_ref],
4723
+ ]);
4724
+ setValue(colLabel, [...newSet]);
4725
+ }, opacity: 0.7, _hover: { opacity: 1 }, ...(selected
4726
+ ? {
4727
+ color: "colorPalette.400/50",
4728
+ fontWeight: "bold",
4729
+ }
4730
+ : {}), children: !!renderDisplay === true
4731
+ ? renderDisplay(item)
4732
+ : item[display_column] }, item[column_ref]));
4733
+ }) })) : (jsx(Text, { children: searchText
4734
+ ? translate.t(removeIndex(`${colLabel}.empty_search_result`))
4735
+ : translate.t(removeIndex(`${colLabel}.initial_results`)) })) }), jsx(PaginationRoot, { justifySelf: "center", count: count, pageSize: limit, defaultPage: 1, page: page + 1, onPageChange: (e) => setPage(e.page - 1), children: jsxs(HStack, { gap: "4", children: [jsx(PaginationPrevTrigger, {}), count > 0 && jsx(PaginationPageText, {}), jsx(PaginationNextTrigger, {})] }) })] }))] }) })] }), errors[`${colLabel}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
4341
4736
  };
4342
4737
 
4343
4738
  const NumberInputRoot = React.forwardRef(function NumberInput$1(props, ref) {
4344
4739
  const { children, ...rest } = props;
4345
- return (jsxs(NumberInput.Root, { ref: ref, variant: "outline", ...rest, children: [children, jsxs(NumberInput.Control, { children: [jsx(NumberInput.IncrementTrigger, {}), jsx(NumberInput.DecrementTrigger, {})] })] }));
4740
+ return (jsx(NumberInput.Root, { ref: ref, variant: "outline", ...rest, children: children }));
4346
4741
  });
4347
4742
  const NumberInputField$1 = NumberInput.Input;
4348
4743
  NumberInput.Scrubber;
@@ -4351,17 +4746,17 @@ NumberInput.Label;
4351
4746
  const NumberInputField = ({ schema, column, prefix, }) => {
4352
4747
  const { setValue, formState: { errors }, watch, } = useFormContext();
4353
4748
  const { translate } = useSchemaContext();
4354
- const { required, gridColumn, gridRow } = schema;
4749
+ const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
4355
4750
  const isRequired = required?.some((columnId) => columnId === column);
4356
4751
  const colLabel = `${prefix}${column}`;
4357
4752
  const value = watch(`${colLabel}`);
4358
- return (jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.fieldLabel`))}`, required: isRequired, gridColumn, gridRow, children: [jsx(NumberInputRoot, { children: jsx(NumberInputField$1, { required: isRequired, value: value, onChange: (event) => {
4753
+ return (jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn, gridRow, children: [jsx(NumberInputRoot, { children: jsx(NumberInputField$1, { required: isRequired, value: value, onChange: (event) => {
4359
4754
  setValue(`${colLabel}`, Number(event.target.value));
4360
- } }) }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.fieldRequired`)) }))] }));
4755
+ } }) }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
4361
4756
  };
4362
4757
 
4363
4758
  const ObjectInput = ({ schema, column, prefix }) => {
4364
- const { properties, gridRow, gridColumn = "1/span 12", required } = schema;
4759
+ const { properties, gridColumn = "span 12", gridRow = "span 1", required, showLabel = true, } = schema;
4365
4760
  const { translate } = useSchemaContext();
4366
4761
  const colLabel = `${prefix}${column}`;
4367
4762
  const isRequired = required?.some((columnId) => columnId === column);
@@ -4369,25 +4764,28 @@ const ObjectInput = ({ schema, column, prefix }) => {
4369
4764
  if (properties === undefined) {
4370
4765
  throw new Error(`properties is undefined when using ObjectInput`);
4371
4766
  }
4372
- return (jsxs(Box, { gridRow, gridColumn, children: [jsxs(Box, { as: "label", gridColumn: "1/span12", children: [`${translate.t(removeIndex(`${colLabel}.fieldLabel`))}`, isRequired && jsx("span", { children: "*" })] }), jsx(Grid, { gap: "4", padding: "4", gridTemplateColumns: "repeat(12, 1fr)", gridTemplateRows: `repeat("auto-fit", auto)`, children: Object.keys(properties ?? {}).map((key) => {
4767
+ return (jsxs(Box, { gridRow, gridColumn, children: [showLabel && (jsxs(Box, { as: "label", children: [`${translate.t(removeIndex(`${colLabel}.field_label`))}`, isRequired && jsx("span", { children: "*" })] })), jsx(Grid, { bgColor: { base: "colorPalette.100", _dark: "colorPalette.900" }, p: 2, borderRadius: 4, borderWidth: 1, borderColor: {
4768
+ base: "colorPalette.200",
4769
+ _dark: "colorPalette.800",
4770
+ }, gap: "4", padding: "4", gridTemplateColumns: "repeat(12, 1fr)", autoFlow: "row", children: Object.keys(properties ?? {}).map((key) => {
4373
4771
  return (
4374
4772
  // @ts-expect-error find suitable types
4375
4773
  jsx(ColumnRenderer, { column: `${key}`,
4376
4774
  prefix: `${prefix}${column}.`,
4377
4775
  properties }, `form-${colLabel}-${key}`));
4378
- }) }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.fieldRequired`)) }))] }));
4776
+ }) }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
4379
4777
  };
4380
4778
 
4381
4779
  const RecordInput$1 = ({ column, schema, prefix }) => {
4382
4780
  const { formState: { errors }, setValue, getValues, } = useFormContext();
4383
4781
  const { translate } = useSchemaContext();
4384
- const { required, gridColumn, gridRow } = schema;
4782
+ const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
4385
4783
  const isRequired = required?.some((columnId) => columnId === column);
4386
4784
  const entries = Object.entries(getValues(column) ?? {});
4387
4785
  const [showNewEntries, setShowNewEntries] = useState(false);
4388
4786
  const [newKey, setNewKey] = useState();
4389
4787
  const [newValue, setNewValue] = useState();
4390
- return (jsxs(Field, { label: `${translate.t(`${column}.fieldLabel`)}`, required: isRequired, alignItems: "stretch", gridColumn, gridRow, children: [entries.map(([key, value]) => {
4788
+ return (jsxs(Field, { label: `${translate.t(`${column}.field_label`)}`, required: isRequired, alignItems: "stretch", gridColumn, gridRow, children: [entries.map(([key, value]) => {
4391
4789
  return (jsxs(Grid, { templateColumns: "1fr 1fr auto", gap: 1, children: [jsx(Input, { value: key, onChange: (e) => {
4392
4790
  const filtered = entries.filter(([target]) => {
4393
4791
  return target !== key;
@@ -4427,16 +4825,16 @@ const RecordInput$1 = ({ column, schema, prefix }) => {
4427
4825
  setShowNewEntries(true);
4428
4826
  setNewKey(undefined);
4429
4827
  setNewValue(undefined);
4430
- }, children: translate.t(`${column}.addNew`) }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(`${column}.fieldRequired`) }))] }));
4828
+ }, children: translate.t(`${column}.addNew`) }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(`${column}.field_required`) }))] }));
4431
4829
  };
4432
4830
 
4433
4831
  const StringInputField = ({ column, schema, prefix, }) => {
4434
4832
  const { register, formState: { errors }, } = useFormContext();
4435
4833
  const { translate } = useSchemaContext();
4436
- const { required, gridColumn, gridRow } = schema;
4834
+ const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
4437
4835
  const isRequired = required?.some((columnId) => columnId === column);
4438
4836
  const colLabel = `${prefix}${column}`;
4439
- return (jsx(Fragment, { children: jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.fieldLabel`))}`, required: isRequired, gridColumn: gridColumn ?? "span 4", gridRow: gridRow ?? "span 1", children: [jsx(Input, { ...register(`${colLabel}`, { required: isRequired }), autoComplete: "off" }), errors[colLabel] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.fieldRequired`)) }))] }) }));
4837
+ return (jsx(Fragment, { children: jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn: gridColumn, gridRow: gridRow, children: [jsx(Input, { ...register(`${colLabel}`, { required: isRequired }), autoComplete: "off" }), errors[colLabel] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }) }));
4440
4838
  };
4441
4839
 
4442
4840
  const RadioCardItem = React.forwardRef(function RadioCardItem(props, ref) {
@@ -4534,9 +4932,576 @@ const TagPicker = ({ column, schema, prefix }) => {
4534
4932
  }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: (errors[`${column}`]?.message ?? "No error message") }))] }));
4535
4933
  };
4536
4934
 
4935
+ const Textarea = forwardRef(({ value, defaultValue, placeholder, onChange, onFocus, onBlur, disabled = false, readOnly = false, className, rows = 4, maxLength, autoFocus = false, invalid = false, required = false, label, helperText, errorText, ...props }, ref) => {
4936
+ const contentEditableRef = useRef(null);
4937
+ const isControlled = value !== undefined;
4938
+ // Handle input changes
4939
+ const handleInput = (e) => {
4940
+ const text = e.currentTarget.textContent || "";
4941
+ // Check maxLength if specified
4942
+ if (maxLength && text.length > maxLength) {
4943
+ e.currentTarget.textContent = text.slice(0, maxLength);
4944
+ // Move cursor to end
4945
+ const selection = window.getSelection();
4946
+ if (selection) {
4947
+ selection.selectAllChildren(e.currentTarget);
4948
+ selection.collapseToEnd();
4949
+ }
4950
+ return;
4951
+ }
4952
+ onChange?.(text);
4953
+ };
4954
+ // Handle paste events to strip formatting and respect maxLength
4955
+ const handlePaste = (e) => {
4956
+ e.preventDefault();
4957
+ const text = e.clipboardData.getData('text/plain');
4958
+ const currentText = e.currentTarget.textContent || "";
4959
+ let pasteText = text;
4960
+ if (maxLength) {
4961
+ const remainingLength = maxLength - currentText.length;
4962
+ pasteText = text.slice(0, remainingLength);
4963
+ }
4964
+ document.execCommand('insertText', false, pasteText);
4965
+ };
4966
+ // Set initial content
4967
+ useEffect(() => {
4968
+ if (contentEditableRef.current && !isControlled) {
4969
+ const initialValue = defaultValue || "";
4970
+ if (contentEditableRef.current.textContent !== initialValue) {
4971
+ contentEditableRef.current.textContent = initialValue;
4972
+ }
4973
+ }
4974
+ }, [defaultValue, isControlled]);
4975
+ // Update content when value changes (controlled mode)
4976
+ useEffect(() => {
4977
+ if (contentEditableRef.current && isControlled && value !== undefined) {
4978
+ if (contentEditableRef.current.textContent !== value) {
4979
+ contentEditableRef.current.textContent = value;
4980
+ }
4981
+ }
4982
+ }, [value, isControlled]);
4983
+ // Auto focus
4984
+ useEffect(() => {
4985
+ if (autoFocus && contentEditableRef.current) {
4986
+ contentEditableRef.current.focus();
4987
+ }
4988
+ }, [autoFocus]);
4989
+ // Forward ref
4990
+ useEffect(() => {
4991
+ if (typeof ref === 'function') {
4992
+ ref(contentEditableRef.current);
4993
+ }
4994
+ else if (ref) {
4995
+ ref.current = contentEditableRef.current;
4996
+ }
4997
+ }, [ref]);
4998
+ const textareaElement = (jsx(Box, { ref: contentEditableRef, contentEditable: !disabled && !readOnly, onInput: handleInput, onPaste: handlePaste, onFocus: onFocus, onBlur: onBlur, className: className, minHeight: `${rows * 1.5}em`, padding: "2", border: "1px solid", borderColor: invalid ? "red.500" : "gray.200", borderRadius: "md", outline: "none", _focus: {
4999
+ borderColor: invalid ? "red.500" : "blue.500",
5000
+ boxShadow: `0 0 0 1px ${invalid ? "red.500" : "blue.500"}`,
5001
+ }, _disabled: {
5002
+ opacity: 0.6,
5003
+ cursor: "not-allowed",
5004
+ bg: "gray.50",
5005
+ }, _empty: {
5006
+ _before: {
5007
+ content: placeholder ? `"${placeholder}"` : undefined,
5008
+ color: "gray.400",
5009
+ pointerEvents: "none",
5010
+ }
5011
+ }, whiteSpace: "pre-wrap", overflowWrap: "break-word", overflow: "auto", maxHeight: `${rows * 4}em`, suppressContentEditableWarning: true, ...props }));
5012
+ // If we have additional field props, wrap in Field component
5013
+ if (label || helperText || errorText || required) {
5014
+ return (jsxs(Field$1.Root, { invalid: invalid, required: required, children: [label && (jsxs(Field$1.Label, { children: [label, required && jsx(Field$1.RequiredIndicator, {})] })), textareaElement, helperText && jsx(Field$1.HelperText, { children: helperText }), errorText && jsx(Field$1.ErrorText, { children: errorText })] }));
5015
+ }
5016
+ return textareaElement;
5017
+ });
5018
+ Textarea.displayName = "Textarea";
5019
+
5020
+ const TextAreaInput = ({ column, schema, prefix, }) => {
5021
+ const { register, formState: { errors }, } = useFormContext();
5022
+ const { translate } = useSchemaContext();
5023
+ const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
5024
+ const isRequired = required?.some((columnId) => columnId === column);
5025
+ const colLabel = `${prefix}${column}`;
5026
+ const form = useFormContext();
5027
+ const { setValue, watch } = form;
5028
+ const watchValue = watch(colLabel);
5029
+ return (jsx(Fragment, { children: jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn: gridColumn ?? "span 4", gridRow: gridRow ?? "span 1", display: "grid", children: [jsx(Textarea, { value: watchValue, onChange: (value) => setValue(colLabel, value) }), errors[colLabel] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }) }));
5030
+ };
5031
+
5032
+ function TimePicker$1({ hour, setHour, minute, setMinute, meridiem, setMeridiem, meridiemLabel = {
5033
+ am: "am",
5034
+ pm: "pm",
5035
+ }, onChange = (_newValue) => { }, timezone = "Asia/Hong_Kong", }) {
5036
+ const handleClear = () => {
5037
+ setHour(null);
5038
+ setMinute(null);
5039
+ setMeridiem(null);
5040
+ setInputValue("");
5041
+ setShowInput(false);
5042
+ onChange({ hour: null, minute: null, meridiem: null });
5043
+ };
5044
+ const getTimeString = (hour, minute, meridiem) => {
5045
+ if (hour === null || minute === null || meridiem === null) {
5046
+ return "";
5047
+ }
5048
+ // if the hour is 24, set the hour to 0
5049
+ if (hour === 24) {
5050
+ return dayjs().tz(timezone).hour(0).minute(minute).format("HH:mmZ");
5051
+ }
5052
+ // use dayjs to format the time at current timezone
5053
+ // if meridiem is pm, add 12 hours
5054
+ let newHour = hour;
5055
+ if (meridiem === "pm" && hour !== 12) {
5056
+ newHour = hour + 12;
5057
+ }
5058
+ // if the hour is 12, set the meridiem to am, and set the hour to 0
5059
+ else if (meridiem === "am" && hour === 12) {
5060
+ newHour = 0;
5061
+ }
5062
+ return dayjs().tz(timezone).hour(newHour).minute(minute).format("HH:mmZ");
5063
+ };
5064
+ const stringTime = getTimeString(hour, minute, meridiem);
5065
+ const [inputValue, setInputValue] = useState("");
5066
+ const [showInput, setShowInput] = useState(false);
5067
+ const handleBlur = (text) => {
5068
+ // ignore all non-numeric characters
5069
+ if (!text) {
5070
+ return;
5071
+ }
5072
+ const value = text.replace(/[^0-9apm]/g, "");
5073
+ if (value === "") {
5074
+ handleClear();
5075
+ return;
5076
+ }
5077
+ // if the value is a valid time, parse it and set the hour, minute, and meridiem
5078
+ // if the value is not a valid time, set the stringTime to the value
5079
+ // first two characters are the hour
5080
+ // next two characters are the minute
5081
+ // final two characters are the meridiem
5082
+ const hour = parseInt(value.slice(0, 2));
5083
+ const minute = parseInt(value.slice(2, 4));
5084
+ const meridiem = value.slice(4, 6);
5085
+ // validate the hour and minute
5086
+ if (isNaN(hour) || isNaN(minute)) {
5087
+ setInputValue("");
5088
+ return;
5089
+ }
5090
+ // if the hour is larger than 24, set the hour to 24
5091
+ if (hour > 24) {
5092
+ setInputValue("");
5093
+ return;
5094
+ }
5095
+ let newHour = hour;
5096
+ let newMinute = minute;
5097
+ let newMeridiem = meridiem;
5098
+ // if the hour is 24, set the meridiem to am, and set the hour to 0
5099
+ if (hour === 24) {
5100
+ newMeridiem = "am";
5101
+ newHour = 0;
5102
+ }
5103
+ // if the hour is greater than 12, set the meridiem to pm, and subtract 12 from the hour
5104
+ else if (hour > 12) {
5105
+ newMeridiem = "pm";
5106
+ newHour = hour - 12;
5107
+ }
5108
+ // if the hour is 12, set the meridiem to pm, and set the hour to 12
5109
+ else if (hour === 12) {
5110
+ newMeridiem = "pm";
5111
+ newHour = 12;
5112
+ }
5113
+ // if the hour is 0, set the meridiem to am, and set the hour to 12
5114
+ else if (hour === 0) {
5115
+ newMeridiem = "am";
5116
+ newHour = 12;
5117
+ }
5118
+ else {
5119
+ newMeridiem = meridiem ?? "am";
5120
+ newHour = hour;
5121
+ }
5122
+ if (minute > 59) {
5123
+ newMinute = 0;
5124
+ }
5125
+ else {
5126
+ newMinute = minute;
5127
+ }
5128
+ onChange({
5129
+ hour: newHour,
5130
+ minute: newMinute,
5131
+ meridiem: newMeridiem,
5132
+ });
5133
+ setShowInput(false);
5134
+ };
5135
+ const handleKeyDown = (e) => {
5136
+ if (e.key === "Enter") {
5137
+ handleBlur(e.currentTarget.value);
5138
+ }
5139
+ };
5140
+ const inputRef = useRef(null);
5141
+ return (jsxs(Grid, { justifyContent: "center", alignItems: "center", templateColumns: "200px auto", gap: "2", width: "auto", minWidth: "250px", children: [jsx(Input, { onKeyDown: handleKeyDown, onChange: (e) => {
5142
+ setInputValue(e.currentTarget.value);
5143
+ }, onBlur: (e) => {
5144
+ handleBlur(e.currentTarget.value);
5145
+ }, onFocus: (e) => {
5146
+ e.currentTarget.select();
5147
+ }, value: inputValue, display: showInput ? undefined : "none", ref: inputRef }), jsxs(Button$1, { onClick: () => {
5148
+ setShowInput(true);
5149
+ setInputValue(dayjs(`1970-01-01T${getTimeString(hour, minute, meridiem)}`, "hh:mmZ").format("HH:mm"));
5150
+ inputRef.current?.focus();
5151
+ }, display: showInput ? "none" : "flex", alignItems: "center", justifyContent: "start", variant: "outline", gap: 2, children: [jsx(Icon, { size: "sm", children: jsx(BsClock, {}) }), jsx(Text, { fontSize: "sm", children: stringTime
5152
+ ? dayjs(`1970-01-01T${stringTime}`, "hh:mmZ").format("hh:mm a")
5153
+ : "" })] }), jsx(Button$1, { onClick: handleClear, size: "sm", variant: "ghost", children: jsx(MdCancel, {}) })] }));
5154
+ }
5155
+
5156
+ dayjs.extend(timezone);
5157
+ const TimePicker = ({ column, schema, prefix }) => {
5158
+ const { watch, formState: { errors }, setValue, } = useFormContext();
5159
+ const { translate, timezone } = useSchemaContext();
5160
+ const { required, gridColumn = "span 4", gridRow = "span 1", timeFormat = "HH:mm:ssZ", displayTimeFormat = "hh:mm A", } = schema;
5161
+ const isRequired = required?.some((columnId) => columnId === column);
5162
+ const colLabel = `${prefix}${column}`;
5163
+ const [open, setOpen] = useState(false);
5164
+ const value = watch(colLabel);
5165
+ const displayedTime = dayjs(`1970-01-01T${value}`).tz(timezone).isValid()
5166
+ ? dayjs(`1970-01-01T${value}`).tz(timezone).format(displayTimeFormat)
5167
+ : "";
5168
+ // Parse the initial time parts from the time string (HH:mm:ssZ)
5169
+ const parseTime = (time) => {
5170
+ if (!time)
5171
+ return { hour: 12, minute: 0, meridiem: "am" };
5172
+ const parsed = dayjs(`1970-01-01T${time}`).tz(timezone);
5173
+ if (!parsed.isValid()) {
5174
+ return { hour: 12, minute: 0, meridiem: "am" };
5175
+ }
5176
+ let hour = parsed.hour();
5177
+ const minute = parsed.minute();
5178
+ const meridiem = hour >= 12 ? "pm" : "am";
5179
+ if (hour === 0)
5180
+ hour = 12;
5181
+ else if (hour > 12)
5182
+ hour -= 12;
5183
+ return { hour, minute, meridiem };
5184
+ };
5185
+ const initialTime = parseTime(value);
5186
+ const [hour, setHour] = useState(initialTime.hour);
5187
+ const [minute, setMinute] = useState(initialTime.minute);
5188
+ const [meridiem, setMeridiem] = useState(initialTime.meridiem);
5189
+ useEffect(() => {
5190
+ const { hour, minute, meridiem } = parseTime(value);
5191
+ setHour(hour);
5192
+ setMinute(minute);
5193
+ setMeridiem(meridiem);
5194
+ }, [value]);
5195
+ const getTimeString = (hour, minute, meridiem) => {
5196
+ if (hour === null || minute === null || meridiem === null)
5197
+ return null;
5198
+ let newHour = hour;
5199
+ if (meridiem === "pm" && hour !== 12) {
5200
+ newHour = hour + 12;
5201
+ }
5202
+ return dayjs().tz(timezone).hour(newHour).minute(minute).second(0).format(timeFormat);
5203
+ };
5204
+ // Handle changes to time parts
5205
+ const handleTimeChange = ({ hour: newHour, minute: newMinute, meridiem: newMeridiem, }) => {
5206
+ setHour(newHour);
5207
+ setMinute(newMinute);
5208
+ setMeridiem(newMeridiem);
5209
+ const timeString = getTimeString(newHour, newMinute, newMeridiem);
5210
+ setValue(colLabel, timeString, { shouldValidate: true, shouldDirty: true });
5211
+ };
5212
+ return (jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
5213
+ gridRow, children: [jsxs(Popover.Root, { open: open, onOpenChange: (e) => setOpen(e.open), closeOnInteractOutside: true, children: [jsx(Popover.Trigger, { asChild: true, children: jsxs(Button, { size: "sm", variant: "outline", onClick: () => {
5214
+ setOpen(true);
5215
+ }, justifyContent: "start", children: [jsx(IoMdClock, {}), !!value ? `${displayedTime}` : ""] }) }), jsx(Popover.Positioner, { children: jsx(Popover.Content, { children: jsx(Popover.Body, { children: jsx(TimePicker$1, { hour: hour, setHour: setHour, minute: minute, setMinute: setMinute, meridiem: meridiem, setMeridiem: setMeridiem, onChange: handleTimeChange, meridiemLabel: {
5216
+ am: translate.t(`common.am`, { defaultValue: "AM" }),
5217
+ pm: translate.t(`common.pm`, { defaultValue: "PM" }),
5218
+ } }) }) }) })] }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
5219
+ };
5220
+
5221
+ function IsoTimePicker({ hour, setHour, minute, setMinute, second, setSecond, onChange = (_newValue) => { }, }) {
5222
+ // Refs for focus management
5223
+ const hourInputRef = useRef(null);
5224
+ const minuteInputRef = useRef(null);
5225
+ const secondInputRef = useRef(null);
5226
+ // Centralized handler for key events, value changes, and focus management
5227
+ const handleKeyDown = (e, field) => {
5228
+ const input = e.target;
5229
+ const value = input.value;
5230
+ // Handle navigation between fields
5231
+ if (e.key === "Tab") {
5232
+ return;
5233
+ }
5234
+ if (e.key === ":" && field === "hour") {
5235
+ e.preventDefault();
5236
+ minuteInputRef.current?.focus();
5237
+ return;
5238
+ }
5239
+ if (e.key === ":" && field === "minute") {
5240
+ e.preventDefault();
5241
+ secondInputRef.current?.focus();
5242
+ return;
5243
+ }
5244
+ if (e.key === "Backspace" && value === "") {
5245
+ e.preventDefault();
5246
+ if (field === "minute") {
5247
+ hourInputRef.current?.focus();
5248
+ }
5249
+ else if (field === "second") {
5250
+ minuteInputRef.current?.focus();
5251
+ }
5252
+ return;
5253
+ }
5254
+ // Handle number inputs
5255
+ if (field === "hour") {
5256
+ if (e.key.match(/^[0-9]$/)) {
5257
+ const newValue = value + e.key;
5258
+ const numValue = parseInt(newValue, 10);
5259
+ if (numValue > 23) {
5260
+ const digitValue = parseInt(e.key, 10);
5261
+ setHour(digitValue);
5262
+ onChange({ hour: digitValue, minute, second });
5263
+ return;
5264
+ }
5265
+ if (numValue >= 0 && numValue <= 23) {
5266
+ setHour(numValue);
5267
+ onChange({ hour: numValue, minute, second });
5268
+ e.preventDefault();
5269
+ minuteInputRef.current?.focus();
5270
+ }
5271
+ }
5272
+ }
5273
+ else if (field === "minute") {
5274
+ if (e.key.match(/^[0-9]$/)) {
5275
+ const newValue = value + e.key;
5276
+ const numValue = parseInt(newValue, 10);
5277
+ if (numValue > 59) {
5278
+ const digitValue = parseInt(e.key, 10);
5279
+ setMinute(digitValue);
5280
+ onChange({ hour, minute: digitValue, second });
5281
+ return;
5282
+ }
5283
+ if (numValue >= 0 && numValue <= 59) {
5284
+ setMinute(numValue);
5285
+ onChange({ hour, minute: numValue, second });
5286
+ e.preventDefault();
5287
+ secondInputRef.current?.focus();
5288
+ }
5289
+ }
5290
+ }
5291
+ else if (field === "second") {
5292
+ if (e.key.match(/^[0-9]$/)) {
5293
+ const newValue = value + e.key;
5294
+ const numValue = parseInt(newValue, 10);
5295
+ if (numValue > 59) {
5296
+ const digitValue = parseInt(e.key, 10);
5297
+ setSecond(digitValue);
5298
+ onChange({ hour, minute, second: digitValue });
5299
+ return;
5300
+ }
5301
+ if (numValue >= 0 && numValue <= 59) {
5302
+ setSecond(numValue);
5303
+ onChange({ hour, minute, second: numValue });
5304
+ }
5305
+ }
5306
+ }
5307
+ };
5308
+ const handleClear = () => {
5309
+ setHour(null);
5310
+ setMinute(null);
5311
+ setSecond(null);
5312
+ onChange({ hour: null, minute: null, second: null });
5313
+ hourInputRef.current?.focus();
5314
+ };
5315
+ return (jsx(Flex, { direction: "column", gap: 3, children: jsxs(Grid, { justifyContent: "center", alignItems: "center", templateColumns: "60px 10px 60px 10px 60px auto", gap: "2", width: "auto", minWidth: "300px", children: [jsx(Input, { ref: hourInputRef, type: "text", value: hour === null ? "" : hour.toString().padStart(2, "0"), onKeyDown: (e) => handleKeyDown(e, "hour"), placeholder: "HH", maxLength: 2, textAlign: "center" }), jsx(Text, { children: ":" }), jsx(Input, { ref: minuteInputRef, type: "text", value: minute === null ? "" : minute.toString().padStart(2, "0"), onKeyDown: (e) => handleKeyDown(e, "minute"), placeholder: "MM", maxLength: 2, textAlign: "center" }), jsx(Text, { children: ":" }), jsx(Input, { ref: secondInputRef, type: "text", value: second === null ? "" : second.toString().padStart(2, "0"), onKeyDown: (e) => handleKeyDown(e, "second"), placeholder: "SS", maxLength: 2, textAlign: "center" }), jsx(Button$1, { onClick: handleClear, size: "sm", variant: "ghost", children: jsx(MdCancel, {}) })] }) }));
5316
+ }
5317
+
5318
+ function DateTimePicker$1({ value, onChange, format = "date-time", showSeconds = false, labels = {
5319
+ monthNamesShort: [
5320
+ "Jan",
5321
+ "Feb",
5322
+ "Mar",
5323
+ "Apr",
5324
+ "May",
5325
+ "Jun",
5326
+ "Jul",
5327
+ "Aug",
5328
+ "Sep",
5329
+ "Oct",
5330
+ "Nov",
5331
+ "Dec",
5332
+ ],
5333
+ weekdayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
5334
+ backButtonLabel: "Back",
5335
+ forwardButtonLabel: "Next",
5336
+ }, timezone = "Asia/Hong_Kong", }) {
5337
+ const [selectedDate, setSelectedDate] = useState(value || "");
5338
+ // Time state for 12-hour format
5339
+ const [hour12, setHour12] = useState(value ? dayjs(value).hour() % 12 || 12 : null);
5340
+ const [minute, setMinute] = useState(value ? dayjs(value).minute() : null);
5341
+ const [meridiem, setMeridiem] = useState(value ? (dayjs(value).hour() >= 12 ? "pm" : "am") : null);
5342
+ // Time state for 24-hour format
5343
+ const [hour24, setHour24] = useState(value ? dayjs(value).hour() : null);
5344
+ const [second, setSecond] = useState(value ? dayjs(value).second() : null);
5345
+ const handleDateChange = (date) => {
5346
+ setSelectedDate(date);
5347
+ updateDateTime(dayjs(date).tz(timezone).toISOString());
5348
+ };
5349
+ const handleTimeChange = (timeData) => {
5350
+ if (format === "iso-date-time") {
5351
+ setHour24(timeData.hour);
5352
+ setMinute(timeData.minute);
5353
+ if (showSeconds)
5354
+ setSecond(timeData.second);
5355
+ }
5356
+ else {
5357
+ setHour12(timeData.hour);
5358
+ setMinute(timeData.minute);
5359
+ setMeridiem(timeData.meridiem);
5360
+ }
5361
+ updateDateTime(dayjs(selectedDate).tz(timezone).toISOString(), timeData);
5362
+ };
5363
+ const updateDateTime = (date, timeData) => {
5364
+ if (!date) {
5365
+ onChange?.(undefined);
5366
+ return;
5367
+ }
5368
+ // use dayjs to convert the date to the timezone
5369
+ const newDate = dayjs(date).tz(timezone).toDate();
5370
+ if (format === "iso-date-time") {
5371
+ const h = timeData?.hour ?? hour24;
5372
+ const m = timeData?.minute ?? minute;
5373
+ const s = showSeconds ? timeData?.second ?? second : 0;
5374
+ if (h !== null)
5375
+ newDate.setHours(h);
5376
+ if (m !== null)
5377
+ newDate.setMinutes(m);
5378
+ if (s !== null)
5379
+ newDate.setSeconds(s);
5380
+ }
5381
+ else {
5382
+ const h = timeData?.hour ?? hour12;
5383
+ const m = timeData?.minute ?? minute;
5384
+ const mer = timeData?.meridiem ?? meridiem;
5385
+ if (h !== null && mer !== null) {
5386
+ let hour24 = h;
5387
+ if (mer === "am" && h === 12)
5388
+ hour24 = 0;
5389
+ else if (mer === "pm" && h < 12)
5390
+ hour24 = h + 12;
5391
+ newDate.setHours(hour24);
5392
+ }
5393
+ if (m !== null)
5394
+ newDate.setMinutes(m);
5395
+ newDate.setSeconds(0);
5396
+ }
5397
+ onChange?.(dayjs(newDate).tz(timezone).toISOString());
5398
+ };
5399
+ const handleClear = () => {
5400
+ setSelectedDate("");
5401
+ setHour12(null);
5402
+ setHour24(null);
5403
+ setMinute(null);
5404
+ setSecond(null);
5405
+ setMeridiem(null);
5406
+ onChange?.(undefined);
5407
+ };
5408
+ const isISO = format === "iso-date-time";
5409
+ return (jsxs(Flex, { direction: "column", gap: 4, p: 4, border: "1px solid", borderColor: "gray.200", borderRadius: "md", children: [jsx(DatePicker$1, { selected: selectedDate
5410
+ ? dayjs(selectedDate).tz(timezone).toDate()
5411
+ : new Date(), onDateSelected: ({ date }) => handleDateChange(dayjs(date).tz(timezone).toISOString()), monthsToDisplay: 1, labels: labels }), jsxs(Grid, { templateColumns: "1fr auto", alignItems: "center", gap: 4, children: [isISO ? (jsx(IsoTimePicker, { hour: hour24, setHour: setHour24, minute: minute, setMinute: setMinute, second: second, setSecond: setSecond, onChange: handleTimeChange })) : (jsx(TimePicker$1, { hour: hour12, setHour: setHour12, minute: minute, setMinute: setMinute, meridiem: meridiem, setMeridiem: setMeridiem, onChange: handleTimeChange })), jsx(Button$1, { onClick: handleClear, size: "sm", variant: "outline", colorScheme: "red", children: jsx(Icon, { as: FaTrash }) })] }), selectedDate && (jsxs(Flex, { gap: 2, children: [jsx(Text, { fontSize: "sm", color: { base: "gray.600", _dark: "gray.600" }, children: dayjs(value).format(isISO
5412
+ ? showSeconds
5413
+ ? "YYYY-MM-DD HH:mm:ss"
5414
+ : "YYYY-MM-DD HH:mm"
5415
+ : "YYYY-MM-DD hh:mm A ") }), jsx(Text, { fontSize: "sm", color: { base: "gray.600", _dark: "gray.600" }, children: dayjs(value).tz(timezone).format("Z") }), jsx(Text, { fontSize: "sm", color: { base: "gray.600", _dark: "gray.600" }, children: timezone })] }))] }));
5416
+ }
5417
+
5418
+ dayjs.extend(utc);
5419
+ dayjs.extend(timezone);
5420
+ const DateTimePicker = ({ column, schema, prefix, }) => {
5421
+ const { watch, formState: { errors }, setValue, } = useFormContext();
5422
+ const { translate, timezone } = useSchemaContext();
5423
+ const { required, gridColumn = "span 4", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD HH:mm:ss",
5424
+ // with timezone
5425
+ dateFormat = "YYYY-MM-DD[T]HH:mm:ssZ", } = schema;
5426
+ const isRequired = required?.some((columnId) => columnId === column);
5427
+ const colLabel = `${prefix}${column}`;
5428
+ const [open, setOpen] = useState(false);
5429
+ const selectedDate = watch(colLabel);
5430
+ const displayDate = dayjs(selectedDate)
5431
+ .tz(timezone)
5432
+ .format(displayDateFormat);
5433
+ useEffect(() => {
5434
+ try {
5435
+ if (selectedDate) {
5436
+ // Parse the selectedDate as UTC or in a specific timezone to avoid +8 hour shift
5437
+ // For example, parse as UTC:
5438
+ const parsedDate = dayjs(selectedDate).tz(timezone);
5439
+ if (!parsedDate.isValid())
5440
+ return;
5441
+ // Format according to dateFormat from schema
5442
+ const formatted = parsedDate.format(dateFormat);
5443
+ // Update the form value only if different to avoid loops
5444
+ if (formatted !== selectedDate) {
5445
+ setValue(colLabel, formatted, {
5446
+ shouldValidate: true,
5447
+ shouldDirty: true,
5448
+ });
5449
+ }
5450
+ }
5451
+ }
5452
+ catch (e) {
5453
+ console.error(e);
5454
+ }
5455
+ }, [selectedDate, dateFormat, colLabel, setValue]);
5456
+ const customTranslate = (label) => {
5457
+ return translateWrapper({ prefix, column, label, translate });
5458
+ };
5459
+ return (jsxs(Field, { label: `${customTranslate(`field_label`)}`, required: isRequired, alignItems: "stretch", gridColumn,
5460
+ gridRow, children: [jsxs(PopoverRoot, { open: open, onOpenChange: (e) => setOpen(e.open), closeOnInteractOutside: true, children: [jsx(PopoverTrigger, { asChild: true, children: jsxs(Button, { size: "sm", variant: "outline", onClick: () => {
5461
+ setOpen(true);
5462
+ }, justifyContent: "start", children: [jsx(MdDateRange, {}), selectedDate !== undefined ? `${displayDate}` : ""] }) }), jsx(PopoverContent, { minW: "450px", children: jsxs(PopoverBody, { children: [jsx(PopoverTitle, {}), jsx(DateTimePicker$1, { value: selectedDate, onChange: (date) => {
5463
+ setValue(colLabel, dayjs(date).tz(timezone).format(dateFormat));
5464
+ }, timezone: timezone, labels: {
5465
+ monthNamesShort: [
5466
+ translate.t(`common.month_1`, { defaultValue: "January" }),
5467
+ translate.t(`common.month_2`, { defaultValue: "February" }),
5468
+ translate.t(`common.month_3`, { defaultValue: "March" }),
5469
+ translate.t(`common.month_4`, { defaultValue: "April" }),
5470
+ translate.t(`common.month_5`, { defaultValue: "May" }),
5471
+ translate.t(`common.month_6`, { defaultValue: "June" }),
5472
+ translate.t(`common.month_7`, { defaultValue: "July" }),
5473
+ translate.t(`common.month_8`, { defaultValue: "August" }),
5474
+ translate.t(`common.month_9`, { defaultValue: "September" }),
5475
+ translate.t(`common.month_10`, { defaultValue: "October" }),
5476
+ translate.t(`common.month_11`, { defaultValue: "November" }),
5477
+ translate.t(`common.month_12`, { defaultValue: "December" }),
5478
+ ],
5479
+ weekdayNamesShort: [
5480
+ translate.t(`common.weekday_1`, { defaultValue: "Sun" }),
5481
+ translate.t(`common.weekday_2`, { defaultValue: "Mon" }),
5482
+ translate.t(`common.weekday_3`, { defaultValue: "Tue" }),
5483
+ translate.t(`common.weekday_4`, {
5484
+ defaultValue: "Wed",
5485
+ }),
5486
+ translate.t(`common.weekday_5`, { defaultValue: "Thu" }),
5487
+ translate.t(`common.weekday_6`, { defaultValue: "Fri" }),
5488
+ translate.t(`common.weekday_7`, { defaultValue: "Sat" }),
5489
+ ],
5490
+ backButtonLabel: translate.t(`common.back_button`, {
5491
+ defaultValue: "Back",
5492
+ }),
5493
+ forwardButtonLabel: translate.t(`common.forward_button`, {
5494
+ defaultValue: "Forward",
5495
+ }),
5496
+ } })] }) })] }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: customTranslate(`field_required`) }))] }));
5497
+ };
5498
+
4537
5499
  const SchemaRenderer = ({ schema, prefix, column, }) => {
4538
5500
  const colSchema = schema;
4539
- const { type, variant, properties: innerProperties, foreign_key, items, } = schema;
5501
+ const { type, variant, properties: innerProperties, foreign_key, format, items, } = schema;
5502
+ if (variant === "custom-input") {
5503
+ return jsx(CustomInput, { schema: colSchema, prefix, column });
5504
+ }
4540
5505
  if (type === "string") {
4541
5506
  if ((schema.enum ?? []).length > 0) {
4542
5507
  return jsx(EnumPicker, { schema: colSchema, prefix, column });
@@ -4545,9 +5510,18 @@ const SchemaRenderer = ({ schema, prefix, column, }) => {
4545
5510
  idPickerSanityCheck(column, foreign_key);
4546
5511
  return jsx(IdPicker, { schema: colSchema, prefix, column });
4547
5512
  }
4548
- if (variant === "date-picker") {
5513
+ if (format === "date") {
4549
5514
  return jsx(DatePicker, { schema: colSchema, prefix, column });
4550
5515
  }
5516
+ if (format === "time") {
5517
+ return jsx(TimePicker, { schema: colSchema, prefix, column });
5518
+ }
5519
+ if (format === "date-time") {
5520
+ return jsx(DateTimePicker, { schema: colSchema, prefix, column });
5521
+ }
5522
+ if (variant === "text-area") {
5523
+ return jsx(TextAreaInput, { schema: colSchema, prefix, column });
5524
+ }
4551
5525
  return jsx(StringInputField, { schema: colSchema, prefix, column });
4552
5526
  }
4553
5527
  if (type === "number" || type === "integer") {
@@ -4573,6 +5547,15 @@ const SchemaRenderer = ({ schema, prefix, column, }) => {
4573
5547
  if (variant === "file-picker") {
4574
5548
  return jsx(FilePicker, { schema: colSchema, prefix, column });
4575
5549
  }
5550
+ if (variant === "enum-picker") {
5551
+ const { items } = colSchema;
5552
+ const { enum: enumItems } = items;
5553
+ const enumSchema = {
5554
+ type: "string",
5555
+ enum: enumItems,
5556
+ };
5557
+ return (jsx(EnumPicker, { isMultiple: true, schema: enumSchema, prefix, column }));
5558
+ }
4576
5559
  if (items) {
4577
5560
  return jsx(ArrayRenderer, { schema: colSchema, prefix, column });
4578
5561
  }
@@ -4594,39 +5577,56 @@ const ColumnRenderer = ({ column, properties, prefix, }) => {
4594
5577
  };
4595
5578
 
4596
5579
  const ArrayViewer = ({ schema, column, prefix }) => {
4597
- const { gridRow, gridColumn = "1/span 12", required, items } = schema;
5580
+ const { gridColumn = "span 12", gridRow = "span 1", required, items, } = schema;
4598
5581
  const { translate } = useSchemaContext();
4599
5582
  const colLabel = `${prefix}${column}`;
4600
5583
  const isRequired = required?.some((columnId) => columnId === column);
4601
5584
  const { watch, formState: { errors }, } = useFormContext();
4602
5585
  const values = watch(colLabel) ?? [];
4603
- return (jsxs(Box, { gridRow, gridColumn, children: [jsxs(Box, { as: "label", gridColumn: "1/span12", children: [`${translate.t(removeIndex(`${colLabel}.fieldLabel`))}`, isRequired && jsx("span", { children: "*" })] }), values.map((field, index) => (jsx(Flex, { flexFlow: "column", children: jsx(Grid, { gap: "4", padding: "4", gridTemplateColumns: "repeat(12, 1fr)", gridTemplateRows: `repeat("auto-fit", auto)`, children: jsx(SchemaViewer, { column: `${index}`,
4604
- prefix: `${colLabel}.`,
4605
- schema: items }) }) }, `form-${prefix}${column}.${index}`))), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.fieldRequired`)) }))] }));
5586
+ return (jsxs(Box, { gridRow, gridColumn, children: [jsxs(Box, { as: "label", gridColumn: "1/span12", children: [`${translate.t(removeIndex(`${colLabel}.field_label`))}`, isRequired && jsx("span", { children: "*" })] }), jsx(Flex, { flexFlow: "column", gap: 1, children: values.map((field, index) => (jsx(Flex, { flexFlow: "column", bgColor: { base: "colorPalette.100", _dark: "colorPalette.900" }, p: "2", borderRadius: "md", borderWidth: "thin", borderColor: {
5587
+ base: "colorPalette.200",
5588
+ _dark: "colorPalette.800",
5589
+ }, children: jsx(Grid, { gap: "4", gridTemplateColumns: "repeat(12, 1fr)", autoFlow: "row", children: jsx(SchemaViewer, { column: `${index}`,
5590
+ prefix: `${colLabel}.`,
5591
+ // @ts-expect-error find suitable types
5592
+ schema: { showLabel: false, ...(items ?? {}) } }) }) }, `form-${prefix}${column}.${index}`))) }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
4606
5593
  };
4607
5594
 
4608
5595
  const BooleanViewer = ({ schema, column, prefix, }) => {
4609
5596
  const { watch, formState: { errors }, } = useFormContext();
4610
5597
  const { translate } = useSchemaContext();
4611
- const { required, gridColumn, gridRow } = schema;
5598
+ const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
4612
5599
  const isRequired = required?.some((columnId) => columnId === column);
4613
5600
  const colLabel = `${prefix}${column}`;
4614
5601
  const value = watch(colLabel);
4615
- return (jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.fieldLabel`))}`, required: isRequired, alignItems: "stretch", gridColumn,
5602
+ return (jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
4616
5603
  gridRow, children: [jsx(Text, { children: value
4617
5604
  ? translate.t(removeIndex(`${colLabel}.true`))
4618
- : translate.t(removeIndex(`${colLabel}.false`)) }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.fieldRequired`)) }))] }));
5605
+ : translate.t(removeIndex(`${colLabel}.false`)) }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
5606
+ };
5607
+
5608
+ const CustomViewer = ({ column, schema, prefix }) => {
5609
+ const formContext = useFormContext();
5610
+ const { inputViewerRender } = schema;
5611
+ return (inputViewerRender &&
5612
+ inputViewerRender({
5613
+ column,
5614
+ schema,
5615
+ prefix,
5616
+ formContext,
5617
+ }));
4619
5618
  };
4620
5619
 
4621
5620
  const DateViewer = ({ column, schema, prefix }) => {
4622
5621
  const { watch, formState: { errors }, } = useFormContext();
4623
- const { translate } = useSchemaContext();
4624
- const { required, gridColumn, gridRow } = schema;
5622
+ const { translate, timezone } = useSchemaContext();
5623
+ const { required, gridColumn = "span 4", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD", } = schema;
4625
5624
  const isRequired = required?.some((columnId) => columnId === column);
4626
5625
  const colLabel = `${prefix}${column}`;
4627
5626
  const selectedDate = watch(colLabel);
4628
- return (jsxs(Field, { label: `${translate.t(removeIndex(`${column}.fieldLabel`))}`, required: isRequired, alignItems: "stretch", gridColumn,
4629
- gridRow, children: [jsxs(Text, { children: [" ", selectedDate !== undefined ? selectedDate : ""] }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(`${column}.fieldRequired`) }))] }));
5627
+ const displayDate = dayjs(selectedDate).tz(timezone).format(displayDateFormat);
5628
+ return (jsxs(Field, { label: `${translate.t(removeIndex(`${column}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
5629
+ gridRow, children: [jsxs(Text, { children: [" ", selectedDate !== undefined ? displayDate : ""] }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(`${column}.field_required`) }))] }));
4630
5630
  };
4631
5631
 
4632
5632
  const EnumViewer = ({ column, isMultiple = false, schema, prefix, }) => {
@@ -4634,45 +5634,41 @@ const EnumViewer = ({ column, isMultiple = false, schema, prefix, }) => {
4634
5634
  const { translate } = useSchemaContext();
4635
5635
  const { required } = schema;
4636
5636
  const isRequired = required?.some((columnId) => columnId === column);
4637
- const { gridColumn, gridRow, renderDisplay } = schema;
5637
+ const { gridColumn = "span 4", gridRow = "span 1", renderDisplay } = schema;
4638
5638
  const colLabel = `${prefix}${column}`;
4639
5639
  const watchEnum = watch(colLabel);
4640
5640
  const watchEnums = (watch(colLabel) ?? []);
4641
- return (jsxs(Field, { label: `${translate.t(removeIndex(`${column}.fieldLabel`))}`, required: isRequired, alignItems: "stretch", gridColumn,
5641
+ const customTranslate = (label) => {
5642
+ return translateWrapper({ prefix, column, label, translate });
5643
+ };
5644
+ return (jsxs(Field, { label: `${customTranslate(`field_label`)}`, required: isRequired, alignItems: "stretch", gridColumn,
4642
5645
  gridRow, children: [isMultiple && (jsx(Flex, { flexFlow: "wrap", gap: 1, children: watchEnums.map((enumValue) => {
4643
5646
  const item = enumValue;
4644
5647
  if (item === undefined) {
4645
5648
  return jsx(Fragment, { children: "undefined" });
4646
5649
  }
4647
- return (jsx(Tag, { closable: true, children: !!renderDisplay === true
5650
+ return (jsx(Tag, { size: "lg", children: !!renderDisplay === true
4648
5651
  ? renderDisplay(item)
4649
- : translate.t(removeIndex(`${colLabel}.${item}`)) }));
4650
- }) })), !isMultiple && (jsx(Text, { children: translate.t(removeIndex(`${colLabel}.${watchEnum}`)) })), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.fieldRequired`)) }))] }));
5652
+ : customTranslate(item) }, item));
5653
+ }) })), !isMultiple && jsx(Text, { children: customTranslate(watchEnum) }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: customTranslate(`field_required`) }))] }));
4651
5654
  };
4652
5655
 
4653
5656
  const FileViewer = ({ column, schema, prefix }) => {
4654
- const { setValue, formState: { errors }, watch, } = useFormContext();
5657
+ const { watch } = useFormContext();
4655
5658
  const { translate } = useSchemaContext();
4656
- const { required, gridColumn, gridRow } = schema;
5659
+ const { required, gridColumn = "span 4", gridRow = "span 1", } = schema;
4657
5660
  const isRequired = required?.some((columnId) => columnId === column);
4658
5661
  const currentFiles = (watch(column) ?? []);
4659
5662
  const colLabel = `${prefix}${column}`;
4660
- return (jsxs(Field, { label: `${translate.t(`${colLabel}.fieldLabel`)}`, required: isRequired, gridColumn: gridColumn ?? "span 4", gridRow: gridRow ?? "span 1", display: "grid", gridTemplateRows: "auto 1fr auto", alignItems: "stretch", children: [jsx(FileDropzone, { onDrop: ({ files }) => {
4661
- const newFiles = files.filter(({ name }) => !currentFiles.some((cur) => cur.name === name));
4662
- setValue(colLabel, [...currentFiles, ...newFiles]);
4663
- }, placeholder: translate.t(`${colLabel}.fileDropzone`) }), jsx(Flex, { flexFlow: "column", gap: 1, children: currentFiles.map((file) => {
4664
- return (jsx(Card.Root, { variant: "subtle", children: jsxs(Card.Body, { gap: "2", cursor: "pointer", onClick: () => {
4665
- setValue(column, currentFiles.filter(({ name }) => {
4666
- return name !== file.name;
4667
- }));
4668
- }, display: "flex", flexFlow: "row", alignItems: "center", padding: "2", children: [jsx(Box, { children: file.name }), jsx(TiDeleteOutline, {})] }) }, file.name));
4669
- }) }), errors[`${colLabel}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.fieldRequired`)) }))] }));
5663
+ return (jsx(Field, { label: `${translate.t(`${colLabel}.field_label`)}`, required: isRequired, gridColumn: gridColumn, gridRow: gridRow, display: "grid", gridTemplateRows: "auto 1fr auto", alignItems: "stretch", children: jsx(Flex, { flexFlow: "column", gap: 1, children: currentFiles.map((file) => {
5664
+ return (jsx(Card.Root, { variant: "subtle", children: jsxs(Card.Body, { gap: "2", display: "flex", flexFlow: "row", alignItems: "center", padding: "2", children: [file.type.startsWith("image/") && (jsx(Image, { src: URL.createObjectURL(file), alt: file.name, boxSize: "50px", objectFit: "cover", borderRadius: "md", marginRight: "2" })), jsx(Box, { children: file.name })] }) }, file.name));
5665
+ }) }) }));
4670
5666
  };
4671
5667
 
4672
5668
  const IdViewer = ({ column, schema, prefix, isMultiple = false, }) => {
4673
5669
  const { watch, formState: { errors }, } = useFormContext();
4674
5670
  const { idMap, translate } = useSchemaContext();
4675
- const { required, gridColumn, gridRow, renderDisplay, foreign_key } = schema;
5671
+ const { required, gridColumn = "span 4", gridRow = "span 1", renderDisplay, foreign_key, } = schema;
4676
5672
  const isRequired = required?.some((columnId) => columnId === column);
4677
5673
  const { display_column } = foreign_key;
4678
5674
  const colLabel = `${prefix}${column}`;
@@ -4688,7 +5684,7 @@ const IdViewer = ({ column, schema, prefix, isMultiple = false, }) => {
4688
5684
  }
4689
5685
  return record[display_column];
4690
5686
  };
4691
- return (jsxs(Field, { label: `${translate.t(removeIndex(`${column}.fieldLabel`))}`, required: isRequired, alignItems: "stretch", gridColumn,
5687
+ return (jsxs(Field, { label: `${translate.t(removeIndex(`${column}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
4692
5688
  gridRow, children: [isMultiple && (jsx(Flex, { flexFlow: "wrap", gap: 1, children: watchIds.map((id) => {
4693
5689
  const item = idMap[id];
4694
5690
  if (item === undefined) {
@@ -4697,21 +5693,21 @@ const IdViewer = ({ column, schema, prefix, isMultiple = false, }) => {
4697
5693
  return (jsx(Tag, { closable: true, children: !!renderDisplay === true
4698
5694
  ? renderDisplay(item)
4699
5695
  : item[display_column] }, id));
4700
- }) })), !isMultiple && jsx(Text, { children: getPickedValue() }), errors[`${colLabel}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.fieldRequired`)) }))] }));
5696
+ }) })), !isMultiple && jsx(Text, { children: getPickedValue() }), errors[`${colLabel}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
4701
5697
  };
4702
5698
 
4703
5699
  const NumberViewer = ({ schema, column, prefix, }) => {
4704
5700
  const { watch, formState: { errors }, } = useFormContext();
4705
5701
  const { translate } = useSchemaContext();
4706
- const { required, gridColumn, gridRow } = schema;
5702
+ const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
4707
5703
  const isRequired = required?.some((columnId) => columnId === column);
4708
5704
  const colLabel = `${prefix}${column}`;
4709
5705
  const value = watch(colLabel);
4710
- return (jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.fieldLabel`))}`, required: isRequired, gridColumn, gridRow, children: [jsx(Text, { children: value }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.fieldRequired`)) }))] }));
5706
+ return (jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn, gridRow, children: [jsx(Text, { children: value }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
4711
5707
  };
4712
5708
 
4713
5709
  const ObjectViewer = ({ schema, column, prefix }) => {
4714
- const { properties, gridRow, gridColumn = "1/span 12", required } = schema;
5710
+ const { properties, gridColumn = "span 12", gridRow = "span 1", required, showLabel = true, } = schema;
4715
5711
  const { translate } = useSchemaContext();
4716
5712
  const colLabel = `${prefix}${column}`;
4717
5713
  const isRequired = required?.some((columnId) => columnId === column);
@@ -4719,25 +5715,28 @@ const ObjectViewer = ({ schema, column, prefix }) => {
4719
5715
  if (properties === undefined) {
4720
5716
  throw new Error(`properties is undefined when using ObjectInput`);
4721
5717
  }
4722
- return (jsxs(Box, { gridRow, gridColumn, children: [jsxs(Box, { as: "label", gridColumn: "1/span12", children: [`${translate.t(removeIndex(`${colLabel}.fieldLabel`))}`, isRequired && jsx("span", { children: "*" })] }), jsx(Grid, { gap: "4", padding: "4", gridTemplateColumns: "repeat(12, 1fr)", gridTemplateRows: `repeat("auto-fit", auto)`, children: Object.keys(properties ?? {}).map((key) => {
5718
+ return (jsxs(Box, { gridRow, gridColumn, children: [showLabel && (jsxs(Box, { as: "label", children: [`${translate.t(removeIndex(`${colLabel}.field_label`))}`, isRequired && jsx("span", { children: "*" })] })), jsx(Grid, { gap: "4", padding: "4", gridTemplateColumns: "repeat(12, 1fr)", autoFlow: "row", bgColor: { base: "colorPalette.100", _dark: "colorPalette.900" }, p: "1", borderRadius: "md", borderWidth: "thin", borderColor: {
5719
+ base: "colorPalette.200",
5720
+ _dark: "colorPalette.800",
5721
+ }, children: Object.keys(properties ?? {}).map((key) => {
4723
5722
  return (
4724
5723
  // @ts-expect-error find suitable types
4725
5724
  jsx(ColumnViewer, { column: `${key}`,
4726
5725
  prefix: `${prefix}${column}.`,
4727
5726
  properties }, `form-objectviewer-${colLabel}-${key}`));
4728
- }) }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.fieldRequired`)) }))] }));
5727
+ }) }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
4729
5728
  };
4730
5729
 
4731
5730
  const RecordInput = ({ column, schema, prefix }) => {
4732
5731
  const { formState: { errors }, setValue, getValues, } = useFormContext();
4733
5732
  const { translate } = useSchemaContext();
4734
- const { required, gridColumn, gridRow } = schema;
5733
+ const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
4735
5734
  const isRequired = required?.some((columnId) => columnId === column);
4736
5735
  const entries = Object.entries(getValues(column) ?? {});
4737
5736
  const [showNewEntries, setShowNewEntries] = useState(false);
4738
5737
  const [newKey, setNewKey] = useState();
4739
5738
  const [newValue, setNewValue] = useState();
4740
- return (jsxs(Field, { label: `${translate.t(`${column}.fieldLabel`)}`, required: isRequired, alignItems: "stretch", gridColumn, gridRow, children: [entries.map(([key, value]) => {
5739
+ return (jsxs(Field, { label: `${translate.t(`${column}.field_label`)}`, required: isRequired, alignItems: "stretch", gridColumn, gridRow, children: [entries.map(([key, value]) => {
4741
5740
  return (jsxs(Grid, { templateColumns: "1fr 1fr auto", gap: 1, children: [jsx(Input, { value: key, onChange: (e) => {
4742
5741
  const filtered = entries.filter(([target]) => {
4743
5742
  return target !== key;
@@ -4777,7 +5776,17 @@ const RecordInput = ({ column, schema, prefix }) => {
4777
5776
  setShowNewEntries(true);
4778
5777
  setNewKey(undefined);
4779
5778
  setNewValue(undefined);
4780
- }, children: translate.t(`${column}.addNew`) }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(`${column}.fieldRequired`) }))] }));
5779
+ }, children: translate.t(`${column}.addNew`) }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(`${column}.field_required`) }))] }));
5780
+ };
5781
+
5782
+ const StringViewer = ({ column, schema, prefix, }) => {
5783
+ const { watch, formState: { errors }, } = useFormContext();
5784
+ const { translate } = useSchemaContext();
5785
+ const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
5786
+ const isRequired = required?.some((columnId) => columnId === column);
5787
+ const colLabel = `${prefix}${column}`;
5788
+ const value = watch(colLabel);
5789
+ return (jsx(Fragment, { children: jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn: gridColumn ?? "span 4", gridRow: gridRow ?? "span 1", children: [jsx(Text, { children: value }), errors[colLabel] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }) }));
4781
5790
  };
4782
5791
 
4783
5792
  const TagViewer = ({ column, schema, prefix }) => {
@@ -4865,19 +5874,50 @@ const TagViewer = ({ column, schema, prefix }) => {
4865
5874
  }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: (errors[`${column}`]?.message ?? "No error message") }))] }));
4866
5875
  };
4867
5876
 
4868
- const StringViewer = ({ column, schema, prefix, }) => {
5877
+ const TextAreaViewer = ({ column, schema, prefix, }) => {
4869
5878
  const { watch, formState: { errors }, } = useFormContext();
4870
5879
  const { translate } = useSchemaContext();
4871
- const { required, gridColumn, gridRow } = schema;
5880
+ const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
4872
5881
  const isRequired = required?.some((columnId) => columnId === column);
4873
5882
  const colLabel = `${prefix}${column}`;
4874
5883
  const value = watch(colLabel);
4875
- return (jsx(Fragment, { children: jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.fieldLabel`))}`, required: isRequired, gridColumn: gridColumn ?? "span 4", gridRow: gridRow ?? "span 1", children: [jsx(Text, { children: value }), errors[colLabel] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.fieldRequired`)) }))] }) }));
5884
+ return (jsx(Fragment, { children: jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn: gridColumn, gridRow: gridRow, children: [jsx(Text, { whiteSpace: "pre-wrap", children: value }), " ", errors[colLabel] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }) }));
5885
+ };
5886
+
5887
+ const TimeViewer = ({ column, schema, prefix }) => {
5888
+ const { watch, formState: { errors }, } = useFormContext();
5889
+ const { translate, timezone } = useSchemaContext();
5890
+ const { required, gridColumn = "span 4", gridRow = "span 1", displayTimeFormat = "hh:mm A", } = schema;
5891
+ const isRequired = required?.some((columnId) => columnId === column);
5892
+ const colLabel = `${prefix}${column}`;
5893
+ const selectedDate = watch(colLabel);
5894
+ const displayedTime = dayjs(`1970-01-01T${selectedDate}`)
5895
+ .tz(timezone)
5896
+ .isValid()
5897
+ ? dayjs(`1970-01-01T${selectedDate}`).tz(timezone).format(displayTimeFormat)
5898
+ : "";
5899
+ return (jsxs(Field, { label: `${translate.t(removeIndex(`${column}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
5900
+ gridRow, children: [jsx(Text, { children: displayedTime }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(`${column}.field_required`) }))] }));
5901
+ };
5902
+
5903
+ const DateTimeViewer = ({ column, schema, prefix }) => {
5904
+ const { watch, formState: { errors }, } = useFormContext();
5905
+ const { translate, timezone } = useSchemaContext();
5906
+ const { required, gridColumn = "span 4", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD HH:mm:ss", } = schema;
5907
+ const isRequired = required?.some((columnId) => columnId === column);
5908
+ const colLabel = `${prefix}${column}`;
5909
+ const selectedDate = watch(colLabel);
5910
+ const displayDate = dayjs(selectedDate).tz(timezone).format(displayDateFormat);
5911
+ return (jsxs(Field, { label: `${translate.t(removeIndex(`${column}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
5912
+ gridRow, children: [jsxs(Text, { children: [" ", selectedDate !== undefined ? displayDate : ""] }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(`${column}.field_required`) }))] }));
4876
5913
  };
4877
5914
 
4878
5915
  const SchemaViewer = ({ schema, prefix, column, }) => {
4879
5916
  const colSchema = schema;
4880
- const { type, variant, properties: innerProperties, foreign_key, items, } = schema;
5917
+ const { type, variant, properties: innerProperties, foreign_key, items, format, } = schema;
5918
+ if (variant === "custom-input") {
5919
+ return jsx(CustomViewer, { schema: colSchema, prefix, column });
5920
+ }
4881
5921
  if (type === "string") {
4882
5922
  if ((schema.enum ?? []).length > 0) {
4883
5923
  return jsx(EnumViewer, { schema: colSchema, prefix, column });
@@ -4886,9 +5926,18 @@ const SchemaViewer = ({ schema, prefix, column, }) => {
4886
5926
  idPickerSanityCheck(column, foreign_key);
4887
5927
  return jsx(IdViewer, { schema: colSchema, prefix, column });
4888
5928
  }
4889
- if (variant === "date-picker") {
5929
+ if (format === "time") {
5930
+ return jsx(TimeViewer, { schema: colSchema, prefix, column });
5931
+ }
5932
+ if (format === "date") {
4890
5933
  return jsx(DateViewer, { schema: colSchema, prefix, column });
4891
5934
  }
5935
+ if (format === "date-time") {
5936
+ return jsx(DateTimeViewer, { schema: colSchema, prefix, column });
5937
+ }
5938
+ if (variant === "text-area") {
5939
+ return jsx(TextAreaViewer, { schema: colSchema, prefix, column });
5940
+ }
4892
5941
  return jsx(StringViewer, { schema: colSchema, prefix, column });
4893
5942
  }
4894
5943
  if (type === "number" || type === "integer") {
@@ -4914,6 +5963,15 @@ const SchemaViewer = ({ schema, prefix, column, }) => {
4914
5963
  if (variant === "file-picker") {
4915
5964
  return jsx(FileViewer, { schema: colSchema, prefix, column });
4916
5965
  }
5966
+ if (variant === "enum-picker") {
5967
+ const { items } = schema;
5968
+ const { enum: enumItems } = items;
5969
+ const enumSchema = {
5970
+ type: "string",
5971
+ enum: enumItems,
5972
+ };
5973
+ return (jsx(EnumViewer, { isMultiple: true, schema: enumSchema, prefix, column }));
5974
+ }
4917
5975
  if (items) {
4918
5976
  return jsx(ArrayViewer, { schema: colSchema, prefix, column });
4919
5977
  }
@@ -4937,10 +5995,20 @@ const ColumnViewer = ({ column, properties, prefix, }) => {
4937
5995
  };
4938
5996
 
4939
5997
  const SubmitButton = () => {
4940
- const { translate, setValidatedData, setIsError, setIsConfirming } = useSchemaContext();
5998
+ const { translate, setValidatedData, setIsError, setIsConfirming, setError, schema, } = useSchemaContext();
4941
5999
  const methods = useFormContext();
4942
6000
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
4943
6001
  const onValid = (data) => {
6002
+ const { isValid, errors } = validateData(data, schema);
6003
+ if (!isValid) {
6004
+ setError({
6005
+ type: "validation",
6006
+ errors,
6007
+ });
6008
+ setIsError(true);
6009
+ return;
6010
+ }
6011
+ // If validation passes, proceed to confirmation
4944
6012
  setValidatedData(data);
4945
6013
  setIsError(false);
4946
6014
  setIsConfirming(true);
@@ -4951,7 +6019,8 @@ const SubmitButton = () => {
4951
6019
  };
4952
6020
 
4953
6021
  const FormBody = () => {
4954
- const { schema, requestUrl, order, ignore, include, onSubmit, rowNumber, translate, requestOptions, isSuccess, setIsSuccess, isError, setIsError, isSubmiting, setIsSubmiting, isConfirming, setIsConfirming, validatedData, setValidatedData, error, setError, getUpdatedData, } = useSchemaContext();
6022
+ const { schema, requestUrl, order, ignore, include, onSubmit, translate, requestOptions, isSuccess, setIsSuccess, isError, setIsError, isSubmiting, setIsSubmiting, isConfirming, setIsConfirming, validatedData, setValidatedData, error, setError, getUpdatedData, customErrorRenderer, displayConfig, } = useSchemaContext();
6023
+ const { showSubmitButton, showResetButton } = displayConfig;
4955
6024
  const methods = useFormContext();
4956
6025
  const { properties } = schema;
4957
6026
  const onBeforeSubmit = () => {
@@ -4967,6 +6036,26 @@ const FormBody = () => {
4967
6036
  const onSubmitSuccess = () => {
4968
6037
  setIsSuccess(true);
4969
6038
  };
6039
+ const validateFormData = (data) => {
6040
+ try {
6041
+ const { isValid, errors } = validateData(data, schema);
6042
+ return {
6043
+ isValid,
6044
+ errors,
6045
+ };
6046
+ }
6047
+ catch (error) {
6048
+ return {
6049
+ isValid: false,
6050
+ errors: [
6051
+ {
6052
+ field: "validation",
6053
+ message: error instanceof Error ? error.message : "Unknown error",
6054
+ },
6055
+ ],
6056
+ };
6057
+ }
6058
+ };
4970
6059
  const defaultOnSubmit = async (promise) => {
4971
6060
  try {
4972
6061
  onBeforeSubmit();
@@ -4991,12 +6080,28 @@ const FormBody = () => {
4991
6080
  };
4992
6081
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
4993
6082
  const onFormSubmit = async (data) => {
6083
+ // Validate data using AJV before submission
6084
+ const validationResult = validateFormData(data);
6085
+ if (!validationResult.isValid) {
6086
+ // Set validation errors
6087
+ const validationErrorMessage = {
6088
+ type: "validation",
6089
+ errors: validationResult.errors,
6090
+ message: translate.t("validation_error"),
6091
+ };
6092
+ onSubmitError(validationErrorMessage);
6093
+ return;
6094
+ }
4994
6095
  if (onSubmit === undefined) {
4995
6096
  await defaultOnSubmit(defaultSubmitPromise(data));
4996
6097
  return;
4997
6098
  }
4998
6099
  await defaultOnSubmit(onSubmit(data));
4999
6100
  };
6101
+ // Custom error renderer for validation errors with i18n support
6102
+ const renderValidationErrors = (validationErrors) => {
6103
+ return (jsx(Flex, { flexFlow: "column", gap: "2", children: validationErrors.map((err, index) => (jsxs(Alert.Root, { status: "error", display: "flex", alignItems: "center", children: [jsx(Alert.Indicator, {}), jsx(Alert.Content, { children: jsx(Alert.Description, { children: err.message }) })] }, index))) }));
6104
+ };
5000
6105
  const renderColumns = ({ order, keys, ignore, include, }) => {
5001
6106
  const included = include.length > 0 ? include : keys;
5002
6107
  const not_exist = included.filter((columnA) => !order.some((columnB) => columnA === columnB));
@@ -5011,7 +6116,7 @@ const FormBody = () => {
5011
6116
  include,
5012
6117
  });
5013
6118
  if (isSuccess) {
5014
- return (jsxs(Flex, { flexFlow: "column", gap: "2", children: [jsxs(Alert.Root, { status: "success", children: [jsx(Alert.Indicator, {}), jsx(Alert.Title, { children: translate.t("submitSuccess") })] }), jsx(Flex, { justifyContent: "end", children: jsx(Button$1, { onClick: async () => {
6119
+ return (jsxs(Flex, { flexFlow: "column", gap: "2", children: [jsxs(Alert.Root, { status: "success", children: [jsx(Alert.Indicator, {}), jsx(Alert.Content, { children: jsx(Alert.Title, { children: translate.t("submit_success") }) })] }), jsx(Flex, { justifyContent: "end", children: jsx(Button$1, { onClick: async () => {
5015
6120
  setIsError(false);
5016
6121
  setIsSubmiting(false);
5017
6122
  setIsSuccess(false);
@@ -5019,10 +6124,10 @@ const FormBody = () => {
5019
6124
  setValidatedData(undefined);
5020
6125
  const data = await getUpdatedData();
5021
6126
  methods.reset(data);
5022
- }, formNoValidate: true, children: translate.t("submitAgain") }) })] }));
6127
+ }, formNoValidate: true, children: translate.t("submit_again") }) })] }));
5023
6128
  }
5024
6129
  if (isConfirming) {
5025
- return (jsxs(Flex, { flexFlow: "column", gap: "2", children: [jsx(Grid, { gap: 4, gridTemplateColumns: "repeat(12, 1fr)", gridTemplateRows: `repeat(${rowNumber ?? "auto-fit"}, auto)`, children: ordered.map((column) => {
6130
+ return (jsxs(Flex, { flexFlow: "column", gap: "2", children: [jsx(Grid, { gap: 4, gridTemplateColumns: "repeat(12, 1fr)", gridTemplateRows: "repeat(12, max-content)", autoFlow: "row", children: ordered.map((column) => {
5026
6131
  return (jsx(ColumnViewer
5027
6132
  // @ts-expect-error find suitable types
5028
6133
  , {
@@ -5032,17 +6137,19 @@ const FormBody = () => {
5032
6137
  setIsConfirming(false);
5033
6138
  }, variant: "subtle", children: translate.t("cancel") }), jsx(Button$1, { onClick: () => {
5034
6139
  onFormSubmit(validatedData);
5035
- }, children: translate.t("confirm") })] }), isSubmiting && (jsx(Box, { pos: "absolute", inset: "0", bg: "bg/80", children: jsx(Center, { h: "full", children: jsx(Spinner, { color: "teal.500" }) }) })), isError && (jsx(Fragment, { children: jsx(Alert.Root, { status: "error", children: jsx(Alert.Title, { children: jsx(AccordionRoot, { collapsible: true, defaultValue: [], children: jsxs(AccordionItem, { value: "b", children: [jsxs(AccordionItemTrigger, { children: [jsx(Alert.Indicator, {}), `${error}`] }), jsx(AccordionItemContent, { children: `${JSON.stringify(error)}` })] }) }) }) }) }))] }));
6140
+ }, children: translate.t("confirm") })] }), isSubmiting && (jsx(Box, { pos: "absolute", inset: "0", bg: "bg/80", children: jsx(Center, { h: "full", children: jsx(Spinner, { color: "teal.500" }) }) })), isError && (jsx(Fragment, { children: customErrorRenderer ? (customErrorRenderer(error)) : (jsx(Fragment, { children: error?.type === "validation" &&
6141
+ error?.errors ? (renderValidationErrors(error.errors)) : (jsxs(Alert.Root, { status: "error", children: [jsx(Alert.Indicator, {}), jsxs(Alert.Content, { children: [jsx(Alert.Title, { children: "Error" }), jsx(Alert.Description, { children: jsx(AccordionRoot, { collapsible: true, defaultValue: [], children: jsxs(AccordionItem, { value: "b", children: [jsx(AccordionItemTrigger, { children: `${error}` }), jsx(AccordionItemContent, { children: `${JSON.stringify(error)}` })] }) }) })] })] })) })) }))] }));
5036
6142
  }
5037
- return (jsxs(Flex, { flexFlow: "column", gap: "2", children: [jsx(Grid, { gap: "4", gridTemplateColumns: "repeat(12, 1fr)", gridTemplateRows: `repeat(${rowNumber ?? "auto-fit"}, auto)`, children: ordered.map((column) => {
6143
+ return (jsxs(Flex, { flexFlow: "column", gap: "2", children: [jsx(Grid, { gap: "4", gridTemplateColumns: "repeat(12, 1fr)", autoFlow: "row", children: ordered.map((column) => {
5038
6144
  return (jsx(ColumnRenderer
5039
6145
  // @ts-expect-error find suitable types
5040
6146
  , {
5041
6147
  // @ts-expect-error find suitable types
5042
6148
  properties: properties, prefix: ``, column }, `form-input-${column}`));
5043
- }) }), jsxs(Flex, { justifyContent: "end", gap: "2", children: [jsx(Button$1, { onClick: () => {
6149
+ }) }), jsxs(Flex, { justifyContent: "end", gap: "2", children: [showResetButton && (jsx(Button$1, { onClick: () => {
5044
6150
  methods.reset();
5045
- }, variant: "subtle", children: translate.t("reset") }), jsx(SubmitButton, {})] })] }));
6151
+ }, variant: "subtle", children: translate.t("reset") })), showSubmitButton && jsx(SubmitButton, {})] }), isError && (jsx(Fragment, { children: customErrorRenderer ? (customErrorRenderer(error)) : (jsx(Fragment, { children: error?.type === "validation" &&
6152
+ error?.errors ? (renderValidationErrors(error.errors)) : (jsxs(Alert.Root, { status: "error", children: [jsx(Alert.Indicator, {}), jsxs(Alert.Content, { children: [jsx(Alert.Title, { children: "Error" }), jsx(Alert.Description, { children: jsx(AccordionRoot, { collapsible: true, defaultValue: [], children: jsxs(AccordionItem, { value: "b", children: [jsx(AccordionItemTrigger, { children: `${error}` }), jsx(AccordionItemContent, { children: `${JSON.stringify(error)}` })] }) }) })] })] })) })) }))] }));
5046
6153
  };
5047
6154
 
5048
6155
  const FormTitle = () => {
@@ -5051,7 +6158,8 @@ const FormTitle = () => {
5051
6158
  };
5052
6159
 
5053
6160
  const DefaultForm = ({ formConfig, }) => {
5054
- return (jsx(FormRoot, { ...formConfig, children: jsxs(Grid, { gap: "2", children: [jsx(FormTitle, {}), jsx(FormBody, {})] }) }));
6161
+ const { showTitle } = formConfig.displayConfig ?? {};
6162
+ return (jsx(FormRoot, { ...formConfig, children: jsxs(Grid, { gap: "2", children: [showTitle && jsx(FormTitle, {}), jsx(FormBody, {})] }) }));
5055
6163
  };
5056
6164
 
5057
6165
  const useForm = ({ preLoadedValues, keyPrefix }) => {
@@ -5084,4 +6192,4 @@ const getMultiDates = ({ selected, selectedDate, selectedDates, selectable, }) =
5084
6192
  }
5085
6193
  };
5086
6194
 
5087
- export { CardHeader, DataDisplay, DataTable, DataTableServer, DefaultCardTitle, DefaultForm, DefaultTable, DensityToggleButton, EditSortingButton, EmptyState$1 as EmptyState, ErrorAlert, FilterDialog, FilterOptions, FormBody, FormRoot, FormTitle, GlobalFilter, PageSizeControl, Pagination, RecordDisplay, ReloadButton, ResetFilteringButton, ResetSelectionButton, ResetSortingButton, RowCountText, Table, TableBody, TableCardContainer, TableCards, TableComponent, TableControls, TableFilter, TableFilterTags, TableFooter, TableHeader, TableLoadingComponent, TableSelector, TableSorter, TableViewer, TextCell, ViewDialog, getColumns, getMultiDates, getRangeDates, idPickerSanityCheck, useDataTable, useDataTableContext, useDataTableServer, useForm, widthSanityCheck };
6195
+ export { CardHeader, DataDisplay, DataTable, DataTableServer, DefaultCardTitle, DefaultForm, DefaultTable, DensityToggleButton, EditSortingButton, EmptyState$1 as EmptyState, ErrorAlert, FilterDialog, FormBody, FormRoot, FormTitle, GlobalFilter, PageSizeControl, Pagination, RecordDisplay, ReloadButton, ResetFilteringButton, ResetSelectionButton, ResetSortingButton, RowCountText, Table, TableBody, TableCardContainer, TableCards, TableComponent, TableControls, TableDataDisplay, TableFilter, TableFilterTags, TableFooter, TableHeader, TableLoadingComponent, TableSelector, TableSorter, TableViewer, TextCell, ViewDialog, getColumns, getMultiDates, getRangeDates, idPickerSanityCheck, useDataTable, useDataTableContext, useDataTableServer, useForm, widthSanityCheck };