@jirawatpyk/aura-react 5.1.1 → 5.3.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.
@@ -378,6 +378,12 @@ window.Aura = (() => {
378
378
  page: function(p, total) {
379
379
  return "Page " + p + " of " + total;
380
380
  },
381
+ rangeOpen: function(a, b) {
382
+ return a + "\u2013" + b + " of many";
383
+ },
384
+ pageOpen: function(p) {
385
+ return "Page " + p;
386
+ },
381
387
  prevPage: "Previous page",
382
388
  nextPage: "Next page",
383
389
  totals: "Totals",
@@ -391,6 +397,7 @@ window.Aura = (() => {
391
397
  timeOutOfRange: function(a, b) {
392
398
  return "Choose a time between " + a + " and " + b;
393
399
  },
400
+ timeUnavailable: "That time isn't available. Choose another.",
394
401
  dropFiles: "Drag files here or",
395
402
  browse: "Choose files",
396
403
  browseOne: "Choose a file",
@@ -492,6 +499,12 @@ window.Aura = (() => {
492
499
  page: function(p, total) {
493
500
  return "\u0E2B\u0E19\u0E49\u0E32 " + p + " / " + total;
494
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
+ },
495
508
  prevPage: "\u0E2B\u0E19\u0E49\u0E32\u0E01\u0E48\u0E2D\u0E19\u0E2B\u0E19\u0E49\u0E32",
496
509
  nextPage: "\u0E2B\u0E19\u0E49\u0E32\u0E16\u0E31\u0E14\u0E44\u0E1B",
497
510
  totals: "\u0E23\u0E27\u0E21",
@@ -505,6 +518,7 @@ window.Aura = (() => {
505
518
  timeOutOfRange: function(a, b) {
506
519
  return "\u0E40\u0E25\u0E37\u0E2D\u0E01\u0E40\u0E27\u0E25\u0E32\u0E23\u0E30\u0E2B\u0E27\u0E48\u0E32\u0E07 " + a + "\u2013" + b + " \u0E19.";
507
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",
508
522
  dropFiles: "\u0E25\u0E32\u0E01\u0E44\u0E1F\u0E25\u0E4C\u0E21\u0E32\u0E27\u0E32\u0E07 \u0E2B\u0E23\u0E37\u0E2D",
509
523
  browse: "\u0E40\u0E25\u0E37\u0E2D\u0E01\u0E44\u0E1F\u0E25\u0E4C",
510
524
  browseOne: "\u0E40\u0E25\u0E37\u0E2D\u0E01\u0E44\u0E1F\u0E25\u0E4C",
@@ -606,6 +620,12 @@ window.Aura = (() => {
606
620
  page: function(p, total) {
607
621
  return "Sida " + p + " av " + total;
608
622
  },
623
+ rangeOpen: function(a, b) {
624
+ return a + "\u2013" + b + " av m\xE5nga";
625
+ },
626
+ pageOpen: function(p) {
627
+ return "Sida " + p;
628
+ },
609
629
  prevPage: "F\xF6reg\xE5ende sida",
610
630
  nextPage: "N\xE4sta sida",
611
631
  totals: "Summa",
@@ -619,6 +639,7 @@ window.Aura = (() => {
619
639
  timeOutOfRange: function(a, b) {
620
640
  return "V\xE4lj en tid mellan " + a + " och " + b;
621
641
  },
642
+ timeUnavailable: "Den tiden \xE4r inte ledig. V\xE4lj en annan.",
622
643
  dropFiles: "Dra filer hit eller",
623
644
  browse: "V\xE4lj filer",
624
645
  browseOne: "V\xE4lj en fil",
@@ -1203,7 +1224,52 @@ window.Aura = (() => {
1203
1224
 
1204
1225
  // src/Select.tsx
1205
1226
  var React13 = __toESM(require_react(), 1);
1227
+ var import_react_dom2 = __toESM(require_react_dom(), 1);
1206
1228
  var h3 = React13.createElement;
1229
+ var FORM_KEYS = ["name", "form", "value", "defaultValue", "disabled", "autoComplete", "onInput", "onInvalid"];
1230
+ var HANDLED_KEYS = FORM_KEYS.concat([
1231
+ "onChange",
1232
+ "onBlur",
1233
+ "onFocus",
1234
+ "onKeyDown",
1235
+ "onClick",
1236
+ "autoFocus",
1237
+ "tabIndex",
1238
+ "aria-label",
1239
+ "aria-labelledby",
1240
+ "aria-describedby",
1241
+ "multiple",
1242
+ "size"
1243
+ ]);
1244
+ function pick(o, keys) {
1245
+ const r = {};
1246
+ for (const k of keys) if (k in o) r[k] = o[k];
1247
+ return r;
1248
+ }
1249
+ function readItems(el) {
1250
+ if (!el) return [];
1251
+ return Array.prototype.map.call(el.options, function(o, i) {
1252
+ const g = o.parentElement && o.parentElement.tagName === "OPTGROUP" ? o.parentElement : null;
1253
+ return {
1254
+ value: o.value,
1255
+ label: o.textContent || "",
1256
+ disabled: o.disabled || !!(g && g.disabled),
1257
+ group: g ? g.label : null,
1258
+ index: i
1259
+ };
1260
+ });
1261
+ }
1262
+ function initialLabel(props) {
1263
+ const opts = (props.options || []).map(function(o) {
1264
+ return typeof o === "object" ? o : { value: o, label: o };
1265
+ });
1266
+ const v = props.value !== void 0 && props.value !== null ? String(props.value) : props.defaultValue !== void 0 && props.defaultValue !== null ? String(props.defaultValue) : props.placeholder ? "" : opts[0] ? opts[0].value : "";
1267
+ const hit = opts.filter(function(o) {
1268
+ return o.value === v;
1269
+ })[0];
1270
+ if (hit) return { label: hit.label, empty: false };
1271
+ return { label: props.placeholder || "", empty: true };
1272
+ }
1207
1273
  var Select = React13.forwardRef(function Select2(props, ref) {
1208
1274
  const auto = uid(), id = props.id || auto;
1209
1275
  const rest = omit(props, FIELD_KEYS.concat(["children"]));
@@ -1216,10 +1282,259 @@ window.Aura = (() => {
1216
1282
  /* @__PURE__ */ React13.createElement("option", { key: "__ph", value: "", disabled: true }, props.placeholder)
1217
1283
  );
1218
1284
  const extra = props.value === void 0 && props.defaultValue === void 0 && props.placeholder ? { defaultValue: "" } : {};
1219
- return /* @__PURE__ */ React13.createElement(
1285
+ const native = !!props.multiple || props.size != null && props.size > 1;
1286
+ const mounted = useMounted();
1287
+ const live = !native && mounted;
1288
+ const density = useDensity();
1289
+ const selRef = React13.useRef(null), trigRef = React13.useRef(null), listRef = React13.useRef(null);
1290
+ const shown = React13.useState(function() {
1291
+ return initialLabel(props);
1292
+ });
1293
+ const openState = React13.useState(false), open = openState[0];
1294
+ const activeState = React13.useState(-1), active = activeState[0];
1295
+ const items2 = React13.useState([]);
1296
+ const pos = React13.useState(null);
1297
+ const typed = React13.useRef({ text: "", at: 0 });
1298
+ const sync = React13.useCallback(function() {
1299
+ const el = selRef.current;
1300
+ if (!el) return;
1301
+ const o = el.selectedIndex >= 0 ? el.options[el.selectedIndex] : null;
1302
+ const next = o ? { label: o.textContent || "", empty: o.value === "" } : { label: "", empty: true };
1303
+ shown[1](function(cur) {
1304
+ return cur.label === next.label && cur.empty === next.empty ? cur : next;
1305
+ });
1306
+ }, []);
1307
+ const hook = React13.useCallback(
1308
+ function(el) {
1309
+ selRef.current = el;
1310
+ if (!el || native || el.__auraHooked) return;
1311
+ el.__auraHooked = true;
1312
+ const proto = HTMLSelectElement.prototype;
1313
+ const pv = Object.getOwnPropertyDescriptor(proto, "value"), pi = Object.getOwnPropertyDescriptor(proto, "selectedIndex");
1314
+ if (pv && pv.set && pv.get)
1315
+ Object.defineProperty(el, "value", {
1316
+ configurable: true,
1317
+ get: function() {
1318
+ return pv.get.call(el);
1319
+ },
1320
+ set: function(v) {
1321
+ pv.set.call(el, v);
1322
+ sync();
1323
+ }
1324
+ });
1325
+ if (pi && pi.set && pi.get)
1326
+ Object.defineProperty(el, "selectedIndex", {
1327
+ configurable: true,
1328
+ get: function() {
1329
+ return pi.get.call(el);
1330
+ },
1331
+ set: function(v) {
1332
+ pi.set.call(el, v);
1333
+ sync();
1334
+ }
1335
+ });
1336
+ el.focus = function(o) {
1337
+ if (trigRef.current) trigRef.current.focus(o);
1338
+ else proto.focus.call(el, o);
1339
+ };
1340
+ },
1341
+ [native, sync]
1342
+ );
1343
+ const selMerged = useMergedRef(ref, hook);
1344
+ React13.useEffect(
1345
+ function() {
1346
+ const f = selRef.current && selRef.current.form;
1347
+ if (!f || native) return;
1348
+ function onReset() {
1349
+ setTimeout(sync, 0);
1350
+ }
1351
+ f.addEventListener("reset", onReset);
1352
+ return function() {
1353
+ f.removeEventListener("reset", onReset);
1354
+ };
1355
+ },
1356
+ [native, sync]
1357
+ );
1358
+ const focusedOnce = React13.useRef(false);
1359
+ React13.useEffect(
1360
+ function() {
1361
+ if (!live || focusedOnce.current || !trigRef.current) return;
1362
+ focusedOnce.current = true;
1363
+ if (props.autoFocus || selRef.current && document.activeElement === selRef.current) trigRef.current.focus();
1364
+ },
1365
+ [live]
1366
+ );
1367
+ useIsoLayoutEffect(function() {
1368
+ if (!live) return;
1369
+ sync();
1370
+ if (!open) return;
1371
+ const now = readItems(selRef.current), was = items2[0];
1372
+ const same2 = now.length === was.length && now.every(function(it, i) {
1373
+ const w = was[i];
1374
+ return w.value === it.value && w.label === it.label && w.disabled === it.disabled && w.group === it.group;
1375
+ });
1376
+ if (same2) return;
1377
+ items2[1](now);
1378
+ if (!choices(now).length) {
1379
+ close(false);
1380
+ return;
1381
+ }
1382
+ const hv = was[active] ? was[active].value : null;
1383
+ const again = now.filter(function(it) {
1384
+ return !it.disabled && it.value === hv;
1385
+ })[0];
1386
+ const cur = selRef.current ? selRef.current.selectedIndex : -1;
1387
+ activeState[1](again ? again.index : now[cur] && !now[cur].disabled ? cur : choices(now)[0].index);
1388
+ });
1389
+ function choices(list) {
1390
+ return list.filter(function(i) {
1391
+ return !i.disabled;
1392
+ });
1393
+ }
1394
+ function choose(it) {
1395
+ const el = selRef.current;
1396
+ if (!el || it.disabled) return;
1397
+ if (el.value !== it.value) {
1398
+ el.value = it.value;
1399
+ el.dispatchEvent(new Event("input", { bubbles: true }));
1400
+ el.dispatchEvent(new Event("change", { bubbles: true }));
1401
+ }
1402
+ sync();
1403
+ close(true);
1404
+ }
1405
+ function openList(at) {
1406
+ if (props.disabled || trigRef.current && trigRef.current.disabled) return;
1407
+ const list = readItems(selRef.current);
1408
+ const ok = choices(list);
1409
+ if (!ok.length) return;
1410
+ items2[1](list);
1411
+ const cur = selRef.current ? selRef.current.selectedIndex : -1;
1412
+ let a = at === "first" ? ok[0].index : at === "last" ? ok[ok.length - 1].index : cur;
1413
+ if (typeof at === "number") a = at;
1414
+ if (a < 0 || !list[a] || list[a].disabled) a = ok[0].index;
1415
+ activeState[1](a);
1416
+ openState[1](true);
1417
+ }
1418
+ function close(focus) {
1419
+ openState[1](false);
1420
+ pos[1](null);
1421
+ if (focus && trigRef.current) trigRef.current.focus();
1422
+ }
1423
+ function step(from, dir, list) {
1424
+ for (let i = from + dir; i >= 0 && i < list.length; i += dir) if (!list[i].disabled) return i;
1425
+ return from;
1426
+ }
1427
+ function typing() {
1428
+ return !!typed.current.text && Date.now() - typed.current.at < 500;
1429
+ }
1430
+ function typeahead(ch, list, from) {
1431
+ const now = Date.now(), t = typed.current;
1432
+ t.text = now - t.at < 500 ? t.text + ch : ch;
1433
+ t.at = now;
1434
+ const q = t.text.toLocaleLowerCase();
1435
+ for (let k = 1; k <= list.length; k++) {
1436
+ const i = (from + (t.text.length > 1 ? 0 : 1) + k - 1 + list.length) % list.length;
1437
+ if (!list[i].disabled && list[i].label.toLocaleLowerCase().indexOf(q) === 0) return i;
1438
+ }
1439
+ t.text = "";
1440
+ return -1;
1441
+ }
1442
+ function onKeyDown(e) {
1443
+ const k = e.key;
1444
+ const printable = k.length === 1 && !e.ctrlKey && !e.metaKey && !e.altKey;
1445
+ const search = printable && (k !== " " || typing());
1446
+ if (!open) {
1447
+ if (search) {
1448
+ const list2 = readItems(selRef.current);
1449
+ const i = typeahead(k, list2, selRef.current ? selRef.current.selectedIndex : -1);
1450
+ e.preventDefault();
1451
+ if (i >= 0) openList(i);
1452
+ } else if (k === "ArrowDown" || k === "ArrowUp" || k === "Enter" || k === " ") {
1453
+ e.preventDefault();
1454
+ openList(k === "ArrowUp" && !(selRef.current && selRef.current.value) ? "last" : void 0);
1455
+ }
1456
+ return;
1457
+ }
1458
+ const list = items2[0];
1459
+ if (search) {
1460
+ e.preventDefault();
1461
+ const i = typeahead(k, list, active);
1462
+ if (i >= 0) activeState[1](i);
1463
+ } else if (k === "ArrowDown") {
1464
+ e.preventDefault();
1465
+ activeState[1](step(active, 1, list));
1466
+ } else if (k === "ArrowUp") {
1467
+ e.preventDefault();
1468
+ activeState[1](step(active, -1, list));
1469
+ } else if (k === "Home" || k === "PageUp") {
1470
+ e.preventDefault();
1471
+ activeState[1](k === "Home" ? step(-1, 1, list) : Math.max(step(-1, 1, list), step(active - 9, 1, list)));
1472
+ } else if (k === "End" || k === "PageDown") {
1473
+ e.preventDefault();
1474
+ activeState[1](
1475
+ k === "End" ? step(list.length, -1, list) : Math.min(step(list.length, -1, list), step(active + 9, -1, list))
1476
+ );
1477
+ } else if (k === "Enter" || k === " ") {
1478
+ e.preventDefault();
1479
+ if (list[active]) choose(list[active]);
1480
+ } else if (k === "Escape") {
1481
+ e.preventDefault();
1482
+ e.stopPropagation();
1483
+ close(true);
1484
+ } else if (k === "Tab") {
1485
+ close(false);
1486
+ }
1487
+ }
1488
+ useIsoLayoutEffect(
1489
+ function() {
1490
+ if (!open) return;
1491
+ function place() {
1492
+ const t = trigRef.current && trigRef.current.parentElement;
1493
+ if (!t) return;
1494
+ const r = t.getBoundingClientRect(), below2 = window.innerHeight - r.bottom - 8, above = r.top - 8, want = listRef.current ? listRef.current.scrollHeight : 320, up = below2 < Math.min(want, 200) && above > below2;
1495
+ pos[1]({
1496
+ left: r.left,
1497
+ width: r.width,
1498
+ top: up ? void 0 : r.bottom + 4,
1499
+ bottom: up ? window.innerHeight - r.top + 4 : void 0,
1500
+ maxHeight: Math.min(320, (up ? above : below2) - 4)
1501
+ });
1502
+ }
1503
+ place();
1504
+ function outside(e) {
1505
+ const n2 = e.target;
1506
+ if (listRef.current && listRef.current.contains(n2)) return;
1507
+ if (trigRef.current && trigRef.current.contains(n2)) return;
1508
+ close(false);
1509
+ }
1510
+ function onScroll(e) {
1511
+ if (!listRef.current || !listRef.current.contains(e.target)) place();
1512
+ }
1513
+ document.addEventListener("pointerdown", outside, true);
1514
+ window.addEventListener("scroll", onScroll, true);
1515
+ window.addEventListener("resize", place);
1516
+ return function() {
1517
+ document.removeEventListener("pointerdown", outside, true);
1518
+ window.removeEventListener("scroll", onScroll, true);
1519
+ window.removeEventListener("resize", place);
1520
+ };
1521
+ },
1522
+ [open]
1523
+ );
1524
+ React13.useEffect(
1525
+ function() {
1526
+ if (!open || !listRef.current || active < 0) return;
1527
+ const el = listRef.current.querySelector('[data-idx="' + active + '"]');
1528
+ if (el && el.scrollIntoView) el.scrollIntoView({ block: "nearest" });
1529
+ },
1530
+ [open, active, pos[0] != null]
1531
+ );
1532
+ const described = [describedBy(id, props), rest["aria-describedby"]].filter(Boolean).join(" ") || void 0;
1533
+ const field = (child) => /* @__PURE__ */ React13.createElement(
1220
1534
  Field,
1221
1535
  {
1222
1536
  id,
1537
+ labelId: native ? void 0 : id + "-label",
1223
1538
  label: props.label,
1224
1539
  hint: props.hint,
1225
1540
  error: props.error,
@@ -1228,19 +1543,180 @@ window.Aura = (() => {
1228
1543
  disabled: props.disabled,
1229
1544
  className: props.className
1230
1545
  },
1231
- /* @__PURE__ */ React13.createElement("div", { className: cx("aura-input aura-select", props.icon && "has-icon") }, props.icon ? /* @__PURE__ */ React13.createElement(Icon, { name: props.icon, className: "aura-input__icon" }) : null, h3(
1232
- "select",
1233
- Object.assign(extra, rest, {
1234
- ref,
1235
- id,
1236
- className: "aura-input__control",
1237
- required: props.required,
1238
- "aria-invalid": props.error ? true : void 0,
1239
- "aria-describedby": describedBy(id, props)
1240
- }),
1241
- opts,
1242
- props.children
1243
- ), /* @__PURE__ */ React13.createElement(Icon, { name: "chevron-down", className: "aura-select__chevron" }))
1546
+ child
1547
+ );
1548
+ if (!live)
1549
+ return field(
1550
+ /* @__PURE__ */ React13.createElement("div", { className: cx("aura-input aura-select", props.icon && "has-icon") }, props.icon ? /* @__PURE__ */ React13.createElement(Icon, { name: props.icon, className: "aura-input__icon" }) : null, h3(
1551
+ "select",
1552
+ Object.assign(extra, rest, {
1553
+ ref: native ? ref : selMerged,
1554
+ id,
1555
+ className: "aura-input__control",
1556
+ required: props.required,
1557
+ "aria-invalid": props.error ? true : void 0,
1558
+ "aria-describedby": described
1559
+ }),
1560
+ opts,
1561
+ props.children
1562
+ ), /* @__PURE__ */ React13.createElement(Icon, { name: "chevron-down", className: "aura-select__chevron" }))
1563
+ );
1564
+ const listId = id + "-list", labelId = id + "-label";
1565
+ const optId = function(i) {
1566
+ return id + "-opt-" + i;
1567
+ };
1568
+ const labelledBy = rest["aria-labelledby"] || (props.label ? labelId : void 0);
1569
+ const selIndex = selRef.current ? selRef.current.selectedIndex : -1;
1570
+ const option = function(it) {
1571
+ const sel = selIndex === it.index;
1572
+ return /* @__PURE__ */ React13.createElement(
1573
+ "div",
1574
+ {
1575
+ key: it.index,
1576
+ id: optId(it.index),
1577
+ role: "option",
1578
+ "data-idx": it.index,
1579
+ "aria-selected": sel,
1580
+ "aria-disabled": it.disabled || void 0,
1581
+ className: cx(
1582
+ "aura-combo__option",
1583
+ it.index === active && "is-active",
1584
+ sel && "is-selected",
1585
+ it.disabled && "is-disabled"
1586
+ ),
1587
+ onPointerDown: function(e) {
1588
+ e.preventDefault();
1589
+ },
1590
+ onPointerMove: function() {
1591
+ if (!it.disabled && active !== it.index) activeState[1](it.index);
1592
+ },
1593
+ onClick: function() {
1594
+ choose(it);
1595
+ }
1596
+ },
1597
+ /* @__PURE__ */ React13.createElement("span", { className: "aura-combo__text" }, /* @__PURE__ */ React13.createElement("span", { className: "aura-combo__label" }, it.label)),
1598
+ sel ? /* @__PURE__ */ React13.createElement(Icon, { name: "check", className: "aura-combo__check" }) : null
1599
+ );
1600
+ };
1601
+ const runs = [];
1602
+ items2[0].forEach(function(it) {
1603
+ if (it.value === "" && it.disabled) return;
1604
+ const last = runs[runs.length - 1];
1605
+ if (last && last.group === it.group) last.items.push(it);
1606
+ else runs.push({ group: it.group, items: [it] });
1607
+ });
1608
+ const popup = open ? (0, import_react_dom2.createPortal)(
1609
+ /* @__PURE__ */ React13.createElement(
1610
+ "div",
1611
+ {
1612
+ ref: listRef,
1613
+ "data-density": density,
1614
+ className: "aura-combo__popover aura-select__popover",
1615
+ style: pos[0] ? {
1616
+ left: pos[0].left,
1617
+ minWidth: pos[0].width,
1618
+ top: pos[0].top,
1619
+ bottom: pos[0].bottom,
1620
+ maxHeight: pos[0].maxHeight
1621
+ } : { left: -9999, top: -9999 }
1622
+ },
1623
+ /* @__PURE__ */ React13.createElement(
1624
+ "div",
1625
+ {
1626
+ id: listId,
1627
+ role: "listbox",
1628
+ "aria-labelledby": labelledBy,
1629
+ "aria-label": labelledBy ? void 0 : rest["aria-label"],
1630
+ className: "aura-combo__list"
1631
+ },
1632
+ runs.map(function(r, n2) {
1633
+ if (r.group === null) return /* @__PURE__ */ React13.createElement(React13.Fragment, { key: "r" + n2 }, r.items.map(option));
1634
+ const gid = id + "-group-" + n2;
1635
+ return /* @__PURE__ */ React13.createElement("div", { key: "r" + n2, role: "group", "aria-labelledby": gid }, /* @__PURE__ */ React13.createElement("div", { id: gid, className: "aura-select__group" }, r.group), r.items.map(option));
1636
+ })
1637
+ )
1638
+ ),
1639
+ document.body
1640
+ ) : null;
1641
+ const userFocus = rest.onFocus, userBlur = rest.onBlur, userKey = rest.onKeyDown, userClick = rest.onClick;
1642
+ return field(
1643
+ /* @__PURE__ */ React13.createElement(
1644
+ "div",
1645
+ {
1646
+ className: cx("aura-input aura-select aura-select--custom", props.icon && "has-icon", open && "is-open"),
1647
+ "data-invalid": props.error ? "" : void 0
1648
+ },
1649
+ props.icon ? /* @__PURE__ */ React13.createElement(Icon, { name: props.icon, className: "aura-input__icon" }) : null,
1650
+ h3(
1651
+ "select",
1652
+ Object.assign(extra, pick(rest, FORM_KEYS), {
1653
+ ref: selMerged,
1654
+ id: id + "-select",
1655
+ className: "aura-select__native",
1656
+ tabIndex: -1,
1657
+ "aria-hidden": true,
1658
+ required: props.required,
1659
+ onChange: function(e) {
1660
+ sync();
1661
+ if (props.onChange) props.onChange(e);
1662
+ },
1663
+ /* A browser focusing the <select> (the required bubble, a label click) hands focus to the button. */
1664
+ onFocus: function() {
1665
+ if (trigRef.current) trigRef.current.focus();
1666
+ },
1667
+ /* Only the blur the button reports (below): the <select>'s own, while it hands focus over, is not one. */
1668
+ onBlur: function(e) {
1669
+ if (!e.nativeEvent.isTrusted && userBlur) userBlur(e);
1670
+ }
1671
+ }),
1672
+ opts,
1673
+ props.children
1674
+ ),
1675
+ /* @__PURE__ */ React13.createElement(
1676
+ "button",
1677
+ {
1678
+ ...omit(rest, HANDLED_KEYS),
1679
+ ref: trigRef,
1680
+ type: "button",
1681
+ role: "combobox",
1682
+ form: id + "-no-form",
1683
+ className: "aura-input__control aura-select__trigger",
1684
+ disabled: props.disabled,
1685
+ tabIndex: rest.tabIndex,
1686
+ "aria-haspopup": "listbox",
1687
+ "aria-expanded": open,
1688
+ "aria-controls": open ? listId : void 0,
1689
+ "aria-activedescendant": open && active >= 0 ? optId(active) : void 0,
1690
+ id,
1691
+ "aria-label": rest["aria-label"],
1692
+ "aria-labelledby": rest["aria-labelledby"],
1693
+ "aria-required": props.required || void 0,
1694
+ "aria-invalid": props.error ? true : void 0,
1695
+ "aria-describedby": described,
1696
+ onFocus: function(e) {
1697
+ if (userFocus) userFocus(e);
1698
+ },
1699
+ onClick: function(e) {
1700
+ if (userClick) userClick(e);
1701
+ if (e.defaultPrevented) return;
1702
+ if (open) close(true);
1703
+ else openList();
1704
+ },
1705
+ onKeyDown: function(e) {
1706
+ if (userKey) userKey(e);
1707
+ if (!e.defaultPrevented) onKeyDown(e);
1708
+ },
1709
+ onBlur: function(e) {
1710
+ if (listRef.current && e.relatedTarget && listRef.current.contains(e.relatedTarget)) return;
1711
+ if (open) close(false);
1712
+ if (selRef.current) selRef.current.dispatchEvent(new FocusEvent("focusout", { bubbles: true }));
1713
+ }
1714
+ },
1715
+ /* @__PURE__ */ React13.createElement("span", { id: id + "-value", className: cx("aura-select__value", shown[0].empty && "is-placeholder") }, shown[0].label || " ")
1716
+ ),
1717
+ /* @__PURE__ */ React13.createElement(Icon, { name: "chevron-down", className: "aura-select__chevron" }),
1718
+ popup
1719
+ )
1244
1720
  );
1245
1721
  });
1246
1722
 
@@ -1339,7 +1815,7 @@ window.Aura = (() => {
1339
1815
 
1340
1816
  // src/Combobox.tsx
1341
1817
  var React16 = __toESM(require_react(), 1);
1342
- var import_react_dom2 = __toESM(require_react_dom(), 1);
1818
+ var import_react_dom3 = __toESM(require_react_dom(), 1);
1343
1819
  function norm(s) {
1344
1820
  return String(s == null ? "" : s).normalize("NFC").toLocaleLowerCase("th");
1345
1821
  }
@@ -1359,6 +1835,7 @@ window.Aura = (() => {
1359
1835
  const multi = all.multiple === true;
1360
1836
  const mp = all;
1361
1837
  const t = useStrings();
1838
+ const density = useDensity();
1362
1839
  const auto = uid(), id = props.id || auto, listId = id + "-list";
1363
1840
  const options = (props.options || []).map(toOpt);
1364
1841
  const st = useMaybeControlled(
@@ -1521,8 +1998,8 @@ window.Aura = (() => {
1521
1998
  const optId = function(i) {
1522
1999
  return id + "-opt-" + i;
1523
2000
  };
1524
- const list = open && mounted && posState[0] ? (0, import_react_dom2.createPortal)(
1525
- /* @__PURE__ */ React16.createElement("div", { ref: listRef, className: "aura-combo__popover", style: posState[0] }, live.length ? /* @__PURE__ */ React16.createElement(
2001
+ const list = open && mounted && posState[0] ? (0, import_react_dom3.createPortal)(
2002
+ /* @__PURE__ */ React16.createElement("div", { ref: listRef, "data-density": density, className: "aura-combo__popover", style: posState[0] }, live.length ? /* @__PURE__ */ React16.createElement(
1526
2003
  "ul",
1527
2004
  {
1528
2005
  id: listId,
@@ -1682,7 +2159,7 @@ window.Aura = (() => {
1682
2159
 
1683
2160
  // src/DatePicker.tsx
1684
2161
  var React17 = __toESM(require_react(), 1);
1685
- var import_react_dom3 = __toESM(require_react_dom(), 1);
2162
+ var import_react_dom4 = __toESM(require_react_dom(), 1);
1686
2163
 
1687
2164
  // src/dates.ts
1688
2165
  var ERA = /^พ\.ศ\.\s?|\s?(BE|พ\.ศ\.)$/g;
@@ -1690,20 +2167,29 @@ window.Aura = (() => {
1690
2167
  return (n2 < 10 ? "0" : "") + n2;
1691
2168
  };
1692
2169
  function toISO(d) {
1693
- return d ? d.getFullYear() + "-" + pad(d.getMonth() + 1) + "-" + pad(d.getDate()) : null;
2170
+ if (!d) return null;
2171
+ const y = String(d.getFullYear());
2172
+ return ("000" + y).slice(-Math.max(4, y.length)) + "-" + pad(d.getMonth() + 1) + "-" + pad(d.getDate());
2173
+ }
2174
+ function makeDate(y, monthIndex2, day) {
2175
+ const d = new Date(2e3, 0, 1);
2176
+ d.setFullYear(y, monthIndex2, day);
2177
+ return d;
1694
2178
  }
1695
2179
  function fromISO(s) {
1696
2180
  if (!s) return null;
1697
2181
  const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(s);
1698
- return m ? new Date(+m[1], +m[2] - 1, +m[3]) : null;
2182
+ if (!m) return null;
2183
+ const d = makeDate(+m[1], +m[2] - 1, +m[3]);
2184
+ return d.getMonth() === +m[2] - 1 && d.getDate() === +m[3] ? d : null;
1699
2185
  }
1700
2186
  function addDays(d, n2) {
1701
- return new Date(d.getFullYear(), d.getMonth(), d.getDate() + n2);
2187
+ return makeDate(d.getFullYear(), d.getMonth(), d.getDate() + n2);
1702
2188
  }
1703
2189
  function addMonths(d, n2) {
1704
- const t = new Date(d.getFullYear(), d.getMonth() + n2, 1);
1705
- const last = new Date(t.getFullYear(), t.getMonth() + 1, 0).getDate();
1706
- return new Date(t.getFullYear(), t.getMonth(), Math.min(d.getDate(), last));
2190
+ const t = makeDate(d.getFullYear(), d.getMonth() + n2, 1);
2191
+ const last = makeDate(t.getFullYear(), t.getMonth() + 1, 0).getDate();
2192
+ return makeDate(t.getFullYear(), t.getMonth(), Math.min(d.getDate(), last));
1707
2193
  }
1708
2194
  function same(a, b) {
1709
2195
  return !!a && !!b && a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
@@ -1811,7 +2297,15 @@ window.Aura = (() => {
1811
2297
  return MONTHS[k] != null ? MONTHS[k] : -1;
1812
2298
  }
1813
2299
  function parseDate(text) {
1814
- const s = String(text || "").trim();
2300
+ const raw = String(text || "").trim();
2301
+ const gregorian = /ค\.ศ\.|\d\s*(AD|CE)\b|^\s*(AD|CE)\s/i.test(raw);
2302
+ 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();
2303
+ const eight = /^(\d{2})(\d{2})(\d{4})$/.exec(s);
2304
+ if (eight) {
2305
+ const a = +eight[3] >= 1e3 ? parseDate(eight[1] + "/" + eight[2] + "/" + eight[3] + (gregorian ? " \u0E04.\u0E28." : "")) : null;
2306
+ if (a) return a;
2307
+ s = s.slice(0, 4) + "-" + s.slice(4, 6) + "-" + s.slice(6);
2308
+ }
1815
2309
  let m = /^(\d{4})-(\d{1,2})-(\d{1,2})$/.exec(s), y, mo, d;
1816
2310
  if (m) {
1817
2311
  y = +m[1];
@@ -1821,13 +2315,13 @@ window.Aura = (() => {
1821
2315
  d = +m[1];
1822
2316
  mo = +m[2];
1823
2317
  y = +m[3];
1824
- } else if ((m = /^(\d{1,2})\s+(\S+)\s+(\d{4})$/.exec(s.replace(ERA, "").trim())) && monthIndex(m[2]) >= 0) {
2318
+ } else if ((m = /^(\d{1,2})\s+(\S+)\s+(\d{4})$/.exec(s)) && monthIndex(m[2]) >= 0) {
1825
2319
  d = +m[1];
1826
2320
  mo = monthIndex(m[2]) + 1;
1827
2321
  y = +m[3];
1828
2322
  } else return null;
1829
- if (y >= 2400) y -= 543;
1830
- const dt = new Date(y, mo - 1, d);
2323
+ if (y >= 2400 && !gregorian) y -= 543;
2324
+ const dt = makeDate(y, mo - 1, d);
1831
2325
  return dt.getMonth() === mo - 1 && dt.getDate() === d ? toISO(dt) : null;
1832
2326
  }
1833
2327
  function todayIn(timeZone) {
@@ -2118,16 +2612,16 @@ window.Aura = (() => {
2118
2612
  const pos = React17.useState(null), popRef = React17.useRef(null), mounted = useMounted();
2119
2613
  function place() {
2120
2614
  if (!boxRef.current) return;
2121
- const r = boxRef.current.getBoundingClientRect(), H = 380;
2122
- const up = window.innerHeight - r.bottom < H && r.top > H;
2123
- const left = Math.max(8, Math.min(r.left, window.innerWidth - 320 - 8));
2615
+ const el = popRef.current, r = boxRef.current.getBoundingClientRect(), W = el ? el.offsetWidth : 320, H = el ? el.offsetHeight : 380;
2616
+ const up = window.innerHeight - r.bottom < H + 12 && r.top > H + 12;
2617
+ const left = Math.max(8, Math.min(r.left, window.innerWidth - W - 8));
2124
2618
  pos[1](up ? { left, bottom: window.innerHeight - r.top + 4 } : { left, top: r.bottom + 4 });
2125
2619
  }
2126
2620
  useIsoLayoutEffect(
2127
2621
  function() {
2128
2622
  if (open) place();
2129
2623
  },
2130
- [open]
2624
+ [open, !!pos[0]]
2131
2625
  );
2132
2626
  React17.useEffect(
2133
2627
  function() {
@@ -2270,7 +2764,7 @@ window.Aura = (() => {
2270
2764
  pop.setOpen(false);
2271
2765
  if (inputRef.current) inputRef.current.focus();
2272
2766
  }
2273
- const cal = pop.open && pop.mounted && pop.pos ? (0, import_react_dom3.createPortal)(
2767
+ const cal = pop.open && pop.mounted && pop.pos ? (0, import_react_dom4.createPortal)(
2274
2768
  /* @__PURE__ */ React17.createElement(
2275
2769
  "div",
2276
2770
  {
@@ -2395,7 +2889,7 @@ window.Aura = (() => {
2395
2889
  draft[1](null);
2396
2890
  if (inputRef.current) inputRef.current.focus();
2397
2891
  }
2398
- function pick(iso) {
2892
+ function pick2(iso) {
2399
2893
  if (!draft[0]) {
2400
2894
  draft[1](iso);
2401
2895
  return;
@@ -2405,7 +2899,7 @@ window.Aura = (() => {
2405
2899
  st[1](a <= b ? { start: a, end: b } : { start: b, end: a });
2406
2900
  close();
2407
2901
  }
2408
- const cal = pop.open && pop.mounted && pop.pos ? (0, import_react_dom3.createPortal)(
2902
+ const cal = pop.open && pop.mounted && pop.pos ? (0, import_react_dom4.createPortal)(
2409
2903
  /* @__PURE__ */ React17.createElement(
2410
2904
  "div",
2411
2905
  {
@@ -2439,7 +2933,7 @@ window.Aura = (() => {
2439
2933
  start: draft[0] || v.start,
2440
2934
  end: draft[0] ? null : v.end,
2441
2935
  focus: draft[0] || v.start,
2442
- onSelect: pick
2936
+ onSelect: pick2
2443
2937
  }
2444
2938
  )
2445
2939
  ),
@@ -2509,7 +3003,7 @@ window.Aura = (() => {
2509
3003
 
2510
3004
  // src/Toaster.tsx
2511
3005
  var React19 = __toESM(require_react(), 1);
2512
- var import_react_dom4 = __toESM(require_react_dom(), 1);
3006
+ var import_react_dom5 = __toESM(require_react_dom(), 1);
2513
3007
  var MAX_VISIBLE = 3;
2514
3008
  var toastState = {
2515
3009
  list: [],
@@ -2670,7 +3164,7 @@ window.Aura = (() => {
2670
3164
  };
2671
3165
  }, []);
2672
3166
  if (!mounted) return null;
2673
- return (0, import_react_dom4.createPortal)(
3167
+ return (0, import_react_dom5.createPortal)(
2674
3168
  /* @__PURE__ */ React19.createElement(
2675
3169
  "div",
2676
3170
  {
@@ -2951,7 +3445,7 @@ window.Aura = (() => {
2951
3445
 
2952
3446
  // src/Command.tsx
2953
3447
  var React25 = __toESM(require_react(), 1);
2954
- var import_react_dom5 = __toESM(require_react_dom(), 1);
3448
+ var import_react_dom6 = __toESM(require_react_dom(), 1);
2955
3449
 
2956
3450
  // src/useModal.tsx
2957
3451
  var React24 = __toESM(require_react(), 1);
@@ -3155,7 +3649,7 @@ window.Aura = (() => {
3155
3649
  }
3156
3650
  if (!modal.ready) return null;
3157
3651
  let i = -1;
3158
- return (0, import_react_dom5.createPortal)(
3652
+ return (0, import_react_dom6.createPortal)(
3159
3653
  /* @__PURE__ */ React25.createElement(
3160
3654
  "div",
3161
3655
  {
@@ -3264,7 +3758,7 @@ window.Aura = (() => {
3264
3758
 
3265
3759
  // src/Tooltip.tsx
3266
3760
  var React26 = __toESM(require_react(), 1);
3267
- var import_react_dom6 = __toESM(require_react_dom(), 1);
3761
+ var import_react_dom7 = __toESM(require_react_dom(), 1);
3268
3762
  var Tooltip = React26.forwardRef(function Tooltip2(props, ref) {
3269
3763
  const id = uid(), st = React26.useState(false), open = props.open !== void 0 ? props.open : st[0], set = st[1];
3270
3764
  const anchor = React26.useRef(null), anchorMerged = useMergedRef(ref, anchor), tip = React26.useRef(null), timer = React26.useRef(void 0);
@@ -3362,7 +3856,7 @@ window.Aura = (() => {
3362
3856
  },
3363
3857
  React26.cloneElement(child, { "aria-describedby": open ? id : child.props["aria-describedby"] })
3364
3858
  );
3365
- return /* @__PURE__ */ React26.createElement(React26.Fragment, null, trigger, open && mounted ? (0, import_react_dom6.createPortal)(
3859
+ return /* @__PURE__ */ React26.createElement(React26.Fragment, null, trigger, open && mounted ? (0, import_react_dom7.createPortal)(
3366
3860
  /* @__PURE__ */ React26.createElement(
3367
3861
  "div",
3368
3862
  {
@@ -3384,7 +3878,7 @@ window.Aura = (() => {
3384
3878
 
3385
3879
  // src/Dialog.tsx
3386
3880
  var React27 = __toESM(require_react(), 1);
3387
- var import_react_dom7 = __toESM(require_react_dom(), 1);
3881
+ var import_react_dom8 = __toESM(require_react_dom(), 1);
3388
3882
  var Dialog = React27.forwardRef(function Dialog2(props, ref) {
3389
3883
  const t = useStrings();
3390
3884
  const density = useDensity();
@@ -3399,7 +3893,7 @@ window.Aura = (() => {
3399
3893
  footSelector: ".aura-dialog__foot"
3400
3894
  });
3401
3895
  if (!modal.ready) return null;
3402
- return (0, import_react_dom7.createPortal)(
3896
+ return (0, import_react_dom8.createPortal)(
3403
3897
  /* @__PURE__ */ React27.createElement("div", { className: "aura-dialog-layer", "data-density": density, onKeyDown: modal.onKeyDown }, /* @__PURE__ */ React27.createElement("div", { className: "aura-scrim", onClick: close, "aria-hidden": true }), /* @__PURE__ */ React27.createElement(
3404
3898
  "div",
3405
3899
  {
@@ -3434,7 +3928,7 @@ window.Aura = (() => {
3434
3928
  });
3435
3929
  if (!modal.ready) return null;
3436
3930
  const side = props.side === "left" ? "left" : "right";
3437
- return (0, import_react_dom7.createPortal)(
3931
+ return (0, import_react_dom8.createPortal)(
3438
3932
  /* @__PURE__ */ React27.createElement("div", { className: "aura-dialog-layer aura-drawer-layer", "data-density": density, onKeyDown: modal.onKeyDown }, /* @__PURE__ */ React27.createElement("div", { className: "aura-scrim", onClick: close, "aria-hidden": true }), /* @__PURE__ */ React27.createElement(
3439
3933
  "div",
3440
3934
  {
@@ -3458,7 +3952,7 @@ window.Aura = (() => {
3458
3952
 
3459
3953
  // src/DataTable.tsx
3460
3954
  var React28 = __toESM(require_react(), 1);
3461
- var import_react_dom8 = __toESM(require_react_dom(), 1);
3955
+ var import_react_dom9 = __toESM(require_react_dom(), 1);
3462
3956
  var BP = { sm: 640, md: 768, lg: 1024, xl: 1280 };
3463
3957
  var DEFAULT_COLUMNS = [
3464
3958
  { key: "id", label: "ID", width: 96, mono: true },
@@ -3615,7 +4109,7 @@ window.Aura = (() => {
3615
4109
  function hideFull() {
3616
4110
  setTip(null);
3617
4111
  }
3618
- const tipEl = tip && typeof document !== "undefined" ? (0, import_react_dom8.createPortal)(
4112
+ const tipEl = tip && typeof document !== "undefined" ? (0, import_react_dom9.createPortal)(
3619
4113
  /* @__PURE__ */ React28.createElement(
3620
4114
  "div",
3621
4115
  {
@@ -3696,11 +4190,12 @@ window.Aura = (() => {
3696
4190
  if (lv && boxWidth[0] == null) hideTerms += " + " + w + "px * var(--aura-h" + lv + "-on, 1)";
3697
4191
  else fixedSum += w;
3698
4192
  });
3699
- let pinOffsets = {}, acc = 0;
4193
+ let pinOffsets = {}, acc = "0px";
3700
4194
  vis.forEach(function(c) {
3701
4195
  if (isPinned(c)) {
3702
4196
  pinOffsets[c.key] = acc;
3703
- acc += widthOf(c);
4197
+ const lv = hideLevel(c);
4198
+ acc += " + " + widthOf(c) + "px" + (lv && boxWidth[0] == null ? " * var(--aura-h" + lv + "-on, 1)" : "");
3704
4199
  }
3705
4200
  });
3706
4201
  const selW = selectable ? " + var(--aura-table-select-width)" : "";
@@ -3715,7 +4210,7 @@ window.Aura = (() => {
3715
4210
  s["--aura-cell-flex"] = !hasFlex && i === vis.length - 1 ? "1 0 auto" : "none";
3716
4211
  s["--aura-cell-w"] = w + "px";
3717
4212
  }
3718
- if (isPinned(c)) s["--aura-cell-left"] = "calc(var(--aura-space-6)" + selW + " + " + pinOffsets[c.key] + "px)";
4213
+ if (isPinned(c)) s["--aura-cell-left"] = "calc(var(--aura-space-6)" + selW + " + " + pinOffsets[c.key] + ")";
3719
4214
  return s;
3720
4215
  }
3721
4216
  const sortCol = sort && sort.key ? byKey[sort.key] : void 0;
@@ -3761,6 +4256,20 @@ window.Aura = (() => {
3761
4256
  const pageRows = pageSize && !manual ? view.slice(first, first + pageSize) : view;
3762
4257
  const canSortAny = !busy && (manual ? total > 1 : rows.length > 1);
3763
4258
  const shownTotal = manual && props.totalRows == null ? first + rows.length : total;
4259
+ const prevCount = React28.useRef(pageCount);
4260
+ React28.useEffect(
4261
+ function() {
4262
+ if (busy) return;
4263
+ const before = prevCount.current;
4264
+ prevCount.current = pageCount;
4265
+ const asked = pageState[0] || 1;
4266
+ if (asked === page || pageCount >= before || asked > before) return;
4267
+ if (props.getPageHref && !props.onPageChange && !props.onStateChange) return;
4268
+ pageState[1](page);
4269
+ emit(sort, page);
4270
+ },
4271
+ [pageState[0], page, busy, pageCount]
4272
+ );
3764
4273
  const linkPaging = !!props.getPageHref && !props.onPageChange && !oneCallback;
3765
4274
  const prevLink = React28.useRef(null), nextLink = React28.useRef(null), jumpLink = React28.useRef(null);
3766
4275
  const jumpState = React28.useState(null);
@@ -3829,9 +4338,10 @@ window.Aura = (() => {
3829
4338
  const visibleRows = Math.max(1, Math.floor(bodyH / ROW_H));
3830
4339
  const nCols = vis.length + (selectable ? 1 : 0);
3831
4340
  const nRows = loading ? 0 : pageRows.length;
4341
+ const hasTotal = !!(props.footer && rows.length && !loading), T = nRows + 1, lastR = nRows + (hasTotal ? 1 : 0);
3832
4342
  const active = activeState[0];
3833
- const ar = Math.min(active.r, nRows), ac = Math.min(active.c, nCols - 1);
3834
- const activeRendered = ar === 0 || ar - 1 >= start && ar - 1 < end;
4343
+ const ar = Math.min(active.r, lastR), ac = Math.min(active.c, nCols - 1);
4344
+ const activeRendered = ar === 0 || hasTotal && ar === T || ar - 1 >= start && ar - 1 < end;
3835
4345
  function colAt(ci) {
3836
4346
  return selectable ? ci === 0 ? null : vis[ci - 1] : vis[ci];
3837
4347
  }
@@ -3862,12 +4372,33 @@ window.Aura = (() => {
3862
4372
  }
3863
4373
  });
3864
4374
  function focusCell(r, c) {
3865
- r = Math.max(0, Math.min(r, nRows));
4375
+ r = Math.max(0, Math.min(r, lastR));
3866
4376
  c = Math.max(0, Math.min(c, nCols - 1));
3867
4377
  if (stacked && r === 0 && nRows > 0 && !(selectable && c === 0)) r = 1;
4378
+ if (gridRef.current && r === T && hasTotal) {
4379
+ const shown2 = function(cc) {
4380
+ const e = gridRef.current.querySelector('[data-rc="' + r + ":" + cc + '"]');
4381
+ return !!e && e.getClientRects().length > 0;
4382
+ };
4383
+ if (!shown2(c))
4384
+ for (let d = 1; d < nCols; d++) {
4385
+ if (c + d < nCols && shown2(c + d)) {
4386
+ c = c + d;
4387
+ break;
4388
+ }
4389
+ if (c - d >= 0 && shown2(c - d)) {
4390
+ c = c - d;
4391
+ break;
4392
+ }
4393
+ }
4394
+ }
3868
4395
  activeState[1]({ r, c });
3869
4396
  pending.current = { r, c };
3870
- if (virtual && r > 0) {
4397
+ if (virtual && hasTotal && r === T && !props.stickyFooter) {
4398
+ const sc = scrollRef.current;
4399
+ sc.scrollTop = sc.scrollHeight;
4400
+ setScrollTop(sc.scrollTop);
4401
+ } else if (virtual && r > 0 && r <= nRows) {
3871
4402
  const sc = scrollRef.current, top = (r - 1) * ROW_H;
3872
4403
  if (top < sc.scrollTop) sc.scrollTop = top;
3873
4404
  else if (top + ROW_H > sc.scrollTop + bodyH) sc.scrollTop = top + ROW_H - bodyH;
@@ -4110,7 +4641,7 @@ window.Aura = (() => {
4110
4641
  return;
4111
4642
  }
4112
4643
  const p = rc.split(":"), r = +p[0], c = +p[1], k = e.key, col = colAt(c);
4113
- const row = r > 0 ? pageRows[r - 1] : null;
4644
+ const row = r > 0 && r <= nRows ? pageRows[r - 1] : null, isTotal = hasTotal && r === T;
4114
4645
  let handled = true;
4115
4646
  if (r === 0 && col && e.altKey && (k === "ArrowLeft" || k === "ArrowRight") && canResize(col))
4116
4647
  setW(col, widthOf(col) + (k === "ArrowLeft" ? -1 : 1) * (e.shiftKey ? 48 : 16), true);
@@ -4121,21 +4652,23 @@ window.Aura = (() => {
4121
4652
  else if (k === "ArrowRight") focusCell(r, c + 1);
4122
4653
  else if (k === "ArrowLeft") focusCell(r, c - 1);
4123
4654
  else if (k === "ArrowDown") {
4124
- if (r < nRows) focusCell(r + 1, c);
4655
+ if (r < lastR) focusCell(r + 1, c);
4125
4656
  else if (pageSize && page < pageCount && goPage(page + 1, { r: 1, c })) activeState[1]({ r: 1, c });
4126
4657
  } else if (k === "ArrowUp") {
4127
4658
  if (r > 1 || r === 1 && !(pageSize && page > 1)) focusCell(r - 1, c);
4128
4659
  else if (r === 1 && goPage(page - 1, { r: pageSize, c })) activeState[1]({ r: pageSize, c });
4129
4660
  } else if (k === "Home") focusCell(e.ctrlKey ? 1 : r, 0);
4130
- else if (k === "End") focusCell(e.ctrlKey ? nRows : r, nCols - 1);
4661
+ else if (k === "End") focusCell(e.ctrlKey ? lastR : r, nCols - 1);
4131
4662
  else if (k === "PageDown") {
4132
4663
  if (pageSize) {
4133
4664
  if (goPage(page + 1, { r: 1, c })) activeState[1]({ r: 1, c });
4134
- } else focusCell(Math.min(nRows, r + visibleRows), c);
4665
+ } else focusCell(Math.min(lastR, r + visibleRows), c);
4135
4666
  } else if (k === "PageUp") {
4136
4667
  if (pageSize) {
4137
4668
  if (goPage(page - 1, { r: 1, c })) activeState[1]({ r: 1, c });
4138
4669
  } else focusCell(Math.max(1, r - visibleRows), c);
4670
+ } else if (isTotal && (k === " " || k === "Enter" || k === "F2")) {
4671
+ handled = false;
4139
4672
  } else if (k === "F2" && r > 0) {
4140
4673
  const inner = target.querySelector("button, a[href], input, select, textarea");
4141
4674
  if (inner) inner.focus();
@@ -4506,9 +5039,10 @@ window.Aura = (() => {
4506
5039
  }
4507
5040
  );
4508
5041
  }
5042
+ const openTotal = manual && props.totalRows == null && !!pageSize && rows.length >= pageSize;
4509
5043
  if (pageSize && (rows.length || busy || page > 1)) {
4510
5044
  const from = rows.length ? first + 1 : 0, to = manual ? first + rows.length : Math.min(first + pageSize, view.length);
4511
- 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)));
5045
+ 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)));
4512
5046
  } else if (height && rows.length && !loading) {
4513
5047
  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));
4514
5048
  }
@@ -4522,15 +5056,32 @@ window.Aura = (() => {
4522
5056
  style: rowStyle
4523
5057
  },
4524
5058
  /* @__PURE__ */ React28.createElement("span", { className: "aura-table__gutter", "aria-hidden": true }),
4525
- selectable ? /* @__PURE__ */ React28.createElement("span", { className: cx("aura-table__sel", nPinned && "is-pinned"), "aria-hidden": true }) : null,
5059
+ selectable ? /* @__PURE__ */ React28.createElement(
5060
+ "span",
5061
+ {
5062
+ role: "gridcell",
5063
+ "aria-colindex": 1,
5064
+ className: cx("aura-table__sel", nPinned && "is-pinned"),
5065
+ tabIndex: tabFor(T, 0),
5066
+ "data-rc": T + ":0",
5067
+ onFocus: function() {
5068
+ activeState[1]({ r: T, c: 0 });
5069
+ }
5070
+ }
5071
+ ) : null,
4526
5072
  vis.map(function(c, j) {
4527
- const pin = isPinned(c);
5073
+ const pin = isPinned(c), ci = j + (selectable ? 1 : 0);
4528
5074
  return /* @__PURE__ */ React28.createElement(
4529
5075
  "span",
4530
5076
  {
4531
5077
  key: c.key,
4532
5078
  role: "gridcell",
4533
5079
  "aria-colindex": j + (selectable ? 2 : 1),
5080
+ tabIndex: tabFor(T, ci),
5081
+ "data-rc": T + ":" + ci,
5082
+ onFocus: function() {
5083
+ if (activeState[0].r !== T || activeState[0].c !== ci) activeState[1]({ r: T, c: ci });
5084
+ },
4534
5085
  className: cx(
4535
5086
  "aura-table__td",
4536
5087
  c.mono && "aura-table__mono",
@@ -4556,7 +5107,7 @@ window.Aura = (() => {
4556
5107
  )
4557
5108
  ) : null;
4558
5109
  const scrollStyle = {
4559
- scrollPaddingLeft: "calc(var(--aura-space-6)" + selW + " + " + acc + "px)",
5110
+ scrollPaddingLeft: "calc(var(--aura-space-6)" + selW + " + " + acc + ")",
4560
5111
  scrollPaddingTop: ROW_H + "px",
4561
5112
  scrollPaddingBottom: stickyTotal ? ROW_H + "px" : void 0
4562
5113
  };
@@ -4808,7 +5359,7 @@ window.Aura = (() => {
4808
5359
 
4809
5360
  // src/SideNav.tsx
4810
5361
  var React31 = __toESM(require_react(), 1);
4811
- var import_react_dom9 = __toESM(require_react_dom(), 1);
5362
+ var import_react_dom10 = __toESM(require_react_dom(), 1);
4812
5363
  function contains(it, id) {
4813
5364
  return !!id && !!it.children && it.children.some(function(c) {
4814
5365
  return c.id === id || contains(c, id);
@@ -5001,7 +5552,7 @@ window.Aura = (() => {
5001
5552
  }
5002
5553
  }
5003
5554
  )) : null,
5004
- tip && typeof document !== "undefined" ? (0, import_react_dom9.createPortal)(
5555
+ tip && typeof document !== "undefined" ? (0, import_react_dom10.createPortal)(
5005
5556
  /* @__PURE__ */ React31.createElement(
5006
5557
  "div",
5007
5558
  {
@@ -5445,7 +5996,7 @@ window.Aura = (() => {
5445
5996
 
5446
5997
  // src/TimePicker.tsx
5447
5998
  var React45 = __toESM(require_react(), 1);
5448
- var import_react_dom10 = __toESM(require_react_dom(), 1);
5999
+ var import_react_dom11 = __toESM(require_react_dom(), 1);
5449
6000
 
5450
6001
  // src/text.ts
5451
6002
  function formatBytes(n2) {
@@ -5468,6 +6019,7 @@ window.Aura = (() => {
5468
6019
  const m = /^(\d{1,2})(?:[:.](\d{2}))?$/.exec(s) || /^(\d{1,2})(\d{2})$/.exec(s);
5469
6020
  if (!m) return null;
5470
6021
  let hh = +m[1], mm = m[2] ? +m[2] : 0;
6022
+ if ((am || pm) && (hh < 1 || hh > 12)) return null;
5471
6023
  if (pm && hh < 12) hh += 12;
5472
6024
  if (am && hh === 12) hh = 0;
5473
6025
  if (hh > 23 || mm > 59) return null;
@@ -5582,7 +6134,8 @@ window.Aura = (() => {
5582
6134
  return true;
5583
6135
  }
5584
6136
  if (blocked(v)) {
5585
- errState[1](t.timeOutOfRange(fromMin(lo), fromMin(hi)));
6137
+ const n2 = toMin(v);
6138
+ errState[1](n2 != null && n2 >= lo && n2 <= hi ? t.timeUnavailable : t.timeOutOfRange(fromMin(lo), fromMin(hi)));
5586
6139
  return false;
5587
6140
  }
5588
6141
  errState[1](null);
@@ -5659,7 +6212,7 @@ window.Aura = (() => {
5659
6212
  }
5660
6213
  }
5661
6214
  const error = errState[0] || props.error;
5662
- const list = open && mounted && pos[0] ? (0, import_react_dom10.createPortal)(
6215
+ const list = open && mounted && pos[0] ? (0, import_react_dom11.createPortal)(
5663
6216
  /* @__PURE__ */ React45.createElement("div", { ref: listRef, className: "aura-combo__popover aura-time__popover", style: pos[0] }, /* @__PURE__ */ React45.createElement("ul", { id: listId, role: "listbox", "aria-label": props.label, className: "aura-combo__list" }, slots.map(function(s, i) {
5664
6217
  const dis = blocked(s), sel = s === value;
5665
6218
  return /* @__PURE__ */ React45.createElement(
@@ -5841,6 +6394,7 @@ window.Aura = (() => {
5841
6394
  [items2, props.name]
5842
6395
  );
5843
6396
  function thumb(it) {
6397
+ if (!it.file && it.url && /^image\//.test(it.type || "")) return it.url;
5844
6398
  if (!it.file || !/^image\//.test(it.type || "") || typeof URL === "undefined" || !URL.createObjectURL) return null;
5845
6399
  if (!urls.current[it.id]) urls.current[it.id] = URL.createObjectURL(it.file);
5846
6400
  return urls.current[it.id];
@@ -5946,7 +6500,7 @@ window.Aura = (() => {
5946
6500
  ),
5947
6501
  items2.length ? /* @__PURE__ */ React46.createElement("ul", { className: "aura-upload__list", "aria-live": "polite" }, items2.map(function(it) {
5948
6502
  const src = thumb(it);
5949
- 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(
6503
+ 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(
5950
6504
  "span",
5951
6505
  {
5952
6506
  className: "aura-upload__bar",
@@ -6649,15 +7203,22 @@ window.Aura = (() => {
6649
7203
 
6650
7204
  // src/Popover.tsx
6651
7205
  var React55 = __toESM(require_react(), 1);
6652
- var import_react_dom11 = __toESM(require_react_dom(), 1);
7206
+ var import_react_dom12 = __toESM(require_react_dom(), 1);
6653
7207
  function position(anchor, pop, placement) {
6654
- const r = anchor.getBoundingClientRect(), pw = pop.offsetWidth, ph = pop.offsetHeight, vw = window.innerWidth, vh = window.innerHeight, gap = 6;
7208
+ const r = anchor.getBoundingClientRect(), pw = pop.offsetWidth, ph = pop.scrollHeight, vw = window.innerWidth, vh = window.innerHeight, gap = 6;
6655
7209
  let side = (placement || "bottom-start").split("-")[0], align = (placement || "bottom-start").split("-")[1] || "start";
6656
7210
  if (side === "bottom" && r.bottom + gap + ph > vh - 8 && r.top - gap - ph > 8) side = "top";
6657
7211
  else if (side === "top" && r.top - gap - ph < 8 && r.bottom + gap + ph < vh - 8) side = "bottom";
6658
- const top = side === "top" ? r.top - gap - ph : r.bottom + gap;
7212
+ const below2 = vh - r.bottom - gap - 8, above = r.top - gap - 8;
7213
+ let maxHeight;
7214
+ if (ph > below2 && ph > above) {
7215
+ side = above > below2 ? "top" : "bottom";
7216
+ maxHeight = Math.max(120, side === "top" ? above : below2);
7217
+ }
7218
+ const h9 = maxHeight ? Math.min(ph, maxHeight) : ph;
7219
+ const top = side === "top" ? r.top - gap - h9 : r.bottom + gap;
6659
7220
  const left = align === "end" ? r.right - pw : align === "center" ? r.left + r.width / 2 - pw / 2 : r.left;
6660
- return { top: Math.max(8, top), left: Math.max(8, Math.min(left, vw - pw - 8)), side };
7221
+ return { top: Math.max(8, top), left: Math.max(8, Math.min(left, vw - pw - 8)), side, maxHeight };
6661
7222
  }
6662
7223
  var Popover = React55.forwardRef(function Popover2(props, ref) {
6663
7224
  const t = useStrings();
@@ -6720,7 +7281,7 @@ window.Aura = (() => {
6720
7281
  [open, mounted]
6721
7282
  );
6722
7283
  const child = React55.Children.only(props.trigger);
6723
- const panel = open && mounted ? (0, import_react_dom11.createPortal)(
7284
+ const panel = open && mounted ? (0, import_react_dom12.createPortal)(
6724
7285
  /* @__PURE__ */ React55.createElement(
6725
7286
  "div",
6726
7287
  {
@@ -6737,7 +7298,11 @@ window.Aura = (() => {
6737
7298
  },
6738
7299
  className: cx("aura-popover", pos[0] && "is-" + pos[0].side, props.className),
6739
7300
  style: Object.assign(
6740
- { top: pos[0] ? pos[0].top : -9999, left: pos[0] ? pos[0].left : -9999 },
7301
+ {
7302
+ top: pos[0] ? pos[0].top : -9999,
7303
+ left: pos[0] ? pos[0].left : -9999,
7304
+ maxHeight: pos[0] && pos[0].maxHeight ? pos[0].maxHeight : void 0
7305
+ },
6741
7306
  props.width ? { width: props.width } : null
6742
7307
  ),
6743
7308
  onKeyDown: function(e) {