@jirawatpyk/aura-react 4.15.0 → 4.17.0

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.
@@ -249,6 +249,8 @@ var React4 = __toESM(require("react"), 1);
249
249
 
250
250
  // src/locale.tsx
251
251
  var React3 = __toESM(require("react"), 1);
252
+
253
+ // src/strings.ts
252
254
  var n = function(x) {
253
255
  return Number(x).toLocaleString("en");
254
256
  };
@@ -596,6 +598,8 @@ var STRINGS = {
596
598
  }
597
599
  }
598
600
  };
601
+
602
+ // src/locale.tsx
599
603
  var LocaleContext = React3.createContext(null);
600
604
  function AuraProvider(props) {
601
605
  const outer = React3.useContext(LocaleContext);
@@ -643,7 +647,8 @@ function ButtonLink(props, ref, Link) {
643
647
  "disabled",
644
648
  "linkComponent",
645
649
  "href",
646
- "fullWidth"
650
+ "fullWidth",
651
+ "size"
647
652
  ]);
648
653
  const Tag3 = disabled ? "a" : Link;
649
654
  return /* @__PURE__ */ React4.createElement(
@@ -655,7 +660,13 @@ function ButtonLink(props, ref, Link) {
655
660
  role: disabled ? "link" : void 0,
656
661
  "aria-disabled": disabled || void 0,
657
662
  tabIndex: disabled ? -1 : props.tabIndex,
658
- className: cx("aura-btn", "aura-btn--" + variant, props.fullWidth && "aura-btn--full", props.className),
663
+ className: cx(
664
+ "aura-btn",
665
+ "aura-btn--" + variant,
666
+ props.size === "sm" && "aura-btn--sm",
667
+ props.fullWidth && "aura-btn--full",
668
+ props.className
669
+ ),
659
670
  onClick: disabled ? void 0 : props.onClick
660
671
  },
661
672
  props.icon ? /* @__PURE__ */ React4.createElement(Icon, { name: props.icon }) : null,
@@ -681,7 +692,8 @@ var Button = React4.forwardRef(
681
692
  "iconRight",
682
693
  "loading",
683
694
  "onClick",
684
- "fullWidth"
695
+ "fullWidth",
696
+ "size"
685
697
  ]);
686
698
  return /* @__PURE__ */ React4.createElement(
687
699
  "button",
@@ -692,6 +704,7 @@ var Button = React4.forwardRef(
692
704
  className: cx(
693
705
  "aura-btn",
694
706
  "aura-btn--" + variant,
707
+ props.size === "sm" && "aura-btn--sm",
695
708
  props.fullWidth && "aura-btn--full",
696
709
  loading && "is-loading",
697
710
  props.className
@@ -919,12 +932,8 @@ var Checkbox = React8.forwardRef(function Checkbox2(props, ref) {
919
932
 
920
933
  // src/StatusPill.tsx
921
934
  var React9 = __toESM(require("react"), 1);
922
- var TONE_ICON = {
923
- neutral: "circle",
924
- progress: "circle-dot-dashed",
925
- ready: "circle-check",
926
- blocked: "ban"
927
- };
935
+
936
+ // src/status.ts
928
937
  var TONE_WORDS = {
929
938
  ready: ["ready", "done", "complete", "completed", "approved", "live", "passed"],
930
939
  progress: ["in progress", "in review", "review", "syncing", "running", "pending"],
@@ -936,6 +945,14 @@ function toneFor(status) {
936
945
  return "neutral";
937
946
  }
938
947
  var TONE_ORDER = { neutral: 0, progress: 1, ready: 2, blocked: 3 };
948
+
949
+ // src/StatusPill.tsx
950
+ var TONE_ICON = {
951
+ neutral: "circle",
952
+ progress: "circle-dot-dashed",
953
+ ready: "circle-check",
954
+ blocked: "ban"
955
+ };
939
956
  var StatusPill = React9.forwardRef(function StatusPill2(props, ref) {
940
957
  const tone2 = props.tone || toneFor(props.children);
941
958
  return /* @__PURE__ */ React9.createElement("span", { ref, className: cx("aura-pill", "aura-pill--" + tone2, props.className) }, /* @__PURE__ */ React9.createElement(Icon, { name: TONE_ICON[tone2] || "circle", size: 12 }), props.children);
@@ -1517,6 +1534,8 @@ var Combobox = React16.forwardRef(
1517
1534
  // src/DatePicker.tsx
1518
1535
  var React17 = __toESM(require("react"), 1);
1519
1536
  var import_react_dom3 = require("react-dom");
1537
+
1538
+ // src/dates.ts
1520
1539
  var ERA = /^พ\.ศ\.\s?|\s?(BE|พ\.ศ\.)$/g;
1521
1540
  var pad = function(n2) {
1522
1541
  return (n2 < 10 ? "0" : "") + n2;
@@ -1622,22 +1641,6 @@ function formatDate(iso, opts) {
1622
1641
  const loc = o.locale || "th";
1623
1642
  return fmt(localeTag(loc, o.calendar || defaultCalendar(loc)), f, d).replace(ERA, "");
1624
1643
  }
1625
- function useFormatDate() {
1626
- const ctx = useAuraLocale(), locale = ctx.locale || "en", calendar = ctx.calendar;
1627
- return React17.useCallback(
1628
- function(iso, opts) {
1629
- const o = opts || {}, loc = o.locale || locale;
1630
- return formatDate(
1631
- iso,
1632
- Object.assign({}, o, {
1633
- locale: loc,
1634
- calendar: o.calendar || (o.locale ? void 0 : calendar) || defaultCalendar(loc)
1635
- })
1636
- );
1637
- },
1638
- [locale, calendar]
1639
- );
1640
- }
1641
1644
  var MONTHS = null;
1642
1645
  function monthIndex(word) {
1643
1646
  if (!MONTHS) {
@@ -1675,6 +1678,24 @@ function parseDate(text) {
1675
1678
  const dt = new Date(y, mo - 1, d);
1676
1679
  return dt.getMonth() === mo - 1 && dt.getDate() === d ? toISO(dt) : null;
1677
1680
  }
1681
+
1682
+ // src/DatePicker.tsx
1683
+ function useFormatDate() {
1684
+ const ctx = useAuraLocale(), locale = ctx.locale || "en", calendar = ctx.calendar;
1685
+ return React17.useCallback(
1686
+ function(iso, opts) {
1687
+ const o = opts || {}, loc = o.locale || locale;
1688
+ return formatDate(
1689
+ iso,
1690
+ Object.assign({}, o, {
1691
+ locale: loc,
1692
+ calendar: o.calendar || (o.locale ? void 0 : calendar) || defaultCalendar(loc)
1693
+ })
1694
+ );
1695
+ },
1696
+ [locale, calendar]
1697
+ );
1698
+ }
1678
1699
  var Calendar = React17.forwardRef(function Calendar2(props, ref) {
1679
1700
  const ctx = useAuraLocale(), locale = props.locale || ctx.locale || "en", calendar = props.calendar || ctx.calendar || defaultCalendar(locale), tag = localeTag(locale, calendar);
1680
1701
  const weekStart = props.weekStartsOn == null ? locale === "sv" ? 1 : 0 : props.weekStartsOn;
@@ -2722,7 +2743,12 @@ function Command(props) {
2722
2743
  const id = uid(), listId = id + "-list";
2723
2744
  const box = React25.useRef(null);
2724
2745
  const input = React25.useRef(null);
2725
- const q = React25.useState(""), act = React25.useState(0);
2746
+ const qState = React25.useState(""), act = React25.useState(null);
2747
+ const query = props.query !== void 0 ? props.query : qState[0];
2748
+ function setQuery(v) {
2749
+ if (props.query === void 0) qState[1](v);
2750
+ if (props.onQueryChange) props.onQueryChange(v);
2751
+ }
2726
2752
  const openRef = React25.useRef(props.open);
2727
2753
  openRef.current = props.open;
2728
2754
  const close = function() {
@@ -2748,15 +2774,15 @@ function Command(props) {
2748
2774
  React25.useEffect(
2749
2775
  function() {
2750
2776
  if (!props.open) {
2751
- q[1]("");
2752
- act[1](0);
2777
+ if (query) setQuery("");
2778
+ act[1](null);
2753
2779
  }
2754
2780
  },
2755
2781
  [props.open]
2756
2782
  );
2757
- const filter = props.filter || defaultFilter;
2783
+ const filter = props.filter === false ? null : props.filter || defaultFilter;
2758
2784
  const shown = (props.items || []).filter(function(it) {
2759
- return filter(it, q[0]);
2785
+ return !filter || filter(it, query);
2760
2786
  });
2761
2787
  const groups = [];
2762
2788
  shown.forEach(function(it) {
@@ -2778,7 +2804,10 @@ function Command(props) {
2778
2804
  }).filter(function(i2) {
2779
2805
  return i2 >= 0;
2780
2806
  });
2781
- const active = enabled.indexOf(act[0]) >= 0 ? act[0] : enabled.length ? enabled[0] : -1;
2807
+ const byId = act[0] == null ? -1 : flat.findIndex(function(it) {
2808
+ return it.id === act[0];
2809
+ });
2810
+ const active = enabled.indexOf(byId) >= 0 ? byId : enabled.length ? enabled[0] : -1;
2782
2811
  const optId = function(i2) {
2783
2812
  return id + "-o" + i2;
2784
2813
  };
@@ -2803,7 +2832,7 @@ function Command(props) {
2803
2832
  if (dir === "first") n2 = 0;
2804
2833
  else if (dir === "last") n2 = enabled.length - 1;
2805
2834
  else n2 = (at + dir + enabled.length) % enabled.length;
2806
- act[1](enabled[n2]);
2835
+ act[1](flat[enabled[n2]].id);
2807
2836
  }
2808
2837
  function onKey(e) {
2809
2838
  if (e.key === "ArrowDown") {
@@ -2861,56 +2890,68 @@ function Command(props) {
2861
2890
  "aria-label": props.label || t.commandMenu,
2862
2891
  placeholder: props.placeholder || t.commandPlaceholder,
2863
2892
  className: "aura-command__input",
2864
- value: q[0],
2893
+ value: query,
2865
2894
  autoComplete: "off",
2866
2895
  spellCheck: false,
2867
2896
  onChange: function(e) {
2868
- q[1](e.target.value);
2869
- act[1](0);
2897
+ setQuery(e.target.value);
2898
+ act[1](null);
2870
2899
  },
2871
2900
  onKeyDown: onKey
2872
2901
  }
2873
2902
  ), /* @__PURE__ */ React25.createElement("kbd", { className: "aura-command__kbd" }, "Esc")),
2874
- /* @__PURE__ */ React25.createElement("div", { className: "aura-command__list", id: listId, role: "listbox", "aria-label": props.label || t.commandMenu }, !flat.length ? /* @__PURE__ */ React25.createElement("p", { className: "aura-command__empty", role: "presentation" }, props.emptyText || t.noMatches) : groups.map(function(g, gi) {
2875
- const gid = id + "-g" + gi;
2876
- return /* @__PURE__ */ React25.createElement(
2877
- "div",
2878
- {
2879
- key: g.name || gi,
2880
- role: "group",
2881
- "aria-labelledby": g.name ? gid : void 0,
2882
- className: "aura-command__group"
2883
- },
2884
- g.name ? /* @__PURE__ */ React25.createElement("div", { className: "aura-command__heading", id: gid, role: "presentation" }, g.name) : null,
2885
- g.items.map(function(it) {
2886
- i++;
2887
- const n2 = i;
2888
- return /* @__PURE__ */ React25.createElement(
2889
- "div",
2890
- {
2891
- key: it.id,
2892
- id: optId(n2),
2893
- role: "option",
2894
- "aria-selected": n2 === active,
2895
- "aria-disabled": it.disabled || void 0,
2896
- className: cx("aura-command__item", n2 === active && "is-active", it.disabled && "is-disabled"),
2897
- onPointerDown: function(e) {
2898
- e.preventDefault();
2899
- },
2900
- onPointerMove: function() {
2901
- if (!it.disabled && act[0] !== n2) act[1](n2);
2903
+ /* @__PURE__ */ React25.createElement(
2904
+ "div",
2905
+ {
2906
+ className: "aura-command__list",
2907
+ id: listId,
2908
+ role: "listbox",
2909
+ "aria-label": props.label || t.commandMenu,
2910
+ "aria-busy": props.loading || void 0
2911
+ },
2912
+ props.loading ? /* @__PURE__ */ React25.createElement("div", { className: "aura-command__loading", role: "presentation" }, /* @__PURE__ */ React25.createElement(Icon, { name: "loader-circle", className: "aura-spin" }), t.searching) : null,
2913
+ !flat.length ? props.loading ? null : /* @__PURE__ */ React25.createElement("div", { className: "aura-command__empty", role: "presentation" }, props.empty != null ? props.empty : props.emptyText || t.noMatches) : groups.map(function(g, gi) {
2914
+ const gid = id + "-g" + gi;
2915
+ return /* @__PURE__ */ React25.createElement(
2916
+ "div",
2917
+ {
2918
+ key: g.name || gi,
2919
+ role: "group",
2920
+ "aria-labelledby": g.name ? gid : void 0,
2921
+ className: "aura-command__group"
2922
+ },
2923
+ g.name ? /* @__PURE__ */ React25.createElement("div", { className: "aura-command__heading", id: gid, role: "presentation" }, g.name) : null,
2924
+ g.items.map(function(it) {
2925
+ i++;
2926
+ const n2 = i;
2927
+ return /* @__PURE__ */ React25.createElement(
2928
+ "div",
2929
+ {
2930
+ key: it.id,
2931
+ id: optId(n2),
2932
+ role: "option",
2933
+ "aria-selected": n2 === active,
2934
+ "aria-disabled": it.disabled || void 0,
2935
+ className: cx("aura-command__item", n2 === active && "is-active", it.disabled && "is-disabled"),
2936
+ onPointerDown: function(e) {
2937
+ e.preventDefault();
2938
+ },
2939
+ onPointerMove: function() {
2940
+ if (!it.disabled && act[0] !== it.id) act[1](it.id);
2941
+ },
2942
+ onClick: function() {
2943
+ run(it);
2944
+ }
2902
2945
  },
2903
- onClick: function() {
2904
- run(it);
2905
- }
2906
- },
2907
- it.icon ? /* @__PURE__ */ React25.createElement(Icon, { name: it.icon }) : null,
2908
- /* @__PURE__ */ React25.createElement("span", { className: "aura-command__text" }, /* @__PURE__ */ React25.createElement("span", { className: "aura-command__label" }, it.label), it.description ? /* @__PURE__ */ React25.createElement("span", { className: "aura-command__desc" }, it.description) : null),
2909
- it.shortcut ? /* @__PURE__ */ React25.createElement("kbd", { className: "aura-command__kbd" }, it.shortcut) : null
2910
- );
2911
- })
2912
- );
2913
- })),
2946
+ it.icon ? /* @__PURE__ */ React25.createElement(Icon, { name: it.icon }) : null,
2947
+ /* @__PURE__ */ React25.createElement("span", { className: "aura-command__text" }, /* @__PURE__ */ React25.createElement("span", { className: "aura-command__label" }, it.label), it.description ? /* @__PURE__ */ React25.createElement("span", { className: "aura-command__desc" }, it.description) : null),
2948
+ it.shortcut ? /* @__PURE__ */ React25.createElement("kbd", { className: "aura-command__kbd" }, it.shortcut) : null
2949
+ );
2950
+ })
2951
+ );
2952
+ })
2953
+ ),
2954
+ /* @__PURE__ */ React25.createElement("span", { className: "aura-sr-only", role: "status" }, props.loading ? t.searching : props.loading === false && query ? t.results(flat.length) : ""),
2914
2955
  /* @__PURE__ */ React25.createElement("div", { className: "aura-command__foot", "aria-hidden": true }, t.commandHint, /* @__PURE__ */ React25.createElement("span", { className: "aura-command__mod" }, isMac() ? "\u2318K" : "Ctrl K"))
2915
2956
  )
2916
2957
  ),
@@ -3079,6 +3120,7 @@ var DEFAULT_COLUMNS = [
3079
3120
  { key: "owner", label: "OWNER" }
3080
3121
  ];
3081
3122
  var SKELETON_WIDTHS = ["72%", "56%", "84%", "44%", "64%"];
3123
+ var STACK_WIDTHS = [360, 400, 480, 520, 560, 600, 640, 720, 768, 800, 900, 960, 1024];
3082
3124
  var ROW_H_DEFAULT = 48;
3083
3125
  var OVERSCAN = 8;
3084
3126
  var FLEX_MIN = 160;
@@ -3099,11 +3141,20 @@ var DataTable = React28.forwardRef(function DataTable2(props, ref) {
3099
3141
  const selectable = !!props.selectable;
3100
3142
  const reorderable = props.reorderable !== false && !!props.columnControls;
3101
3143
  const controls = !!props.columnControls;
3102
- const sortState = useMaybeControlled(props.sort, props.defaultSort || null, props.onSortChange);
3144
+ const oneCallback = !!props.onStateChange;
3145
+ const sortState = useMaybeControlled(
3146
+ props.sort,
3147
+ props.defaultSort || null,
3148
+ oneCallback ? null : props.onSortChange
3149
+ );
3103
3150
  const sort = sortState[0], setSort = sortState[1];
3104
3151
  const selState = useMaybeControlled(props.selected, props.defaultSelected || [], props.onSelectionChange);
3105
3152
  const selected = selState[0], setSelected = selState[1];
3106
- const pageState = useMaybeControlled(props.page, props.defaultPage || 1, props.onPageChange);
3153
+ const pageState = useMaybeControlled(
3154
+ props.page,
3155
+ props.defaultPage || 1,
3156
+ oneCallback ? null : props.onPageChange
3157
+ );
3107
3158
  const orderState = useMaybeControlled(
3108
3159
  props.columnOrder,
3109
3160
  columns.map(function(c) {
@@ -3145,6 +3196,7 @@ var DataTable = React28.forwardRef(function DataTable2(props, ref) {
3145
3196
  const measure = !!props.stackBelow || columns.some(function(c) {
3146
3197
  return c.hideBelow != null;
3147
3198
  });
3199
+ const dual = !!props.stackBelow && boxWidth[0] == null && STACK_WIDTHS.indexOf(props.stackBelow) >= 0;
3148
3200
  React28.useEffect(
3149
3201
  function() {
3150
3202
  if (!measure || !wrapRef.current || typeof ResizeObserver === "undefined") return;
@@ -3156,9 +3208,15 @@ var DataTable = React28.forwardRef(function DataTable2(props, ref) {
3156
3208
  ro.disconnect();
3157
3209
  };
3158
3210
  },
3159
- [measure]
3211
+ [measure, dual]
3160
3212
  );
3161
3213
  const stacked = !!props.stackBelow && boxWidth[0] != null && boxWidth[0] < props.stackBelow;
3214
+ useIsoLayoutEffect(
3215
+ function() {
3216
+ if (measure && boxWidth[0] == null && wrapRef.current) boxWidth[1](wrapRef.current.getBoundingClientRect().width);
3217
+ },
3218
+ [measure]
3219
+ );
3162
3220
  function tooNarrow(c) {
3163
3221
  if (c.hideBelow == null || boxWidth[0] == null || stacked) return false;
3164
3222
  const px = typeof c.hideBelow === "number" ? c.hideBelow : BP[c.hideBelow];
@@ -3266,11 +3324,15 @@ var DataTable = React28.forwardRef(function DataTable2(props, ref) {
3266
3324
  const pageRows = pageSize && !manual ? view.slice(first, first + pageSize) : view;
3267
3325
  const canSortAny = !busy && (manual ? total > 1 : rows.length > 1);
3268
3326
  const shownTotal = manual && props.totalRows == null ? first + rows.length : total;
3269
- const linkPaging = !!props.getPageHref && !props.onPageChange;
3327
+ const linkPaging = !!props.getPageHref && !props.onPageChange && !oneCallback;
3270
3328
  const prevLink = React28.useRef(null), nextLink = React28.useRef(null);
3271
- function goPage(p, focus) {
3329
+ function emit(s, p) {
3330
+ if (props.onStateChange) props.onStateChange({ sort: s, page: p });
3331
+ }
3332
+ function goPage(p, focus, quiet) {
3272
3333
  const next = Math.min(Math.max(1, p), pageCount);
3273
3334
  if (next === page) return false;
3335
+ if (!quiet) emit(sort, next);
3274
3336
  if (linkPaging) {
3275
3337
  const a = next === page - 1 ? prevLink.current : next === page + 1 ? nextLink.current : null;
3276
3338
  if (a) a.click();
@@ -3282,8 +3344,12 @@ var DataTable = React28.forwardRef(function DataTable2(props, ref) {
3282
3344
  return true;
3283
3345
  }
3284
3346
  function sortBy(key) {
3285
- setSort(nextSort(key));
3286
- if (!(manual && linkPaging)) goPage(1);
3347
+ applySort(nextSort(key));
3348
+ }
3349
+ function applySort(s) {
3350
+ setSort(s);
3351
+ if (!(manual && linkPaging)) goPage(1, void 0, true);
3352
+ emit(s, 1);
3287
3353
  }
3288
3354
  const rowHref = props.getRowHref;
3289
3355
  function followRow(el, e) {
@@ -3498,16 +3564,14 @@ var DataTable = React28.forwardRef(function DataTable2(props, ref) {
3498
3564
  label: t.sortAsc,
3499
3565
  icon: "arrow-up",
3500
3566
  onSelect: function() {
3501
- setSort({ key: c.key, dir: "asc" });
3502
- goPage(1);
3567
+ applySort({ key: c.key, dir: "asc" });
3503
3568
  }
3504
3569
  },
3505
3570
  {
3506
3571
  label: t.sortDesc,
3507
3572
  icon: "arrow-down",
3508
3573
  onSelect: function() {
3509
- setSort({ key: c.key, dir: "desc" });
3510
- goPage(1);
3574
+ applySort({ key: c.key, dir: "desc" });
3511
3575
  }
3512
3576
  },
3513
3577
  { separator: true }
@@ -3944,9 +4008,10 @@ var DataTable = React28.forwardRef(function DataTable2(props, ref) {
3944
4008
  className: "aura-icon-btn",
3945
4009
  "aria-label": label,
3946
4010
  onClick: function(e) {
3947
- if (props.onPageChange) {
4011
+ if (props.onPageChange || oneCallback) {
3948
4012
  e.preventDefault();
3949
4013
  pageState[1](p);
4014
+ emit(sort, p);
3950
4015
  }
3951
4016
  }
3952
4017
  },
@@ -3970,7 +4035,7 @@ var DataTable = React28.forwardRef(function DataTable2(props, ref) {
3970
4035
  } else if (height && rows.length && !loading) {
3971
4036
  foot = /* @__PURE__ */ React28.createElement("div", { className: "aura-table__foot" }, /* @__PURE__ */ React28.createElement("span", null, t.rowCount(shownTotal)), selectable && selected.length ? /* @__PURE__ */ React28.createElement("span", null, t.selectedCount(selected.length)) : /* @__PURE__ */ React28.createElement("span", null));
3972
4037
  }
3973
- if (stacked) {
4038
+ function renderStacked(wrapRefArg) {
3974
4039
  const titleCol = vis[0], pillCol = vis.filter(function(c) {
3975
4040
  return c.pill && c !== titleCol;
3976
4041
  })[0];
@@ -4034,7 +4099,7 @@ var DataTable = React28.forwardRef(function DataTable2(props, ref) {
4034
4099
  return /* @__PURE__ */ React28.createElement(
4035
4100
  "div",
4036
4101
  {
4037
- ref: wrapMerged,
4102
+ ref: wrapRefArg,
4038
4103
  "data-density": props.density,
4039
4104
  className: cx("aura-table aura-table--stacked", refreshing && "is-refreshing", props.className),
4040
4105
  role: "region",
@@ -4055,15 +4120,16 @@ var DataTable = React28.forwardRef(function DataTable2(props, ref) {
4055
4120
  foot
4056
4121
  );
4057
4122
  }
4123
+ if (stacked) return renderStacked(wrapMerged);
4058
4124
  const scrollStyle = {
4059
4125
  scrollPaddingLeft: "calc(var(--aura-space-6)" + selW + " + " + acc + "px)",
4060
4126
  scrollPaddingTop: ROW_H + "px"
4061
4127
  };
4062
4128
  if (height) scrollStyle.height = height + "px";
4063
- return /* @__PURE__ */ React28.createElement(
4129
+ const gridEl = /* @__PURE__ */ React28.createElement(
4064
4130
  "div",
4065
4131
  {
4066
- ref: wrapMerged,
4132
+ ref: dual ? void 0 : wrapMerged,
4067
4133
  "data-density": props.density,
4068
4134
  className: cx("aura-table", scrolledX[0] && "is-scrolled-x", refreshing && "is-refreshing", props.className)
4069
4135
  },
@@ -4119,6 +4185,8 @@ var DataTable = React28.forwardRef(function DataTable2(props, ref) {
4119
4185
  }
4120
4186
  ) : null
4121
4187
  );
4188
+ if (!dual) return gridEl;
4189
+ return /* @__PURE__ */ React28.createElement("div", { ref: wrapMerged, className: "aura-table-dual", "data-stack-below": props.stackBelow }, renderStacked(void 0), gridEl);
4122
4190
  });
4123
4191
 
4124
4192
  // src/Card.tsx
@@ -4437,7 +4505,7 @@ var SideNav = React31.forwardRef(function SideNav2(props, ref) {
4437
4505
  var React32 = __toESM(require("react"), 1);
4438
4506
  var Breadcrumb = React32.forwardRef(function Breadcrumb2(props, ref) {
4439
4507
  const t = useStrings();
4440
- const Link = useLinkComponent();
4508
+ const Link = useLinkComponent(props.linkComponent);
4441
4509
  const items2 = props.items || [];
4442
4510
  return /* @__PURE__ */ React32.createElement("nav", { ref, "aria-label": props.label || t.breadcrumb, className: cx("aura-crumbs", props.className) }, /* @__PURE__ */ React32.createElement("ol", null, items2.map(function(it, i) {
4443
4511
  const last = i === items2.length - 1;
@@ -4486,7 +4554,11 @@ var React35 = __toESM(require("react"), 1);
4486
4554
 
4487
4555
  // src/responsive.tsx
4488
4556
  var React34 = __toESM(require("react"), 1);
4557
+
4558
+ // src/breakpoints.ts
4489
4559
  var breakpoints = { sm: 640, md: 768, lg: 1024, xl: 1280 };
4560
+
4561
+ // src/responsive.tsx
4490
4562
  var ORDER = ["base", "sm", "md", "lg", "xl"];
4491
4563
  function useBreakpoint() {
4492
4564
  return React34.useSyncExternalStore(subscribe, current, function() {
@@ -4580,26 +4652,25 @@ var React38 = __toESM(require("react"), 1);
4580
4652
  var AppShell = React38.forwardRef(function AppShell2(props, ref) {
4581
4653
  const t = useStrings();
4582
4654
  const bp = useBreakpoint();
4583
- const compact = bp === "base" || bp === "sm" || bp === "md";
4655
+ const wide = bp === "lg" || bp === "xl";
4584
4656
  const st = React38.useState(false), open = st[0], setOpen = st[1];
4585
4657
  React38.useEffect(
4586
4658
  function() {
4587
- if (!compact) setOpen(false);
4659
+ if (wide) setOpen(false);
4588
4660
  },
4589
- [compact]
4661
+ [wide]
4590
4662
  );
4591
- const navEl = props.nav;
4592
- const nav = props.nav && React38.isValidElement(props.nav) && compact ? React38.cloneElement(navEl, {
4663
+ const navEl = props.nav && React38.isValidElement(props.nav) ? props.nav : null;
4664
+ const drawerNav = navEl ? React38.cloneElement(navEl, {
4593
4665
  onChange: function(id) {
4594
4666
  if (navEl.props.onChange) navEl.props.onChange(id);
4595
4667
  setOpen(false);
4596
4668
  },
4597
4669
  className: cx(navEl.props.className, "is-in-drawer"),
4598
- /* The drawer is already full-size: never a rail, no collapse button. */
4599
4670
  collapsed: false,
4600
4671
  collapsible: false
4601
4672
  }) : props.nav;
4602
- return /* @__PURE__ */ React38.createElement("div", { ref, className: cx("aura-shell", compact && "is-compact", props.className) }, !compact ? /* @__PURE__ */ React38.createElement("div", { className: "aura-shell__nav" }, nav) : null, compact ? /* @__PURE__ */ React38.createElement(
4673
+ return /* @__PURE__ */ React38.createElement("div", { ref, className: cx("aura-shell", props.className) }, props.nav ? /* @__PURE__ */ React38.createElement("div", { className: "aura-shell__nav" }, props.nav) : null, props.nav ? /* @__PURE__ */ React38.createElement(
4603
4674
  Drawer,
4604
4675
  {
4605
4676
  open,
@@ -4611,10 +4682,11 @@ var AppShell = React38.forwardRef(function AppShell2(props, ref) {
4611
4682
  "aria-label": props.navLabel || t.navigation,
4612
4683
  dismissible: true
4613
4684
  },
4614
- nav
4615
- ) : null, /* @__PURE__ */ React38.createElement("div", { className: "aura-shell__main" }, props.header || compact ? /* @__PURE__ */ React38.createElement("header", { className: "aura-shell__bar" }, compact ? /* @__PURE__ */ React38.createElement(
4685
+ drawerNav
4686
+ ) : null, /* @__PURE__ */ React38.createElement("div", { className: "aura-shell__main" }, props.header || props.nav ? /* @__PURE__ */ React38.createElement("header", { className: cx("aura-shell__bar", !props.header && "aura-shell__bar--menu-only") }, props.nav ? /* @__PURE__ */ React38.createElement(
4616
4687
  IconButton,
4617
4688
  {
4689
+ className: "aura-shell__menu",
4618
4690
  icon: "menu",
4619
4691
  label: props.menuLabel || t.openNav,
4620
4692
  size: "md",
@@ -4655,7 +4727,7 @@ var Stat = React40.forwardRef(function Stat2(props, ref) {
4655
4727
  const ch = props.change;
4656
4728
  const dir = ch && (ch.direction || "flat");
4657
4729
  const tone2 = ch && (ch.tone || (dir === "up" ? "positive" : dir === "down" ? "negative" : "neutral"));
4658
- const Link = useLinkComponent();
4730
+ const Link = useLinkComponent(props.linkComponent);
4659
4731
  const v = props.value;
4660
4732
  const numeric = typeof v === "number" || typeof v === "string" && /\d/.test(v) && /^[\s\d.,:+\-\u2212%()\u0E3F$\u20AC\u00A3\u00A5kKmMbB]+$/.test(v.replace(/\b[A-Z]{3}\b/g, ""));
4661
4733
  const Tag3 = props.href ? Link : props.onClick ? "button" : "div";
@@ -4679,16 +4751,21 @@ var Stat = React40.forwardRef(function Stat2(props, ref) {
4679
4751
  // src/TimePicker.tsx
4680
4752
  var React41 = __toESM(require("react"), 1);
4681
4753
  var import_react_dom9 = require("react-dom");
4754
+
4755
+ // src/text.ts
4756
+ function formatBytes(n2) {
4757
+ if (n2 == null) return "";
4758
+ if (n2 < 1024) return n2 + " B";
4759
+ let u = ["KB", "MB", "GB"], i = -1;
4760
+ do {
4761
+ n2 /= 1024;
4762
+ i++;
4763
+ } while (n2 >= 1024 && i < u.length - 1);
4764
+ return (n2 >= 10 || Math.round(n2) === n2 ? Math.round(n2) : n2.toFixed(1)) + " " + u[i];
4765
+ }
4682
4766
  function pad2(n2) {
4683
4767
  return (n2 < 10 ? "0" : "") + n2;
4684
4768
  }
4685
- function toMin(t) {
4686
- const m = /^(\d{2}):(\d{2})$/.exec(t || "");
4687
- return m ? +m[1] * 60 + +m[2] : null;
4688
- }
4689
- function fromMin(n2) {
4690
- return pad2(Math.floor(n2 / 60)) + ":" + pad2(n2 % 60);
4691
- }
4692
4769
  function parseTime(text) {
4693
4770
  let s = String(text || "").trim().toLowerCase().replace(/\s*(น\.?|นาฬิกา)$/, "").trim();
4694
4771
  const pm = /\s*(pm|p\.m\.)$/.test(s), am = /\s*(am|a\.m\.)$/.test(s);
@@ -4701,6 +4778,18 @@ function parseTime(text) {
4701
4778
  if (hh > 23 || mm > 59) return null;
4702
4779
  return pad2(hh) + ":" + pad2(mm);
4703
4780
  }
4781
+
4782
+ // src/TimePicker.tsx
4783
+ function pad3(n2) {
4784
+ return (n2 < 10 ? "0" : "") + n2;
4785
+ }
4786
+ function toMin(t) {
4787
+ const m = /^(\d{2}):(\d{2})$/.exec(t || "");
4788
+ return m ? +m[1] * 60 + +m[2] : null;
4789
+ }
4790
+ function fromMin(n2) {
4791
+ return pad3(Math.floor(n2 / 60)) + ":" + pad3(n2 % 60);
4792
+ }
4704
4793
  var TimePicker = React41.forwardRef(function TimePicker2(props, ref) {
4705
4794
  const t = useStrings();
4706
4795
  const auto = uid(), id = props.id || auto, listId = id + "-list";
@@ -5001,16 +5090,6 @@ var TimePicker = React41.forwardRef(function TimePicker2(props, ref) {
5001
5090
 
5002
5091
  // src/FileUpload.tsx
5003
5092
  var React42 = __toESM(require("react"), 1);
5004
- function formatBytes(n2) {
5005
- if (n2 == null) return "";
5006
- if (n2 < 1024) return n2 + " B";
5007
- let u = ["KB", "MB", "GB"], i = -1;
5008
- do {
5009
- n2 /= 1024;
5010
- i++;
5011
- } while (n2 >= 1024 && i < u.length - 1);
5012
- return (n2 >= 10 || Math.round(n2) === n2 ? Math.round(n2) : n2.toFixed(1)) + " " + u[i];
5013
- }
5014
5093
  function matches(file, accept) {
5015
5094
  if (!accept) return true;
5016
5095
  const name = (file.name || "").toLowerCase(), type = (file.type || "").toLowerCase();
@@ -5469,6 +5548,8 @@ function ThemeStyle(props) {
5469
5548
 
5470
5549
  // src/colorScheme.tsx
5471
5550
  var React44 = __toESM(require("react"), 1);
5551
+
5552
+ // src/colorSchemeScript.ts
5472
5553
  var DEFAULT_KEY = "aura-color-scheme";
5473
5554
  var SCHEMES = ["light", "dark", "system"];
5474
5555
  var EVENT = "aura-color-scheme";
@@ -5480,6 +5561,8 @@ function colorSchemeScript(options) {
5480
5561
  const fallback = JSON.stringify(options && options.defaultScheme || "system");
5481
5562
  return "(function(){try{var s=localStorage.getItem(" + key + ");if(s!=='light'&&s!=='dark'&&s!=='system')s=" + fallback + `;var d=document.documentElement;d.setAttribute("data-theme",s);var dark=s==='dark'||(s==='system'&&window.matchMedia('(prefers-color-scheme: dark)').matches);d.classList.toggle("dark",dark);}catch(e){}})();`;
5482
5563
  }
5564
+
5565
+ // src/colorScheme.tsx
5483
5566
  function ColorSchemeScript(props) {
5484
5567
  return /* @__PURE__ */ React44.createElement(
5485
5568
  "script",
@@ -5650,7 +5733,10 @@ var Skeleton = React47.forwardRef(function Skeleton2(props, ref) {
5650
5733
  rows
5651
5734
  );
5652
5735
  }
5653
- const style = { width: props.width, height: props.height };
5736
+ const style = {
5737
+ width: props.width,
5738
+ height: props.height
5739
+ };
5654
5740
  if (v === "circle") {
5655
5741
  style.width = style.height = props.size || props.width || 40;
5656
5742
  }
@@ -5704,7 +5790,7 @@ var Pagination = React49.forwardRef(function Pagination2(props, ref) {
5704
5790
  if (p >= 1 && p <= count && p !== page) st[1](p);
5705
5791
  }
5706
5792
  const link = props.getHref;
5707
- const Link = useLinkComponent();
5793
+ const Link = useLinkComponent(props.linkComponent);
5708
5794
  function item(p, label, extra) {
5709
5795
  const common = Object.assign(
5710
5796
  {
@@ -5739,29 +5825,40 @@ var Pagination = React49.forwardRef(function Pagination2(props, ref) {
5739
5825
  label
5740
5826
  );
5741
5827
  }
5742
- return /* @__PURE__ */ React49.createElement("nav", { ref, className: cx("aura-pagination", props.className), "aria-label": props.label || t.pagination }, /* @__PURE__ */ React49.createElement(
5743
- IconButton,
5744
- {
5745
- icon: "chevron-left",
5746
- label: t.prevPage,
5747
- disabled: page <= 1,
5748
- onClick: function() {
5749
- go(page - 1);
5750
- }
5751
- }
5752
- ), /* @__PURE__ */ React49.createElement("ol", { className: "aura-pagination__list" }, pageList(page, count, props.siblingCount == null ? 1 : props.siblingCount).map(function(p) {
5828
+ function arrow(p, icon, label, rel, disabled) {
5829
+ if (!link || disabled)
5830
+ return /* @__PURE__ */ React49.createElement(
5831
+ IconButton,
5832
+ {
5833
+ icon,
5834
+ label,
5835
+ disabled,
5836
+ onClick: function() {
5837
+ go(p);
5838
+ }
5839
+ }
5840
+ );
5841
+ return /* @__PURE__ */ React49.createElement(
5842
+ Link,
5843
+ {
5844
+ href: link(p),
5845
+ rel,
5846
+ className: "aura-icon-btn",
5847
+ "aria-label": label,
5848
+ title: label,
5849
+ onClick: function(e) {
5850
+ if (props.onChange) {
5851
+ e.preventDefault();
5852
+ go(p);
5853
+ }
5854
+ }
5855
+ },
5856
+ /* @__PURE__ */ React49.createElement(Icon, { name: icon, size: "sm" })
5857
+ );
5858
+ }
5859
+ return /* @__PURE__ */ React49.createElement("nav", { ref, className: cx("aura-pagination", props.className), "aria-label": props.label || t.pagination }, arrow(page - 1, "chevron-left", t.prevPage, "prev", page <= 1), /* @__PURE__ */ React49.createElement("ol", { className: "aura-pagination__list" }, pageList(page, count, props.siblingCount == null ? 1 : props.siblingCount).map(function(p) {
5753
5860
  return typeof p === "number" ? /* @__PURE__ */ React49.createElement("li", { key: p }, item(p, p)) : /* @__PURE__ */ React49.createElement("li", { key: p, className: "aura-pagination__gap", "aria-hidden": true }, "\u2026");
5754
- })), /* @__PURE__ */ React49.createElement("span", { className: "aura-pagination__compact", "aria-hidden": true }, t.page(page, count)), /* @__PURE__ */ React49.createElement(
5755
- IconButton,
5756
- {
5757
- icon: "chevron-right",
5758
- label: t.nextPage,
5759
- disabled: page >= count,
5760
- onClick: function() {
5761
- go(page + 1);
5762
- }
5763
- }
5764
- ));
5861
+ })), /* @__PURE__ */ React49.createElement("span", { className: "aura-pagination__compact", "aria-hidden": true }, t.page(page, count)), arrow(page + 1, "chevron-right", t.nextPage, "next", page >= count));
5765
5862
  });
5766
5863
 
5767
5864
  // src/Accordion.tsx