asma-ui-core 3.86.1 → 3.87.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 (50) hide show
  1. package/dist/asma-ui-core.css +1 -1
  2. package/dist/components/custom/pathfinder-card/PathfinderCard.js +28 -28
  3. package/dist/components/data-display/chip/StyledChip.js +33 -32
  4. package/dist/components/data-display/tooltip/StyledTooltip.js +76 -47
  5. package/dist/components/feedback/dialog/StyledDialog.js +62 -58
  6. package/dist/components/feedback/minimizable-dialog/MinimizableDialog.js +113 -105
  7. package/dist/components/feedback/minimizable-dialog/components/FullscreenBtn.js +10 -12
  8. package/dist/components/feedback/minimizable-dialog/v2/MinimizableDialogV2.js +75 -67
  9. package/dist/components/feedback/snack-bar/StyledSnackbar.js +12 -10
  10. package/dist/components/feedback/snack-bar/components/StyledInfoSnackbar.js +10 -10
  11. package/dist/components/inputs/dynamic-select/components/DynamicSelectAutocomplete.js +69 -71
  12. package/dist/components/inputs/input-field/StyledInputField.js +25 -24
  13. package/dist/components/inputs/phone-field/CountryCodeOptions.js +16 -15
  14. package/dist/components/inputs/phone-field/CountryCodeSelect.js +98 -85
  15. package/dist/components/inputs/phone-field/useCountryPicker.js +44 -24
  16. package/dist/components/inputs/search-field/StyledSearchField.js +10 -10
  17. package/dist/components/inputs/select/StyledSelect.js +16 -15
  18. package/dist/components/inputs/select/StyledSelectItem.js +9 -9
  19. package/dist/components/inputs/select-autocomplete/StyledSelectAutocomplete.js +202 -175
  20. package/dist/components/inputs/switch/base-ui/StyledSwitch.js +22 -22
  21. package/dist/components/navigation/link/StyledLink.js +8 -8
  22. package/dist/components/navigation/listbox/Listbox.js +105 -54
  23. package/dist/components/navigation/menu/StyledMenu.js +22 -18
  24. package/dist/components/navigation/menu/StyledMenuItem.js +6 -6
  25. package/dist/components/navigation/title-chevron/StyledTitleChevron.js +7 -7
  26. package/dist/components/utils/accordion/base-ui/StyledAccordionDetails.js +26 -22
  27. package/dist/components/utils/accordion/base-ui/StyledAccordionSummary.js +14 -14
  28. package/dist/components/utils/copy-wrapper/CopyWrapper.module.js +2 -2
  29. package/dist/components/utils/popover/StyledPopover.js +102 -52
  30. package/dist/datetime/components/date-picker/StyledDatePicker.js +40 -34
  31. package/dist/datetime/components/date-picker/components/StyledCalendarPicker.js +5 -4
  32. package/dist/datetime/components/time-picker/StyledTimePicker.js +69 -56
  33. package/dist/helpers/focusable.js +5 -0
  34. package/dist/hooks/useFocusTrap.hook.js +24 -19
  35. package/dist/src/components/data-display/chip/StyledChip.d.ts +2 -0
  36. package/dist/src/components/inputs/dynamic-select/StyledDynamicSelect.d.ts +3 -4
  37. package/dist/src/components/inputs/dynamic-select/components/DynamicSelectAutocomplete.test.d.ts +1 -0
  38. package/dist/src/components/inputs/phone-field/CountryCodeOptions.d.ts +1 -1
  39. package/dist/src/components/inputs/phone-field/useCountryPicker.d.ts +5 -2
  40. package/dist/src/components/navigation/listbox/Listbox.d.ts +3 -2
  41. package/dist/src/components/navigation/menu/StyledMenu.d.ts +3 -2
  42. package/dist/src/components/utils/accordion/base-ui/StyledAccordionDetails.d.ts +2 -1
  43. package/dist/src/components/utils/popover/StyledPopover.d.ts +9 -2
  44. package/dist/src/helpers/focusable.d.ts +8 -0
  45. package/dist/src/hooks/useFocusTrap.hook.d.ts +2 -1
  46. package/dist/table/components/columns/action-column/components/RowActionMenu.js +30 -34
  47. package/dist/table/components/table-footer/TablePagination.js +18 -17
  48. package/dist/table/components/table-footer/TableRowCountSelect.js +5 -4
  49. package/package.json +1 -1
  50. package/src/styles/touchHardening.interaction.test.tsx +269 -0
@@ -1,54 +1,60 @@
1
- import { setPickerPosition as f } from "./helpers.js";
1
+ import { setPickerPosition as P } from "./helpers.js";
2
2
  import { StyledDayPicker as k } from "./components/StyledDayPicker.js";
3
- import { StyledCalendarPicker as u } from "./components/StyledCalendarPicker.js";
4
- import { DatePickerInputIndex as x } from "./components/DatePickerInputIndex.js";
5
- import { useIsMobileView as v } from "../../hooks/useWindowWidthSize.hook.js";
6
- import { StyledDrawer as C } from "../../../components/navigation/drawer/StyledDrawer.js";
7
- import { useBackNavigationClose as b } from "../../hooks/useBackNavigationClose.hook.js";
8
- import { useState as a } from "react";
9
- import { Fragment as h, jsx as o, jsxs as y } from "react/jsx-runtime";
10
- var E = (p) => {
11
- const s = v(), [e, n] = a(null), [c, m] = a(!1), [d, i] = a(!1), P = (l) => {
12
- n(l.currentTarget), f(l, m);
13
- }, r = () => {
14
- i(!0), n(null);
3
+ import { StyledCalendarPicker as v } from "./components/StyledCalendarPicker.js";
4
+ import { DatePickerInputIndex as y } from "./components/DatePickerInputIndex.js";
5
+ import { useIsMobileView as x } from "../../hooks/useWindowWidthSize.hook.js";
6
+ import { StyledDrawer as b } from "../../../components/navigation/drawer/StyledDrawer.js";
7
+ import { useBackNavigationClose as h } from "../../hooks/useBackNavigationClose.hook.js";
8
+ import { useEffect as C, useState as a } from "react";
9
+ import { Fragment as E, jsx as t, jsxs as w } from "react/jsx-runtime";
10
+ var L = (m) => {
11
+ const s = x(), [e, i] = a(null), [p, d] = a(!1), [f, c] = a(!1), u = (r) => {
12
+ i(r.currentTarget), P(r, d);
13
+ }, o = () => {
14
+ c(!0), i(null);
15
15
  };
16
- b({
16
+ C(() => {
17
+ if (!e) return;
18
+ const r = (l) => {
19
+ document.activeElement === e && (l.key === "Escape" || l.key === "Tab") && o();
20
+ };
21
+ return document.addEventListener("keydown", r), () => document.removeEventListener("keydown", r);
22
+ }, [e]), h({
17
23
  open: !!e,
18
- onClose: r
24
+ onClose: o
19
25
  });
20
- const t = {
21
- ...p,
22
- validateOnCalendarClose: d,
23
- onValidatedOnce: () => i(!1)
26
+ const n = {
27
+ ...m,
28
+ validateOnCalendarClose: f,
29
+ onValidatedOnce: () => c(!1)
24
30
  };
25
- return /* @__PURE__ */ y(h, { children: [
26
- /* @__PURE__ */ o(x, {
27
- datePickerProps: t,
28
- onClick: P
31
+ return /* @__PURE__ */ w(E, { children: [
32
+ /* @__PURE__ */ t(y, {
33
+ datePickerProps: n,
34
+ onClick: u
29
35
  }),
30
- !s && /* @__PURE__ */ o(u, {
31
- datePickerProps: { ...t },
36
+ !s && /* @__PURE__ */ t(v, {
37
+ datePickerProps: { ...n },
32
38
  popoverProps: {
33
39
  open: !!e,
34
40
  anchorEl: e,
35
- onClose: r
41
+ onClose: o
36
42
  },
37
- positionAbove: c
43
+ positionAbove: p
38
44
  }),
39
- s && /* @__PURE__ */ o(C, {
45
+ s && /* @__PURE__ */ t(b, {
40
46
  anchor: "bottom",
41
47
  open: !!e,
42
- onClose: r,
48
+ onClose: o,
43
49
  anchorEl: e,
44
- children: /* @__PURE__ */ o("div", {
50
+ children: /* @__PURE__ */ t("div", {
45
51
  className: "mx-auto max-w-[360px] px-2 pb-[max(1.5rem,env(safe-area-inset-bottom))]",
46
- children: /* @__PURE__ */ o(k, {
47
- datePickerProps: { ...t },
52
+ children: /* @__PURE__ */ t(k, {
53
+ datePickerProps: { ...n },
48
54
  popoverProps: {
49
55
  open: !!e,
50
56
  anchorEl: e,
51
- onClose: r
57
+ onClose: o
52
58
  }
53
59
  })
54
60
  })
@@ -56,5 +62,5 @@ var E = (p) => {
56
62
  ] });
57
63
  };
58
64
  export {
59
- E as StyledDatePicker
65
+ L as StyledDatePicker
60
66
  };
@@ -1,12 +1,13 @@
1
- import { StyledPopover as n } from "../../../../components/utils/popover/StyledPopover.js";
1
+ import { StyledPopover as i } from "../../../../components/utils/popover/StyledPopover.js";
2
2
  import { StyledDayPicker as c } from "./StyledDayPicker.js";
3
3
  import { jsx as r } from "react/jsx-runtime";
4
4
  var h = ({ datePickerProps: e, popoverProps: t, positionAbove: o }) => {
5
- const { open: l, anchorEl: i, onClose: a } = t;
6
- return /* @__PURE__ */ r(n, {
5
+ const { open: l, anchorEl: n, onClose: a } = t;
6
+ return /* @__PURE__ */ r(i, {
7
7
  open: l,
8
- anchorEl: i,
8
+ anchorEl: n,
9
9
  onClose: a,
10
+ tabIntoContent: !1,
10
11
  anchorOrigin: {
11
12
  vertical: o ? "top" : 50,
12
13
  horizontal: "left"
@@ -1,90 +1,103 @@
1
- import { useIsMobileView as N } from "../../hooks/useWindowWidthSize.hook.js";
2
- import { StyledDrawer as E } from "../../../components/navigation/drawer/StyledDrawer.js";
1
+ import { useIsMobileView as O } from "../../hooks/useWindowWidthSize.hook.js";
2
+ import { StyledDrawer as D } from "../../../components/navigation/drawer/StyledDrawer.js";
3
3
  import { useBackNavigationClose as I } from "../../hooks/useBackNavigationClose.hook.js";
4
4
  import { usePopupState as j } from "../../../hooks/usePopupState.js";
5
- import { ClickAwayListener as D } from "../../../components/mui-compat/ClickAwayListener.js";
6
- import { TimePickerPanel as L } from "./components/TimePickerPanel.js";
7
- import { TimePickerPopper as O } from "./TimePickerPopper.js";
5
+ import { ClickAwayListener as A } from "../../../components/mui-compat/ClickAwayListener.js";
6
+ import { TimePickerPanel as B } from "./components/TimePickerPanel.js";
7
+ import { TimePickerPopper as M } from "./TimePickerPopper.js";
8
8
  import { getTimeFromValue as S } from "./helpers/getTimeFromValue.js";
9
- import { TimePickerInput as B } from "./TimePickerInput.js";
10
- import { useState as h } from "react";
11
- import { jsx as o, jsxs as T } from "react/jsx-runtime";
12
- import { format as v, isBefore as M, isValid as A } from "date-fns";
13
- var Z = (i) => {
14
- const { value: a, onSelect: r, notBeforeTime: m } = i, e = j({
9
+ import { TimePickerInput as F } from "./TimePickerInput.js";
10
+ import { useEffect as K, useState as v } from "react";
11
+ import { jsx as o, jsxs as C } from "react/jsx-runtime";
12
+ import { format as y, isBefore as q, isValid as z } from "date-fns";
13
+ var te = (n) => {
14
+ const { value: a, onSelect: r, notBeforeTime: u } = n, t = j({
15
15
  variant: "popper",
16
16
  popupId: "time-picker-popper"
17
- }), V = N();
17
+ }), c = O();
18
18
  I({
19
- open: V && e.isOpen,
20
- onClose: e.close
19
+ open: c && t.isOpen,
20
+ onClose: t.close
21
21
  });
22
- const x = a ? v(a, "HH:mm") : "", [C, s] = h(x), [P, l] = h(!1), [b, n] = h(!0), c = P ? C : x, u = (t) => !t || !m || !A(m) || !M(t, m), k = c.length === 5 ? S(c, a) : null, g = k ? u(k) : !0, H = (t) => {
23
- const p = t.target.value;
24
- if (l(!0), s(p), p.length !== 5) {
25
- n(!1);
22
+ const { isOpen: k, anchorEl: V, close: w } = t;
23
+ K(() => {
24
+ if (!k || c) return;
25
+ const e = (i) => {
26
+ V?.contains(document.activeElement) && (i.key === "Escape" || i.key === "Tab") && w();
27
+ };
28
+ return document.addEventListener("keydown", e), () => document.removeEventListener("keydown", e);
29
+ }, [
30
+ k,
31
+ V,
32
+ w,
33
+ c
34
+ ]);
35
+ const E = a ? y(a, "HH:mm") : "", [b, m] = v(E), [g, l] = v(!1), [H, s] = v(!0), p = g ? b : E, f = (e) => !e || !u || !z(u) || !q(e, u), x = p.length === 5 ? S(p, a) : null, L = x ? f(x) : !0, N = (e) => {
36
+ const i = e.target.value;
37
+ if (l(!0), m(i), i.length !== 5) {
38
+ s(!1);
26
39
  return;
27
40
  }
28
- const d = S(p, a);
29
- if (!d) {
30
- r(void 0), n(!1);
41
+ const h = S(i, a);
42
+ if (!h) {
43
+ r(void 0), s(!1);
31
44
  return;
32
45
  }
33
- n(!0), u(d) ? (r(d), l(!1), e.close()) : r(void 0);
34
- }, w = (t) => {
35
- if (n(!0), u(t)) {
36
- r(t), s(t ? v(t, "HH:mm") : ""), l(!1);
46
+ s(!0), f(h) ? (r(h), l(!1), t.close()) : r(void 0);
47
+ }, T = (e) => {
48
+ if (s(!0), f(e)) {
49
+ r(e), m(e ? y(e, "HH:mm") : ""), l(!1);
37
50
  return;
38
51
  }
39
- r(void 0), s(t ? v(t, "HH:mm") : ""), l(!0);
40
- }, y = () => {
41
- r(void 0), s(""), l(!1), n(!0);
42
- }, f = /* @__PURE__ */ o(B, {
43
- ...i,
44
- popupState: e,
45
- localValue: c,
46
- isValidTime: b,
47
- isValidEndTime: g,
48
- handleChange: H
52
+ r(void 0), m(e ? y(e, "HH:mm") : ""), l(!0);
53
+ }, P = () => {
54
+ r(void 0), m(""), l(!1), s(!0);
55
+ }, d = /* @__PURE__ */ o(F, {
56
+ ...n,
57
+ popupState: t,
58
+ localValue: p,
59
+ isValidTime: H,
60
+ isValidEndTime: L,
61
+ handleChange: N
49
62
  });
50
- return i.disabled || i.readOnly ? f : V ? /* @__PURE__ */ T("div", {
63
+ return n.disabled || n.readOnly ? d : c ? /* @__PURE__ */ C("div", {
51
64
  className: "relative h-auto w-auto",
52
65
  children: [/* @__PURE__ */ o("div", {
53
66
  className: "m-0 flex h-fit items-center justify-center p-0",
54
- children: f
55
- }), /* @__PURE__ */ o(E, {
67
+ children: d
68
+ }), /* @__PURE__ */ o(D, {
56
69
  anchor: "bottom",
57
- open: e.isOpen,
58
- onClose: e.close,
59
- anchorEl: e.anchorEl,
70
+ open: t.isOpen,
71
+ onClose: t.close,
72
+ anchorEl: t.anchorEl,
60
73
  children: /* @__PURE__ */ o("div", {
61
74
  className: "mx-auto w-full max-w-[360px] px-4 pb-[max(1rem,env(safe-area-inset-bottom))] pt-2",
62
- children: /* @__PURE__ */ o(L, {
63
- dataTest: i.dataTest,
75
+ children: /* @__PURE__ */ o(B, {
76
+ dataTest: n.dataTest,
64
77
  value: a,
65
- onSelect: w,
66
- handleClear: y,
67
- onConfirm: e.close
78
+ onSelect: T,
79
+ handleClear: P,
80
+ onConfirm: t.close
68
81
  })
69
82
  })
70
83
  })]
71
- }) : /* @__PURE__ */ o(D, {
84
+ }) : /* @__PURE__ */ o(A, {
72
85
  mouseEvent: "onMouseDown",
73
- onClickAway: e.close,
74
- children: /* @__PURE__ */ T("div", {
86
+ onClickAway: t.close,
87
+ children: /* @__PURE__ */ C("div", {
75
88
  className: "relative h-auto w-auto",
76
89
  children: [/* @__PURE__ */ o("div", {
77
90
  className: "m-0 flex h-fit items-center justify-center p-0",
78
- children: f
79
- }), e.isOpen && /* @__PURE__ */ o(O, {
80
- ...i,
81
- popupState: e,
82
- handleClear: y,
83
- onSelect: w
91
+ children: d
92
+ }), t.isOpen && /* @__PURE__ */ o(M, {
93
+ ...n,
94
+ popupState: t,
95
+ handleClear: P,
96
+ onSelect: T
84
97
  })]
85
98
  })
86
99
  });
87
100
  };
88
101
  export {
89
- Z as StyledTimePicker
102
+ te as StyledTimePicker
90
103
  };
@@ -0,0 +1,5 @@
1
+ var a = (r) => r.tabIndex >= 0 && !r.matches(":disabled") && !r.closest("[inert]") && (r.checkVisibility?.() ?? !0), b = (r) => Array.from(r.querySelectorAll("*")).filter(a), i = (r) => a(r) ? r : Array.from(r.querySelectorAll("*")).find(a) ?? null;
2
+ export {
3
+ i as firstTabbable,
4
+ b as tabbableWithin
5
+ };
@@ -1,34 +1,39 @@
1
- import { useEffect as d } from "react";
2
- var m = 'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])', b = (c, u, a) => {
1
+ import { tabbableWithin as p } from "../helpers/focusable.js";
2
+ import { useEffect as d, useRef as y } from "react";
3
+ var E = (c, i, s) => {
4
+ const f = y(s);
3
5
  d(() => {
6
+ f.current = s;
7
+ }, [s]), d(() => {
4
8
  if (!c) return;
5
- const t = u.current;
9
+ const t = i.current;
6
10
  if (!t) return;
7
- const r = document.activeElement, l = requestAnimationFrame(() => {
8
- t.focus({ preventScroll: !0 });
9
- }), i = (e) => {
11
+ const n = document.activeElement, a = t.getAttribute("tabindex");
12
+ t.setAttribute("tabindex", "-1");
13
+ const b = requestAnimationFrame(() => {
14
+ (!n || !t.contains(n)) && t.focus({ preventScroll: !0 });
15
+ }), l = (e) => {
10
16
  if (e.key === "Escape") {
11
- a?.();
17
+ f.current?.();
12
18
  return;
13
19
  }
14
20
  if (e.key !== "Tab") return;
15
- const n = Array.from(t.querySelectorAll(m));
16
- if (n.length === 0) {
21
+ const r = p(t);
22
+ if (r.length === 0) {
17
23
  e.preventDefault();
18
24
  return;
19
25
  }
20
- const s = n[0], f = n[n.length - 1], o = document.activeElement;
21
- e.shiftKey && (o === s || o === t) ? (e.preventDefault(), f?.focus()) : (!e.shiftKey && o === f || !e.shiftKey && o === t) && (e.preventDefault(), s?.focus());
26
+ const u = r[0], m = r[r.length - 1], o = document.activeElement;
27
+ e.shiftKey && (o === u || o === t) ? (e.preventDefault(), m?.focus()) : (!e.shiftKey && o === m || !e.shiftKey && o === t) && (e.preventDefault(), u?.focus());
22
28
  };
23
- return document.addEventListener("keydown", i), () => {
24
- cancelAnimationFrame(l), document.removeEventListener("keydown", i), r && document.contains(r) && r.focus();
29
+ return document.addEventListener("keydown", l), () => {
30
+ cancelAnimationFrame(b), document.removeEventListener("keydown", l), a === null ? t.removeAttribute("tabindex") : t.setAttribute("tabindex", a), requestAnimationFrame(() => {
31
+ const e = document.activeElement;
32
+ (!e || e === document.body) && n && document.contains(n) && n.focus({ preventScroll: !0 });
33
+ });
25
34
  };
26
- }, [
27
- c,
28
- u,
29
- a
30
- ]);
35
+ }, [c, i]);
31
36
  };
32
37
  export {
33
- b as useFocusTrap
38
+ E as useFocusTrap
34
39
  };
@@ -47,6 +47,8 @@ export interface StyledChipProps {
47
47
  classes?: ChipClasses;
48
48
  sx?: unknown;
49
49
  tabIndex?: number;
50
+ /** Removes the delete affordance from sequential navigation when its owner has a keyboard equivalent. */
51
+ deleteButtonTabIndex?: number;
50
52
  'aria-label'?: string;
51
53
  /** Overrides the default `role="button"`/no-role logic — for `StyledInteractiveChip`'s
52
54
  * checkbox/radio chip, whose inner control is `decorative`/`aria-hidden` (a real, even hidden,
@@ -9,9 +9,8 @@ import { StyledDynamicSelectComponent } from './types';
9
9
  * **Multiple**) to a representation, which this component's thresholds reproduce exactly:
10
10
  * - **≤5 → Chips select** (`DynamicInteractiveChipGroup`): `StyledInteractiveChip` radio (single)
11
11
  * or checkbox (multiple) chips; long labels stack vertically; "Clear selection" link + helper row.
12
- * - **>5 & ≤10 → Select (dropdown)**: outlined `StyledInputField` trigger + `Menus` list, typing
13
- * disabled (caret hidden, keyboard blocked).
14
- * - **>10 → Autocomplete**: same trigger + scrollable `Menus` list with type-ahead search.
12
+ * - **>5 → Autocomplete**: outlined `StyledInputField` trigger + scrollable `Menus` list with
13
+ * type-ahead search.
15
14
  * Each representation is composed from components already aligned to their own Figma nodes (Chip
16
15
  * `13248-31089`, Input field `15561-37391`, Menus `16073-19226`, Autocomplete `20474-27966`), so
17
16
  * parity here is the mode routing + the shared title/clear/helper chrome, not a bespoke visual.
@@ -25,7 +24,7 @@ import { StyledDynamicSelectComponent } from './types';
25
24
  * Long labels automatically switch to a vertical stacked layout.
26
25
  * When `!required` and a value is selected, a "Clear selection" button is shown.
27
26
  * - `0 or 6+ options` → renders as a searchable autocomplete (`DynamicSelectAutocomplete`).
28
- * Typing is disabled when there are ≤10 options (caret hidden, keyboard blocked).
27
+ * All autocomplete option counts remain filterable and keyboard-operable.
29
28
  *
30
29
  * **Option types:**
31
30
  * Options can be primitives (`string | number | boolean`) or objects. When using objects,
@@ -4,7 +4,7 @@ export interface CountryCodeOptionsProps {
4
4
  /** Already filtered — the caller owns the query. */
5
5
  visible: readonly PhoneCountryChoice[];
6
6
  selectedIso2: string;
7
- activeIndex: number;
7
+ activeIndex: number | null;
8
8
  optionId: (index: number) => string;
9
9
  onSelect: (iso2: string) => void;
10
10
  listId: string;
@@ -10,13 +10,16 @@ export interface UseCountryPickerOptions {
10
10
  selectedIso2: string;
11
11
  query: string;
12
12
  listId: string;
13
- onSelect: (iso2: string) => void;
13
+ onSelect: (iso2: string, close?: boolean) => void;
14
14
  onDismiss: () => void;
15
15
  }
16
16
  export interface CountryPicker {
17
17
  visible: readonly PhoneCountryChoice[];
18
- activeIndex: number;
18
+ activeIndex: number | null;
19
19
  optionId: (index: number) => string;
20
+ openWithKeyboard: (direction: -1 | 1) => void;
21
+ select: (iso2: string) => void;
22
+ dismiss: () => void;
20
23
  handleKeyDown: (event: KeyboardEvent<HTMLElement>) => void;
21
24
  }
22
25
  /**
@@ -5,16 +5,17 @@ declare function ListboxRoot<T>({ value, onChange, children, }: {
5
5
  onChange: (value: T) => void;
6
6
  children: ReactNode;
7
7
  }): JSX.Element;
8
- declare function ListboxOption<T>({ value, disabled, children, className, }: {
8
+ declare function ListboxOption<T>({ value, disabled, children, className, optionIndex, }: {
9
9
  value: T;
10
10
  disabled?: boolean;
11
11
  children: RenderProp<{
12
12
  selected: boolean;
13
13
  }>;
14
14
  className?: string;
15
+ optionIndex?: number;
15
16
  }): JSX.Element;
16
17
  export declare const Listbox: typeof ListboxRoot & {
17
- Button: ({ children, className, ...rest }: {
18
+ Button: ({ children, className, onClick, onKeyDown, ...rest }: {
18
19
  children: RenderProp<{
19
20
  open: boolean;
20
21
  }>;
@@ -1,9 +1,10 @@
1
1
  import { CSSProperties, MouseEvent, ReactNode } from 'react';
2
- import { PopoverOrigin, StyledPopoverProps } from '../../utils/popover';
2
+ import { PopoverCloseReason, PopoverOrigin } from '../../utils/popover';
3
+ export type MenuCloseReason = PopoverCloseReason | 'tabKeyDown';
3
4
  export interface MenuProps {
4
5
  open: boolean;
5
6
  anchorEl?: Element | null;
6
- onClose?: StyledPopoverProps['onClose'];
7
+ onClose?: (event: object, reason?: MenuCloseReason) => void;
7
8
  anchorOrigin?: PopoverOrigin;
8
9
  transformOrigin?: PopoverOrigin;
9
10
  id?: string;
@@ -5,7 +5,8 @@ type StyledAccordionDetailsProps = React.HTMLAttributes<HTMLDivElement> & {
5
5
  /**
6
6
  * Native accordion panel (replaces `@base-ui/react`): a `role="region"` whose height animates
7
7
  * between 0 and its measured content height via the SCSS `--accordion-panel-height` var (was
8
- * base-ui-provided). Kept `hidden` when closed after the transition for a11y. TASK-201.
8
+ * base-ui-provided). Collapsed, it is `inert`: the content is still rendered (so it can be measured
9
+ * and animated) but is out of the tab order and the accessibility tree. TASK-201.
9
10
  */
10
11
  export declare const StyledAccordionDetails: ({ children, className, contentClassName, ...props }: StyledAccordionDetailsProps) => JSX.Element;
11
12
  export {};
@@ -3,9 +3,16 @@ export interface PopoverOrigin {
3
3
  vertical: 'top' | 'center' | 'bottom' | number;
4
4
  horizontal: 'left' | 'center' | 'right' | number;
5
5
  }
6
- export type PopoverCloseReason = 'backdropClick' | 'escapeKeyDown';
6
+ export type PopoverCloseReason = 'backdropClick' | 'escapeKeyDown' | 'tabKeyDown';
7
7
  export interface StyledPopoverProps {
8
8
  open: boolean;
9
+ /**
10
+ * Splice the panel into the tab sequence right after the anchor: Tab on the anchor steps into the
11
+ * panel's first control, and Shift+Tab out of that control retraces to the anchor. On by
12
+ * default because a popover's controls must be reachable by keyboard. Opt out only when its
13
+ * trigger owns keyboard navigation (select, country picker, date/time picker).
14
+ */
15
+ tabIntoContent?: boolean;
9
16
  anchorEl?: Element | null;
10
17
  onClose?: (event: object, reason?: PopoverCloseReason) => void;
11
18
  anchorOrigin?: PopoverOrigin;
@@ -44,4 +51,4 @@ export interface StyledPopoverProps {
44
51
  * mapping to MUI's `onClose(event, reason)`. `anchorOrigin`/`transformOrigin`/`slotProps.paper`
45
52
  * preserved (DEC-003). TASK-302.
46
53
  */
47
- export declare const StyledPopover: ({ open, anchorEl, onClose, anchorOrigin, transformOrigin, id, className, sx, slotProps, onClick, children, keepMounted, }: StyledPopoverProps) => JSX.Element | null;
54
+ export declare const StyledPopover: ({ open, anchorEl, onClose, anchorOrigin, transformOrigin, id, className, sx, slotProps, onClick, children, keepMounted, tabIntoContent, }: StyledPopoverProps) => JSX.Element | null;
@@ -0,0 +1,8 @@
1
+ /** Every element inside `root` a Tab press can reach, in DOM order. */
2
+ export declare const tabbableWithin: (root: ParentNode) => HTMLElement[];
3
+ /**
4
+ * The element a keyboard user actually lands on for `root`: `root` itself when it is tabbable, else
5
+ * its first tabbable descendant. `null` when the subtree holds nothing reachable — a decorative or
6
+ * disabled control, which the caller has to decide about.
7
+ */
8
+ export declare const firstTabbable: (root: HTMLElement) => HTMLElement | null;
@@ -3,7 +3,8 @@ import { RefObject } from 'react';
3
3
  * Manual Tab-cycling focus trap for a modal-like panel that (unlike `StyledDialog`) can't use the
4
4
  * native `<dialog>` `showModal()` trap — e.g. a panel that's only modal in ONE of its states
5
5
  * (`MinimizableDialog`'s fullscreen mode), where the rest of the time it's a non-modal floating
6
- * widget that must NOT trap focus. Moves initial focus into the container, cycles Tab/Shift+Tab
6
+ * widget that must NOT trap focus. Moves external focus into the container but retains focus on an
7
+ * in-panel control that activated the trap (such as an Enter Fullscreen button), cycles Tab/Shift+Tab
7
8
  * among its focusable descendants while `active`, restores focus to the trigger on deactivation,
8
9
  * and calls `onEscape` on the Escape key (mirroring `StyledDialog`'s ESC-to-close).
9
10
  */
@@ -1,31 +1,31 @@
1
1
  import { DotsVerticalIcon as S } from "../../../../../components/icons/dots-vertical-icon/DotsVerticalIcon.js";
2
2
  import { CircleWarningOutlineIcon as A } from "../../../../../components/icons/warning-circle-icon/CircleWarningOutlineIcon.js";
3
- import { StyledPopover as O } from "../../../../../components/utils/popover/StyledPopover.js";
4
- import { StyledMenuList as j } from "../../../../../components/navigation/menu/StyledMenuList.js";
5
- import { isCustomAction as k } from "../../../../types.js";
3
+ import { StyledPopover as D } from "../../../../../components/utils/popover/StyledPopover.js";
4
+ import { StyledMenuList as O } from "../../../../../components/navigation/menu/StyledMenuList.js";
5
+ import { isCustomAction as j } from "../../../../types.js";
6
6
  import { StyledTooltip as g } from "../../../../shared-components/tooltip/index.js";
7
- import { useToggleMenuVisibility as F } from "../../../../hooks/useToggleMenuVisibility.hook.js";
7
+ import { useToggleMenuVisibility as k } from "../../../../hooks/useToggleMenuVisibility.hook.js";
8
8
  import { StyledButton as I } from "../../../../shared-components/button/StyledButton.js";
9
9
  import { StyledMenuItem as R } from "../../../../shared-components/StyledMenuItem.js";
10
- import w, { useEffect as V, useMemo as z, useState as D } from "react";
10
+ import w, { useEffect as V, useMemo as z, useState as E } from "react";
11
11
  import { jsx as t, jsxs as b } from "react/jsx-runtime";
12
- function X({ tableData: o, actions: v, rowActionsState: C }) {
13
- const { anchorEl: x, open: a, handleClose: i, handleOpen: P } = F(), l = v(o.row), n = C?.(o.row) ?? { state: "enabled" }, p = o.table.options.meta?.locale, y = p === "no" ? "Ingen handlinger tilgjengelig" : "No actions available", N = p === "no" ? "Radhandlinger" : "Row actions", T = z(() => l.every((e) => "component" in e ? !1 : e.hide), [l]), u = l.length > 0 && !T, m = n.state === "enabled" && !u, M = n.state !== "hidden" && (u || m || n.state === "disabled"), [c, s] = D(!1);
12
+ function X({ tableData: l, actions: v, rowActionsState: x }) {
13
+ const { anchorEl: C, open: a, handleClose: r, handleOpen: P } = k(), i = v(l.row), o = x?.(l.row) ?? { state: "enabled" }, d = l.table.options.meta?.locale, T = d === "no" ? "Ingen handlinger tilgjengelig" : "No actions available", y = d === "no" ? "Radhandlinger" : "Row actions", N = z(() => i.every((e) => "component" in e ? !1 : e.hide), [i]), u = i.length > 0 && !N, m = o.state === "enabled" && !u, M = o.state !== "hidden" && (u || m || o.state === "disabled"), [c, s] = E(!1);
14
14
  if (V(() => {
15
15
  if (!c) return;
16
16
  const e = window.setTimeout(() => s(!1), 1600);
17
17
  return () => window.clearTimeout(e);
18
18
  }, [c]), !M) return /* @__PURE__ */ t("div", { className: "flex w-[40px] items-center justify-center" });
19
- const d = n.state === "disabled", f = /* @__PURE__ */ t(I, {
19
+ const p = o.state === "disabled", f = /* @__PURE__ */ t(I, {
20
20
  dataTest: "row-actions-button",
21
- "aria-label": N,
21
+ "aria-label": y,
22
22
  "aria-haspopup": "true",
23
23
  "aria-expanded": a,
24
24
  variant: "text",
25
25
  size: "small",
26
- disabled: d,
26
+ disabled: p,
27
27
  onClick: (e) => {
28
- e.stopPropagation(), e.preventDefault(), !d && (a ? (i(), o.row.onChangeFocused(!1)) : (P(e), o.row.onChangeFocused(!0)));
28
+ e.stopPropagation(), e.preventDefault(), !p && (e.currentTarget.focus({ preventScroll: !0 }), a ? r() : P(e));
29
29
  },
30
30
  onMouseDown: (e) => {
31
31
  e.stopPropagation(), e.preventDefault();
@@ -34,7 +34,7 @@ function X({ tableData: o, actions: v, rowActionsState: C }) {
34
34
  e.stopPropagation(), e.preventDefault();
35
35
  },
36
36
  children: /* @__PURE__ */ t(S, {
37
- className: d ? "text-delta-300" : "text-delta-700",
37
+ className: p ? "text-delta-300" : "text-delta-700",
38
38
  width: 20,
39
39
  height: 20
40
40
  })
@@ -43,10 +43,10 @@ function X({ tableData: o, actions: v, rowActionsState: C }) {
43
43
  className: "flex w-[40px] items-center justify-center",
44
44
  children: /* @__PURE__ */ b("div", {
45
45
  className: "flex items-center justify-center",
46
- children: [n.state === "disabled" ? /* @__PURE__ */ t(g, {
47
- title: n.tooltipTitle,
46
+ children: [o.state === "disabled" ? /* @__PURE__ */ t(g, {
47
+ title: o.tooltipTitle,
48
48
  arrow: !0,
49
- placement: n.tooltipPlacement ?? "top",
49
+ placement: o.tooltipPlacement ?? "top",
50
50
  open: c,
51
51
  onOpen: () => s(!0),
52
52
  onClose: () => s(!1),
@@ -60,15 +60,11 @@ function X({ tableData: o, actions: v, rowActionsState: C }) {
60
60
  },
61
61
  children: f
62
62
  })
63
- }) : f, n.state === "enabled" && /* @__PURE__ */ t(O, {
63
+ }) : f, o.state === "enabled" && /* @__PURE__ */ t(D, {
64
64
  open: a,
65
- anchorEl: x,
66
- onClose: () => {
67
- i(), o.row.onChangeFocused(!1);
68
- },
69
- onClick: () => {
70
- i(), o.row.onChangeFocused(!1);
71
- },
65
+ anchorEl: C,
66
+ onClose: r,
67
+ onClick: r,
72
68
  anchorOrigin: {
73
69
  horizontal: "right",
74
70
  vertical: "bottom"
@@ -82,13 +78,13 @@ function X({ tableData: o, actions: v, rowActionsState: C }) {
82
78
  children: [/* @__PURE__ */ t(A, {
83
79
  width: 20,
84
80
  height: 20
85
- }), /* @__PURE__ */ t("span", { children: y })]
86
- }) : /* @__PURE__ */ t(j, {
81
+ }), /* @__PURE__ */ t("span", { children: T })]
82
+ }) : /* @__PURE__ */ t(O, {
87
83
  disablePadding: !0,
88
- children: l.map((e, h) => {
89
- if (k(e)) {
90
- const r = e.component(o.row, i);
91
- return w.isValidElement(r) ? /* @__PURE__ */ t(w.Fragment, { children: r }, h) : null;
84
+ children: i.map((e, h) => {
85
+ if (j(e)) {
86
+ const n = e.component(l.row, r);
87
+ return w.isValidElement(n) ? /* @__PURE__ */ t(w.Fragment, { children: n }, h) : null;
92
88
  }
93
89
  return e.hide ? null : /* @__PURE__ */ t(g, {
94
90
  title: e?.tooltipTitle,
@@ -98,13 +94,13 @@ function X({ tableData: o, actions: v, rowActionsState: C }) {
98
94
  className: e.className,
99
95
  disabled: e.disabled,
100
96
  onClick: () => {
101
- e.disabled || e.onClick?.(o.row);
97
+ e.disabled || e.onClick?.(l.row);
102
98
  },
103
- onMouseDown: (r) => {
104
- r.stopPropagation(), r.preventDefault();
99
+ onMouseDown: (n) => {
100
+ n.stopPropagation(), n.preventDefault();
105
101
  },
106
- onMouseUp: (r) => {
107
- r.stopPropagation(), r.preventDefault();
102
+ onMouseUp: (n) => {
103
+ n.stopPropagation(), n.preventDefault();
108
104
  },
109
105
  children: e.label
110
106
  }) })