@eintrek/erp-theme 1.4.10 → 1.4.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.esm.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import require$$1, { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
- import { ChevronDownIcon, ChevronRight, ChevronLeftIcon, ChevronRightIcon, Calendar as Calendar$1, ArrowRight, ArrowLeft, CheckIcon, XIcon, SearchIcon, CircleIcon, ChevronsUpDown, Check, Paperclip, X as X$1, AlertCircle, MoreHorizontalIcon, GripVerticalIcon, ChevronUpIcon, PanelLeftIcon, ChevronLeft, MoreHorizontal, ChevronDown, ChevronUp, EyeOff, Filter, Settings2, ListChecks, ArrowDownUp, Trash2, GripVertical, ListFilter, CalendarIcon, Copy, Code2, FileSpreadsheetIcon, CommandIcon } from 'lucide-react';
2
+ import { ChevronDownIcon, ChevronRight, CheckIcon, ChevronUpIcon, ChevronLeftIcon, ChevronRightIcon, Calendar as Calendar$1, ArrowRight, ArrowLeft, XIcon, SearchIcon, CircleIcon, ChevronsUpDown, Check, Paperclip, X as X$1, AlertCircle, MoreHorizontalIcon, GripVerticalIcon, PanelLeftIcon, ChevronLeft, MoreHorizontal, ChevronDown, ChevronUp, EyeOff, Filter, Settings2, ListChecks, ArrowDownUp, Trash2, GripVertical, ListFilter, CalendarIcon, Copy, Code2, FileSpreadsheetIcon, CommandIcon } from 'lucide-react';
3
3
  import '@radix-ui/react-accessible-icon';
4
4
  import * as AccordionPrimitive from '@radix-ui/react-accordion';
5
5
  import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog';
@@ -213,6 +213,80 @@ function BreadcrumbSeparator({ children, className, ...props }) {
213
213
  return (jsx("li", { "data-slot": "breadcrumb-separator", role: "presentation", "aria-hidden": "true", className: cn$1("[&>svg]:size-3.5", className), ...props, children: children ?? jsx(ChevronRight, {}) }));
214
214
  }
215
215
 
216
+ function Select({ onValueChange, onOpenChange, open, defaultOpen, ...props }) {
217
+ // Tracked in a ref, not state: this only needs to be readable inside the
218
+ // callback below, and putting it in state would re-render on every open.
219
+ const isOpenRef = React.useRef(defaultOpen ?? false);
220
+ if (open !== undefined)
221
+ isOpenRef.current = open;
222
+ return (jsx(SelectPrimitive.Root, { "data-slot": "select", ...props, open: open, defaultOpen: defaultOpen, onOpenChange: next => {
223
+ isOpenRef.current = next;
224
+ onOpenChange?.(next);
225
+ }, onValueChange: value => {
226
+ // Drop ONLY the empty value Radix echoes back on its own.
227
+ //
228
+ // Radix keeps a hidden native <select> so the control works inside
229
+ // real forms. Whenever the controlled value changes it assigns that
230
+ // value to the native node and dispatches a synthetic change event,
231
+ // which comes straight back out through onValueChange:
232
+ //
233
+ // setValue.call(select, selectValue);
234
+ // select.dispatchEvent(new Event("change", { bubbles: true }));
235
+ // ...
236
+ // onChange: (event) => onValueChange(event.target.value)
237
+ //
238
+ // The native <option> list is registered by SelectItem, and the items
239
+ // live inside SelectContent — portalled, and only mounted while the
240
+ // menu is open. On a closed select the option for the incoming value
241
+ // usually does not exist yet, the DOM refuses the assignment,
242
+ // `select.value` collapses to "", and that empty string reaches the
243
+ // consumer. In a form this lands exactly when saved data arrives: the
244
+ // field is set to its stored value, Radix echoes "", and the handler
245
+ // writes that back — enum fields then snap to their fallback and zod
246
+ // rejects the submit with "received ''".
247
+ //
248
+ // The open check is what keeps a real "none" option working. Radix
249
+ // does NOT forbid <SelectItem value="">, and picking one is a
250
+ // legitimate way to clear a selection. A user pick always arrives
251
+ // while the menu is still open — SelectItem's handleSelect calls
252
+ // onValueChange(value) BEFORE onOpenChange(false) — whereas the echo
253
+ // above fires from an effect with the menu closed. So only the closed
254
+ // case is suppressed.
255
+ if (value === "" && !isOpenRef.current)
256
+ return;
257
+ onValueChange?.(value);
258
+ } }));
259
+ }
260
+ function SelectGroup({ ...props }) {
261
+ return jsx(SelectPrimitive.Group, { "data-slot": "select-group", ...props });
262
+ }
263
+ function SelectValue({ ...props }) {
264
+ return jsx(SelectPrimitive.Value, { "data-slot": "select-value", ...props });
265
+ }
266
+ function SelectTrigger({ className, size = "default", children, ...props }) {
267
+ return (jsxs(SelectPrimitive.Trigger, { "data-slot": "select-trigger", "data-size": size, className: cn$1("border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 flex w-fit items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className), ...props, children: [children, jsx(SelectPrimitive.Icon, { asChild: true, children: jsx(ChevronDownIcon, { className: "size-4 opacity-50" }) })] }));
268
+ }
269
+ function SelectContent({ className, children, position = "popper", ...props }) {
270
+ return (jsx(SelectPrimitive.Portal, { children: jsxs(SelectPrimitive.Content, { "data-slot": "select-content", className: cn$1("bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border shadow-md", position === "popper" &&
271
+ "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1", className), position: position, ...props, children: [jsx(SelectScrollUpButton, {}), jsx(SelectPrimitive.Viewport, { className: cn$1("p-1", position === "popper" &&
272
+ "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1"), children: children }), jsx(SelectScrollDownButton, {})] }) }));
273
+ }
274
+ function SelectLabel({ className, ...props }) {
275
+ return (jsx(SelectPrimitive.Label, { "data-slot": "select-label", className: cn$1("text-muted-foreground px-2 py-1.5 text-xs", className), ...props }));
276
+ }
277
+ function SelectItem({ className, children, ...props }) {
278
+ return (jsxs(SelectPrimitive.Item, { "data-slot": "select-item", className: cn$1("focus:bg-accent focus:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2", className), ...props, children: [jsx("span", { className: "absolute right-2 flex size-3.5 items-center justify-center", children: jsx(SelectPrimitive.ItemIndicator, { children: jsx(CheckIcon, { className: "size-4" }) }) }), jsx(SelectPrimitive.ItemText, { children: children })] }));
279
+ }
280
+ function SelectSeparator({ className, ...props }) {
281
+ return (jsx(SelectPrimitive.Separator, { "data-slot": "select-separator", className: cn$1("bg-border pointer-events-none -mx-1 my-1 h-px", className), ...props }));
282
+ }
283
+ function SelectScrollUpButton({ className, ...props }) {
284
+ return (jsx(SelectPrimitive.ScrollUpButton, { "data-slot": "select-scroll-up-button", className: cn$1("flex cursor-default items-center justify-center py-1", className), ...props, children: jsx(ChevronUpIcon, { className: "size-4" }) }));
285
+ }
286
+ function SelectScrollDownButton({ className, ...props }) {
287
+ return (jsx(SelectPrimitive.ScrollDownButton, { "data-slot": "select-scroll-down-button", className: cn$1("flex cursor-default items-center justify-center py-1", className), ...props, children: jsx(ChevronDownIcon, { className: "size-4" }) }));
288
+ }
289
+
216
290
  /**
217
291
  * @module constants
218
292
  * @summary Useful constants
@@ -659,11 +733,35 @@ function getThaiMonthName(monthIndex) {
659
733
 
660
734
  /** Thai weekday abbreviations (Sunday-first, matching JS getDay()). */
661
735
  const WEEK_DAYS_TH = ["อา.", "จ.", "อ.", "พ.", "พฤ.", "ศ.", "ส."];
662
- function formatMonthCaption(date) {
663
- return `${THAI_MONTH_NAMES[date.getMonth()]} ${toBuddhistYear(date.getFullYear())}`;
736
+ function getInitialMonth(selected) {
737
+ if (selected instanceof Date && !Number.isNaN(selected.getTime())) {
738
+ return new Date(selected.getFullYear(), selected.getMonth(), 1);
739
+ }
740
+ if (Array.isArray(selected) && selected[0] instanceof Date) {
741
+ return new Date(selected[0].getFullYear(), selected[0].getMonth(), 1);
742
+ }
743
+ if (selected &&
744
+ typeof selected === "object" &&
745
+ "from" in selected &&
746
+ selected.from instanceof Date) {
747
+ return new Date(selected.from.getFullYear(), selected.from.getMonth(), 1);
748
+ }
749
+ return new Date();
664
750
  }
665
- function Calendar({ className, selected, onSelect, mode = "single", disabled, }) {
666
- const [currentMonth, setCurrentMonth] = React.useState(new Date());
751
+ function Calendar({ className, selected, onSelect, mode = "single", disabled, fromYear = 1900, toYear, }) {
752
+ const maxYear = toYear ?? new Date().getFullYear() + 10;
753
+ const [currentMonth, setCurrentMonth] = React.useState(() => getInitialMonth(selected));
754
+ // Jump the grid to the selected date when it changes (e.g. form load).
755
+ React.useEffect(() => {
756
+ const next = getInitialMonth(selected);
757
+ setCurrentMonth((prev) => {
758
+ if (prev.getFullYear() === next.getFullYear() &&
759
+ prev.getMonth() === next.getMonth()) {
760
+ return prev;
761
+ }
762
+ return next;
763
+ });
764
+ }, [selected]);
667
765
  const today = new Date();
668
766
  const year = currentMonth.getFullYear();
669
767
  const month = currentMonth.getMonth();
@@ -671,13 +769,20 @@ function Calendar({ className, selected, onSelect, mode = "single", disabled, })
671
769
  const lastDayOfMonth = new Date(year, month + 1, 0);
672
770
  const firstDayOfWeek = firstDayOfMonth.getDay();
673
771
  const daysInMonth = lastDayOfMonth.getDate();
772
+ const yearOptions = React.useMemo(() => {
773
+ const years = [];
774
+ const start = Math.min(fromYear, maxYear);
775
+ const end = Math.max(fromYear, maxYear);
776
+ for (let y = end; y >= start; y--) {
777
+ years.push(y);
778
+ }
779
+ return years;
780
+ }, [fromYear, maxYear]);
674
781
  const getDaysInMonth = () => {
675
782
  const days = [];
676
- // Add empty cells for days before the first day of the month
677
783
  for (let i = 0; i < firstDayOfWeek; i++) {
678
784
  days.push(null);
679
785
  }
680
- // Add days of the month
681
786
  for (let day = 1; day <= daysInMonth; day++) {
682
787
  days.push(new Date(year, month, day));
683
788
  }
@@ -689,7 +794,10 @@ function Calendar({ className, selected, onSelect, mode = "single", disabled, })
689
794
  if (mode === "single" && selected instanceof Date) {
690
795
  return date.toDateString() === selected.toDateString();
691
796
  }
692
- if (mode === "range" && selected && typeof selected === "object" && "from" in selected) {
797
+ if (mode === "range" &&
798
+ selected &&
799
+ typeof selected === "object" &&
800
+ "from" in selected) {
693
801
  const range = selected;
694
802
  if (range.from && range.to) {
695
803
  return date >= range.from && date <= range.to;
@@ -699,7 +807,7 @@ function Calendar({ className, selected, onSelect, mode = "single", disabled, })
699
807
  }
700
808
  }
701
809
  if (mode === "multiple" && Array.isArray(selected)) {
702
- return selected.some(d => d.toDateString() === date.toDateString());
810
+ return selected.some((d) => d.toDateString() === date.toDateString());
703
811
  }
704
812
  return false;
705
813
  };
@@ -718,7 +826,6 @@ function Calendar({ className, selected, onSelect, mode = "single", disabled, })
718
826
  onSelect?.(date);
719
827
  }
720
828
  else if (mode === "range") {
721
- // Simple range selection - click to set start, click again to set end
722
829
  if (!selected || typeof selected !== "object" || !("from" in selected)) {
723
830
  onSelect?.({ from: date, to: undefined });
724
831
  }
@@ -742,9 +849,9 @@ function Calendar({ className, selected, onSelect, mode = "single", disabled, })
742
849
  }
743
850
  else if (mode === "multiple") {
744
851
  const currentSelection = Array.isArray(selected) ? selected : [];
745
- const isAlreadySelected = currentSelection.some(d => d.toDateString() === date.toDateString());
852
+ const isAlreadySelected = currentSelection.some((d) => d.toDateString() === date.toDateString());
746
853
  if (isAlreadySelected) {
747
- onSelect?.(currentSelection.filter(d => d.toDateString() !== date.toDateString()));
854
+ onSelect?.(currentSelection.filter((d) => d.toDateString() !== date.toDateString()));
748
855
  }
749
856
  else {
750
857
  onSelect?.([...currentSelection, date]);
@@ -752,7 +859,7 @@ function Calendar({ className, selected, onSelect, mode = "single", disabled, })
752
859
  }
753
860
  };
754
861
  const navigateMonth = (direction) => {
755
- setCurrentMonth(prev => {
862
+ setCurrentMonth((prev) => {
756
863
  const newMonth = new Date(prev);
757
864
  if (direction === "prev") {
758
865
  newMonth.setMonth(prev.getMonth() - 1);
@@ -763,18 +870,34 @@ function Calendar({ className, selected, onSelect, mode = "single", disabled, })
763
870
  return newMonth;
764
871
  });
765
872
  };
873
+ const handleMonthChange = (monthStr) => {
874
+ const nextMonth = Number.parseInt(monthStr, 10);
875
+ if (Number.isNaN(nextMonth))
876
+ return;
877
+ setCurrentMonth((prev) => new Date(prev.getFullYear(), nextMonth, 1));
878
+ };
879
+ const handleYearChange = (buddhistYearStr) => {
880
+ const gregorian = toGregorianYear(Number.parseInt(buddhistYearStr, 10));
881
+ if (Number.isNaN(gregorian))
882
+ return;
883
+ setCurrentMonth((prev) => new Date(gregorian, prev.getMonth(), 1));
884
+ };
766
885
  const days = getDaysInMonth();
767
- return (jsxs("div", { "data-slot": "calendar", className: cn$1("bg-background group/calendar p-3 w-fit", className), children: [jsxs("div", { className: "flex items-center justify-between mb-4", children: [jsx(Button, { variant: "ghost", size: "icon", onClick: () => navigateMonth("prev"), className: "h-8 w-8 p-0", children: jsx(ChevronLeftIcon, { className: "h-4 w-4" }) }), jsx("div", { className: "text-sm font-medium", children: formatMonthCaption(currentMonth) }), jsx(Button, { variant: "ghost", size: "icon", onClick: () => navigateMonth("next"), className: "h-8 w-8 p-0", children: jsx(ChevronRightIcon, { className: "h-4 w-4" }) })] }), jsx("div", { className: "grid grid-cols-7 gap-1 mb-2", children: WEEK_DAYS_TH.map((day) => (jsx("div", { className: "text-muted-foreground text-xs font-normal text-center h-8 flex items-center justify-center", children: day }, day))) }), jsx("div", { className: "grid grid-cols-7 gap-1", children: days.map((date, index) => {
886
+ const canGoPrev = year > fromYear || (year === fromYear && month > 0);
887
+ const canGoNext = year < maxYear || (year === maxYear && month < 11);
888
+ return (jsxs("div", { "data-slot": "calendar", className: cn$1("bg-background group/calendar p-3 w-fit", className), children: [jsxs("div", { className: "mb-4 flex items-center justify-between gap-1", children: [jsx(Button, { type: "button", variant: "ghost", size: "icon", onClick: () => navigateMonth("prev"), disabled: !canGoPrev, className: "h-8 w-8 shrink-0 p-0", "aria-label": "\u0E40\u0E14\u0E37\u0E2D\u0E19\u0E01\u0E48\u0E2D\u0E19\u0E2B\u0E19\u0E49\u0E32", children: jsx(ChevronLeftIcon, { className: "h-4 w-4" }) }), jsxs("div", { className: "flex min-w-0 flex-1 items-center justify-center gap-1", children: [jsxs(Select, { value: String(month), onValueChange: handleMonthChange, children: [jsx(SelectTrigger, { size: "sm", className: "h-8 w-[7.5rem] px-2 text-xs", "aria-label": "\u0E40\u0E25\u0E37\u0E2D\u0E01\u0E40\u0E14\u0E37\u0E2D\u0E19", children: jsx(SelectValue, { children: THAI_MONTH_NAMES[month] }) }), jsx(SelectContent, { className: "z-[100] max-h-60", children: THAI_MONTH_NAMES.map((name, index) => (jsx(SelectItem, { value: String(index), children: name }, name))) })] }), jsxs(Select, { value: String(toBuddhistYear(year)), onValueChange: handleYearChange, children: [jsx(SelectTrigger, { size: "sm", className: "h-8 w-[5.5rem] px-2 text-xs", "aria-label": "\u0E40\u0E25\u0E37\u0E2D\u0E01\u0E1B\u0E35", children: jsx(SelectValue, { children: toBuddhistYear(year) }) }), jsx(SelectContent, { className: "z-[100] max-h-60", children: yearOptions.map((y) => (jsx(SelectItem, { value: String(toBuddhistYear(y)), children: toBuddhistYear(y) }, y))) })] })] }), jsx(Button, { type: "button", variant: "ghost", size: "icon", onClick: () => navigateMonth("next"), disabled: !canGoNext, className: "h-8 w-8 shrink-0 p-0", "aria-label": "\u0E40\u0E14\u0E37\u0E2D\u0E19\u0E16\u0E31\u0E14\u0E44\u0E1B", children: jsx(ChevronRightIcon, { className: "h-4 w-4" }) })] }), jsx("div", { className: "mb-2 grid grid-cols-7 gap-1", children: WEEK_DAYS_TH.map((day) => (jsx("div", { className: "text-muted-foreground flex h-8 items-center justify-center text-center text-xs font-normal", children: day }, day))) }), jsx("div", { className: "grid grid-cols-7 gap-1", children: days.map((date, index) => {
768
889
  if (!date) {
769
890
  return jsx("div", { className: "h-8" }, index);
770
891
  }
771
892
  const isDateSelected = isSelected(date);
772
893
  const isDateToday = isToday(date);
773
894
  const isDateDisabled = isDisabled(date);
774
- return (jsx(Button, { variant: "ghost", size: "icon", className: cn$1("h-8 w-8 p-0 text-sm font-normal", isDateSelected && "bg-primary text-primary-foreground", isDateToday && !isDateSelected && "bg-accent text-accent-foreground", isDateDisabled && "opacity-50 cursor-not-allowed", "hover:bg-accent hover:text-accent-foreground"), onClick: () => handleDateClick(date), disabled: isDateDisabled, children: date.getDate() }, date.toISOString()));
895
+ return (jsx(Button, { type: "button", variant: "ghost", size: "icon", className: cn$1("h-8 w-8 p-0 text-sm font-normal", isDateSelected && "bg-primary text-primary-foreground", isDateToday &&
896
+ !isDateSelected &&
897
+ "bg-accent text-accent-foreground", isDateDisabled && "cursor-not-allowed opacity-50", "hover:bg-accent hover:text-accent-foreground"), onClick: () => handleDateClick(date), disabled: isDateDisabled, children: date.getDate() }, date.toISOString()));
775
898
  }) })] }));
776
899
  }
777
- function DateInput({ value, onChange, placeholder = "Select date", className, disabled = false }) {
900
+ function DateInput({ value, onChange, placeholder = "Select date", className, disabled = false, }) {
778
901
  const handleChange = (event) => {
779
902
  const dateValue = event.target.value;
780
903
  if (dateValue) {
@@ -785,9 +908,9 @@ function DateInput({ value, onChange, placeholder = "Select date", className, di
785
908
  }
786
909
  };
787
910
  const formatDateForInput = (date) => {
788
- return date.toISOString().split('T')[0];
911
+ return date.toISOString().split("T")[0];
789
912
  };
790
- return (jsx("input", { type: "date", value: value ? formatDateForInput(value) : "", onChange: handleChange, placeholder: placeholder, disabled: disabled, className: cn$1("flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50", className) }));
913
+ return (jsx("input", { type: "date", value: value ? formatDateForInput(value) : "", onChange: handleChange, placeholder: placeholder, disabled: disabled, className: cn$1("border-input bg-background ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring flex h-10 w-full rounded-md border px-3 py-2 text-sm file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50", className) }));
791
914
  }
792
915
 
793
916
  const formatDistanceLocale = {
@@ -1282,17 +1405,29 @@ function PopoverContent({ className, align = "center", sideOffset = 4, ...props
1282
1405
  return (jsx(PopoverPrimitive.Portal, { children: jsx(PopoverPrimitive.Content, { "data-slot": "popover-content", align: align, sideOffset: sideOffset, className: cn$1("bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 origin-(--radix-popover-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden", className), ...props }) }));
1283
1406
  }
1284
1407
 
1285
- const defaultDisabledDates = (date) => date > new Date() || date < new Date("1900-01-01");
1408
+ /**
1409
+ * Only the lower bound is universal. Rejecting future dates by default made
1410
+ * every forward-looking field — due dates, expiry, delivery, installment
1411
+ * schedules — silently unusable unless the caller remembered to override it,
1412
+ * and several forms already carried `d => d < new Date("1900-01-01")` purely
1413
+ * to undo it. A field that must stay in the past says so with its own
1414
+ * `disabledDates`; the picker no longer guesses.
1415
+ */
1416
+ const defaultDisabledDates = (date) => date < new Date("1900-01-01");
1417
+ /** Ready-made matcher for fields that genuinely cannot be in the future
1418
+ * (date of birth, an issue date on a document already in hand). */
1419
+ const disallowFutureDates = (date) => date > new Date() || date < new Date("1900-01-01");
1286
1420
  const defaultFormatDate = (date) => new Intl.DateTimeFormat("th-TH", {
1287
1421
  day: "numeric",
1288
1422
  month: "long",
1289
1423
  year: "numeric",
1290
1424
  timeZone: "Asia/Bangkok",
1291
1425
  }).format(date);
1292
- function DatePicker({ date, onDateChange, placeholder = "เลือกวันที่", disabled = false, disabledDates, formatDate = defaultFormatDate, className, id, ariaLabel, "aria-required": ariaRequired, "aria-invalid": ariaInvalid, "aria-describedby": ariaDescribedby, }) {
1426
+ function DatePicker({ date, onDateChange, placeholder = "เลือกวันที่", disabled = false, disabledDates, formatDate = defaultFormatDate, fromYear = 1900, toYear, className, id, ariaLabel, "aria-required": ariaRequired, "aria-invalid": ariaInvalid, "aria-describedby": ariaDescribedby, }) {
1293
1427
  const [open, setOpen] = React.useState(false);
1294
1428
  const isDateDisabled = disabledDates ?? defaultDisabledDates;
1295
- return (jsxs(Popover, { open: open && !disabled, onOpenChange: setOpen, children: [jsx(PopoverTrigger, { asChild: true, children: jsxs("div", { className: "relative w-full", children: [jsx(Input, { readOnly: true, disabled: disabled, value: date ? formatDate(date) : "", placeholder: placeholder, className: cn$1("border-border bg-background text-foreground placeholder:text-muted-foreground w-full pr-9", disabled ? "cursor-not-allowed opacity-50" : "cursor-pointer", className), id: id, "aria-label": date ? undefined : (ariaLabel ?? placeholder), "aria-required": ariaRequired, "aria-invalid": ariaInvalid, "aria-describedby": ariaDescribedby }), jsx(Calendar$1, { className: "text-muted-foreground pointer-events-none absolute top-1/2 right-3 h-4 w-4 -translate-y-1/2" })] }) }), jsx(PopoverContent, { className: "w-[280px] overflow-hidden p-0", align: "start", children: jsx(Calendar, { ...{ locale: th }, mode: "single", selected: date, onSelect: (selectedDate) => {
1429
+ const resolvedToYear = toYear ?? new Date().getFullYear() + 10;
1430
+ return (jsxs(Popover, { open: open && !disabled, onOpenChange: setOpen, children: [jsx(PopoverTrigger, { asChild: true, children: jsxs("div", { className: "relative w-full", children: [jsx(Input, { readOnly: true, disabled: disabled, value: date ? formatDate(date) : "", placeholder: placeholder, className: cn$1("border-border bg-background text-foreground placeholder:text-muted-foreground w-full pr-9", disabled ? "cursor-not-allowed opacity-50" : "cursor-pointer", className), id: id, "aria-label": date ? undefined : (ariaLabel ?? placeholder), "aria-required": ariaRequired, "aria-invalid": ariaInvalid, "aria-describedby": ariaDescribedby }), jsx(Calendar$1, { className: "text-muted-foreground pointer-events-none absolute top-1/2 right-3 h-4 w-4 -translate-y-1/2" })] }) }), jsx(PopoverContent, { className: "w-auto overflow-visible p-0", align: "start", children: jsx(Calendar, { ...{ locale: th }, mode: "single", selected: date, onSelect: (selectedDate) => {
1296
1431
  if (selectedDate instanceof Date) {
1297
1432
  onDateChange?.(selectedDate);
1298
1433
  setOpen(false);
@@ -1301,7 +1436,7 @@ function DatePicker({ date, onDateChange, placeholder = "เลือกวั
1301
1436
  onDateChange?.(undefined);
1302
1437
  setOpen(false);
1303
1438
  }
1304
- }, disabled: isDateDisabled, initialFocus: true }) })] }));
1439
+ }, disabled: isDateDisabled, fromYear: fromYear, toYear: resolvedToYear, initialFocus: true }) })] }));
1305
1440
  }
1306
1441
 
1307
1442
  const labelVariants = cva("text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70");
@@ -16384,80 +16519,6 @@ function ScrollBar({ className, orientation = "vertical", ...props }) {
16384
16519
  "h-2.5 flex-col border-t border-t-transparent", className), ...props, children: jsx(ScrollAreaPrimitive.ScrollAreaThumb, { "data-slot": "scroll-area-thumb", className: "bg-border relative flex-1 rounded-full" }) }));
16385
16520
  }
16386
16521
 
16387
- function Select({ onValueChange, onOpenChange, open, defaultOpen, ...props }) {
16388
- // Tracked in a ref, not state: this only needs to be readable inside the
16389
- // callback below, and putting it in state would re-render on every open.
16390
- const isOpenRef = React.useRef(defaultOpen ?? false);
16391
- if (open !== undefined)
16392
- isOpenRef.current = open;
16393
- return (jsx(SelectPrimitive.Root, { "data-slot": "select", ...props, open: open, defaultOpen: defaultOpen, onOpenChange: next => {
16394
- isOpenRef.current = next;
16395
- onOpenChange?.(next);
16396
- }, onValueChange: value => {
16397
- // Drop ONLY the empty value Radix echoes back on its own.
16398
- //
16399
- // Radix keeps a hidden native <select> so the control works inside
16400
- // real forms. Whenever the controlled value changes it assigns that
16401
- // value to the native node and dispatches a synthetic change event,
16402
- // which comes straight back out through onValueChange:
16403
- //
16404
- // setValue.call(select, selectValue);
16405
- // select.dispatchEvent(new Event("change", { bubbles: true }));
16406
- // ...
16407
- // onChange: (event) => onValueChange(event.target.value)
16408
- //
16409
- // The native <option> list is registered by SelectItem, and the items
16410
- // live inside SelectContent — portalled, and only mounted while the
16411
- // menu is open. On a closed select the option for the incoming value
16412
- // usually does not exist yet, the DOM refuses the assignment,
16413
- // `select.value` collapses to "", and that empty string reaches the
16414
- // consumer. In a form this lands exactly when saved data arrives: the
16415
- // field is set to its stored value, Radix echoes "", and the handler
16416
- // writes that back — enum fields then snap to their fallback and zod
16417
- // rejects the submit with "received ''".
16418
- //
16419
- // The open check is what keeps a real "none" option working. Radix
16420
- // does NOT forbid <SelectItem value="">, and picking one is a
16421
- // legitimate way to clear a selection. A user pick always arrives
16422
- // while the menu is still open — SelectItem's handleSelect calls
16423
- // onValueChange(value) BEFORE onOpenChange(false) — whereas the echo
16424
- // above fires from an effect with the menu closed. So only the closed
16425
- // case is suppressed.
16426
- if (value === "" && !isOpenRef.current)
16427
- return;
16428
- onValueChange?.(value);
16429
- } }));
16430
- }
16431
- function SelectGroup({ ...props }) {
16432
- return jsx(SelectPrimitive.Group, { "data-slot": "select-group", ...props });
16433
- }
16434
- function SelectValue({ ...props }) {
16435
- return jsx(SelectPrimitive.Value, { "data-slot": "select-value", ...props });
16436
- }
16437
- function SelectTrigger({ className, size = "default", children, ...props }) {
16438
- return (jsxs(SelectPrimitive.Trigger, { "data-slot": "select-trigger", "data-size": size, className: cn$1("border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 flex w-fit items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className), ...props, children: [children, jsx(SelectPrimitive.Icon, { asChild: true, children: jsx(ChevronDownIcon, { className: "size-4 opacity-50" }) })] }));
16439
- }
16440
- function SelectContent({ className, children, position = "popper", ...props }) {
16441
- return (jsx(SelectPrimitive.Portal, { children: jsxs(SelectPrimitive.Content, { "data-slot": "select-content", className: cn$1("bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border shadow-md", position === "popper" &&
16442
- "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1", className), position: position, ...props, children: [jsx(SelectScrollUpButton, {}), jsx(SelectPrimitive.Viewport, { className: cn$1("p-1", position === "popper" &&
16443
- "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1"), children: children }), jsx(SelectScrollDownButton, {})] }) }));
16444
- }
16445
- function SelectLabel({ className, ...props }) {
16446
- return (jsx(SelectPrimitive.Label, { "data-slot": "select-label", className: cn$1("text-muted-foreground px-2 py-1.5 text-xs", className), ...props }));
16447
- }
16448
- function SelectItem({ className, children, ...props }) {
16449
- return (jsxs(SelectPrimitive.Item, { "data-slot": "select-item", className: cn$1("focus:bg-accent focus:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2", className), ...props, children: [jsx("span", { className: "absolute right-2 flex size-3.5 items-center justify-center", children: jsx(SelectPrimitive.ItemIndicator, { children: jsx(CheckIcon, { className: "size-4" }) }) }), jsx(SelectPrimitive.ItemText, { children: children })] }));
16450
- }
16451
- function SelectSeparator({ className, ...props }) {
16452
- return (jsx(SelectPrimitive.Separator, { "data-slot": "select-separator", className: cn$1("bg-border pointer-events-none -mx-1 my-1 h-px", className), ...props }));
16453
- }
16454
- function SelectScrollUpButton({ className, ...props }) {
16455
- return (jsx(SelectPrimitive.ScrollUpButton, { "data-slot": "select-scroll-up-button", className: cn$1("flex cursor-default items-center justify-center py-1", className), ...props, children: jsx(ChevronUpIcon, { className: "size-4" }) }));
16456
- }
16457
- function SelectScrollDownButton({ className, ...props }) {
16458
- return (jsx(SelectPrimitive.ScrollDownButton, { "data-slot": "select-scroll-down-button", className: cn$1("flex cursor-default items-center justify-center py-1", className), ...props, children: jsx(ChevronDownIcon, { className: "size-4" }) }));
16459
- }
16460
-
16461
16522
  function SelectField({ id, label, helperText, error, required, placeholder, value, defaultValue, onValueChange, disabled, options, children, containerClassName, labelClassName, triggerClassName, messageClassName, size, "aria-label": ariaLabel, "aria-describedby": ariaDescribedby, }) {
16462
16523
  const reactId = React.useId();
16463
16524
  const inputId = id ?? reactId;
@@ -34802,5 +34863,5 @@ const flagConfig = {
34802
34863
  ],
34803
34864
  };
34804
34865
 
34805
- export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AspectRatio, Avatar, AvatarFallback, AvatarImage, Badge, Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, Calendar, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious, ChartContainer, ChartLegend, ChartLegendContent, ChartTooltip, ChartTooltipContent, Checkbox, Collapsible, CollapsibleContent, CollapsibleTrigger, Command, CommandBlock, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuItem, ContextMenuLabel, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, CustomSelectField2, DataTable, DataTableCell, DataTableColumnHeader, DataTableDateFilter, DataTableFacetedFilter, DataTableFilterDropdown, DataTableFilterList, DataTablePagination, DataTableRangeFilter, DataTableSkeleton, DataTableSliderFilter, DataTableSortList, DataTableToolbar, DataTableViewOptions, DateInput, DatePicker, DatePickerField, Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Faceted, FacetedBadgeList, FacetedContent, FacetedEmpty, FacetedGroup, FacetedInput, FacetedItem, FacetedList, FacetedSeparator, FacetedTrigger, FileUploader, Footer, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, FormSkeleton, FormattedNumberInput, Header, HoverCard, HoverCardContent, HoverCardTrigger, Input, InputField, InputOTP, InputOTPGroup, InputOTPSlot, Label, LoadingScreen, MASK_PRESETS, MaskedTextInput, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, NavigationMenu, NavigationMenuContent, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, PageHeader, Pagination$1 as Pagination, PaginationContent$1 as PaginationContent, PaginationEllipsis$1 as PaginationEllipsis, PaginationItem$1 as PaginationItem, PaginationLink$1 as PaginationLink, PaginationNext$1 as PaginationNext, PaginationPrevious$1 as PaginationPrevious, Popover, PopoverContent, PopoverTrigger, Progress, RadioGroup, RadioGroupItem, RegistryItemRow, ResizableHandle, ResizablePanel, ResizablePanelGroup, ScrollArea, ScrollBar, Select, SelectContent, SelectField, SelectGroup, SelectItem, SelectLabel, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInset, SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarTrigger, Skeleton, Slider, Sortable, SortableContent, SortableItem, SortableItemHandle, SortableOverlay, Switch, THAI_MONTH_NAMES, Table, TableBody, TableCaption, TableCell, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, TextareaField, Toaster, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, ValidationErrors, badgeVariants, buttonVariants, cn$1 as cn, convertFileToUploadedFile, convertFilesToUploadedFiles, dataTableConfig, databasePrefix, flagConfig, formatCurrency, formatDate, formatDateThai, formatDateThaiShort, formatFileSize, formatMasked as formatMaskedValue, formatNumber, formatThaiMonth, formatThaiMonthShort, generateFileId, generateId, getBaseUrl, getCommonPinningStyles, getDefaultFilterOperator, getFilterOperators, getFiltersStateParser, getMonthDateRange, getSortingStateParser, getThaiMonthName, getValidFilters, isImageFile, navigationMenuTriggerStyle, parseDigits as parseMaskedDigits, siteConfig, thaiBahtText, toBuddhistIso, toBuddhistYear, toGregorianYear, toggleVariants, unknownError, useCallbackRef, useDataTable, useDebounce, useDebouncedCallback, useFormField, useIsMobile, useMediaQuery, validateFileSize, validateFileType };
34866
+ export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AspectRatio, Avatar, AvatarFallback, AvatarImage, Badge, Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, Calendar, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious, ChartContainer, ChartLegend, ChartLegendContent, ChartTooltip, ChartTooltipContent, Checkbox, Collapsible, CollapsibleContent, CollapsibleTrigger, Command, CommandBlock, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuItem, ContextMenuLabel, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, CustomSelectField2, DataTable, DataTableCell, DataTableColumnHeader, DataTableDateFilter, DataTableFacetedFilter, DataTableFilterDropdown, DataTableFilterList, DataTablePagination, DataTableRangeFilter, DataTableSkeleton, DataTableSliderFilter, DataTableSortList, DataTableToolbar, DataTableViewOptions, DateInput, DatePicker, DatePickerField, Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Faceted, FacetedBadgeList, FacetedContent, FacetedEmpty, FacetedGroup, FacetedInput, FacetedItem, FacetedList, FacetedSeparator, FacetedTrigger, FileUploader, Footer, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, FormSkeleton, FormattedNumberInput, Header, HoverCard, HoverCardContent, HoverCardTrigger, Input, InputField, InputOTP, InputOTPGroup, InputOTPSlot, Label, LoadingScreen, MASK_PRESETS, MaskedTextInput, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, NavigationMenu, NavigationMenuContent, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, PageHeader, Pagination$1 as Pagination, PaginationContent$1 as PaginationContent, PaginationEllipsis$1 as PaginationEllipsis, PaginationItem$1 as PaginationItem, PaginationLink$1 as PaginationLink, PaginationNext$1 as PaginationNext, PaginationPrevious$1 as PaginationPrevious, Popover, PopoverContent, PopoverTrigger, Progress, RadioGroup, RadioGroupItem, RegistryItemRow, ResizableHandle, ResizablePanel, ResizablePanelGroup, ScrollArea, ScrollBar, Select, SelectContent, SelectField, SelectGroup, SelectItem, SelectLabel, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInset, SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarTrigger, Skeleton, Slider, Sortable, SortableContent, SortableItem, SortableItemHandle, SortableOverlay, Switch, THAI_MONTH_NAMES, Table, TableBody, TableCaption, TableCell, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, TextareaField, Toaster, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, ValidationErrors, badgeVariants, buttonVariants, cn$1 as cn, convertFileToUploadedFile, convertFilesToUploadedFiles, dataTableConfig, databasePrefix, disallowFutureDates, flagConfig, formatCurrency, formatDate, formatDateThai, formatDateThaiShort, formatFileSize, formatMasked as formatMaskedValue, formatNumber, formatThaiMonth, formatThaiMonthShort, generateFileId, generateId, getBaseUrl, getCommonPinningStyles, getDefaultFilterOperator, getFilterOperators, getFiltersStateParser, getMonthDateRange, getSortingStateParser, getThaiMonthName, getValidFilters, isImageFile, navigationMenuTriggerStyle, parseDigits as parseMaskedDigits, siteConfig, thaiBahtText, toBuddhistIso, toBuddhistYear, toGregorianYear, toggleVariants, unknownError, useCallbackRef, useDataTable, useDebounce, useDebouncedCallback, useFormField, useIsMobile, useMediaQuery, validateFileSize, validateFileType };
34806
34867
  //# sourceMappingURL=index.esm.js.map