@jirawatpyk/aura-react 5.15.0 → 5.16.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.
@@ -119,6 +119,7 @@ __export(index_exports, {
119
119
  useBreakpoint: () => useBreakpoint,
120
120
  useColorScheme: () => useColorScheme,
121
121
  useDensity: () => useDensity,
122
+ useDialogClose: () => useDialogClose,
122
123
  useFormatDate: () => useFormatDate,
123
124
  useResponsive: () => useResponsive
124
125
  });
@@ -2448,6 +2449,13 @@ var Combobox = React19.forwardRef(
2448
2449
  const density = useDensity();
2449
2450
  const auto = uid(), id = props.id || auto, listId = id + "-list";
2450
2451
  const options = (props.options || []).map(toOpt);
2452
+ const groups = props.groups || [];
2453
+ groups.forEach(function(g, gi) {
2454
+ g.options.forEach(function(o) {
2455
+ options.push(Object.assign({}, toOpt(o), { __g: gi }));
2456
+ });
2457
+ });
2458
+ const custom = !multi && !!props.allowCustomValue;
2451
2459
  const st = useMaybeControlled(
2452
2460
  multi ? mp.value : props.value === void 0 ? void 0 : props.value == null ? [] : [props.value],
2453
2461
  multi ? mp.defaultValue || [] : props.defaultValue == null ? [] : [props.defaultValue],
@@ -2487,7 +2495,9 @@ var Combobox = React19.forwardRef(
2487
2495
  });
2488
2496
  const more = shown.length > limit;
2489
2497
  shown = shown.slice(0, limit);
2490
- const activeIdx = Math.min(active, shown.length - 1);
2498
+ const activeIdx = active < 0 ? query ? shown.findIndex(function(o) {
2499
+ return !o.disabled && norm(o.label) === norm(query.trim());
2500
+ }) : -1 : Math.min(active, shown.length - 1);
2491
2501
  function place() {
2492
2502
  if (!boxRef.current) return;
2493
2503
  const r = boxRef.current.getBoundingClientRect();
@@ -2512,6 +2522,7 @@ var Combobox = React19.forwardRef(
2512
2522
  function outside(e) {
2513
2523
  if (boxRef.current && boxRef.current.contains(e.target)) return;
2514
2524
  if (listRef.current && listRef.current.contains(e.target)) return;
2525
+ if (commitRef.current()) return;
2515
2526
  close(false);
2516
2527
  }
2517
2528
  function onScroll(e) {
@@ -2548,6 +2559,27 @@ var Combobox = React19.forwardRef(
2548
2559
  setOpen(false);
2549
2560
  setQuery(null);
2550
2561
  }
2562
+ const committed = React19.useRef(false);
2563
+ const commitRef = React19.useRef(function() {
2564
+ return false;
2565
+ });
2566
+ function commitTyped() {
2567
+ if (!custom || query == null || committed.current) return false;
2568
+ committed.current = true;
2569
+ const q = query.trim();
2570
+ if (!q) {
2571
+ if (props.clearable !== false) setValue(null);
2572
+ } else {
2573
+ const hit = options.filter(function(o) {
2574
+ return !o.disabled && norm(o.label) === norm(q);
2575
+ })[0];
2576
+ setValue(hit ? hit.value : q);
2577
+ }
2578
+ setQuery(null);
2579
+ setOpen(false);
2580
+ return true;
2581
+ }
2582
+ commitRef.current = commitTyped;
2551
2583
  function choose(o) {
2552
2584
  if (!o || o.disabled) return;
2553
2585
  if (multi) {
@@ -2588,7 +2620,7 @@ var Combobox = React19.forwardRef(
2588
2620
  if (open && live[activeIdx]) {
2589
2621
  e.preventDefault();
2590
2622
  choose(live[activeIdx]);
2591
- }
2623
+ } else if (commitTyped()) e.preventDefault();
2592
2624
  } else if (k === "Escape") {
2593
2625
  if (open) {
2594
2626
  e.preventDefault();
@@ -2600,58 +2632,95 @@ var Combobox = React19.forwardRef(
2600
2632
  } else if (k === "Backspace" && multi && !props.readOnly && !text2 && values.length) {
2601
2633
  setValues(values.slice(0, -1));
2602
2634
  } else if (k === "Tab") {
2635
+ if (custom && open && query != null && live[activeIdx]) {
2636
+ choose(live[activeIdx]);
2637
+ return;
2638
+ }
2639
+ if (commitTyped()) return;
2603
2640
  if (open) close();
2604
2641
  }
2605
2642
  }
2606
- const text2 = query != null ? query : selected ? selected.label : "";
2643
+ const text2 = query != null ? query : selected ? selected.label : custom && value != null ? value : "";
2607
2644
  const summaryId = id + "-picked";
2608
2645
  const optId = function(i) {
2609
2646
  return id + "-opt-" + i;
2610
2647
  };
2648
+ function renderOpt(o, i) {
2649
+ const isSel = multi ? isPicked(o.value) : !!selected && o.value === selected.value;
2650
+ const blocked = o.disabled || multi && full && !isSel;
2651
+ return /* @__PURE__ */ React19.createElement(
2652
+ "li",
2653
+ {
2654
+ key: o.value,
2655
+ id: optId(i),
2656
+ role: "option",
2657
+ "data-idx": i,
2658
+ "aria-selected": isSel,
2659
+ "aria-disabled": blocked || void 0,
2660
+ className: cx(
2661
+ "aura-combo__option",
2662
+ i === activeIdx && "is-active",
2663
+ isSel && "is-selected",
2664
+ blocked && "is-disabled"
2665
+ ),
2666
+ onPointerDown: function(e) {
2667
+ e.preventDefault();
2668
+ },
2669
+ onClick: function() {
2670
+ if (!blocked || isSel) choose(o);
2671
+ },
2672
+ onPointerMove: function() {
2673
+ if (activeIdx !== i) setActive(i);
2674
+ }
2675
+ },
2676
+ o.icon ? /* @__PURE__ */ React19.createElement(Icon, { name: o.icon }) : null,
2677
+ /* @__PURE__ */ React19.createElement("span", { className: "aura-combo__text" }, /* @__PURE__ */ React19.createElement("span", { className: "aura-combo__label" }, o.label), o.description ? /* @__PURE__ */ React19.createElement("span", { className: "aura-combo__desc" }, o.description) : null),
2678
+ isSel ? /* @__PURE__ */ React19.createElement(Icon, { name: /* @__PURE__ */ React19.createElement(IconCheck, null), className: "aura-combo__check" }) : null
2679
+ );
2680
+ }
2681
+ function grouped(list2) {
2682
+ const out = [];
2683
+ list2.forEach(function(o, i) {
2684
+ const last = out[out.length - 1];
2685
+ if (last && last.g === o.__g) last.items.push([o, i]);
2686
+ else out.push({ g: o.__g, items: [[o, i]] });
2687
+ });
2688
+ return out;
2689
+ }
2611
2690
  const list = open && mounted && posState[0] ? (0, import_react_dom3.createPortal)(
2612
- /* @__PURE__ */ React19.createElement("div", { ref: listRef, "data-density": density, className: "aura-combo__popover", style: posState[0] }, live.length ? /* @__PURE__ */ React19.createElement(
2613
- "ul",
2691
+ /* @__PURE__ */ React19.createElement(
2692
+ "div",
2614
2693
  {
2615
- id: listId,
2616
- role: "listbox",
2617
- "aria-label": props.label,
2618
- "aria-multiselectable": multi || void 0,
2619
- className: "aura-combo__list"
2694
+ ref: listRef,
2695
+ "data-density": density,
2696
+ className: "aura-combo__popover",
2697
+ style: posState[0],
2698
+ onPointerDown: function(e) {
2699
+ e.preventDefault();
2700
+ }
2620
2701
  },
2621
- live.map(function(o, i) {
2622
- const isSel = multi ? isPicked(o.value) : !!selected && o.value === selected.value;
2623
- const blocked = o.disabled || multi && full && !isSel;
2624
- return /* @__PURE__ */ React19.createElement(
2625
- "li",
2626
- {
2627
- key: o.value,
2628
- id: optId(i),
2629
- role: "option",
2630
- "data-idx": i,
2631
- "aria-selected": isSel,
2632
- "aria-disabled": blocked || void 0,
2633
- className: cx(
2634
- "aura-combo__option",
2635
- i === activeIdx && "is-active",
2636
- isSel && "is-selected",
2637
- blocked && "is-disabled"
2638
- ),
2639
- onPointerDown: function(e) {
2640
- e.preventDefault();
2641
- },
2642
- onClick: function() {
2643
- if (!blocked || isSel) choose(o);
2644
- },
2645
- onPointerMove: function() {
2646
- if (activeIdx !== i) setActive(i);
2647
- }
2648
- },
2649
- o.icon ? /* @__PURE__ */ React19.createElement(Icon, { name: o.icon }) : null,
2650
- /* @__PURE__ */ React19.createElement("span", { className: "aura-combo__text" }, /* @__PURE__ */ React19.createElement("span", { className: "aura-combo__label" }, o.label), o.description ? /* @__PURE__ */ React19.createElement("span", { className: "aura-combo__desc" }, o.description) : null),
2651
- isSel ? /* @__PURE__ */ React19.createElement(Icon, { name: /* @__PURE__ */ React19.createElement(IconCheck, null), className: "aura-combo__check" }) : null
2652
- );
2653
- })
2654
- ) : null, props.loading || !live.length || more ? /* @__PURE__ */ React19.createElement("div", { className: "aura-combo__list", role: "status" }, props.loading ? /* @__PURE__ */ React19.createElement("div", { className: "aura-combo__note" }, /* @__PURE__ */ React19.createElement(Icon, { name: /* @__PURE__ */ React19.createElement(IconLoaderCircle, null), className: "aura-spin" }), props.loadingText || t.searching) : !live.length ? /* @__PURE__ */ React19.createElement("div", { className: "aura-combo__note" }, props.emptyText || t.noMatches) : /* @__PURE__ */ React19.createElement("div", { className: "aura-combo__note" }, t.keepTyping((props.options || []).length))) : null),
2702
+ live.length ? /* @__PURE__ */ React19.createElement(
2703
+ "ul",
2704
+ {
2705
+ id: listId,
2706
+ role: "listbox",
2707
+ "aria-label": props.label,
2708
+ "aria-multiselectable": multi || void 0,
2709
+ className: "aura-combo__list"
2710
+ },
2711
+ grouped(live).map(function(seg) {
2712
+ if (seg.g == null)
2713
+ return /* @__PURE__ */ React19.createElement(React19.Fragment, { key: "u" + seg.items[0][1] }, seg.items.map(function(p) {
2714
+ return renderOpt(p[0], p[1]);
2715
+ }));
2716
+ const gid = id + "-group-" + seg.g + "-" + seg.items[0][1];
2717
+ return /* @__PURE__ */ React19.createElement("li", { key: gid, role: "group", "aria-labelledby": gid, className: "aura-combo__group" }, /* @__PURE__ */ React19.createElement("span", { id: gid, role: "presentation", className: "aura-combo__group-label" }, groups[seg.g].label), /* @__PURE__ */ React19.createElement("ul", { role: "none", className: "aura-combo__grouplist" }, seg.items.map(function(p) {
2718
+ return renderOpt(p[0], p[1]);
2719
+ })));
2720
+ })
2721
+ ) : null,
2722
+ props.loading || !live.length || more ? /* @__PURE__ */ React19.createElement("div", { className: "aura-combo__list", role: "status" }, props.loading ? /* @__PURE__ */ React19.createElement("div", { className: "aura-combo__note" }, /* @__PURE__ */ React19.createElement(Icon, { name: /* @__PURE__ */ React19.createElement(IconLoaderCircle, null), className: "aura-spin" }), props.loadingText || t.searching) : !live.length ? /* @__PURE__ */ React19.createElement("div", { className: "aura-combo__note" }, props.emptyText || t.noMatches) : /* @__PURE__ */ React19.createElement("div", { className: "aura-combo__note" }, t.keepTyping(options.length))) : null
2723
+ ),
2655
2724
  document.body
2656
2725
  ) : null;
2657
2726
  return /* @__PURE__ */ React19.createElement(
@@ -2713,8 +2782,9 @@ var Combobox = React19.forwardRef(
2713
2782
  required: props.required && (!multi || !values.length),
2714
2783
  value: text2,
2715
2784
  onChange: function(e) {
2785
+ committed.current = false;
2716
2786
  setQuery(e.target.value);
2717
- setActive(0);
2787
+ setActive(custom ? -1 : 0);
2718
2788
  if (!open) setOpen(true);
2719
2789
  if (props.onSearch) props.onSearch(e.target.value);
2720
2790
  },
@@ -2723,6 +2793,8 @@ var Combobox = React19.forwardRef(
2723
2793
  onBlur: function() {
2724
2794
  setTimeout(function() {
2725
2795
  if (listRef.current && listRef.current.contains(document.activeElement)) return;
2796
+ if (custom && document.activeElement === inputRef.current) return;
2797
+ if (commitRef.current()) return;
2726
2798
  setOpen(false);
2727
2799
  setQuery(null);
2728
2800
  }, 0);
@@ -4252,6 +4324,8 @@ function useModal(open, ref, opts) {
4252
4324
  const mounted = useMounted();
4253
4325
  const prev = React27.useRef(null);
4254
4326
  const o = opts || {};
4327
+ const latest = React27.useRef(o);
4328
+ latest.current = o;
4255
4329
  React27.useEffect(
4256
4330
  function() {
4257
4331
  if (!open || !mounted) return;
@@ -4272,7 +4346,12 @@ function useModal(open, ref, opts) {
4272
4346
  if (target && o.autoFocus !== false) target.focus();
4273
4347
  return function() {
4274
4348
  unlock();
4275
- if (prev.current && prev.current.focus) prev.current.focus();
4349
+ const l = latest.current;
4350
+ const ff = l.finalFocus;
4351
+ const to = ff ? typeof ff === "function" ? ff() : ff.current : null;
4352
+ const back = to && to.isConnected ? to : prev.current;
4353
+ if (back && back.focus) back.focus();
4354
+ if (l.onCloseComplete) l.onCloseComplete();
4276
4355
  };
4277
4356
  },
4278
4357
  [open, mounted]
@@ -4654,22 +4733,77 @@ var Tooltip = React29.forwardRef(function Tooltip2(props, ref) {
4654
4733
  // src/Dialog.tsx
4655
4734
  var React30 = __toESM(require("react"), 1);
4656
4735
  var import_react_dom8 = require("react-dom");
4736
+ var DialogClose = React30.createContext(null);
4737
+ function useDialogClose() {
4738
+ return React30.useContext(DialogClose) || function() {
4739
+ };
4740
+ }
4657
4741
  var Dialog = React30.forwardRef(function Dialog2(props, ref) {
4658
4742
  const t = useStrings();
4659
4743
  const density = useDensity();
4660
4744
  const own = React30.useRef(null), merged = useMergedRef(ref, own), titleId = uid(), descId = uid();
4745
+ const openState = useMaybeControlled(props.open, false, null), open = openState[0];
4746
+ if (props.open === void 0 && !props.trigger)
4747
+ devWarnOnce("dialog-no-open", "Dialog has neither `open` nor `trigger`, so it can never open. Pass one of them.");
4748
+ const trigId = uid();
4749
+ function closeNow() {
4750
+ if (props.open === void 0) openState[1](false);
4751
+ if (props.onClose) props.onClose();
4752
+ }
4661
4753
  function close() {
4662
- if (props.dismissible !== false && props.onClose) props.onClose();
4754
+ if (props.dismissible === false) return;
4755
+ closeNow();
4663
4756
  }
4664
4757
  const scrimCloses = props.dismissible !== false && (props.dismissOnScrim !== void 0 ? props.dismissOnScrim : props.role !== "alertdialog");
4665
- const modal = useModal(props.open, own, {
4758
+ const modal = useModal(open, own, {
4666
4759
  autoFocus: props.autoFocus,
4667
4760
  onEscape: close,
4668
4761
  bodySelector: ".aura-dialog__body",
4669
- footSelector: ".aura-dialog__foot"
4762
+ footSelector: ".aura-dialog__foot",
4763
+ /* With a trigger, focus goes back to it even where a click doesn't focus buttons (Safari). */
4764
+ finalFocus: props.trigger ? function() {
4765
+ const ff = props.finalFocus;
4766
+ const to = ff ? typeof ff === "function" ? ff() : ff.current : null;
4767
+ return to || document.querySelector('[data-aura-trigger="' + trigId + '"]');
4768
+ } : props.finalFocus,
4769
+ onCloseComplete: props.onCloseComplete
4670
4770
  });
4671
- if (!modal.ready) return null;
4672
- return (0, import_react_dom8.createPortal)(
4771
+ const trig = props.trigger;
4772
+ const trigger = trig && React30.isValidElement(trig) ? React30.cloneElement(trig, {
4773
+ "aria-haspopup": "dialog",
4774
+ "aria-expanded": open,
4775
+ "data-aura-trigger": trigId,
4776
+ onClick: function(e) {
4777
+ const own2 = trig.props.onClick;
4778
+ if (own2) own2(e);
4779
+ if (e.defaultPrevented) return;
4780
+ if (props.open === void 0) openState[1](true);
4781
+ if (props.onOpen) props.onOpen();
4782
+ }
4783
+ }) : null;
4784
+ if (!modal.ready) return trigger;
4785
+ const rest = omit(props, [
4786
+ "open",
4787
+ "onClose",
4788
+ "title",
4789
+ "description",
4790
+ "children",
4791
+ "footer",
4792
+ "size",
4793
+ "dismissible",
4794
+ "dismissOnScrim",
4795
+ "role",
4796
+ "autoFocus",
4797
+ "className",
4798
+ "trigger",
4799
+ "onOpen",
4800
+ "finalFocus",
4801
+ "onCloseComplete",
4802
+ "aria-labelledby",
4803
+ "aria-describedby",
4804
+ "aria-modal"
4805
+ ]);
4806
+ const panel = (0, import_react_dom8.createPortal)(
4673
4807
  /* @__PURE__ */ React30.createElement("div", { className: "aura-dialog-layer", "data-density": density, onKeyDown: modal.onKeyDown }, /* @__PURE__ */ React30.createElement(
4674
4808
  "div",
4675
4809
  {
@@ -4683,21 +4817,22 @@ var Dialog = React30.forwardRef(function Dialog2(props, ref) {
4683
4817
  ), /* @__PURE__ */ React30.createElement(
4684
4818
  "div",
4685
4819
  {
4820
+ ...rest,
4686
4821
  ref: merged,
4687
4822
  role: props.role || "dialog",
4688
4823
  "aria-modal": true,
4689
4824
  "aria-labelledby": titleId,
4690
- "aria-describedby": props.description ? descId : void 0,
4825
+ "aria-describedby": cx(props.description ? descId : "", props["aria-describedby"]) || void 0,
4691
4826
  tabIndex: -1,
4692
4827
  className: cx("aura-dialog", "aura-dialog--" + (props.size || "md"), props.className)
4693
4828
  },
4694
4829
  /* @__PURE__ */ React30.createElement("div", { className: "aura-dialog__head" }, /* @__PURE__ */ React30.createElement("h2", { className: "aura-dialog__title", id: titleId }, props.title), props.dismissible !== false ? /* @__PURE__ */ React30.createElement(IconButton, { icon: /* @__PURE__ */ React30.createElement(IconX, null), label: t.close, className: "aura-dialog__close", onClick: close }) : null),
4695
4830
  props.description ? /* @__PURE__ */ React30.createElement("p", { className: "aura-dialog__desc", id: descId }, props.description) : null,
4696
- props.children ? /* @__PURE__ */ React30.createElement("div", { className: "aura-dialog__body" }, props.children) : null,
4697
- props.footer ? /* @__PURE__ */ React30.createElement("div", { className: "aura-dialog__foot" }, props.footer) : null
4831
+ /* @__PURE__ */ React30.createElement(DialogClose.Provider, { value: closeNow }, props.children ? /* @__PURE__ */ React30.createElement("div", { className: "aura-dialog__body" }, props.children) : null, props.footer ? /* @__PURE__ */ React30.createElement("div", { className: "aura-dialog__foot" }, props.footer) : null)
4698
4832
  )),
4699
4833
  document.body
4700
4834
  );
4835
+ return trigger ? /* @__PURE__ */ React30.createElement(React30.Fragment, null, trigger, panel) : panel;
4701
4836
  });
4702
4837
  var Drawer = React30.forwardRef(function Drawer2(props, ref) {
4703
4838
  const t = useStrings();
@@ -4710,7 +4845,9 @@ var Drawer = React30.forwardRef(function Drawer2(props, ref) {
4710
4845
  autoFocus: props.autoFocus,
4711
4846
  onEscape: close,
4712
4847
  bodySelector: ".aura-drawer__body",
4713
- footSelector: ".aura-drawer__foot"
4848
+ footSelector: ".aura-drawer__foot",
4849
+ finalFocus: props.finalFocus,
4850
+ onCloseComplete: props.onCloseComplete
4714
4851
  });
4715
4852
  if (!modal.ready) return null;
4716
4853
  const side = props.side === "left" ? "left" : "right";
@@ -4731,7 +4868,9 @@ var Drawer = React30.forwardRef(function Drawer2(props, ref) {
4731
4868
  "aria-labelledby",
4732
4869
  "className",
4733
4870
  "closeLabel",
4734
- "closeProps"
4871
+ "closeProps",
4872
+ "finalFocus",
4873
+ "onCloseComplete"
4735
4874
  ]);
4736
4875
  const drawerScrimCloses = props.dismissible !== false && props.dismissOnScrim !== false;
4737
4876
  return (0, import_react_dom8.createPortal)(
@@ -4827,7 +4966,9 @@ var DataTableImpl = React31.forwardRef(function DataTable(props, ref) {
4827
4966
  oneCallback ? null : props.onSortChange
4828
4967
  );
4829
4968
  const sort = sortState[0], setSort = sortState[1];
4830
- const selState = useMaybeControlled(props.selected, props.defaultSelected || [], props.onSelectionChange);
4969
+ const selState = useMaybeControlled(props.selected, props.defaultSelected || [], null);
4970
+ const onSel = React31.useRef(props.onSelectionChange);
4971
+ onSel.current = props.onSelectionChange;
4831
4972
  const canSelect = function(r) {
4832
4973
  return !!r && (!props.isRowSelectable || !!props.isRowSelectable(r));
4833
4974
  };
@@ -4838,7 +4979,11 @@ var DataTableImpl = React31.forwardRef(function DataTable(props, ref) {
4838
4979
  });
4839
4980
  const selected = selState[0].filter(function(k) {
4840
4981
  return !rejected[String(k)];
4841
- }), setSelected = selState[1];
4982
+ });
4983
+ function setSelected(next, change) {
4984
+ selState[1](next);
4985
+ if (onSel.current) onSel.current(next, change || { key: null, shiftKey: false, source: "sync" });
4986
+ }
4842
4987
  const droppedSig = selState[0].length === selected.length ? "" : "#" + selState[0].filter(function(k) {
4843
4988
  return rejected[String(k)];
4844
4989
  }).join("\0") + "#" + selected.join("\0");
@@ -5326,11 +5471,39 @@ var DataTableImpl = React31.forwardRef(function DataTable(props, ref) {
5326
5471
  return selSet[String(k)];
5327
5472
  }).length;
5328
5473
  const all = nSel > 0 && nSel === pageKeys.length;
5329
- function toggle(k, on) {
5474
+ const anchor = React31.useRef(null);
5475
+ const shiftClick = React31.useRef(false);
5476
+ function toggle(k, on, how) {
5477
+ const same2 = function(x) {
5478
+ return String(x) === String(k);
5479
+ };
5480
+ let range = null;
5481
+ if (props.rangeSelect && how.shiftKey && anchor.current != null) {
5482
+ const from = pageKeys.findIndex(function(x) {
5483
+ return String(x) === String(anchor.current);
5484
+ });
5485
+ const to = pageKeys.findIndex(same2);
5486
+ if (from >= 0 && to >= 0) range = pageKeys.slice(Math.min(from, to), Math.max(from, to) + 1);
5487
+ }
5488
+ anchor.current = k;
5489
+ const change = { key: k, shiftKey: how.shiftKey, source: how.source };
5490
+ if (range) {
5491
+ const inRange = {};
5492
+ range.forEach(function(x) {
5493
+ inRange[String(x)] = true;
5494
+ });
5495
+ const rest = selected.filter(function(x) {
5496
+ return !inRange[String(x)];
5497
+ });
5498
+ change.range = range;
5499
+ setSelected(on ? rest.concat(range) : rest, change);
5500
+ return;
5501
+ }
5330
5502
  setSelected(
5331
5503
  on ? selected.concat([k]) : selected.filter(function(x) {
5332
- return String(x) !== String(k);
5333
- })
5504
+ return !same2(x);
5505
+ }),
5506
+ change
5334
5507
  );
5335
5508
  }
5336
5509
  function toggleAll() {
@@ -5343,7 +5516,8 @@ var DataTableImpl = React31.forwardRef(function DataTable(props, ref) {
5343
5516
  pageKeys.filter(function(k) {
5344
5517
  return !selSet[String(k)];
5345
5518
  })
5346
- )
5519
+ ),
5520
+ { key: null, shiftKey: false, source: "all" }
5347
5521
  );
5348
5522
  }
5349
5523
  function canResize(c) {
@@ -5522,8 +5696,8 @@ var DataTableImpl = React31.forwardRef(function DataTable(props, ref) {
5522
5696
  };
5523
5697
  }).concat([{ separator: true }, { label: t.resetColumns, icon: /* @__PURE__ */ React31.createElement(IconRotateCcw, null), onSelect: resetColumns }]);
5524
5698
  }
5525
- function openMenu(kind, key, anchor, rc) {
5526
- setMenu({ kind, key, anchor, rc });
5699
+ function openMenu(kind, key, anchor2, rc) {
5700
+ setMenu({ kind, key, anchor: anchor2, rc });
5527
5701
  }
5528
5702
  function closeMenu(restore) {
5529
5703
  const m = menu;
@@ -5583,7 +5757,8 @@ var DataTableImpl = React31.forwardRef(function DataTable(props, ref) {
5583
5757
  if (pageKeys.length) toggleAll();
5584
5758
  } else if (r === 0 && col && col.sortable && canSortAny) sortBy(col.key);
5585
5759
  else if (r > 0 && k === " " && selectable) {
5586
- if (canSelect(row) && !(stacked && noCardSel)) toggle(row[rowKey], !selSet[row[rowKey]]);
5760
+ if (canSelect(row) && !(stacked && noCardSel))
5761
+ toggle(row[rowKey], !selSet[row[rowKey]], { shiftKey: e.shiftKey, source: "keyboard" });
5587
5762
  } else if (r > 0 && k === "Enter" && rowHref && !target.querySelector("button, a[href]:not(.aura-table__row-link), input, select, textarea"))
5588
5763
  followRow(target.closest('[role="row"]'), e);
5589
5764
  else if (r > 0 && k === "Enter" && target.querySelector("button, a[href], input, select, textarea"))
@@ -5773,6 +5948,9 @@ var DataTableImpl = React31.forwardRef(function DataTable(props, ref) {
5773
5948
  "aria-label": canSelect(r) ? selLabel : props.rowSelectDisabledLabel ? props.rowSelectDisabledLabel(r) : void 0,
5774
5949
  onFocus: function(e) {
5775
5950
  if (e.target === e.currentTarget) activeState[1]({ r: ri, c: 0 });
5951
+ },
5952
+ onClickCapture: function(e) {
5953
+ shiftClick.current = e.shiftKey;
5776
5954
  }
5777
5955
  },
5778
5956
  canSelect(r) ? /* @__PURE__ */ React31.createElement(
@@ -5783,7 +5961,9 @@ var DataTableImpl = React31.forwardRef(function DataTable(props, ref) {
5783
5961
  tabIndex: -1,
5784
5962
  label: selLabel,
5785
5963
  onChange: function(on) {
5786
- toggle(k, on);
5964
+ const shift = shiftClick.current;
5965
+ shiftClick.current = false;
5966
+ toggle(k, on, { shiftKey: shift, source: "click" });
5787
5967
  }
5788
5968
  }
5789
5969
  ) : null
@@ -6493,16 +6673,19 @@ var SideNav = React34.forwardRef(function SideNav2(props, ref) {
6493
6673
  return item(c, depth + 1);
6494
6674
  })));
6495
6675
  }
6496
- const on = active === it.id;
6676
+ const action = it.selectable === false;
6677
+ const on = !action && active === it.id;
6497
6678
  const common = {
6498
6679
  ...tipHandlers(it.label),
6499
- className: cx("aura-nav__item", on && "is-active"),
6680
+ className: cx("aura-nav__item", action && "aura-nav__item--action", on && "is-active"),
6500
6681
  "aria-current": on ? "page" : void 0,
6501
6682
  style: depth ? { ["--aura-nav-depth"]: depth } : void 0,
6502
6683
  onClick: function(e) {
6503
6684
  if (!it.href) e.preventDefault();
6504
6685
  else if (!plainClick(e)) return;
6505
- st[1](it.id);
6686
+ if (!action) st[1](it.id);
6687
+ if (it.onSelect) it.onSelect();
6688
+ if (action && props.onAction) props.onAction(it.id);
6506
6689
  }
6507
6690
  };
6508
6691
  return /* @__PURE__ */ React34.createElement("li", { key: it.id }, it.href ? /* @__PURE__ */ React34.createElement(Link, { href: it.href, ...common }, inner(it, false, false)) : /* @__PURE__ */ React34.createElement("button", { type: "button", ...common }, inner(it, false, false)));
@@ -6519,6 +6702,7 @@ var SideNav = React34.forwardRef(function SideNav2(props, ref) {
6519
6702
  "aura-nav",
6520
6703
  collapsed && "aura-nav--collapsed",
6521
6704
  props.bordered === false && "aura-nav--borderless",
6705
+ props.chevron === "right" && "aura-nav--chevron-right",
6522
6706
  props.className
6523
6707
  ),
6524
6708
  "data-collapsed": collapsed ? "" : void 0,
@@ -6532,7 +6716,20 @@ var SideNav = React34.forwardRef(function SideNav2(props, ref) {
6532
6716
  })));
6533
6717
  })),
6534
6718
  props.footer ? /* @__PURE__ */ React34.createElement("div", { className: "aura-nav__footer" }, props.footer) : null,
6535
- props.collapsible ? /* @__PURE__ */ React34.createElement("div", { className: "aura-nav__toggle" }, /* @__PURE__ */ React34.createElement(
6719
+ props.collapsible && props.collapseToggle === "row" ? /* @__PURE__ */ React34.createElement("div", { className: "aura-nav__toggle aura-nav__toggle--row" }, /* @__PURE__ */ React34.createElement(
6720
+ "button",
6721
+ {
6722
+ type: "button",
6723
+ className: "aura-nav__item aura-nav__item--action",
6724
+ ...tipHandlers(collapsed ? t.expandNav : t.collapseNav),
6725
+ onClick: function() {
6726
+ setTip(null);
6727
+ col[1](!collapsed);
6728
+ }
6729
+ },
6730
+ /* @__PURE__ */ React34.createElement(Icon, { name: collapsed ? /* @__PURE__ */ React34.createElement(IconPanelLeftOpen, null) : /* @__PURE__ */ React34.createElement(IconPanelLeftClose, null) }),
6731
+ /* @__PURE__ */ React34.createElement("span", { className: "aura-nav__label" }, collapsed ? t.expandNav : t.collapseNav)
6732
+ )) : props.collapsible ? /* @__PURE__ */ React34.createElement("div", { className: "aura-nav__toggle" }, /* @__PURE__ */ React34.createElement(
6536
6733
  IconButton,
6537
6734
  {
6538
6735
  icon: collapsed ? /* @__PURE__ */ React34.createElement(IconPanelLeftOpen, null) : /* @__PURE__ */ React34.createElement(IconPanelLeftClose, null),
@@ -6799,6 +6996,11 @@ var AppShell = React41.forwardRef(function AppShell2(props, ref) {
6799
6996
  onNav(id);
6800
6997
  setOpen(false);
6801
6998
  },
6999
+ /* 5.16: an action row (Sign out) closes the drawer too. */
7000
+ onAction: function(id) {
7001
+ setOpen(false);
7002
+ if (navEl.props.onAction) navEl.props.onAction(id);
7003
+ },
6802
7004
  className: cx(navEl.props.className, "is-in-drawer"),
6803
7005
  collapsed: false,
6804
7006
  collapsible: false
@@ -52,6 +52,11 @@ const AppShell = React.forwardRef(function AppShell2(props, ref) {
52
52
  onNav(id);
53
53
  setOpen(false);
54
54
  },
55
+ /* 5.16: an action row (Sign out) closes the drawer too. */
56
+ onAction: function(id) {
57
+ setOpen(false);
58
+ if (navEl.props.onAction) navEl.props.onAction(id);
59
+ },
55
60
  className: cx(navEl.props.className, "is-in-drawer"),
56
61
  collapsed: false,
57
62
  collapsible: false