@jirawatpyk/aura-react 5.1.0 → 5.2.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.
Files changed (48) hide show
  1. package/README.md +10 -0
  2. package/dist/aura.bundle.js +562 -183
  3. package/dist/cjs/index.cjs +562 -183
  4. package/dist/esm/AppShell.js +10 -2
  5. package/dist/esm/Avatar.js +4 -3
  6. package/dist/esm/BottomNav.js +2 -1
  7. package/dist/esm/Checkbox.js +3 -2
  8. package/dist/esm/Combobox.js +19 -19
  9. package/dist/esm/Command.js +1 -0
  10. package/dist/esm/DataTable.js +116 -29
  11. package/dist/esm/DatePicker.js +85 -22
  12. package/dist/esm/DropdownMenu.js +12 -0
  13. package/dist/esm/FileUpload.js +17 -1
  14. package/dist/esm/FormErrorSummary.js +19 -4
  15. package/dist/esm/Menu.js +20 -7
  16. package/dist/esm/NumberField.js +3 -1
  17. package/dist/esm/Pagination.js +3 -3
  18. package/dist/esm/Popover.js +26 -5
  19. package/dist/esm/RadioGroup.js +14 -1
  20. package/dist/esm/SideNav.js +2 -1
  21. package/dist/esm/Switch.js +1 -1
  22. package/dist/esm/Table.js +3 -2
  23. package/dist/esm/Tabs.js +11 -7
  24. package/dist/esm/TextField.js +2 -2
  25. package/dist/esm/Textarea.js +2 -2
  26. package/dist/esm/ThemeStyle.js +13 -3
  27. package/dist/esm/TimePicker.js +2 -1
  28. package/dist/esm/Toaster.js +1 -0
  29. package/dist/esm/Tooltip.js +54 -29
  30. package/dist/esm/colorScheme.js +7 -3
  31. package/dist/esm/colorSchemeScript.js +3 -3
  32. package/dist/esm/dates.js +34 -13
  33. package/dist/esm/internal.js +18 -7
  34. package/dist/esm/locale.js +6 -5
  35. package/dist/esm/strings.js +21 -0
  36. package/dist/esm/text.js +1 -0
  37. package/dist/esm/theme.js +3 -1
  38. package/dist/esm/useModal.js +31 -8
  39. package/dist/index.d.cts +1513 -0
  40. package/dist/index.d.ts +6 -1
  41. package/dist/server/index.cjs +51 -10
  42. package/dist/server/index.d.cts +182 -0
  43. package/dist/server/index.d.ts +6 -0
  44. package/dist/server/index.js +51 -10
  45. package/dist/styles.css +26 -5
  46. package/dist/styles.layer.css +26 -5
  47. package/package.json +19 -8
  48. package/scripts/aura-theme.mjs +31 -6
@@ -156,14 +156,21 @@ window.Aura = (() => {
156
156
  }
157
157
  function useMaybeControlled(value, initial, onChange) {
158
158
  const s = React.useState(initial);
159
+ const wasSet = React.useState(value !== void 0);
160
+ if (value !== void 0 && !wasSet[0]) wasSet[1](true);
161
+ else if (value === void 0 && wasSet[0]) {
162
+ wasSet[1](false);
163
+ s[1](initial);
164
+ }
159
165
  const controlled = value !== void 0;
160
- return [
161
- controlled ? value : s[0],
162
- function(next) {
163
- if (!controlled) s[1](next);
164
- if (onChange) onChange(next);
165
- }
166
- ];
166
+ const latest = React.useRef({ controlled, onChange, set: s[1] });
167
+ latest.current = { controlled, onChange, set: s[1] };
168
+ const set = React.useCallback(function(next) {
169
+ const l = latest.current;
170
+ if (!l.controlled) l.set(next);
171
+ if (l.onChange) l.onChange(next);
172
+ }, []);
173
+ return [controlled ? value : s[0], set];
167
174
  }
168
175
  var collator = typeof Intl !== "undefined" ? new Intl.Collator(["th", "en"], { numeric: true, sensitivity: "base" }) : null;
169
176
  function compare(a, b) {
@@ -228,6 +235,9 @@ window.Aura = (() => {
228
235
  return TONES.indexOf(t) >= 0 ? t : "neutral";
229
236
  }
230
237
  var warned = {};
238
+ function plainClick(e) {
239
+ return !e.defaultPrevented && e.button === 0 && !e.metaKey && !e.ctrlKey && !e.shiftKey && !e.altKey;
240
+ }
231
241
  function devWarnOnce(key, message) {
232
242
  if (warned[key]) return;
233
243
  let dev = false;
@@ -368,6 +378,12 @@ window.Aura = (() => {
368
378
  page: function(p, total) {
369
379
  return "Page " + p + " of " + total;
370
380
  },
381
+ rangeOpen: function(a, b) {
382
+ return a + "\u2013" + b + " of many";
383
+ },
384
+ pageOpen: function(p) {
385
+ return "Page " + p;
386
+ },
371
387
  prevPage: "Previous page",
372
388
  nextPage: "Next page",
373
389
  totals: "Totals",
@@ -381,6 +397,7 @@ window.Aura = (() => {
381
397
  timeOutOfRange: function(a, b) {
382
398
  return "Choose a time between " + a + " and " + b;
383
399
  },
400
+ timeUnavailable: "That time isn't available. Choose another.",
384
401
  dropFiles: "Drag files here or",
385
402
  browse: "Choose files",
386
403
  browseOne: "Choose a file",
@@ -482,6 +499,12 @@ window.Aura = (() => {
482
499
  page: function(p, total) {
483
500
  return "\u0E2B\u0E19\u0E49\u0E32 " + p + " / " + total;
484
501
  },
502
+ rangeOpen: function(a, b) {
503
+ return a + "\u2013" + b + " \u0E08\u0E32\u0E01\u0E2B\u0E25\u0E32\u0E22\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23";
504
+ },
505
+ pageOpen: function(p) {
506
+ return "\u0E2B\u0E19\u0E49\u0E32 " + p;
507
+ },
485
508
  prevPage: "\u0E2B\u0E19\u0E49\u0E32\u0E01\u0E48\u0E2D\u0E19\u0E2B\u0E19\u0E49\u0E32",
486
509
  nextPage: "\u0E2B\u0E19\u0E49\u0E32\u0E16\u0E31\u0E14\u0E44\u0E1B",
487
510
  totals: "\u0E23\u0E27\u0E21",
@@ -495,6 +518,7 @@ window.Aura = (() => {
495
518
  timeOutOfRange: function(a, b) {
496
519
  return "\u0E40\u0E25\u0E37\u0E2D\u0E01\u0E40\u0E27\u0E25\u0E32\u0E23\u0E30\u0E2B\u0E27\u0E48\u0E32\u0E07 " + a + "\u2013" + b + " \u0E19.";
497
520
  },
521
+ timeUnavailable: "\u0E40\u0E27\u0E25\u0E32\u0E19\u0E35\u0E49\u0E44\u0E21\u0E48\u0E27\u0E48\u0E32\u0E07 \u0E40\u0E25\u0E37\u0E2D\u0E01\u0E40\u0E27\u0E25\u0E32\u0E2D\u0E37\u0E48\u0E19",
498
522
  dropFiles: "\u0E25\u0E32\u0E01\u0E44\u0E1F\u0E25\u0E4C\u0E21\u0E32\u0E27\u0E32\u0E07 \u0E2B\u0E23\u0E37\u0E2D",
499
523
  browse: "\u0E40\u0E25\u0E37\u0E2D\u0E01\u0E44\u0E1F\u0E25\u0E4C",
500
524
  browseOne: "\u0E40\u0E25\u0E37\u0E2D\u0E01\u0E44\u0E1F\u0E25\u0E4C",
@@ -596,6 +620,12 @@ window.Aura = (() => {
596
620
  page: function(p, total) {
597
621
  return "Sida " + p + " av " + total;
598
622
  },
623
+ rangeOpen: function(a, b) {
624
+ return a + "\u2013" + b + " av m\xE5nga";
625
+ },
626
+ pageOpen: function(p) {
627
+ return "Sida " + p;
628
+ },
599
629
  prevPage: "F\xF6reg\xE5ende sida",
600
630
  nextPage: "N\xE4sta sida",
601
631
  totals: "Summa",
@@ -609,6 +639,7 @@ window.Aura = (() => {
609
639
  timeOutOfRange: function(a, b) {
610
640
  return "V\xE4lj en tid mellan " + a + " och " + b;
611
641
  },
642
+ timeUnavailable: "Den tiden \xE4r inte ledig. V\xE4lj en annan.",
612
643
  dropFiles: "Dra filer hit eller",
613
644
  browse: "V\xE4lj filer",
614
645
  browseOne: "V\xE4lj en fil",
@@ -652,17 +683,18 @@ window.Aura = (() => {
652
683
  const timeZone = props.timeZone || outer && outer.timeZone || null;
653
684
  const value = React3.useMemo(
654
685
  function() {
655
- const base = props.locale && STRINGS[props.locale] || STRINGS.en;
686
+ const own = !!props.locale || !outer || !outer.locale;
687
+ const base = own ? props.locale && STRINGS[props.locale] || STRINGS.en : outer.strings;
656
688
  return {
657
- locale: props.locale || "en",
658
- calendar: props.calendar || null,
689
+ locale: props.locale || outer && outer.locale || "en",
690
+ calendar: props.calendar || (own ? null : outer.calendar),
659
691
  strings: props.strings ? Object.assign({}, base, props.strings) : base,
660
- linkComponent: props.linkComponent || null,
692
+ linkComponent: props.linkComponent || outer && outer.linkComponent || null,
661
693
  density,
662
694
  timeZone
663
695
  };
664
696
  },
665
- [props.locale, props.calendar, props.strings, props.linkComponent, density, timeZone]
697
+ [props.locale, props.calendar, props.strings, props.linkComponent, density, timeZone, outer]
666
698
  );
667
699
  return /* @__PURE__ */ React3.createElement(LocaleContext.Provider, { value }, props.density ? /* @__PURE__ */ React3.createElement("div", { className: "aura-density", "data-density": props.density }, props.children) : props.children);
668
700
  }
@@ -801,11 +833,17 @@ window.Aura = (() => {
801
833
  function() {
802
834
  const a = props.anchor, m = own.current;
803
835
  if (!a || !m) return;
804
- const r = a.getBoundingClientRect(), mh = m.offsetHeight, mw = m.offsetWidth;
805
- let top = r.bottom + 4;
806
- if (top + mh > window.innerHeight - 8 && r.top - mh - 4 > 8) top = r.top - mh - 4;
836
+ const r = a.getBoundingClientRect(), mh = m.scrollHeight, mw = m.offsetWidth, below2 = window.innerHeight - r.bottom - 12, above = r.top - 12;
837
+ let top = r.bottom + 4, maxHeight;
838
+ if (mh > below2) {
839
+ if (mh <= above) top = r.top - mh - 4;
840
+ else if (above > below2) {
841
+ maxHeight = above;
842
+ top = r.top - above - 4;
843
+ } else maxHeight = below2;
844
+ }
807
845
  const left = Math.max(8, Math.min(r.right - mw, window.innerWidth - mw - 8));
808
- setPos({ top, left });
846
+ setPos({ top, left, maxHeight });
809
847
  },
810
848
  [props.anchor, mounted]
811
849
  );
@@ -849,6 +887,9 @@ window.Aura = (() => {
849
887
  } else if (e.key === "End") {
850
888
  e.preventDefault();
851
889
  list[list.length - 1].focus();
890
+ } else if (e.key === " " && document.activeElement && document.activeElement.tagName === "A") {
891
+ e.preventDefault();
892
+ document.activeElement.click();
852
893
  } else if (e.key === "Escape") {
853
894
  e.preventDefault();
854
895
  props.onClose(true);
@@ -889,9 +930,9 @@ window.Aura = (() => {
889
930
  tabIndex: -1,
890
931
  role: "menuitem",
891
932
  className: cls,
892
- onClick: function() {
933
+ onClick: function(e) {
893
934
  if (it.onSelect) it.onSelect();
894
- props.onClose(false);
935
+ props.onClose(e.detail === 0);
895
936
  }
896
937
  },
897
938
  body
@@ -922,7 +963,11 @@ window.Aura = (() => {
922
963
  "aria-label": props.label,
923
964
  className: "aura-menu",
924
965
  onKeyDown,
925
- style: { top: pos ? pos.top : -9999, left: pos ? pos.left : -9999 }
966
+ style: {
967
+ top: pos ? pos.top : -9999,
968
+ left: pos ? pos.left : -9999,
969
+ maxHeight: pos && pos.maxHeight ? pos.maxHeight : void 0
970
+ }
926
971
  },
927
972
  groupItems(items2).map(function(block, bi) {
928
973
  const rendered = block.items.map(function(x) {
@@ -940,6 +985,16 @@ window.Aura = (() => {
940
985
  const st = React7.useState(null), anchor = st[0], setAnchor = st[1];
941
986
  const wrap = React7.useRef(null), wrapMerged = useMergedRef(ref, wrap);
942
987
  const child = React7.Children.only(props.trigger);
988
+ const menuRef = React7.useRef(null), toLast = React7.useRef(false);
989
+ React7.useEffect(
990
+ function() {
991
+ if (!anchor || !toLast.current || !menuRef.current) return;
992
+ toLast.current = false;
993
+ const list = menuRef.current.querySelectorAll('[role^="menuitem"]:not([disabled])');
994
+ if (list.length) list[list.length - 1].focus();
995
+ },
996
+ [anchor]
997
+ );
943
998
  function toggle(e) {
944
999
  if (child.props.onClick) child.props.onClick(e);
945
1000
  const el = wrap.current && (wrap.current.querySelector('button, [role="button"], a') || wrap.current);
@@ -948,12 +1003,14 @@ window.Aura = (() => {
948
1003
  function onKeyDown(e) {
949
1004
  if ((e.key === "ArrowDown" || e.key === "ArrowUp") && !anchor) {
950
1005
  e.preventDefault();
1006
+ toLast.current = e.key === "ArrowUp";
951
1007
  setAnchor(wrap.current.querySelector('button, [role="button"], a') || wrap.current);
952
1008
  }
953
1009
  }
954
1010
  return /* @__PURE__ */ React7.createElement("span", { ref: wrapMerged, className: "aura-dropdown", onKeyDown }, React7.cloneElement(child, { onClick: toggle, "aria-haspopup": "menu", "aria-expanded": anchor ? true : false }), anchor ? /* @__PURE__ */ React7.createElement(
955
1011
  Menu,
956
1012
  {
1013
+ ref: menuRef,
957
1014
  anchor,
958
1015
  label: props.label,
959
1016
  items: props.items,
@@ -972,6 +1029,7 @@ window.Aura = (() => {
972
1029
  const own = React8.useRef(null), merged = useMergedRef(ref, own);
973
1030
  const st = useMaybeControlled(props.checked, !!props.defaultChecked, props.onChange);
974
1031
  const on = !!st[0];
1032
+ const auto = uid();
975
1033
  React8.useEffect(function() {
976
1034
  if (own.current) own.current.indeterminate = !!props.indeterminate;
977
1035
  });
@@ -995,7 +1053,7 @@ window.Aura = (() => {
995
1053
  "checkbox-label",
996
1054
  "Checkbox `label` is only the accessible name: it is not shown. In 6.0 it will be shown beside the box, like Switch and TextField. For visible text now pass it as children; for a bare box (a table row) add `hideLabel`."
997
1055
  );
998
- const descId = props.description && props.id ? props.id + "-desc" : void 0;
1056
+ const descId = props.description ? (props.id || auto) + "-desc" : void 0;
999
1057
  return /* @__PURE__ */ React8.createElement(
1000
1058
  "label",
1001
1059
  {
@@ -1123,8 +1181,8 @@ window.Aura = (() => {
1123
1181
  className: "aura-input__control",
1124
1182
  placeholder: props.placeholder,
1125
1183
  required: props.required,
1126
- "aria-invalid": props.error ? true : void 0,
1127
- "aria-describedby": describedBy(id, props)
1184
+ "aria-invalid": props.error ? true : rest["aria-invalid"],
1185
+ "aria-describedby": [describedBy(id, props), rest["aria-describedby"]].filter(Boolean).join(" ") || void 0
1128
1186
  }
1129
1187
  ), props.suffix ? /* @__PURE__ */ React11.createElement("span", { className: "aura-input__suffix" }, props.suffix) : null)
1130
1188
  );
@@ -1157,8 +1215,8 @@ window.Aura = (() => {
1157
1215
  className: "aura-input aura-textarea",
1158
1216
  placeholder: props.placeholder,
1159
1217
  required: props.required,
1160
- "aria-invalid": props.error ? true : void 0,
1161
- "aria-describedby": describedBy(id, props)
1218
+ "aria-invalid": props.error ? true : rest["aria-invalid"],
1219
+ "aria-describedby": [describedBy(id, props), rest["aria-describedby"]].filter(Boolean).join(" ") || void 0
1162
1220
  }
1163
1221
  )
1164
1222
  );
@@ -1217,10 +1275,22 @@ window.Aura = (() => {
1217
1275
  props.onChange
1218
1276
  );
1219
1277
  const name = props.name || id;
1278
+ const setRef = React14.useCallback(
1279
+ function(el) {
1280
+ if (el)
1281
+ el.focus = function(opts) {
1282
+ const r = el.querySelector('input[type="radio"]:checked') || el.querySelector('input[type="radio"]:not(:disabled)');
1283
+ if (r) r.focus(opts);
1284
+ };
1285
+ if (typeof ref === "function") ref(el);
1286
+ else if (ref) ref.current = el;
1287
+ },
1288
+ [ref]
1289
+ );
1220
1290
  return /* @__PURE__ */ React14.createElement(
1221
1291
  "fieldset",
1222
1292
  {
1223
- ref,
1293
+ ref: setRef,
1224
1294
  className: cx("aura-field aura-radio-group", props.error && "is-invalid", props.className),
1225
1295
  "aria-describedby": describedBy(id, props),
1226
1296
  "aria-invalid": props.error ? true : void 0,
@@ -1237,6 +1307,7 @@ window.Aura = (() => {
1237
1307
  name,
1238
1308
  value: v.value,
1239
1309
  disabled: v.disabled,
1310
+ required: props.required || void 0,
1240
1311
  checked: st[0] === v.value,
1241
1312
  onChange: function() {
1242
1313
  st[1](v.value);
@@ -1283,7 +1354,7 @@ window.Aura = (() => {
1283
1354
  },
1284
1355
  /* @__PURE__ */ React15.createElement("span", { className: "aura-switch__thumb" })
1285
1356
  ),
1286
- props.label ? /* @__PURE__ */ React15.createElement("span", { className: "aura-choice__text" }, /* @__PURE__ */ React15.createElement("label", { className: "aura-choice__label", id: id + "-label", htmlFor: id }, props.label), props.description ? /* @__PURE__ */ React15.createElement("span", { className: "aura-choice__desc", id: id + "-desc" }, props.description) : null) : null
1357
+ props.label ? /* @__PURE__ */ React15.createElement("span", { className: "aura-choice__text" }, /* @__PURE__ */ React15.createElement("label", { className: "aura-choice__label", id: id + "-label", htmlFor: id }, props.label), props.description ? /* @__PURE__ */ React15.createElement("span", { className: "aura-choice__desc", id: id + "-desc" }, props.description) : null) : props.description ? /* @__PURE__ */ React15.createElement("span", { className: "aura-sr-only", id: id + "-desc" }, props.description) : null
1287
1358
  );
1288
1359
  });
1289
1360
 
@@ -1367,7 +1438,7 @@ window.Aura = (() => {
1367
1438
  function() {
1368
1439
  if (open) place();
1369
1440
  },
1370
- [open, shown.length]
1441
+ [open, shown.length, values.length]
1371
1442
  );
1372
1443
  React16.useEffect(
1373
1444
  function() {
@@ -1399,6 +1470,7 @@ window.Aura = (() => {
1399
1470
  },
1400
1471
  [activeIdx, open]
1401
1472
  );
1473
+ const live = props.loading ? [] : shown;
1402
1474
  function openList() {
1403
1475
  if (!open && !props.disabled && !props.readOnly) {
1404
1476
  setOpen(true);
@@ -1434,7 +1506,7 @@ window.Aura = (() => {
1434
1506
  if (k === "ArrowDown") {
1435
1507
  e.preventDefault();
1436
1508
  if (!open) openList();
1437
- else setActive(Math.min(activeIdx + 1, shown.length - 1));
1509
+ else setActive(Math.max(0, Math.min(activeIdx + 1, live.length - 1)));
1438
1510
  } else if (k === "ArrowUp") {
1439
1511
  e.preventDefault();
1440
1512
  if (!open) openList();
@@ -1444,21 +1516,22 @@ window.Aura = (() => {
1444
1516
  setActive(0);
1445
1517
  } else if (k === "End" && open) {
1446
1518
  e.preventDefault();
1447
- setActive(shown.length - 1);
1519
+ setActive(Math.max(0, live.length - 1));
1448
1520
  } else if (k === "Enter") {
1449
- if (open && shown[activeIdx]) {
1521
+ if (e.nativeEvent.isComposing || e.keyCode === 229) return;
1522
+ if (open && live[activeIdx]) {
1450
1523
  e.preventDefault();
1451
- choose(shown[activeIdx]);
1524
+ choose(live[activeIdx]);
1452
1525
  }
1453
1526
  } else if (k === "Escape") {
1454
1527
  if (open) {
1455
1528
  e.preventDefault();
1456
1529
  e.stopPropagation();
1457
1530
  close();
1458
- } else if (!multi && props.clearable !== false && value != null && query == null) {
1531
+ } else if (!multi && !props.readOnly && props.clearable !== false && value != null && query == null) {
1459
1532
  setValue(null);
1460
1533
  }
1461
- } else if (k === "Backspace" && multi && !text && values.length) {
1534
+ } else if (k === "Backspace" && multi && !props.readOnly && !text && values.length) {
1462
1535
  setValues(values.slice(0, -1));
1463
1536
  } else if (k === "Tab") {
1464
1537
  if (open) close();
@@ -1470,7 +1543,7 @@ window.Aura = (() => {
1470
1543
  return id + "-opt-" + i;
1471
1544
  };
1472
1545
  const list = open && mounted && posState[0] ? (0, import_react_dom2.createPortal)(
1473
- /* @__PURE__ */ React16.createElement("div", { ref: listRef, className: "aura-combo__popover", style: posState[0] }, /* @__PURE__ */ React16.createElement(
1546
+ /* @__PURE__ */ React16.createElement("div", { ref: listRef, className: "aura-combo__popover", style: posState[0] }, live.length ? /* @__PURE__ */ React16.createElement(
1474
1547
  "ul",
1475
1548
  {
1476
1549
  id: listId,
@@ -1479,7 +1552,7 @@ window.Aura = (() => {
1479
1552
  "aria-multiselectable": multi || void 0,
1480
1553
  className: "aura-combo__list"
1481
1554
  },
1482
- props.loading ? /* @__PURE__ */ React16.createElement("li", { className: "aura-combo__note", role: "presentation" }, /* @__PURE__ */ React16.createElement(Icon, { name: "loader-circle", className: "aura-spin" }), props.loadingText || t.searching) : !shown.length ? /* @__PURE__ */ React16.createElement("li", { className: "aura-combo__note", role: "presentation" }, props.emptyText || t.noMatches) : shown.map(function(o, i) {
1555
+ live.map(function(o, i) {
1483
1556
  const isSel = multi ? isPicked(o.value) : !!selected && o.value === selected.value;
1484
1557
  const blocked = o.disabled || multi && full && !isSel;
1485
1558
  return /* @__PURE__ */ React16.createElement(
@@ -1511,9 +1584,8 @@ window.Aura = (() => {
1511
1584
  /* @__PURE__ */ React16.createElement("span", { className: "aura-combo__text" }, /* @__PURE__ */ React16.createElement("span", { className: "aura-combo__label" }, o.label), o.description ? /* @__PURE__ */ React16.createElement("span", { className: "aura-combo__desc" }, o.description) : null),
1512
1585
  isSel ? /* @__PURE__ */ React16.createElement(Icon, { name: "check", className: "aura-combo__check" }) : null
1513
1586
  );
1514
- }),
1515
- more && !props.loading ? /* @__PURE__ */ React16.createElement("li", { className: "aura-combo__note", role: "presentation" }, t.keepTyping((props.options || []).length)) : null
1516
- )),
1587
+ })
1588
+ ) : null, props.loading || !live.length || more ? /* @__PURE__ */ React16.createElement("div", { className: "aura-combo__list", role: "status" }, props.loading ? /* @__PURE__ */ React16.createElement("div", { className: "aura-combo__note" }, /* @__PURE__ */ React16.createElement(Icon, { name: "loader-circle", className: "aura-spin" }), props.loadingText || t.searching) : !live.length ? /* @__PURE__ */ React16.createElement("div", { className: "aura-combo__note" }, props.emptyText || t.noMatches) : /* @__PURE__ */ React16.createElement("div", { className: "aura-combo__note" }, t.keepTyping((props.options || []).length))) : null),
1517
1589
  document.body
1518
1590
  ) : null;
1519
1591
  return /* @__PURE__ */ React16.createElement(
@@ -1552,9 +1624,9 @@ window.Aura = (() => {
1552
1624
  ));
1553
1625
  })) : null, multi ? /* @__PURE__ */ React16.createElement("span", { id: summaryId, className: "aura-sr-only" }, picked.length ? t.selectedCount(picked.length) + ": " + picked.map(function(o) {
1554
1626
  return o.label;
1555
- }).join(", ") : "") : null, multi && props.name ? values.map(function(v) {
1627
+ }).join(", ") : "") : null, props.name ? multi ? values.map(function(v) {
1556
1628
  return /* @__PURE__ */ React16.createElement("input", { key: v, type: "hidden", name: props.name, value: v });
1557
- }) : null, /* @__PURE__ */ React16.createElement(
1629
+ }) : /* @__PURE__ */ React16.createElement("input", { type: "hidden", name: props.name, value: value == null ? "" : value }) : null, /* @__PURE__ */ React16.createElement(
1558
1630
  "input",
1559
1631
  {
1560
1632
  ref: inputMerged,
@@ -1563,17 +1635,16 @@ window.Aura = (() => {
1563
1635
  role: "combobox",
1564
1636
  className: "aura-input__control",
1565
1637
  autoComplete: "off",
1566
- "aria-expanded": open,
1567
- "aria-controls": listId,
1638
+ "aria-expanded": open && live.length > 0,
1639
+ "aria-controls": open && live.length ? listId : void 0,
1568
1640
  "aria-autocomplete": "list",
1569
- "aria-activedescendant": open && shown[activeIdx] ? optId(activeIdx) : void 0,
1641
+ "aria-activedescendant": open && live[activeIdx] ? optId(activeIdx) : void 0,
1570
1642
  "aria-invalid": props.error ? true : void 0,
1571
1643
  "aria-describedby": [props.error ? id + "-error" : props.hint ? id + "-hint" : "", multi && picked.length ? summaryId : ""].filter(Boolean).join(" ") || void 0,
1572
1644
  placeholder: multi && values.length ? void 0 : props.placeholder,
1573
1645
  disabled: props.disabled,
1574
1646
  readOnly: props.readOnly,
1575
1647
  required: props.required && (!multi || !values.length),
1576
- name: multi ? void 0 : props.name,
1577
1648
  value: text,
1578
1649
  onChange: function(e) {
1579
1650
  setQuery(e.target.value);
@@ -1591,7 +1662,7 @@ window.Aura = (() => {
1591
1662
  }, 0);
1592
1663
  }
1593
1664
  }
1594
- ), props.clearable !== false && values.length && !props.disabled ? /* @__PURE__ */ React16.createElement(
1665
+ ), props.clearable !== false && values.length && !props.disabled && !props.readOnly ? /* @__PURE__ */ React16.createElement(
1595
1666
  "button",
1596
1667
  {
1597
1668
  type: "button",
@@ -1640,20 +1711,29 @@ window.Aura = (() => {
1640
1711
  return (n2 < 10 ? "0" : "") + n2;
1641
1712
  };
1642
1713
  function toISO(d) {
1643
- return d ? d.getFullYear() + "-" + pad(d.getMonth() + 1) + "-" + pad(d.getDate()) : null;
1714
+ if (!d) return null;
1715
+ const y = String(d.getFullYear());
1716
+ return ("000" + y).slice(-Math.max(4, y.length)) + "-" + pad(d.getMonth() + 1) + "-" + pad(d.getDate());
1717
+ }
1718
+ function makeDate(y, monthIndex2, day) {
1719
+ const d = new Date(2e3, 0, 1);
1720
+ d.setFullYear(y, monthIndex2, day);
1721
+ return d;
1644
1722
  }
1645
1723
  function fromISO(s) {
1646
1724
  if (!s) return null;
1647
1725
  const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(s);
1648
- return m ? new Date(+m[1], +m[2] - 1, +m[3]) : null;
1726
+ if (!m) return null;
1727
+ const d = makeDate(+m[1], +m[2] - 1, +m[3]);
1728
+ return d.getMonth() === +m[2] - 1 && d.getDate() === +m[3] ? d : null;
1649
1729
  }
1650
1730
  function addDays(d, n2) {
1651
- return new Date(d.getFullYear(), d.getMonth(), d.getDate() + n2);
1731
+ return makeDate(d.getFullYear(), d.getMonth(), d.getDate() + n2);
1652
1732
  }
1653
1733
  function addMonths(d, n2) {
1654
- const t = new Date(d.getFullYear(), d.getMonth() + n2, 1);
1655
- const last = new Date(t.getFullYear(), t.getMonth() + 1, 0).getDate();
1656
- return new Date(t.getFullYear(), t.getMonth(), Math.min(d.getDate(), last));
1734
+ const t = makeDate(d.getFullYear(), d.getMonth() + n2, 1);
1735
+ const last = makeDate(t.getFullYear(), t.getMonth() + 1, 0).getDate();
1736
+ return makeDate(t.getFullYear(), t.getMonth(), Math.min(d.getDate(), last));
1657
1737
  }
1658
1738
  function same(a, b) {
1659
1739
  return !!a && !!b && a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
@@ -1682,7 +1762,8 @@ window.Aura = (() => {
1682
1762
  rangePlaceholder: "\u0E27\u0E27/\u0E14\u0E14/\u0E1B\u0E1B\u0E1B\u0E1B \u2013 \u0E27\u0E27/\u0E14\u0E14/\u0E1B\u0E1B\u0E1B\u0E1B",
1683
1763
  clearDates: "\u0E25\u0E49\u0E32\u0E07\u0E0A\u0E48\u0E27\u0E07\u0E27\u0E31\u0E19\u0E17\u0E35\u0E48",
1684
1764
  chooseStart: "\u0E40\u0E25\u0E37\u0E2D\u0E01\u0E27\u0E31\u0E19\u0E40\u0E23\u0E34\u0E48\u0E21\u0E15\u0E49\u0E19",
1685
- chooseEnd: "\u0E40\u0E25\u0E37\u0E2D\u0E01\u0E27\u0E31\u0E19\u0E2A\u0E34\u0E49\u0E19\u0E2A\u0E38\u0E14"
1765
+ chooseEnd: "\u0E40\u0E25\u0E37\u0E2D\u0E01\u0E27\u0E31\u0E19\u0E2A\u0E34\u0E49\u0E19\u0E2A\u0E38\u0E14",
1766
+ dateUnavailable: "\u0E40\u0E25\u0E37\u0E2D\u0E01\u0E27\u0E31\u0E19\u0E17\u0E35\u0E48\u0E19\u0E35\u0E49\u0E44\u0E21\u0E48\u0E44\u0E14\u0E49 \u0E25\u0E2D\u0E07\u0E40\u0E1B\u0E34\u0E14\u0E1B\u0E0F\u0E34\u0E17\u0E34\u0E19\u0E14\u0E39\u0E27\u0E31\u0E19\u0E17\u0E35\u0E48\u0E40\u0E25\u0E37\u0E2D\u0E01\u0E44\u0E14\u0E49"
1686
1767
  },
1687
1768
  en: {
1688
1769
  prevYears: "Previous years",
@@ -1699,7 +1780,8 @@ window.Aura = (() => {
1699
1780
  rangePlaceholder: "DD/MM/YYYY \u2013 DD/MM/YYYY",
1700
1781
  clearDates: "Clear dates",
1701
1782
  chooseStart: "Choose the start date",
1702
- chooseEnd: "Choose the end date"
1783
+ chooseEnd: "Choose the end date",
1784
+ dateUnavailable: "That date can't be chosen. Open the calendar to see the dates you can pick."
1703
1785
  },
1704
1786
  sv: {
1705
1787
  prevYears: "Tidigare \xE5r",
@@ -1716,7 +1798,8 @@ window.Aura = (() => {
1716
1798
  rangePlaceholder: "\xE5\xE5\xE5\xE5-mm-dd \u2013 \xE5\xE5\xE5\xE5-mm-dd",
1717
1799
  clearDates: "Rensa datumen",
1718
1800
  chooseStart: "V\xE4lj startdatum",
1719
- chooseEnd: "V\xE4lj slutdatum"
1801
+ chooseEnd: "V\xE4lj slutdatum",
1802
+ dateUnavailable: "Det datumet g\xE5r inte att v\xE4lja. \xD6ppna kalendern f\xF6r att se vilka datum som g\xE5r."
1720
1803
  }
1721
1804
  };
1722
1805
  function dateText(locale) {
@@ -1758,7 +1841,15 @@ window.Aura = (() => {
1758
1841
  return MONTHS[k] != null ? MONTHS[k] : -1;
1759
1842
  }
1760
1843
  function parseDate(text) {
1761
- const s = String(text || "").trim();
1844
+ const raw = String(text || "").trim();
1845
+ const gregorian = /ค\.ศ\.|\d\s*(AD|CE)\b|^\s*(AD|CE)\s/i.test(raw);
1846
+ let s = raw.replace(/พ\.ศ\.|ค\.ศ\./g, " ").replace(/(\d)\s*(BE|AD|CE)\b/gi, "$1 ").replace(/^\s*(BE|AD|CE)\s+/i, " ").replace(/\s+/g, " ").trim();
1847
+ const eight = /^(\d{2})(\d{2})(\d{4})$/.exec(s);
1848
+ if (eight) {
1849
+ const a = +eight[3] >= 1e3 ? parseDate(eight[1] + "/" + eight[2] + "/" + eight[3] + (gregorian ? " \u0E04.\u0E28." : "")) : null;
1850
+ if (a) return a;
1851
+ s = s.slice(0, 4) + "-" + s.slice(4, 6) + "-" + s.slice(6);
1852
+ }
1762
1853
  let m = /^(\d{4})-(\d{1,2})-(\d{1,2})$/.exec(s), y, mo, d;
1763
1854
  if (m) {
1764
1855
  y = +m[1];
@@ -1768,13 +1859,13 @@ window.Aura = (() => {
1768
1859
  d = +m[1];
1769
1860
  mo = +m[2];
1770
1861
  y = +m[3];
1771
- } else if ((m = /^(\d{1,2})\s+(\S+)\s+(\d{4})$/.exec(s.replace(ERA, "").trim())) && monthIndex(m[2]) >= 0) {
1862
+ } else if ((m = /^(\d{1,2})\s+(\S+)\s+(\d{4})$/.exec(s)) && monthIndex(m[2]) >= 0) {
1772
1863
  d = +m[1];
1773
1864
  mo = monthIndex(m[2]) + 1;
1774
1865
  y = +m[3];
1775
1866
  } else return null;
1776
- if (y >= 2400) y -= 543;
1777
- const dt = new Date(y, mo - 1, d);
1867
+ if (y >= 2400 && !gregorian) y -= 543;
1868
+ const dt = makeDate(y, mo - 1, d);
1778
1869
  return dt.getMonth() === mo - 1 && dt.getDate() === d ? toISO(dt) : null;
1779
1870
  }
1780
1871
  function todayIn(timeZone) {
@@ -1809,14 +1900,37 @@ window.Aura = (() => {
1809
1900
  [locale, calendar]
1810
1901
  );
1811
1902
  }
1903
+ function allowedDate(iso, o) {
1904
+ const t = o.min === "today" || o.max === "today" ? o.today && fromISO(o.today) ? o.today : todayIn(o.timeZone) : "";
1905
+ const lo = o.min === "today" ? t : o.min, hi = o.max === "today" ? t : o.max;
1906
+ if (lo && fromISO(lo) && iso < lo) return false;
1907
+ if (hi && fromISO(hi) && iso > hi) return false;
1908
+ return !(o.isDateDisabled && o.isDateDisabled(iso));
1909
+ }
1812
1910
  var Calendar = React17.forwardRef(function Calendar2(props, ref) {
1813
1911
  const ctx = useAuraLocale(), locale = props.locale || ctx.locale || "en", calendar = props.calendar || ctx.calendar || defaultCalendar(locale), tag = localeTag(locale, calendar);
1814
1912
  const weekStart = props.weekStartsOn == null ? locale === "sv" ? 1 : 0 : props.weekStartsOn;
1815
- const todayISO = (props.today && fromISO(props.today) ? props.today : null) || todayIn(props.timeZone || ctx.timeZone);
1913
+ const given = props.today && fromISO(props.today) ? props.today : null, zone = props.timeZone || ctx.timeZone;
1914
+ const todayISO = given || todayIn(zone);
1816
1915
  const today = fromISO(todayISO);
1916
+ const mounted = useMounted(), gridKey = given || mounted ? "client" : "server";
1817
1917
  const min = fromISO(props.min === "today" ? todayISO : props.min), max = fromISO(props.max === "today" ? todayISO : props.max);
1818
1918
  const start = fromISO(props.start), end = fromISO(props.end);
1819
- const focusState = React17.useState(fromISO(props.focus) || start || today);
1919
+ function disabledAt(d) {
1920
+ return !!(min && d < min || max && d > max || props.isDateDisabled && props.isDateDisabled(toISO(d)));
1921
+ }
1922
+ function select(iso) {
1923
+ if (props.onSelect) props.onSelect(iso);
1924
+ }
1925
+ const focusState = React17.useState(function() {
1926
+ const d0 = fromISO(props.focus) || start || today;
1927
+ if (!disabledAt(d0)) return d0;
1928
+ for (let i = 1; i <= 366; i++) {
1929
+ if (!disabledAt(addDays(d0, i))) return addDays(d0, i);
1930
+ if (!disabledAt(addDays(d0, -i))) return addDays(d0, -i);
1931
+ }
1932
+ return d0;
1933
+ });
1820
1934
  const focusDate = focusState[0], setFocus = focusState[1];
1821
1935
  const viewState = React17.useState("days"), view = viewState[0], setView = viewState[1];
1822
1936
  const hoverState = React17.useState(null);
@@ -1824,7 +1938,7 @@ window.Aura = (() => {
1824
1938
  const th = locale === "th";
1825
1939
  const dt = dateText(locale);
1826
1940
  function disabled(d) {
1827
- return !!(min && d < min || max && d > max || props.isDateDisabled && props.isDateDisabled(toISO(d)));
1941
+ return disabledAt(d);
1828
1942
  }
1829
1943
  React17.useEffect(function() {
1830
1944
  if (!moved.current) return;
@@ -1832,11 +1946,14 @@ window.Aura = (() => {
1832
1946
  const el = gridRef.current && gridRef.current.querySelector('[data-date="' + toISO(focusDate) + '"]');
1833
1947
  if (el) el.focus();
1834
1948
  });
1835
- React17.useEffect(function() {
1836
- if (props.autoFocus === false) return;
1837
- const el = gridRef.current && gridRef.current.querySelector('[tabindex="0"]');
1838
- if (el) el.focus();
1839
- }, []);
1949
+ React17.useEffect(
1950
+ function() {
1951
+ if (props.autoFocus === false) return;
1952
+ const el = gridRef.current && gridRef.current.querySelector('[tabindex="0"]');
1953
+ if (el) el.focus();
1954
+ },
1955
+ [gridKey]
1956
+ );
1840
1957
  function move(d) {
1841
1958
  moved.current = true;
1842
1959
  setFocus(d);
@@ -1861,7 +1978,7 @@ window.Aura = (() => {
1861
1978
  else if (k === "PageDown") n2 = addMonths(d, e.shiftKey ? 12 : 1);
1862
1979
  else if (k === "Enter" || k === " ") {
1863
1980
  e.preventDefault();
1864
- if (!disabled(d)) props.onSelect(toISO(d));
1981
+ if (!disabled(d)) select(toISO(d));
1865
1982
  return;
1866
1983
  }
1867
1984
  if (n2) {
@@ -1884,7 +2001,7 @@ window.Aura = (() => {
1884
2001
  const yr = focusDate.getFullYear(), base = yr - yr % 12;
1885
2002
  const years = [];
1886
2003
  for (let y = base; y < base + 12; y++) years.push(y);
1887
- return /* @__PURE__ */ React17.createElement("div", { className: "aura-cal", ref: gridMerged }, /* @__PURE__ */ React17.createElement("div", { className: "aura-cal__head" }, /* @__PURE__ */ React17.createElement(
2004
+ return /* @__PURE__ */ React17.createElement("div", { className: "aura-cal", ref: gridMerged, key: gridKey }, /* @__PURE__ */ React17.createElement("div", { className: "aura-cal__head" }, /* @__PURE__ */ React17.createElement(
1888
2005
  IconButton,
1889
2006
  {
1890
2007
  icon: "chevron-left",
@@ -1931,7 +2048,7 @@ window.Aura = (() => {
1931
2048
  );
1932
2049
  })));
1933
2050
  }
1934
- return /* @__PURE__ */ React17.createElement("div", { className: "aura-cal", ref: gridMerged }, /* @__PURE__ */ React17.createElement("div", { className: "aura-cal__head" }, /* @__PURE__ */ React17.createElement(
2051
+ return /* @__PURE__ */ React17.createElement("div", { className: "aura-cal", ref: gridMerged, key: gridKey }, /* @__PURE__ */ React17.createElement("div", { className: "aura-cal__head" }, /* @__PURE__ */ React17.createElement(
1935
2052
  IconButton,
1936
2053
  {
1937
2054
  icon: "chevron-left",
@@ -1993,7 +2110,7 @@ window.Aura = (() => {
1993
2110
  type: "button",
1994
2111
  "data-date": iso,
1995
2112
  tabIndex: same(d, focusDate) ? 0 : -1,
1996
- disabled: dis,
2113
+ "aria-disabled": dis || void 0,
1997
2114
  "aria-label": fmt(tag, { weekday: "long", day: "numeric", month: "long", year: "numeric" }, d),
1998
2115
  suppressHydrationWarning: true,
1999
2116
  "aria-current": same(d, today) ? "date" : void 0,
@@ -2006,7 +2123,7 @@ window.Aura = (() => {
2006
2123
  ),
2007
2124
  onClick: function() {
2008
2125
  setFocus(d);
2009
- props.onSelect(iso);
2126
+ if (!dis) select(iso);
2010
2127
  },
2011
2128
  onKeyDown: function(e) {
2012
2129
  onKey(e, d);
@@ -2028,7 +2145,7 @@ window.Aura = (() => {
2028
2145
  disabled: disabled(today),
2029
2146
  onClick: function() {
2030
2147
  move(today);
2031
- props.onSelect(toISO(today));
2148
+ select(toISO(today));
2032
2149
  }
2033
2150
  },
2034
2151
  dt.today
@@ -2039,16 +2156,16 @@ window.Aura = (() => {
2039
2156
  const pos = React17.useState(null), popRef = React17.useRef(null), mounted = useMounted();
2040
2157
  function place() {
2041
2158
  if (!boxRef.current) return;
2042
- const r = boxRef.current.getBoundingClientRect(), H = 380;
2043
- const up = window.innerHeight - r.bottom < H && r.top > H;
2044
- const left = Math.max(8, Math.min(r.left, window.innerWidth - 320 - 8));
2159
+ const el = popRef.current, r = boxRef.current.getBoundingClientRect(), W = el ? el.offsetWidth : 320, H = el ? el.offsetHeight : 380;
2160
+ const up = window.innerHeight - r.bottom < H + 12 && r.top > H + 12;
2161
+ const left = Math.max(8, Math.min(r.left, window.innerWidth - W - 8));
2045
2162
  pos[1](up ? { left, bottom: window.innerHeight - r.top + 4 } : { left, top: r.bottom + 4 });
2046
2163
  }
2047
2164
  useIsoLayoutEffect(
2048
2165
  function() {
2049
2166
  if (open) place();
2050
2167
  },
2051
- [open]
2168
+ [open, !!pos[0]]
2052
2169
  );
2053
2170
  React17.useEffect(
2054
2171
  function() {
@@ -2162,13 +2279,30 @@ window.Aura = (() => {
2162
2279
  );
2163
2280
  const boxRef = React17.useRef(null), inputRef = React17.useRef(null), inputMerged = useMergedRef(ref, inputRef);
2164
2281
  const pop = useCalendarPopover(boxRef);
2282
+ const limits = {
2283
+ min: props.min,
2284
+ max: props.max,
2285
+ today: props.today,
2286
+ timeZone: props.timeZone || ctx.timeZone,
2287
+ isDateDisabled: props.isDateDisabled
2288
+ };
2289
+ const bad = React17.useState(null);
2290
+ React17.useEffect(
2291
+ function() {
2292
+ bad[1](null);
2293
+ },
2294
+ [st[0]]
2295
+ );
2165
2296
  function commit(text) {
2297
+ bad[1](null);
2166
2298
  if (!text.trim()) {
2167
2299
  st[1](null);
2168
2300
  return;
2169
2301
  }
2170
2302
  const iso = parseDate(text);
2171
- if (iso) st[1](iso);
2303
+ if (!iso) return;
2304
+ if (allowedDate(iso, limits)) st[1](iso);
2305
+ else bad[1](dt.dateUnavailable);
2172
2306
  }
2173
2307
  function close() {
2174
2308
  pop.setOpen(false);
@@ -2206,6 +2340,7 @@ window.Aura = (() => {
2206
2340
  start: st[0],
2207
2341
  focus: st[0],
2208
2342
  onSelect: function(iso) {
2343
+ bad[1](null);
2209
2344
  st[1](iso);
2210
2345
  close();
2211
2346
  }
@@ -2221,7 +2356,7 @@ window.Aura = (() => {
2221
2356
  dialogId,
2222
2357
  label: props.label,
2223
2358
  hint: props.hint,
2224
- error: props.error,
2359
+ error: bad[0] || props.error,
2225
2360
  required: props.required,
2226
2361
  optional: props.optional,
2227
2362
  disabled: props.disabled,
@@ -2235,6 +2370,7 @@ window.Aura = (() => {
2235
2370
  hasValue: st[0] != null,
2236
2371
  clearable: props.clearable,
2237
2372
  onClear: function() {
2373
+ bad[1](null);
2238
2374
  st[1](null);
2239
2375
  inputRef.current && inputRef.current.focus();
2240
2376
  },
@@ -2261,20 +2397,36 @@ window.Aura = (() => {
2261
2397
  const draft = React17.useState(null);
2262
2398
  const boxRef = React17.useRef(null), inputRef = React17.useRef(null), inputMerged = useMergedRef(ref, inputRef);
2263
2399
  const pop = useCalendarPopover(boxRef);
2400
+ const limits = {
2401
+ min: props.min,
2402
+ max: props.max,
2403
+ today: props.today,
2404
+ timeZone: props.timeZone || ctx.timeZone,
2405
+ isDateDisabled: props.isDateDisabled
2406
+ };
2264
2407
  const o = { locale, calendar };
2265
2408
  function show2(r) {
2266
2409
  if (!r.start) return "";
2267
2410
  if (!r.end) return formatDate(r.start, o) + " \u2013";
2268
2411
  return formatDate(r.start, o) + " \u2013 " + formatDate(r.end, o);
2269
2412
  }
2413
+ const bad = React17.useState(null);
2414
+ React17.useEffect(
2415
+ function() {
2416
+ bad[1](null);
2417
+ },
2418
+ [v.start, v.end]
2419
+ );
2270
2420
  function commit(text) {
2421
+ bad[1](null);
2271
2422
  const parts = String(text).split(/\s[–-]\s|\s*–\s*/);
2272
2423
  if (!text.trim()) {
2273
2424
  st[1]({ start: null, end: null });
2274
2425
  return;
2275
2426
  }
2276
2427
  const a = parseDate(parts[0]), b = parseDate(parts[1] || "");
2277
- if (a && b) st[1](a <= b ? { start: a, end: b } : { start: b, end: a });
2428
+ if (a && b && !(allowedDate(a, limits) && allowedDate(b, limits))) bad[1](dt.dateUnavailable);
2429
+ else if (a && b) st[1](a <= b ? { start: a, end: b } : { start: b, end: a });
2278
2430
  }
2279
2431
  function close() {
2280
2432
  pop.setOpen(false);
@@ -2287,6 +2439,7 @@ window.Aura = (() => {
2287
2439
  return;
2288
2440
  }
2289
2441
  const a = draft[0], b = iso;
2442
+ bad[1](null);
2290
2443
  st[1](a <= b ? { start: a, end: b } : { start: b, end: a });
2291
2444
  close();
2292
2445
  }
@@ -2337,7 +2490,7 @@ window.Aura = (() => {
2337
2490
  dialogId,
2338
2491
  label: props.label,
2339
2492
  hint: props.hint,
2340
- error: props.error,
2493
+ error: bad[0] || props.error,
2341
2494
  required: props.required,
2342
2495
  optional: props.optional,
2343
2496
  disabled: props.disabled,
@@ -2351,6 +2504,7 @@ window.Aura = (() => {
2351
2504
  hasValue: v.start != null,
2352
2505
  clearable: props.clearable,
2353
2506
  onClear: function() {
2507
+ bad[1](null);
2354
2508
  st[1]({ start: null, end: null });
2355
2509
  inputRef.current && inputRef.current.focus();
2356
2510
  },
@@ -2546,6 +2700,7 @@ window.Aura = (() => {
2546
2700
  const s = React19.useState(toastState.list);
2547
2701
  React19.useEffect(function() {
2548
2702
  toastState.subs.push(s[1]);
2703
+ s[1](toastState.list.slice());
2549
2704
  return function() {
2550
2705
  toastState.subs = toastState.subs.filter(function(f) {
2551
2706
  return f !== s[1];
@@ -2607,15 +2762,30 @@ window.Aura = (() => {
2607
2762
  function items(errors) {
2608
2763
  if (Array.isArray(errors)) return errors;
2609
2764
  const out = [];
2610
- for (const k in errors || {}) {
2611
- const e = errors[k];
2612
- if (e && e.message) out.push({ field: k, message: e.message });
2765
+ function walk(e, path, depth) {
2766
+ if (!e || typeof e !== "object" || depth > 8) return;
2767
+ const o = e;
2768
+ if (o.message) out.push({ field: path, message: o.message });
2769
+ for (const k in o) {
2770
+ if (k === "ref" || k === "type" || k === "types" || k === "message") continue;
2771
+ walk(o[k], path ? path + "." + k : k, depth + 1);
2772
+ }
2613
2773
  }
2774
+ walk(errors, "", 0);
2614
2775
  return out;
2615
2776
  }
2616
2777
  function fieldElement(field) {
2617
2778
  if (typeof document === "undefined") return null;
2618
- return document.getElementById(field) || document.querySelector('[name="' + field.replace(/"/g, '\\"') + '"]');
2779
+ const byId = document.getElementById(field);
2780
+ if (byId) return byId;
2781
+ const named = document.querySelector('[name="' + field.replace(/"/g, '\\"') + '"]');
2782
+ if (named && named.getAttribute("type") === "hidden") {
2783
+ const box = named.closest(".aura-field") || named.parentElement;
2784
+ return box && box.querySelector(
2785
+ 'input:not([type="hidden"]), [role="combobox"], select, textarea, button:not([tabindex="-1"])'
2786
+ ) || named;
2787
+ }
2788
+ return named;
2619
2789
  }
2620
2790
  var FormErrorSummary = React21.forwardRef(
2621
2791
  function FormErrorSummary2(props, ref) {
@@ -2823,6 +2993,30 @@ window.Aura = (() => {
2823
2993
 
2824
2994
  // src/useModal.tsx
2825
2995
  var React24 = __toESM(require_react(), 1);
2996
+ var locks = 0;
2997
+ var savedOverflow = "";
2998
+ function lockScroll() {
2999
+ const body = document.body;
3000
+ if (locks === 0) savedOverflow = body.style.overflow;
3001
+ locks++;
3002
+ body.style.overflow = "hidden";
3003
+ let done = false;
3004
+ return function() {
3005
+ if (done) return;
3006
+ done = true;
3007
+ locks--;
3008
+ if (locks === 0) body.style.overflow = savedOverflow;
3009
+ };
3010
+ }
3011
+ function tabbable(el) {
3012
+ const all = Array.prototype.filter.call(el.querySelectorAll(FOCUSABLE), function(c) {
3013
+ return c.tabIndex >= 0;
3014
+ });
3015
+ const shown = all.filter(function(c) {
3016
+ return c.getClientRects().length > 0;
3017
+ });
3018
+ return shown.length ? shown : all;
3019
+ }
2826
3020
  function useModal(open, ref, opts) {
2827
3021
  const mounted = useMounted();
2828
3022
  const prev = React24.useRef(null);
@@ -2831,8 +3025,7 @@ window.Aura = (() => {
2831
3025
  function() {
2832
3026
  if (!open || !mounted) return;
2833
3027
  prev.current = document.activeElement;
2834
- const body = document.body, overflow = body.style.overflow;
2835
- body.style.overflow = "hidden";
3028
+ const unlock = lockScroll();
2836
3029
  const el = ref.current;
2837
3030
  const firstIn = function(scope) {
2838
3031
  if (!scope || !el) return null;
@@ -2847,7 +3040,7 @@ window.Aura = (() => {
2847
3040
  const target = el && (el.querySelector("[data-autofocus]") || firstIn(o.bodySelector) || firstIn(o.footSelector) || el);
2848
3041
  if (target && o.autoFocus !== false) target.focus();
2849
3042
  return function() {
2850
- body.style.overflow = overflow;
3043
+ unlock();
2851
3044
  if (prev.current && prev.current.focus) prev.current.focus();
2852
3045
  };
2853
3046
  },
@@ -2859,17 +3052,18 @@ window.Aura = (() => {
2859
3052
  if (o.onEscape) o.onEscape();
2860
3053
  return;
2861
3054
  }
2862
- if (e.key !== "Tab" || !ref.current) return;
2863
- const list = Array.prototype.slice.call(ref.current.querySelectorAll(FOCUSABLE));
3055
+ if (e.key !== "Tab" || !ref.current || e.defaultPrevented) return;
3056
+ if (!ref.current.contains(e.target)) return;
3057
+ const list = tabbable(ref.current);
2864
3058
  if (!list.length) {
2865
3059
  e.preventDefault();
2866
3060
  return;
2867
3061
  }
2868
- const first = list[0], last = list[list.length - 1];
2869
- if (e.shiftKey && (document.activeElement === first || document.activeElement === ref.current)) {
3062
+ const first = list[0], last = list[list.length - 1], active = document.activeElement, stray = active === ref.current;
3063
+ if (e.shiftKey && (active === first || stray)) {
2870
3064
  e.preventDefault();
2871
3065
  last.focus();
2872
- } else if (!e.shiftKey && document.activeElement === last) {
3066
+ } else if (!e.shiftKey && (active === last || stray)) {
2873
3067
  e.preventDefault();
2874
3068
  first.focus();
2875
3069
  }
@@ -2992,6 +3186,7 @@ window.Aura = (() => {
2992
3186
  e.preventDefault();
2993
3187
  move("last");
2994
3188
  } else if (e.key === "Enter") {
3189
+ if (e.nativeEvent.isComposing || e.keyCode === 229) return;
2995
3190
  e.preventDefault();
2996
3191
  if (active >= 0) run(flat[active]);
2997
3192
  }
@@ -3111,7 +3306,7 @@ window.Aura = (() => {
3111
3306
  var Tooltip = React26.forwardRef(function Tooltip2(props, ref) {
3112
3307
  const id = uid(), st = React26.useState(false), open = props.open !== void 0 ? props.open : st[0], set = st[1];
3113
3308
  const anchor = React26.useRef(null), anchorMerged = useMergedRef(ref, anchor), tip = React26.useRef(null), timer = React26.useRef(void 0);
3114
- const pos = React26.useState(null);
3309
+ const pos = React26.useState(null), mounted = useMounted();
3115
3310
  function show2(now) {
3116
3311
  clearTimeout(timer.current);
3117
3312
  timer.current = setTimeout(
@@ -3125,34 +3320,55 @@ window.Aura = (() => {
3125
3320
  clearTimeout(timer.current);
3126
3321
  set(false);
3127
3322
  }
3323
+ function hideSoon() {
3324
+ clearTimeout(timer.current);
3325
+ timer.current = setTimeout(function() {
3326
+ set(false);
3327
+ }, 120);
3328
+ }
3329
+ React26.useEffect(function() {
3330
+ return function() {
3331
+ clearTimeout(timer.current);
3332
+ };
3333
+ }, []);
3334
+ function place() {
3335
+ if (!anchor.current || !tip.current) return;
3336
+ const r = anchor.current.getBoundingClientRect(), t = tip.current.getBoundingClientRect();
3337
+ const vw = window.innerWidth, vh = window.innerHeight, gap = 8, m = 8;
3338
+ let side = props.side || "top";
3339
+ if (side === "top" && r.top - t.height - gap < m && r.bottom + gap + t.height <= vh - m) side = "bottom";
3340
+ else if (side === "bottom" && r.bottom + gap + t.height > vh - m && r.top - t.height - gap >= m) side = "top";
3341
+ else if (side === "left" && r.left - t.width - gap < m && r.right + gap + t.width <= vw - m) side = "right";
3342
+ else if (side === "right" && r.right + gap + t.width > vw - m && r.left - t.width - gap >= m) side = "left";
3343
+ const clampX = function(x) {
3344
+ return Math.max(m, Math.min(x, vw - t.width - m));
3345
+ };
3346
+ const clampY = function(y) {
3347
+ return Math.max(m, Math.min(y, vh - t.height - m));
3348
+ };
3349
+ let top, left;
3350
+ if (side === "top" || side === "bottom") {
3351
+ top = clampY(side === "top" ? r.top - t.height - gap : r.bottom + gap);
3352
+ left = clampX(r.left + r.width / 2 - t.width / 2);
3353
+ } else {
3354
+ left = side === "left" ? r.left - t.width - gap : r.right + gap;
3355
+ left = clampX(left);
3356
+ top = clampY(r.top + r.height / 2 - t.height / 2);
3357
+ }
3358
+ pos[1]({ top, left });
3359
+ }
3128
3360
  useIsoLayoutEffect(
3129
3361
  function() {
3130
- if (!open || !anchor.current || !tip.current) return;
3131
- const r = anchor.current.getBoundingClientRect(), t = tip.current.getBoundingClientRect();
3132
- const vw = window.innerWidth, vh = window.innerHeight, gap = 8, m = 8;
3133
- let side = props.side || "top";
3134
- if (side === "top" && r.top - t.height - gap < m && r.bottom + gap + t.height <= vh - m) side = "bottom";
3135
- else if (side === "bottom" && r.bottom + gap + t.height > vh - m && r.top - t.height - gap >= m) side = "top";
3136
- else if (side === "left" && r.left - t.width - gap < m && r.right + gap + t.width <= vw - m) side = "right";
3137
- else if (side === "right" && r.right + gap + t.width > vw - m && r.left - t.width - gap >= m) side = "left";
3138
- const clampX = function(x) {
3139
- return Math.max(m, Math.min(x, vw - t.width - m));
3140
- };
3141
- const clampY = function(y) {
3142
- return Math.max(m, Math.min(y, vh - t.height - m));
3362
+ if (!open) return;
3363
+ place();
3364
+ window.addEventListener("scroll", place, true);
3365
+ window.addEventListener("resize", place);
3366
+ return function() {
3367
+ window.removeEventListener("scroll", place, true);
3368
+ window.removeEventListener("resize", place);
3143
3369
  };
3144
- let top, left;
3145
- if (side === "top" || side === "bottom") {
3146
- top = clampY(side === "top" ? r.top - t.height - gap : r.bottom + gap);
3147
- left = clampX(r.left + r.width / 2 - t.width / 2);
3148
- } else {
3149
- left = side === "left" ? r.left - t.width - gap : r.right + gap;
3150
- left = clampX(left);
3151
- top = clampY(r.top + r.height / 2 - t.height / 2);
3152
- }
3153
- pos[1]({ top, left });
3154
3370
  },
3155
- [open]
3371
+ [open, mounted]
3156
3372
  );
3157
3373
  React26.useEffect(
3158
3374
  function() {
@@ -3176,7 +3392,7 @@ window.Aura = (() => {
3176
3392
  onMouseEnter: function() {
3177
3393
  show2(false);
3178
3394
  },
3179
- onMouseLeave: hide,
3395
+ onMouseLeave: hideSoon,
3180
3396
  onFocus: function() {
3181
3397
  show2(true);
3182
3398
  },
@@ -3184,14 +3400,18 @@ window.Aura = (() => {
3184
3400
  },
3185
3401
  React26.cloneElement(child, { "aria-describedby": open ? id : child.props["aria-describedby"] })
3186
3402
  );
3187
- return /* @__PURE__ */ React26.createElement(React26.Fragment, null, trigger, open ? (0, import_react_dom6.createPortal)(
3403
+ return /* @__PURE__ */ React26.createElement(React26.Fragment, null, trigger, open && mounted ? (0, import_react_dom6.createPortal)(
3188
3404
  /* @__PURE__ */ React26.createElement(
3189
3405
  "div",
3190
3406
  {
3191
3407
  ref: tip,
3192
3408
  id,
3193
3409
  role: "tooltip",
3194
- className: "aura-tooltip",
3410
+ onMouseEnter: function() {
3411
+ clearTimeout(timer.current);
3412
+ },
3413
+ onMouseLeave: hideSoon,
3414
+ className: "aura-tooltip aura-tooltip--hoverable",
3195
3415
  style: { top: pos[0] ? pos[0].top : -9999, left: pos[0] ? pos[0].left : -9999 }
3196
3416
  },
3197
3417
  props.content
@@ -3306,7 +3526,7 @@ window.Aura = (() => {
3306
3526
  byKey[c.key] = c;
3307
3527
  });
3308
3528
  const rows = props.rows || [];
3309
- const rowKey = props.rowKey || columns[0].key;
3529
+ const rowKey = props.rowKey || (columns[0] ? columns[0].key : "id");
3310
3530
  const manual = !!props.manual;
3311
3531
  const Link = useLinkComponent(props.linkComponent);
3312
3532
  const busy = !!props.loading;
@@ -3514,11 +3734,12 @@ window.Aura = (() => {
3514
3734
  if (lv && boxWidth[0] == null) hideTerms += " + " + w + "px * var(--aura-h" + lv + "-on, 1)";
3515
3735
  else fixedSum += w;
3516
3736
  });
3517
- let pinOffsets = {}, acc = 0;
3737
+ let pinOffsets = {}, acc = "0px";
3518
3738
  vis.forEach(function(c) {
3519
3739
  if (isPinned(c)) {
3520
3740
  pinOffsets[c.key] = acc;
3521
- acc += widthOf(c);
3741
+ const lv = hideLevel(c);
3742
+ acc += " + " + widthOf(c) + "px" + (lv && boxWidth[0] == null ? " * var(--aura-h" + lv + "-on, 1)" : "");
3522
3743
  }
3523
3744
  });
3524
3745
  const selW = selectable ? " + var(--aura-table-select-width)" : "";
@@ -3533,9 +3754,10 @@ window.Aura = (() => {
3533
3754
  s["--aura-cell-flex"] = !hasFlex && i === vis.length - 1 ? "1 0 auto" : "none";
3534
3755
  s["--aura-cell-w"] = w + "px";
3535
3756
  }
3536
- if (isPinned(c)) s["--aura-cell-left"] = "calc(var(--aura-space-6)" + selW + " + " + pinOffsets[c.key] + "px)";
3757
+ if (isPinned(c)) s["--aura-cell-left"] = "calc(var(--aura-space-6)" + selW + " + " + pinOffsets[c.key] + ")";
3537
3758
  return s;
3538
3759
  }
3760
+ const sortCol = sort && sort.key ? byKey[sort.key] : void 0;
3539
3761
  const view = React28.useMemo(
3540
3762
  function() {
3541
3763
  if (manual || !sort || !sort.key || !byKey[sort.key]) return rows;
@@ -3554,7 +3776,16 @@ window.Aura = (() => {
3554
3776
  return p[0];
3555
3777
  });
3556
3778
  },
3557
- [rows, manual, sort && sort.key, sort && sort.dir]
3779
+ [
3780
+ rows,
3781
+ manual,
3782
+ sort && sort.key,
3783
+ sort && sort.dir,
3784
+ !!sortCol,
3785
+ sortCol && sortCol.sortValue,
3786
+ sortCol && sortCol.pill,
3787
+ sortCol && sortCol.tones
3788
+ ]
3558
3789
  );
3559
3790
  function nextSort(key) {
3560
3791
  if (!sort || sort.key !== key) return { key, dir: "asc" };
@@ -3563,14 +3794,37 @@ window.Aura = (() => {
3563
3794
  }
3564
3795
  const pageSize = props.pageSize || 0;
3565
3796
  const total = manual ? props.totalRows != null ? props.totalRows : (Math.max(1, pageState[0] || 1) - 1) * pageSize + rows.length + (pageSize && rows.length >= pageSize ? 1 : 0) : view.length;
3566
- const pageCount = pageSize ? Math.max(1, Math.ceil(total / pageSize)) : 1;
3797
+ const pageCount = pageSize ? Math.max(1, Math.ceil(total / pageSize), manual && props.totalRows == null ? pageState[0] || 1 : 1) : 1;
3567
3798
  const page = Math.min(Math.max(1, pageState[0] || 1), pageCount);
3568
3799
  const first = pageSize ? (page - 1) * pageSize : 0;
3569
3800
  const pageRows = pageSize && !manual ? view.slice(first, first + pageSize) : view;
3570
3801
  const canSortAny = !busy && (manual ? total > 1 : rows.length > 1);
3571
3802
  const shownTotal = manual && props.totalRows == null ? first + rows.length : total;
3803
+ const prevCount = React28.useRef(pageCount);
3804
+ React28.useEffect(
3805
+ function() {
3806
+ if (busy) return;
3807
+ const before = prevCount.current;
3808
+ prevCount.current = pageCount;
3809
+ const asked = pageState[0] || 1;
3810
+ if (asked === page || pageCount >= before || asked > before) return;
3811
+ if (props.getPageHref && !props.onPageChange && !props.onStateChange) return;
3812
+ pageState[1](page);
3813
+ emit(sort, page);
3814
+ },
3815
+ [pageState[0], page, busy, pageCount]
3816
+ );
3572
3817
  const linkPaging = !!props.getPageHref && !props.onPageChange && !oneCallback;
3573
- const prevLink = React28.useRef(null), nextLink = React28.useRef(null);
3818
+ const prevLink = React28.useRef(null), nextLink = React28.useRef(null), jumpLink = React28.useRef(null);
3819
+ const jumpState = React28.useState(null);
3820
+ React28.useEffect(
3821
+ function() {
3822
+ if (jumpState[0] == null) return;
3823
+ if (jumpLink.current) jumpLink.current.click();
3824
+ jumpState[1](null);
3825
+ },
3826
+ [jumpState[0]]
3827
+ );
3574
3828
  function emit(s, p) {
3575
3829
  if (props.onStateChange) props.onStateChange({ sort: s, page: p });
3576
3830
  }
@@ -3581,6 +3835,7 @@ window.Aura = (() => {
3581
3835
  if (linkPaging) {
3582
3836
  const a = next === page - 1 ? prevLink.current : next === page + 1 ? nextLink.current : null;
3583
3837
  if (a) a.click();
3838
+ else jumpState[1](next);
3584
3839
  return false;
3585
3840
  }
3586
3841
  if (focus) pending.current = focus;
@@ -3617,7 +3872,8 @@ window.Aura = (() => {
3617
3872
  }
3618
3873
  const height = props.height || 0;
3619
3874
  const virtual = !!height && !loading && pageRows.length > 0 && !stacked;
3620
- const bodyH = Math.max(ROW_H, height - ROW_H);
3875
+ const stickyTotal = !!(props.footer && props.stickyFooter && rows.length && !loading);
3876
+ const bodyH = Math.max(ROW_H, height - ROW_H - (stickyTotal ? ROW_H : 0));
3621
3877
  let start = 0, end = pageRows.length;
3622
3878
  if (virtual) {
3623
3879
  start = Math.max(0, Math.floor(scrollTop / ROW_H) - OVERSCAN);
@@ -3626,9 +3882,10 @@ window.Aura = (() => {
3626
3882
  const visibleRows = Math.max(1, Math.floor(bodyH / ROW_H));
3627
3883
  const nCols = vis.length + (selectable ? 1 : 0);
3628
3884
  const nRows = loading ? 0 : pageRows.length;
3885
+ const hasTotal = !!(props.footer && rows.length && !loading), T = nRows + 1, lastR = nRows + (hasTotal ? 1 : 0);
3629
3886
  const active = activeState[0];
3630
- const ar = Math.min(active.r, nRows), ac = Math.min(active.c, nCols - 1);
3631
- const activeRendered = ar === 0 || ar - 1 >= start && ar - 1 < end;
3887
+ const ar = Math.min(active.r, lastR), ac = Math.min(active.c, nCols - 1);
3888
+ const activeRendered = ar === 0 || hasTotal && ar === T || ar - 1 >= start && ar - 1 < end;
3632
3889
  function colAt(ci) {
3633
3890
  return selectable ? ci === 0 ? null : vis[ci - 1] : vis[ci];
3634
3891
  }
@@ -3647,6 +3904,11 @@ window.Aura = (() => {
3647
3904
  });
3648
3905
  c = at >= 0 ? at + (selectable ? 1 : 0) : Math.min(p.c || 0, nCols - 1);
3649
3906
  }
3907
+ const ae = document.activeElement;
3908
+ if (ae && ae !== document.body && !gridRef.current.contains(ae)) {
3909
+ pending.current = null;
3910
+ return;
3911
+ }
3650
3912
  const el = gridRef.current.querySelector('[data-rc="' + p.r + ":" + c + '"]');
3651
3913
  if (el) {
3652
3914
  pending.current = null;
@@ -3654,12 +3916,33 @@ window.Aura = (() => {
3654
3916
  }
3655
3917
  });
3656
3918
  function focusCell(r, c) {
3657
- r = Math.max(0, Math.min(r, nRows));
3919
+ r = Math.max(0, Math.min(r, lastR));
3658
3920
  c = Math.max(0, Math.min(c, nCols - 1));
3659
3921
  if (stacked && r === 0 && nRows > 0 && !(selectable && c === 0)) r = 1;
3922
+ if (gridRef.current && r === T && hasTotal) {
3923
+ const shown2 = function(cc) {
3924
+ const e = gridRef.current.querySelector('[data-rc="' + r + ":" + cc + '"]');
3925
+ return !!e && e.getClientRects().length > 0;
3926
+ };
3927
+ if (!shown2(c))
3928
+ for (let d = 1; d < nCols; d++) {
3929
+ if (c + d < nCols && shown2(c + d)) {
3930
+ c = c + d;
3931
+ break;
3932
+ }
3933
+ if (c - d >= 0 && shown2(c - d)) {
3934
+ c = c - d;
3935
+ break;
3936
+ }
3937
+ }
3938
+ }
3660
3939
  activeState[1]({ r, c });
3661
3940
  pending.current = { r, c };
3662
- if (virtual && r > 0) {
3941
+ if (virtual && hasTotal && r === T && !props.stickyFooter) {
3942
+ const sc = scrollRef.current;
3943
+ sc.scrollTop = sc.scrollHeight;
3944
+ setScrollTop(sc.scrollTop);
3945
+ } else if (virtual && r > 0 && r <= nRows) {
3663
3946
  const sc = scrollRef.current, top = (r - 1) * ROW_H;
3664
3947
  if (top < sc.scrollTop) sc.scrollTop = top;
3665
3948
  else if (top + ROW_H > sc.scrollTop + bodyH) sc.scrollTop = top + ROW_H - bodyH;
@@ -3676,26 +3959,28 @@ window.Aura = (() => {
3676
3959
  });
3677
3960
  const selSet = {};
3678
3961
  selected.forEach(function(k) {
3679
- selSet[k] = true;
3962
+ selSet[String(k)] = true;
3680
3963
  });
3681
3964
  const nSel = pageKeys.filter(function(k) {
3682
- return selSet[k];
3965
+ return selSet[String(k)];
3683
3966
  }).length;
3684
3967
  const all = nSel > 0 && nSel === pageKeys.length;
3685
3968
  function toggle(k, on) {
3686
3969
  setSelected(
3687
3970
  on ? selected.concat([k]) : selected.filter(function(x) {
3688
- return x !== k;
3971
+ return String(x) !== String(k);
3689
3972
  })
3690
3973
  );
3691
3974
  }
3692
3975
  function toggleAll() {
3693
3976
  setSelected(
3694
3977
  all ? selected.filter(function(k) {
3695
- return pageKeys.indexOf(k) < 0;
3978
+ return !pageKeys.some(function(p) {
3979
+ return String(p) === String(k);
3980
+ });
3696
3981
  }) : selected.concat(
3697
3982
  pageKeys.filter(function(k) {
3698
- return !selSet[k];
3983
+ return !selSet[String(k)];
3699
3984
  })
3700
3985
  )
3701
3986
  );
@@ -3900,7 +4185,7 @@ window.Aura = (() => {
3900
4185
  return;
3901
4186
  }
3902
4187
  const p = rc.split(":"), r = +p[0], c = +p[1], k = e.key, col = colAt(c);
3903
- const row = r > 0 ? pageRows[r - 1] : null;
4188
+ const row = r > 0 && r <= nRows ? pageRows[r - 1] : null, isTotal = hasTotal && r === T;
3904
4189
  let handled = true;
3905
4190
  if (r === 0 && col && e.altKey && (k === "ArrowLeft" || k === "ArrowRight") && canResize(col))
3906
4191
  setW(col, widthOf(col) + (k === "ArrowLeft" ? -1 : 1) * (e.shiftKey ? 48 : 16), true);
@@ -3911,21 +4196,23 @@ window.Aura = (() => {
3911
4196
  else if (k === "ArrowRight") focusCell(r, c + 1);
3912
4197
  else if (k === "ArrowLeft") focusCell(r, c - 1);
3913
4198
  else if (k === "ArrowDown") {
3914
- if (r < nRows) focusCell(r + 1, c);
4199
+ if (r < lastR) focusCell(r + 1, c);
3915
4200
  else if (pageSize && page < pageCount && goPage(page + 1, { r: 1, c })) activeState[1]({ r: 1, c });
3916
4201
  } else if (k === "ArrowUp") {
3917
4202
  if (r > 1 || r === 1 && !(pageSize && page > 1)) focusCell(r - 1, c);
3918
4203
  else if (r === 1 && goPage(page - 1, { r: pageSize, c })) activeState[1]({ r: pageSize, c });
3919
4204
  } else if (k === "Home") focusCell(e.ctrlKey ? 1 : r, 0);
3920
- else if (k === "End") focusCell(e.ctrlKey ? nRows : r, nCols - 1);
4205
+ else if (k === "End") focusCell(e.ctrlKey ? lastR : r, nCols - 1);
3921
4206
  else if (k === "PageDown") {
3922
4207
  if (pageSize) {
3923
4208
  if (goPage(page + 1, { r: 1, c })) activeState[1]({ r: 1, c });
3924
- } else focusCell(Math.min(nRows, r + visibleRows), c);
4209
+ } else focusCell(Math.min(lastR, r + visibleRows), c);
3925
4210
  } else if (k === "PageUp") {
3926
4211
  if (pageSize) {
3927
4212
  if (goPage(page - 1, { r: 1, c })) activeState[1]({ r: 1, c });
3928
4213
  } else focusCell(Math.max(1, r - visibleRows), c);
4214
+ } else if (isTotal && (k === " " || k === "Enter" || k === "F2")) {
4215
+ handled = false;
3929
4216
  } else if (k === "F2" && r > 0) {
3930
4217
  const inner = target.querySelector("button, a[href], input, select, textarea");
3931
4218
  if (inner) inner.focus();
@@ -4296,9 +4583,10 @@ window.Aura = (() => {
4296
4583
  }
4297
4584
  );
4298
4585
  }
4299
- if (pageSize && (rows.length || busy)) {
4586
+ const openTotal = manual && props.totalRows == null && !!pageSize && rows.length >= pageSize;
4587
+ if (pageSize && (rows.length || busy || page > 1)) {
4300
4588
  const from = rows.length ? first + 1 : 0, to = manual ? first + rows.length : Math.min(first + pageSize, view.length);
4301
- foot = /* @__PURE__ */ React28.createElement("div", { className: "aura-table__foot" }, /* @__PURE__ */ React28.createElement("span", { "aria-live": "polite" }, busy ? t.loading : t.range(from, to, shownTotal)), /* @__PURE__ */ React28.createElement("span", { className: "aura-table__pager" }, /* @__PURE__ */ React28.createElement("span", null, t.page(page, pageCount)), pagerButton(-1), pagerButton(1)));
4589
+ foot = /* @__PURE__ */ React28.createElement("div", { className: "aura-table__foot" }, /* @__PURE__ */ React28.createElement("span", { "aria-live": "polite" }, busy ? t.loading : openTotal ? t.rangeOpen(from, to) : t.range(from, to, shownTotal)), /* @__PURE__ */ React28.createElement("span", { className: "aura-table__pager" }, /* @__PURE__ */ React28.createElement("span", null, openTotal ? t.pageOpen(page) : t.page(page, pageCount)), pagerButton(-1), pagerButton(1)));
4302
4590
  } else if (height && rows.length && !loading) {
4303
4591
  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));
4304
4592
  }
@@ -4312,15 +4600,32 @@ window.Aura = (() => {
4312
4600
  style: rowStyle
4313
4601
  },
4314
4602
  /* @__PURE__ */ React28.createElement("span", { className: "aura-table__gutter", "aria-hidden": true }),
4315
- selectable ? /* @__PURE__ */ React28.createElement("span", { className: cx("aura-table__sel", nPinned && "is-pinned"), "aria-hidden": true }) : null,
4603
+ selectable ? /* @__PURE__ */ React28.createElement(
4604
+ "span",
4605
+ {
4606
+ role: "gridcell",
4607
+ "aria-colindex": 1,
4608
+ className: cx("aura-table__sel", nPinned && "is-pinned"),
4609
+ tabIndex: tabFor(T, 0),
4610
+ "data-rc": T + ":0",
4611
+ onFocus: function() {
4612
+ activeState[1]({ r: T, c: 0 });
4613
+ }
4614
+ }
4615
+ ) : null,
4316
4616
  vis.map(function(c, j) {
4317
- const pin = isPinned(c);
4617
+ const pin = isPinned(c), ci = j + (selectable ? 1 : 0);
4318
4618
  return /* @__PURE__ */ React28.createElement(
4319
4619
  "span",
4320
4620
  {
4321
4621
  key: c.key,
4322
4622
  role: "gridcell",
4323
4623
  "aria-colindex": j + (selectable ? 2 : 1),
4624
+ tabIndex: tabFor(T, ci),
4625
+ "data-rc": T + ":" + ci,
4626
+ onFocus: function() {
4627
+ if (activeState[0].r !== T || activeState[0].c !== ci) activeState[1]({ r: T, c: ci });
4628
+ },
4324
4629
  className: cx(
4325
4630
  "aura-table__td",
4326
4631
  c.mono && "aura-table__mono",
@@ -4346,8 +4651,9 @@ window.Aura = (() => {
4346
4651
  )
4347
4652
  ) : null;
4348
4653
  const scrollStyle = {
4349
- scrollPaddingLeft: "calc(var(--aura-space-6)" + selW + " + " + acc + "px)",
4350
- scrollPaddingTop: ROW_H + "px"
4654
+ scrollPaddingLeft: "calc(var(--aura-space-6)" + selW + " + " + acc + ")",
4655
+ scrollPaddingTop: ROW_H + "px",
4656
+ scrollPaddingBottom: stickyTotal ? ROW_H + "px" : void 0
4351
4657
  };
4352
4658
  if (height) scrollStyle["--aura-table-h"] = height + "px";
4353
4659
  const gridEl = /* @__PURE__ */ React28.createElement(
@@ -4381,7 +4687,7 @@ window.Aura = (() => {
4381
4687
  role: "grid",
4382
4688
  "aria-label": props.label,
4383
4689
  "aria-busy": busy || void 0,
4384
- "aria-rowcount": loading ? -1 : shownTotal + 1 + (totalRow ? 1 : 0),
4690
+ "aria-rowcount": loading || manual && props.totalRows == null && pageSize && rows.length >= pageSize ? -1 : shownTotal + 1 + (totalRow ? 1 : 0),
4385
4691
  "aria-colcount": nCols,
4386
4692
  "aria-multiselectable": selectable || void 0,
4387
4693
  onKeyDown: onGridKey,
@@ -4429,7 +4735,8 @@ window.Aura = (() => {
4429
4735
  items: menu.kind === "picker" ? pickerItems() : byKey[menu.key] ? columnMenuItems(byKey[menu.key]) : []
4430
4736
  }
4431
4737
  ) : null,
4432
- tipEl
4738
+ tipEl,
4739
+ jumpState[0] != null && props.getPageHref ? /* @__PURE__ */ React28.createElement(Link, { ref: jumpLink, href: props.getPageHref(jumpState[0]), hidden: true, tabIndex: -1, "aria-hidden": true }) : null
4433
4740
  );
4434
4741
  if (!levels.length) return gridEl;
4435
4742
  let out = gridEl;
@@ -4474,19 +4781,23 @@ window.Aura = (() => {
4474
4781
  var React30 = __toESM(require_react(), 1);
4475
4782
  var Tabs = React30.forwardRef(function Tabs2(props, ref) {
4476
4783
  const items2 = props.tabs || [], base = uid();
4784
+ const asLinks = items2.length > 0 && items2.every(function(t) {
4785
+ return !!t.href;
4786
+ });
4787
+ const firstOn = items2.filter(function(t) {
4788
+ return !t.disabled;
4789
+ })[0];
4477
4790
  const st = useMaybeControlled(
4478
4791
  props.value,
4479
- props.defaultValue || items2[0] && items2[0].id,
4792
+ props.defaultValue || (asLinks ? void 0 : firstOn && firstOn.id),
4480
4793
  props.onChange
4481
4794
  );
4795
+ const cur = asLinks && "value" in props ? props.value : st[0];
4482
4796
  const refs = React30.useRef({});
4483
4797
  const current2 = items2.filter(function(t) {
4484
- return t.id === st[0];
4485
- })[0] || items2[0];
4798
+ return t.id === cur;
4799
+ })[0] || firstOn || items2[0];
4486
4800
  const Link = useLinkComponent(props.linkComponent);
4487
- const asLinks = items2.length > 0 && items2.every(function(t) {
4488
- return !!t.href;
4489
- });
4490
4801
  if (asLinks)
4491
4802
  return /* @__PURE__ */ React30.createElement(
4492
4803
  "nav",
@@ -4496,7 +4807,7 @@ window.Aura = (() => {
4496
4807
  className: cx("aura-tabs aura-tabs--links", props.className)
4497
4808
  },
4498
4809
  /* @__PURE__ */ React30.createElement("div", { className: "aura-tabs__list" }, items2.map(function(t) {
4499
- const on = t.id === st[0];
4810
+ const on = t.id === cur;
4500
4811
  const inner = [
4501
4812
  t.icon ? /* @__PURE__ */ React30.createElement(Icon, { key: "i", name: t.icon }) : null,
4502
4813
  t.label,
@@ -4742,6 +5053,7 @@ window.Aura = (() => {
4742
5053
  style: depth ? { ["--aura-nav-depth"]: depth } : void 0,
4743
5054
  onClick: function(e) {
4744
5055
  if (!it.href) e.preventDefault();
5056
+ else if (!plainClick(e)) return;
4745
5057
  st[1](it.id);
4746
5058
  }
4747
5059
  };
@@ -4819,7 +5131,7 @@ window.Aura = (() => {
4819
5131
  return ((parts[0] || "?")[0] + (parts.length > 1 ? parts[parts.length - 1][0] : parts[0][1] || "")).toUpperCase();
4820
5132
  }
4821
5133
  var Avatar = React33.forwardRef(function Avatar2(props, ref) {
4822
- const size = props.size || "md", errState = React33.useState(false);
5134
+ const size = props.size || "md", errState = React33.useState(null);
4823
5135
  let hash = 0;
4824
5136
  String(props.name || "").split("").forEach(function(ch) {
4825
5137
  hash = hash * 31 + ch.charCodeAt(0) >>> 0;
@@ -4833,13 +5145,14 @@ window.Aura = (() => {
4833
5145
  role: "img",
4834
5146
  "aria-label": props.name + (props.status ? ", " + props.status : "")
4835
5147
  },
4836
- props.src && !errState[0] ? /* @__PURE__ */ React33.createElement(
5148
+ props.src && errState[0] !== props.src ? /* @__PURE__ */ React33.createElement(
4837
5149
  "img",
4838
5150
  {
5151
+ key: props.src,
4839
5152
  src: props.src,
4840
5153
  alt: "",
4841
5154
  onError: function() {
4842
- errState[1](true);
5155
+ errState[1](props.src || null);
4843
5156
  }
4844
5157
  }
4845
5158
  ) : /* @__PURE__ */ React33.createElement("span", { "aria-hidden": true }, initials(props.name)),
@@ -4959,16 +5272,24 @@ window.Aura = (() => {
4959
5272
  [wide]
4960
5273
  );
4961
5274
  const navEl = props.nav && React38.isValidElement(props.nav) ? props.nav : null;
5275
+ const shared = !!navEl && navEl.props.value === void 0 && (navEl.props.defaultValue !== void 0 || navEl.props.sections !== void 0 || navEl.props.items !== void 0);
5276
+ const navState = React38.useState(navEl ? navEl.props.defaultValue : void 0);
5277
+ function onNav(id) {
5278
+ if (shared) navState[1](id);
5279
+ if (navEl && navEl.props.onChange) navEl.props.onChange(id);
5280
+ }
5281
+ const deskNav = navEl && shared ? React38.cloneElement(navEl, { value: navState[0], onChange: onNav }) : props.nav;
4962
5282
  const drawerNav = navEl ? React38.cloneElement(navEl, {
5283
+ value: shared ? navState[0] : navEl.props.value,
4963
5284
  onChange: function(id) {
4964
- if (navEl.props.onChange) navEl.props.onChange(id);
5285
+ onNav(id);
4965
5286
  setOpen(false);
4966
5287
  },
4967
5288
  className: cx(navEl.props.className, "is-in-drawer"),
4968
5289
  collapsed: false,
4969
5290
  collapsible: false
4970
5291
  }) : props.nav;
4971
- return /* @__PURE__ */ React38.createElement("div", { ref, className: cx("aura-shell", props.bottomNav && "aura-shell--bottomnav", props.className) }, props.nav ? /* @__PURE__ */ React38.createElement("div", { className: "aura-shell__nav" }, props.nav) : null, props.nav ? /* @__PURE__ */ React38.createElement(
5292
+ return /* @__PURE__ */ React38.createElement("div", { ref, className: cx("aura-shell", props.bottomNav && "aura-shell--bottomnav", props.className) }, props.nav ? /* @__PURE__ */ React38.createElement("div", { className: "aura-shell__nav" }, deskNav) : null, props.nav ? /* @__PURE__ */ React38.createElement(
4972
5293
  Drawer,
4973
5294
  {
4974
5295
  open,
@@ -5082,8 +5403,9 @@ window.Aura = (() => {
5082
5403
  className: "aura-tbl-wrap",
5083
5404
  "data-density": density,
5084
5405
  tabIndex: scrolls ? 0 : void 0,
5085
- role: scrolls ? "region" : void 0,
5086
- "aria-labelledby": scrolls && caption != null ? capId : void 0
5406
+ role: scrolls && (caption != null || rest["aria-label"]) ? "region" : void 0,
5407
+ "aria-labelledby": scrolls && caption != null ? capId : void 0,
5408
+ "aria-label": scrolls && caption == null ? rest["aria-label"] : void 0
5087
5409
  },
5088
5410
  /* @__PURE__ */ React41.createElement("table", { ref, className: cx("aura-tbl", className), ...rest }, caption != null ? /* @__PURE__ */ React41.createElement("caption", { id: capId, className: cx("aura-tbl__caption", captionHidden && "aura-sr-only") }, caption) : null, children)
5089
5411
  );
@@ -5152,6 +5474,7 @@ window.Aura = (() => {
5152
5474
  "aria-current": on ? "page" : void 0,
5153
5475
  onClick: function(e) {
5154
5476
  if (!it.href) e.preventDefault();
5477
+ else if (!plainClick(e)) return;
5155
5478
  st[1](it.id);
5156
5479
  }
5157
5480
  };
@@ -5240,6 +5563,7 @@ window.Aura = (() => {
5240
5563
  const m = /^(\d{1,2})(?:[:.](\d{2}))?$/.exec(s) || /^(\d{1,2})(\d{2})$/.exec(s);
5241
5564
  if (!m) return null;
5242
5565
  let hh = +m[1], mm = m[2] ? +m[2] : 0;
5566
+ if ((am || pm) && (hh < 1 || hh > 12)) return null;
5243
5567
  if (pm && hh < 12) hh += 12;
5244
5568
  if (am && hh === 12) hh = 0;
5245
5569
  if (hh > 23 || mm > 59) return null;
@@ -5354,7 +5678,8 @@ window.Aura = (() => {
5354
5678
  return true;
5355
5679
  }
5356
5680
  if (blocked(v)) {
5357
- errState[1](t.timeOutOfRange(fromMin(lo), fromMin(hi)));
5681
+ const n2 = toMin(v);
5682
+ errState[1](n2 != null && n2 >= lo && n2 <= hi ? t.timeUnavailable : t.timeOutOfRange(fromMin(lo), fromMin(hi)));
5358
5683
  return false;
5359
5684
  }
5360
5685
  errState[1](null);
@@ -5597,7 +5922,23 @@ window.Aura = (() => {
5597
5922
  });
5598
5923
  };
5599
5924
  }, []);
5925
+ React46.useEffect(
5926
+ function() {
5927
+ const el = inputRef.current;
5928
+ if (!el || !props.name || typeof DataTransfer === "undefined") return;
5929
+ try {
5930
+ const dt = new DataTransfer();
5931
+ items2.forEach(function(i) {
5932
+ if (i.file && !i.error) dt.items.add(i.file);
5933
+ });
5934
+ el.files = dt.files;
5935
+ } catch (e) {
5936
+ }
5937
+ },
5938
+ [items2, props.name]
5939
+ );
5600
5940
  function thumb(it) {
5941
+ if (!it.file && it.url && /^image\//.test(it.type || "")) return it.url;
5601
5942
  if (!it.file || !/^image\//.test(it.type || "") || typeof URL === "undefined" || !URL.createObjectURL) return null;
5602
5943
  if (!urls.current[it.id]) urls.current[it.id] = URL.createObjectURL(it.file);
5603
5944
  return urls.current[it.id];
@@ -5703,7 +6044,7 @@ window.Aura = (() => {
5703
6044
  ),
5704
6045
  items2.length ? /* @__PURE__ */ React46.createElement("ul", { className: "aura-upload__list", "aria-live": "polite" }, items2.map(function(it) {
5705
6046
  const src = thumb(it);
5706
- return /* @__PURE__ */ React46.createElement("li", { key: it.id, className: cx("aura-upload__item", it.error && "is-error") }, src ? /* @__PURE__ */ React46.createElement("img", { className: "aura-upload__thumb", src, alt: "" }) : /* @__PURE__ */ React46.createElement("span", { className: "aura-upload__thumb is-icon", "aria-hidden": true }, /* @__PURE__ */ React46.createElement(Icon, { name: /^image\//.test(it.type || "") ? "image" : "file", size: "md" })), /* @__PURE__ */ React46.createElement("span", { className: "aura-upload__meta" }, /* @__PURE__ */ React46.createElement("span", { className: "aura-upload__name" }, it.name), /* @__PURE__ */ React46.createElement("span", { className: "aura-upload__sub" }, it.error ? /* @__PURE__ */ React46.createElement(React46.Fragment, null, /* @__PURE__ */ React46.createElement(Icon, { name: "circle-alert", size: 12 }), it.error) : it.status === "uploading" ? t.uploading + (it.progress != null ? " " + Math.round(it.progress) + "%" : "") : it.status === "done" ? /* @__PURE__ */ React46.createElement(React46.Fragment, null, /* @__PURE__ */ React46.createElement(Icon, { name: "circle-check", size: 12 }), formatBytes(it.size)) : formatBytes(it.size)), it.status === "uploading" ? /* @__PURE__ */ React46.createElement(
6047
+ return /* @__PURE__ */ React46.createElement("li", { key: it.id, className: cx("aura-upload__item", it.error && "is-error") }, src ? /* @__PURE__ */ React46.createElement("img", { className: "aura-upload__thumb", src, alt: "" }) : /* @__PURE__ */ React46.createElement("span", { className: "aura-upload__thumb is-icon", "aria-hidden": true }, /* @__PURE__ */ React46.createElement(Icon, { name: /^image\//.test(it.type || "") ? "image" : "file", size: "md" })), /* @__PURE__ */ React46.createElement("span", { className: "aura-upload__meta" }, it.url && !it.error ? /* @__PURE__ */ React46.createElement("a", { className: "aura-upload__name", href: it.url, target: "_blank", rel: "noreferrer" }, it.name) : /* @__PURE__ */ React46.createElement("span", { className: "aura-upload__name" }, it.name), /* @__PURE__ */ React46.createElement("span", { className: "aura-upload__sub" }, it.error ? /* @__PURE__ */ React46.createElement(React46.Fragment, null, /* @__PURE__ */ React46.createElement(Icon, { name: "circle-alert", size: 12 }), it.error) : it.status === "uploading" ? t.uploading + (it.progress != null ? " " + Math.round(it.progress) + "%" : "") : it.status === "done" ? /* @__PURE__ */ React46.createElement(React46.Fragment, null, /* @__PURE__ */ React46.createElement(Icon, { name: "circle-check", size: 12 }), formatBytes(it.size)) : formatBytes(it.size)), it.status === "uploading" ? /* @__PURE__ */ React46.createElement(
5707
6048
  "span",
5708
6049
  {
5709
6050
  className: "aura-upload__bar",
@@ -5975,6 +6316,8 @@ window.Aura = (() => {
5975
6316
  }
5976
6317
  if (s) check("light", "ink", "accent-lime (signal)", 4.5, INK, s[200]);
5977
6318
  function css(selector) {
6319
+ if (selector !== void 0 && /[<{};@\r\n]|\/\*|\*\//.test(selector))
6320
+ throw new Error('createTheme: "' + selector + '" is not a plain CSS selector');
5978
6321
  const light = selector ? selector : ':root, [data-theme="light"]';
5979
6322
  const dark = selector ? selector + ".dark, .dark " + selector + ", " + selector + '[data-theme="dark"], [data-theme="dark"] ' + selector : '.dark, [data-theme="dark"]';
5980
6323
  const system = selector ? '[data-theme="system"] ' + selector + ", " + selector + '[data-theme="system"]' : '[data-theme="system"]';
@@ -5983,7 +6326,7 @@ window.Aura = (() => {
5983
6326
  return " --aura-" + k + ": " + m[k] + ";";
5984
6327
  }).join("\n") + "\n}";
5985
6328
  }
5986
- return "/* AURA theme" + (o.name ? ' "' + o.name + '"' : "") + ": brand " + o.brand + (o.signal ? ", signal " + o.signal : "") + (o.primary === "brand" ? ", brand primary buttons" : "") + ". Load after aura.css. Generated by createTheme. */\n" + block(light, L) + "\n" + block(dark, D) + "\n@media (prefers-color-scheme: dark) {\n" + block(system, D) + "\n}\n";
6329
+ return "/* AURA theme" + (o.name ? ' "' + String(o.name).replace(/[*/<>\\]/g, "") + '"' : "") + ": brand " + o.brand + (o.signal ? ", signal " + o.signal : "") + (o.primary === "brand" ? ", brand primary buttons" : "") + ". Load after aura.css. Generated by createTheme. */\n" + block(light, L) + "\n" + block(dark, D) + "\n@media (prefers-color-scheme: dark) {\n" + block(system, D) + "\n}\n";
5987
6330
  }
5988
6331
  return {
5989
6332
  name: o.name || null,
@@ -6004,12 +6347,21 @@ window.Aura = (() => {
6004
6347
  function ThemeStyle(props) {
6005
6348
  const css = React47.useMemo(
6006
6349
  function() {
6007
- return createTheme({ brand: props.brand, signal: props.signal, primary: props.primary, name: props.name }).css(
6008
- props.selector
6009
- );
6350
+ try {
6351
+ return createTheme({
6352
+ brand: props.brand,
6353
+ signal: props.signal,
6354
+ primary: props.primary,
6355
+ name: props.name
6356
+ }).css(props.selector);
6357
+ } catch (e) {
6358
+ devWarnOnce("theme-style", "ThemeStyle ignored: " + e.message);
6359
+ return null;
6360
+ }
6010
6361
  },
6011
6362
  [props.brand, props.signal, props.primary, props.name, props.selector]
6012
6363
  );
6364
+ if (css === null) return null;
6013
6365
  return /* @__PURE__ */ React47.createElement("style", { "data-aura-theme": props.name || props.brand, dangerouslySetInnerHTML: { __html: css } });
6014
6366
  }
6015
6367
 
@@ -6024,9 +6376,9 @@ window.Aura = (() => {
6024
6376
  return typeof v === "string" && SCHEMES.indexOf(v) >= 0;
6025
6377
  }
6026
6378
  function colorSchemeScript(options) {
6027
- const key = JSON.stringify(options && options.storageKey || DEFAULT_KEY);
6028
- const fallback = JSON.stringify(options && options.defaultScheme || "system");
6029
- 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){}})();`;
6379
+ const key = JSON.stringify(options && options.storageKey || DEFAULT_KEY).replace(/</g, "\\u003c");
6380
+ const fallback = JSON.stringify(options && options.defaultScheme || "system").replace(/</g, "\\u003c");
6381
+ 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 m=window.matchMedia('(prefers-color-scheme: dark)');d.classList.toggle('dark',s==='dark'||(s==='system'&&m.matches));if(m.addEventListener)m.addEventListener('change',function(e){if(d.getAttribute('data-theme')==='system')d.classList.toggle('dark',e.matches)});}catch(e){}})();`;
6030
6382
  }
6031
6383
 
6032
6384
  // src/colorScheme.tsx
@@ -6063,16 +6415,20 @@ window.Aura = (() => {
6063
6415
  if (readScheme(fallback) === "system") apply("system");
6064
6416
  cb();
6065
6417
  }
6418
+ function onStorage(e) {
6419
+ if (e.key === key) apply(valid(e.newValue) ? e.newValue : fallback);
6420
+ cb();
6421
+ }
6066
6422
  if (mq) mq.addEventListener("change", onSystem);
6067
6423
  window.addEventListener(EVENT, cb);
6068
- window.addEventListener("storage", cb);
6424
+ window.addEventListener("storage", onStorage);
6069
6425
  return function() {
6070
6426
  if (mq) mq.removeEventListener("change", onSystem);
6071
6427
  window.removeEventListener(EVENT, cb);
6072
- window.removeEventListener("storage", cb);
6428
+ window.removeEventListener("storage", onStorage);
6073
6429
  };
6074
6430
  },
6075
- [fallback]
6431
+ [fallback, key]
6076
6432
  );
6077
6433
  const snapshot = React48.useSyncExternalStore(
6078
6434
  subscribe2,
@@ -6272,7 +6628,7 @@ window.Aura = (() => {
6272
6628
  {
6273
6629
  href: link(p),
6274
6630
  onClick: function(e) {
6275
- if (props.onChange) {
6631
+ if (props.onChange && plainClick(e)) {
6276
6632
  e.preventDefault();
6277
6633
  go(p);
6278
6634
  }
@@ -6314,7 +6670,7 @@ window.Aura = (() => {
6314
6670
  "aria-label": label,
6315
6671
  title: label,
6316
6672
  onClick: function(e) {
6317
- if (props.onChange) {
6673
+ if (props.onChange && plainClick(e)) {
6318
6674
  e.preventDefault();
6319
6675
  go(p);
6320
6676
  }
@@ -6393,13 +6749,20 @@ window.Aura = (() => {
6393
6749
  var React55 = __toESM(require_react(), 1);
6394
6750
  var import_react_dom11 = __toESM(require_react_dom(), 1);
6395
6751
  function position(anchor, pop, placement) {
6396
- const r = anchor.getBoundingClientRect(), pw = pop.offsetWidth, ph = pop.offsetHeight, vw = window.innerWidth, vh = window.innerHeight, gap = 6;
6752
+ const r = anchor.getBoundingClientRect(), pw = pop.offsetWidth, ph = pop.scrollHeight, vw = window.innerWidth, vh = window.innerHeight, gap = 6;
6397
6753
  let side = (placement || "bottom-start").split("-")[0], align = (placement || "bottom-start").split("-")[1] || "start";
6398
6754
  if (side === "bottom" && r.bottom + gap + ph > vh - 8 && r.top - gap - ph > 8) side = "top";
6399
6755
  else if (side === "top" && r.top - gap - ph < 8 && r.bottom + gap + ph < vh - 8) side = "bottom";
6400
- const top = side === "top" ? r.top - gap - ph : r.bottom + gap;
6756
+ const below2 = vh - r.bottom - gap - 8, above = r.top - gap - 8;
6757
+ let maxHeight;
6758
+ if (ph > below2 && ph > above) {
6759
+ side = above > below2 ? "top" : "bottom";
6760
+ maxHeight = Math.max(120, side === "top" ? above : below2);
6761
+ }
6762
+ const h9 = maxHeight ? Math.min(ph, maxHeight) : ph;
6763
+ const top = side === "top" ? r.top - gap - h9 : r.bottom + gap;
6401
6764
  const left = align === "end" ? r.right - pw : align === "center" ? r.left + r.width / 2 - pw / 2 : r.left;
6402
- return { top: Math.max(8, top), left: Math.max(8, Math.min(left, vw - pw - 8)), side };
6765
+ return { top: Math.max(8, top), left: Math.max(8, Math.min(left, vw - pw - 8)), side, maxHeight };
6403
6766
  }
6404
6767
  var Popover = React55.forwardRef(function Popover2(props, ref) {
6405
6768
  const t = useStrings();
@@ -6409,6 +6772,7 @@ window.Aura = (() => {
6409
6772
  const open = !!st[0];
6410
6773
  const wrap = React55.useRef(null), pop = React55.useRef(null), popMerged = useMergedRef(ref, pop);
6411
6774
  const pos = React55.useState(null), mounted = useMounted();
6775
+ const inTree = React55.useRef(false);
6412
6776
  function trigger() {
6413
6777
  return wrap.current && (wrap.current.querySelector('button, [role="button"], a, input') || wrap.current.firstElementChild);
6414
6778
  }
@@ -6442,13 +6806,19 @@ window.Aura = (() => {
6442
6806
  const f = pop.current.querySelector("[data-autofocus]") || pop.current.querySelector(FOCUSABLE);
6443
6807
  (f || pop.current).focus();
6444
6808
  }
6809
+ let timer;
6445
6810
  function outside(e) {
6446
6811
  if (pop.current && pop.current.contains(e.target)) return;
6447
6812
  if (wrap.current && wrap.current.contains(e.target)) return;
6448
- close(false);
6813
+ inTree.current = false;
6814
+ clearTimeout(timer);
6815
+ timer = setTimeout(function() {
6816
+ if (!inTree.current) close(false);
6817
+ }, 0);
6449
6818
  }
6450
6819
  document.addEventListener("pointerdown", outside, true);
6451
6820
  return function() {
6821
+ clearTimeout(timer);
6452
6822
  document.removeEventListener("pointerdown", outside, true);
6453
6823
  };
6454
6824
  },
@@ -6467,9 +6837,16 @@ window.Aura = (() => {
6467
6837
  "aria-label": props.title ? void 0 : props.label,
6468
6838
  "aria-labelledby": props.title ? id + "-title" : void 0,
6469
6839
  tabIndex: -1,
6840
+ onPointerDownCapture: function() {
6841
+ inTree.current = true;
6842
+ },
6470
6843
  className: cx("aura-popover", pos[0] && "is-" + pos[0].side, props.className),
6471
6844
  style: Object.assign(
6472
- { top: pos[0] ? pos[0].top : -9999, left: pos[0] ? pos[0].left : -9999 },
6845
+ {
6846
+ top: pos[0] ? pos[0].top : -9999,
6847
+ left: pos[0] ? pos[0].left : -9999,
6848
+ maxHeight: pos[0] && pos[0].maxHeight ? pos[0].maxHeight : void 0
6849
+ },
6473
6850
  props.width ? { width: props.width } : null
6474
6851
  ),
6475
6852
  onKeyDown: function(e) {
@@ -6516,7 +6893,9 @@ window.Aura = (() => {
6516
6893
  return i < 0 ? 0 : s.length - i - 1;
6517
6894
  }
6518
6895
  function parse(text) {
6519
- const s = text.replace(/[,\s ]/g, "");
6896
+ let t = text.trim();
6897
+ if (t.indexOf(".") < 0 && /^-?\d+,\d+$/.test(t.replace(/[\s ]/g, "")) && !/,\d{3}$/.test(t)) t = t.replace(",", ".");
6898
+ const s = t.replace(/[,\s ]/g, "");
6520
6899
  if (!/^-?(\d+\.?\d*|\.\d+)$/.test(s)) return NaN;
6521
6900
  return Number(s);
6522
6901
  }