@salt-ds/lab 1.0.0-alpha.60 → 1.0.0-alpha.62

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 (96) hide show
  1. package/CHANGELOG.md +93 -0
  2. package/css/salt-lab.css +185 -1
  3. package/dist-cjs/date-picker/DatePickerRangeInput.js +1 -0
  4. package/dist-cjs/date-picker/DatePickerRangeInput.js.map +1 -1
  5. package/dist-cjs/date-picker/DatePickerSingleInput.js +1 -0
  6. package/dist-cjs/date-picker/DatePickerSingleInput.js.map +1 -1
  7. package/dist-cjs/index.js +6 -0
  8. package/dist-cjs/index.js.map +1 -1
  9. package/dist-cjs/splitter/SplitHandle.css.js +6 -0
  10. package/dist-cjs/splitter/SplitHandle.css.js.map +1 -0
  11. package/dist-cjs/splitter/SplitHandle.js +60 -0
  12. package/dist-cjs/splitter/SplitHandle.js.map +1 -0
  13. package/dist-cjs/splitter/SplitPanel.css.js +6 -0
  14. package/dist-cjs/splitter/SplitPanel.css.js.map +1 -0
  15. package/dist-cjs/splitter/SplitPanel.js +37 -0
  16. package/dist-cjs/splitter/SplitPanel.js.map +1 -0
  17. package/dist-cjs/splitter/Splitter.js +31 -0
  18. package/dist-cjs/splitter/Splitter.js.map +1 -0
  19. package/dist-cjs/splitter/utils.js +18 -0
  20. package/dist-cjs/splitter/utils.js.map +1 -0
  21. package/dist-cjs/stepped-tracker/stepReducer.js +127 -81
  22. package/dist-cjs/stepped-tracker/stepReducer.js.map +1 -1
  23. package/dist-cjs/stepped-tracker/useStepReducer.js +6 -4
  24. package/dist-cjs/stepped-tracker/useStepReducer.js.map +1 -1
  25. package/dist-cjs/stepped-tracker/utils.js +44 -9
  26. package/dist-cjs/stepped-tracker/utils.js.map +1 -1
  27. package/dist-cjs/stepper-input/StepperInput.js +6 -5
  28. package/dist-cjs/stepper-input/StepperInput.js.map +1 -1
  29. package/dist-cjs/tabs-next/TabListNext.css.js +1 -1
  30. package/dist-cjs/tabs-next/TabListNext.js +10 -16
  31. package/dist-cjs/tabs-next/TabListNext.js.map +1 -1
  32. package/dist-cjs/tabs-next/TabOverflowList.js +1 -1
  33. package/dist-cjs/tabs-next/TabOverflowList.js.map +1 -1
  34. package/dist-cjs/tabs-next/TabsNext.js +4 -51
  35. package/dist-cjs/tabs-next/TabsNext.js.map +1 -1
  36. package/dist-cjs/tabs-next/TabsNextContext.js +1 -1
  37. package/dist-cjs/tabs-next/TabsNextContext.js.map +1 -1
  38. package/dist-cjs/tabs-next/hooks/useCollection.js.map +1 -1
  39. package/dist-cjs/tabs-next/hooks/useOverflow.js +48 -5
  40. package/dist-cjs/tabs-next/hooks/useOverflow.js.map +1 -1
  41. package/dist-cjs/tabs-next/hooks/useRestoreActiveTab.js +93 -0
  42. package/dist-cjs/tabs-next/hooks/useRestoreActiveTab.js.map +1 -0
  43. package/dist-es/date-picker/DatePickerRangeInput.js +1 -0
  44. package/dist-es/date-picker/DatePickerRangeInput.js.map +1 -1
  45. package/dist-es/date-picker/DatePickerSingleInput.js +1 -0
  46. package/dist-es/date-picker/DatePickerSingleInput.js.map +1 -1
  47. package/dist-es/index.js +3 -0
  48. package/dist-es/index.js.map +1 -1
  49. package/dist-es/splitter/SplitHandle.css.js +4 -0
  50. package/dist-es/splitter/SplitHandle.css.js.map +1 -0
  51. package/dist-es/splitter/SplitHandle.js +58 -0
  52. package/dist-es/splitter/SplitHandle.js.map +1 -0
  53. package/dist-es/splitter/SplitPanel.css.js +4 -0
  54. package/dist-es/splitter/SplitPanel.css.js.map +1 -0
  55. package/dist-es/splitter/SplitPanel.js +35 -0
  56. package/dist-es/splitter/SplitPanel.js.map +1 -0
  57. package/dist-es/splitter/Splitter.js +27 -0
  58. package/dist-es/splitter/Splitter.js.map +1 -0
  59. package/dist-es/splitter/utils.js +15 -0
  60. package/dist-es/splitter/utils.js.map +1 -0
  61. package/dist-es/stepped-tracker/stepReducer.js +128 -82
  62. package/dist-es/stepped-tracker/stepReducer.js.map +1 -1
  63. package/dist-es/stepped-tracker/useStepReducer.js +7 -5
  64. package/dist-es/stepped-tracker/useStepReducer.js.map +1 -1
  65. package/dist-es/stepped-tracker/utils.js +43 -9
  66. package/dist-es/stepped-tracker/utils.js.map +1 -1
  67. package/dist-es/stepper-input/StepperInput.js +6 -5
  68. package/dist-es/stepper-input/StepperInput.js.map +1 -1
  69. package/dist-es/tabs-next/TabListNext.css.js +1 -1
  70. package/dist-es/tabs-next/TabListNext.js +11 -17
  71. package/dist-es/tabs-next/TabListNext.js.map +1 -1
  72. package/dist-es/tabs-next/TabOverflowList.js +1 -1
  73. package/dist-es/tabs-next/TabOverflowList.js.map +1 -1
  74. package/dist-es/tabs-next/TabsNext.js +5 -52
  75. package/dist-es/tabs-next/TabsNext.js.map +1 -1
  76. package/dist-es/tabs-next/TabsNextContext.js +1 -1
  77. package/dist-es/tabs-next/TabsNextContext.js.map +1 -1
  78. package/dist-es/tabs-next/hooks/useCollection.js.map +1 -1
  79. package/dist-es/tabs-next/hooks/useOverflow.js +49 -6
  80. package/dist-es/tabs-next/hooks/useOverflow.js.map +1 -1
  81. package/dist-es/tabs-next/hooks/useRestoreActiveTab.js +91 -0
  82. package/dist-es/tabs-next/hooks/useRestoreActiveTab.js.map +1 -0
  83. package/dist-types/index.d.ts +1 -0
  84. package/dist-types/splitter/SplitHandle.d.ts +21 -0
  85. package/dist-types/splitter/SplitPanel.d.ts +10 -0
  86. package/dist-types/splitter/Splitter.d.ts +22 -0
  87. package/dist-types/splitter/index.d.ts +4 -0
  88. package/dist-types/splitter/utils.d.ts +4 -0
  89. package/dist-types/stepped-tracker/Step.types.d.ts +2 -4
  90. package/dist-types/stepped-tracker/stepReducer.types.d.ts +6 -4
  91. package/dist-types/stepped-tracker/utils.d.ts +6 -3
  92. package/dist-types/tabs/drag-drop/drag-utils.d.ts +6 -6
  93. package/dist-types/tabs-next/TabsNextContext.d.ts +1 -1
  94. package/dist-types/tabs-next/hooks/useOverflow.d.ts +1 -1
  95. package/dist-types/tabs-next/hooks/useRestoreActiveTab.d.ts +10 -0
  96. package/package.json +5 -4
@@ -10,6 +10,7 @@ var TabListNext$1 = require('./TabListNext.css.js');
10
10
  var TabOverflowList = require('./TabOverflowList.js');
11
11
  var TabsNextContext = require('./TabsNextContext.js');
12
12
  var useOverflow = require('./hooks/useOverflow.js');
13
+ var useRestoreActiveTab = require('./hooks/useRestoreActiveTab.js');
13
14
 
14
15
  const withBaseName = core.makePrefixer("saltTabListNext");
15
16
  const TabListNext = react.forwardRef(
@@ -39,18 +40,24 @@ const TabListNext = react.forwardRef(
39
40
  activeTab,
40
41
  menuOpen,
41
42
  setMenuOpen,
42
- returnFocus
43
+ removedActiveTabRef
43
44
  } = TabsNextContext.useTabsNext();
44
45
  const tabstripRef = react.useRef(null);
45
46
  const handleRef = core.useForkRef(tabstripRef, ref);
46
47
  const overflowButtonRef = react.useRef(null);
47
- const [visible, hidden, isMeasuring] = useOverflow.useOverflow({
48
+ const [visible, hidden, isMeasuring, realSelectedIndexRef] = useOverflow.useOverflow({
48
49
  container: tabstripRef,
49
50
  tabs: items,
50
51
  children,
51
52
  selected,
52
53
  overflowButton: overflowButtonRef
53
54
  });
55
+ useRestoreActiveTab.useRestoreActiveTab({
56
+ container: tabstripRef,
57
+ tabs: items,
58
+ realSelectedIndex: realSelectedIndexRef,
59
+ removedActiveTabRef
60
+ });
54
61
  const handleKeyDown = (event) => {
55
62
  var _a, _b, _c;
56
63
  onKeyDown == null ? void 0 : onKeyDown(event);
@@ -77,19 +84,6 @@ const TabListNext = react.forwardRef(
77
84
  }
78
85
  }
79
86
  };
80
- core.useIsomorphicLayoutEffect(() => {
81
- var _a;
82
- if (!returnFocus.current || visible.length < 1 || selected === void 0)
83
- return;
84
- const itemToFocus = items.find((i) => i.value === returnFocus.current);
85
- (_a = itemToFocus == null ? void 0 : itemToFocus.element) == null ? void 0 : _a.focus({ preventScroll: true });
86
- requestAnimationFrame(() => {
87
- var _a2;
88
- if (((_a2 = targetWindow == null ? void 0 : targetWindow.document) == null ? void 0 : _a2.activeElement) === (itemToFocus == null ? void 0 : itemToFocus.element)) {
89
- returnFocus.current = void 0;
90
- }
91
- });
92
- }, [visible, returnFocus, targetWindow, items, selected]);
93
87
  const warningId = core.useId();
94
88
  return /* @__PURE__ */ jsxRuntime.jsxs(
95
89
  "div",
@@ -108,7 +102,7 @@ const TabListNext = react.forwardRef(
108
102
  "aria-describedby": clsx.clsx(ariaDescribedBy, warningId),
109
103
  ...rest,
110
104
  children: [
111
- hidden.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { id: warningId, className: withBaseName("overflowWarning"), children: "Note: This tab list includes overflow; tab positions may be inaccurate or change when a tab is selected" }),
105
+ !isMeasuring && hidden.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { id: warningId, className: withBaseName("overflowWarning"), children: "Note: This tab list includes overflow; tab positions may be inaccurate or change when a tab is selected" }),
112
106
  visible,
113
107
  /* @__PURE__ */ jsxRuntime.jsx(
114
108
  TabOverflowList.TabOverflowList,
@@ -1 +1 @@
1
- {"version":3,"file":"TabListNext.js","sources":["../src/tabs-next/TabListNext.tsx"],"sourcesContent":["import {\n capitalize,\n makePrefixer,\n useForkRef,\n useId,\n useIsomorphicLayoutEffect,\n} from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { clsx } from \"clsx\";\nimport {\n type ComponentPropsWithoutRef,\n type KeyboardEvent,\n forwardRef,\n useRef,\n} from \"react\";\n\nimport tablistNextCss from \"./TabListNext.css\";\nimport { TabOverflowList } from \"./TabOverflowList\";\nimport { useTabsNext } from \"./TabsNextContext\";\nimport { useOverflow } from \"./hooks/useOverflow\";\n\nconst withBaseName = makePrefixer(\"saltTabListNext\");\n\nexport interface TabListNextProps\n extends Omit<ComponentPropsWithoutRef<\"div\">, \"onChange\"> {\n /**\n * Styling active color variant. Defaults to \"primary\".\n */\n activeColor?: \"primary\" | \"secondary\" | \"tertiary\";\n /**\n * The appearance of the tabs. Defaults to \"bordered\".\n */\n appearance?: \"bordered\" | \"transparent\";\n}\n\nexport const TabListNext = forwardRef<HTMLDivElement, TabListNextProps>(\n function TabstripNext(props, ref) {\n const {\n appearance = \"bordered\",\n activeColor = \"primary\",\n \"aria-describedby\": ariaDescribedBy,\n children,\n className,\n onKeyDown,\n ...rest\n } = props;\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-tablist-next\",\n css: tablistNextCss,\n window: targetWindow,\n });\n\n const {\n selected,\n getNext,\n getPrevious,\n getFirst,\n getLast,\n items,\n activeTab,\n menuOpen,\n setMenuOpen,\n returnFocus,\n } = useTabsNext();\n\n const tabstripRef = useRef<HTMLDivElement>(null);\n const handleRef = useForkRef(tabstripRef, ref);\n const overflowButtonRef = useRef<HTMLButtonElement>(null);\n\n const [visible, hidden, isMeasuring] = useOverflow({\n container: tabstripRef,\n tabs: items,\n children,\n selected,\n overflowButton: overflowButtonRef,\n });\n\n const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(event);\n\n const actionMap = {\n ArrowRight: getNext,\n ArrowLeft: getPrevious,\n Home: getFirst,\n End: getLast,\n ArrowUp: menuOpen ? getPrevious : undefined,\n ArrowDown: menuOpen ? getNext : undefined,\n };\n\n const action = actionMap[event.key as keyof typeof actionMap];\n\n if (action) {\n event.preventDefault();\n const activeTabId = activeTab.current?.id;\n if (!activeTabId) return;\n const nextItem = action(activeTabId);\n if (nextItem) {\n nextItem.element?.scrollIntoView({\n block: \"nearest\",\n inline: \"nearest\",\n });\n nextItem.element?.focus({ preventScroll: true });\n }\n }\n };\n\n useIsomorphicLayoutEffect(() => {\n if (!returnFocus.current || visible.length < 1 || selected === undefined)\n return;\n\n const itemToFocus = items.find((i) => i.value === returnFocus.current);\n itemToFocus?.element?.focus({ preventScroll: true });\n\n requestAnimationFrame(() => {\n if (targetWindow?.document?.activeElement === itemToFocus?.element) {\n returnFocus.current = undefined;\n }\n });\n }, [visible, returnFocus, targetWindow, items, selected]);\n\n const warningId = useId();\n\n return (\n <div\n role=\"tablist\"\n className={clsx(\n withBaseName(),\n withBaseName(appearance),\n withBaseName(\"horizontal\"),\n withBaseName(`activeColor${capitalize(activeColor)}`),\n className,\n )}\n data-ismeasuring={isMeasuring ? true : undefined}\n ref={handleRef}\n onKeyDown={handleKeyDown}\n aria-describedby={clsx(ariaDescribedBy, warningId)}\n {...rest}\n >\n {hidden.length > 0 && (\n <span id={warningId} className={withBaseName(\"overflowWarning\")}>\n Note: This tab list includes overflow; tab positions may be\n inaccurate or change when a tab is selected\n </span>\n )}\n {visible}\n <TabOverflowList\n isMeasuring={isMeasuring}\n buttonRef={overflowButtonRef}\n tabstripRef={tabstripRef}\n open={menuOpen}\n setOpen={setMenuOpen}\n >\n {hidden}\n </TabOverflowList>\n </div>\n );\n },\n);\n"],"names":["makePrefixer","forwardRef","useWindow","useComponentCssInjection","tablistNextCss","useTabsNext","useRef","useForkRef","useOverflow","useIsomorphicLayoutEffect","_a","useId","jsxs","clsx","capitalize","jsx","TabOverflowList"],"mappings":"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"}
1
+ {"version":3,"file":"TabListNext.js","sources":["../src/tabs-next/TabListNext.tsx"],"sourcesContent":["import { capitalize, makePrefixer, useForkRef, useId } from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { clsx } from \"clsx\";\nimport {\n type ComponentPropsWithoutRef,\n type KeyboardEvent,\n forwardRef,\n useRef,\n} from \"react\";\n\nimport tablistNextCss from \"./TabListNext.css\";\nimport { TabOverflowList } from \"./TabOverflowList\";\nimport { useTabsNext } from \"./TabsNextContext\";\nimport { useOverflow } from \"./hooks/useOverflow\";\nimport { useRestoreActiveTab } from \"./hooks/useRestoreActiveTab\";\n\nconst withBaseName = makePrefixer(\"saltTabListNext\");\n\nexport interface TabListNextProps\n extends Omit<ComponentPropsWithoutRef<\"div\">, \"onChange\"> {\n /**\n * Styling active color variant. Defaults to \"primary\".\n */\n activeColor?: \"primary\" | \"secondary\" | \"tertiary\";\n /**\n * The appearance of the tabs. Defaults to \"bordered\".\n */\n appearance?: \"bordered\" | \"transparent\";\n}\n\nexport const TabListNext = forwardRef<HTMLDivElement, TabListNextProps>(\n function TabstripNext(props, ref) {\n const {\n appearance = \"bordered\",\n activeColor = \"primary\",\n \"aria-describedby\": ariaDescribedBy,\n children,\n className,\n onKeyDown,\n ...rest\n } = props;\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-tablist-next\",\n css: tablistNextCss,\n window: targetWindow,\n });\n\n const {\n selected,\n getNext,\n getPrevious,\n getFirst,\n getLast,\n items,\n activeTab,\n menuOpen,\n setMenuOpen,\n removedActiveTabRef,\n } = useTabsNext();\n\n const tabstripRef = useRef<HTMLDivElement>(null);\n const handleRef = useForkRef(tabstripRef, ref);\n const overflowButtonRef = useRef<HTMLButtonElement>(null);\n\n const [visible, hidden, isMeasuring, realSelectedIndexRef] = useOverflow({\n container: tabstripRef,\n tabs: items,\n children,\n selected,\n overflowButton: overflowButtonRef,\n });\n\n useRestoreActiveTab({\n container: tabstripRef,\n tabs: items,\n realSelectedIndex: realSelectedIndexRef,\n removedActiveTabRef,\n });\n\n const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(event);\n\n const actionMap = {\n ArrowRight: getNext,\n ArrowLeft: getPrevious,\n Home: getFirst,\n End: getLast,\n ArrowUp: menuOpen ? getPrevious : undefined,\n ArrowDown: menuOpen ? getNext : undefined,\n };\n\n const action = actionMap[event.key as keyof typeof actionMap];\n\n if (action) {\n event.preventDefault();\n const activeTabId = activeTab.current?.id;\n if (!activeTabId) return;\n const nextItem = action(activeTabId);\n if (nextItem) {\n nextItem.element?.scrollIntoView({\n block: \"nearest\",\n inline: \"nearest\",\n });\n nextItem.element?.focus({ preventScroll: true });\n }\n }\n };\n\n const warningId = useId();\n\n return (\n <div\n role=\"tablist\"\n className={clsx(\n withBaseName(),\n withBaseName(appearance),\n withBaseName(\"horizontal\"),\n withBaseName(`activeColor${capitalize(activeColor)}`),\n className,\n )}\n data-ismeasuring={isMeasuring ? true : undefined}\n ref={handleRef}\n onKeyDown={handleKeyDown}\n aria-describedby={clsx(ariaDescribedBy, warningId)}\n {...rest}\n >\n {!isMeasuring && hidden.length > 0 && (\n <span id={warningId} className={withBaseName(\"overflowWarning\")}>\n Note: This tab list includes overflow; tab positions may be\n inaccurate or change when a tab is selected\n </span>\n )}\n {visible}\n <TabOverflowList\n isMeasuring={isMeasuring}\n buttonRef={overflowButtonRef}\n tabstripRef={tabstripRef}\n open={menuOpen}\n setOpen={setMenuOpen}\n >\n {hidden}\n </TabOverflowList>\n </div>\n );\n },\n);\n"],"names":["makePrefixer","forwardRef","useWindow","useComponentCssInjection","tablistNextCss","useTabsNext","useRef","useForkRef","useOverflow","useRestoreActiveTab","useId","jsxs","clsx","capitalize","jsx","TabOverflowList"],"mappings":"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"}
@@ -89,7 +89,7 @@ const TabOverflowList = react.forwardRef(
89
89
  const listId = core.useId();
90
90
  const childCount = react.Children.count(children);
91
91
  if (childCount === 0 && !isMeasuring) return null;
92
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: withBaseName(), ref: handleRootRef, children: [
92
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: withBaseName(), ref: handleRootRef, "data-overflow": true, children: [
93
93
  /* @__PURE__ */ jsxRuntime.jsx(
94
94
  core.Button,
95
95
  {
@@ -1 +1 @@
1
- {"version":3,"file":"TabOverflowList.js","sources":["../src/tabs-next/TabOverflowList.tsx"],"sourcesContent":["import {\n FloatingTree,\n offset,\n size,\n useDismiss,\n useInteractions,\n} from \"@floating-ui/react\";\nimport {\n Button,\n makePrefixer,\n useFloatingUI,\n useForkRef,\n useIcon,\n useId,\n} from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport {\n Children,\n type ComponentPropsWithoutRef,\n type Dispatch,\n type ReactNode,\n type Ref,\n type RefObject,\n type SetStateAction,\n forwardRef,\n useCallback,\n useRef,\n} from \"react\";\nimport tabOverflowListCss from \"./TabOverflowList.css\";\nimport { useFocusOutside } from \"./hooks/useFocusOutside\";\n\ninterface TabOverflowListProps extends ComponentPropsWithoutRef<\"button\"> {\n buttonRef?: Ref<HTMLButtonElement>;\n tabstripRef: RefObject<HTMLDivElement>;\n children?: ReactNode;\n isMeasuring?: boolean;\n open: boolean;\n setOpen: Dispatch<SetStateAction<boolean>>;\n}\n\nconst withBaseName = makePrefixer(\"saltTabOverflow\");\n\nexport const TabOverflowList = forwardRef<HTMLDivElement, TabOverflowListProps>(\n function TabOverflowList(props, ref) {\n const {\n buttonRef,\n tabstripRef,\n children,\n isMeasuring,\n open,\n setOpen,\n ...rest\n } = props;\n\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-tabs-next-overflow-list\",\n css: tabOverflowListCss,\n window: targetWindow,\n });\n\n const { OverflowIcon } = useIcon();\n\n const { refs, x, y, strategy, context } = useFloatingUI({\n open: open,\n onOpenChange(open, _, reason) {\n if (reason === \"escape-key\") {\n queueMicrotask(() => {\n const allTabs =\n tabstripRef.current?.querySelectorAll<HTMLElement>(\n '[role=\"tab\"]:not([aria-hidden])',\n ) ?? [];\n const numberOfTabsInOverflow =\n listRef.current?.querySelectorAll<HTMLElement>('[role=\"tab\"]')\n .length ?? 0;\n\n allTabs[allTabs.length - numberOfTabsInOverflow - 1]?.focus({\n preventScroll: true,\n });\n });\n }\n\n setOpen(open);\n },\n placement: \"bottom-start\",\n middleware: [\n offset(1),\n size({\n apply({ elements, availableHeight }) {\n Object.assign(elements.floating.style, {\n maxHeight: `max(calc((var(--salt-size-base) + var(--salt-spacing-100)) * 5), calc(${availableHeight}px - var(--salt-spacing-100)))`,\n });\n },\n }),\n ],\n });\n\n const { getFloatingProps } = useInteractions([useDismiss(context)]);\n\n const rootRef = useRef<HTMLDivElement>(null);\n const handleRootRef = useForkRef(rootRef, ref);\n const listRef = useRef<HTMLDivElement>(null);\n const handleListRef = useForkRef<HTMLDivElement>(listRef, refs.setFloating);\n\n const handleFocusOutside = useCallback(() => {\n setOpen(false);\n }, [setOpen]);\n\n useFocusOutside(\n rootRef,\n handleFocusOutside,\n open,\n \"[data-floating-ui-portal]\",\n );\n\n const handleClick = () => {\n if (!open) {\n listRef.current\n ?.querySelectorAll<HTMLElement>('[role=\"tab\"]')[0]\n ?.focus({ preventScroll: true });\n } else {\n setOpen(false);\n }\n };\n\n const handleFocus = () => {\n setOpen(true);\n };\n\n const handleButtonRef = useForkRef<HTMLButtonElement>(\n buttonRef,\n refs.setReference,\n );\n\n const listId = useId();\n\n const childCount = Children.count(children);\n if (childCount === 0 && !isMeasuring) return null;\n\n return (\n <div className={withBaseName()} ref={handleRootRef}>\n <Button\n data-overflowbutton\n tabIndex={-1}\n appearance=\"transparent\"\n sentiment=\"neutral\"\n onClick={handleClick}\n ref={handleButtonRef}\n aria-label={`Overflow menu. ${childCount} tabs hidden`}\n aria-expanded={open}\n aria-controls={listId}\n aria-hidden=\"true\"\n role=\"tab\"\n aria-haspopup\n {...rest}\n >\n <OverflowIcon aria-hidden />\n </Button>\n <FloatingTree>\n <div\n ref={handleListRef}\n {...getFloatingProps({\n onFocus: handleFocus,\n role: \"presentation\",\n })}\n className={withBaseName(\"list\")}\n data-hidden={!open}\n style={\n open\n ? { left: x ?? 0, top: y ?? 0, position: strategy }\n : undefined\n }\n id={listId}\n >\n <div className={withBaseName(\"listContainer\")}>{children}</div>\n </div>\n </FloatingTree>\n </div>\n );\n },\n);\n"],"names":["makePrefixer","forwardRef","TabOverflowList","useWindow","useComponentCssInjection","tabOverflowListCss","useIcon","useFloatingUI","open","offset","size","useInteractions","useDismiss","useRef","useForkRef","useCallback","useFocusOutside","useId","Children","jsx","Button","FloatingTree"],"mappings":"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"}
1
+ {"version":3,"file":"TabOverflowList.js","sources":["../src/tabs-next/TabOverflowList.tsx"],"sourcesContent":["import {\n FloatingTree,\n offset,\n size,\n useDismiss,\n useInteractions,\n} from \"@floating-ui/react\";\nimport {\n Button,\n makePrefixer,\n useFloatingUI,\n useForkRef,\n useIcon,\n useId,\n} from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport {\n Children,\n type ComponentPropsWithoutRef,\n type Dispatch,\n type ReactNode,\n type Ref,\n type RefObject,\n type SetStateAction,\n forwardRef,\n useCallback,\n useRef,\n} from \"react\";\nimport tabOverflowListCss from \"./TabOverflowList.css\";\nimport { useFocusOutside } from \"./hooks/useFocusOutside\";\n\ninterface TabOverflowListProps extends ComponentPropsWithoutRef<\"button\"> {\n buttonRef?: Ref<HTMLButtonElement>;\n tabstripRef: RefObject<HTMLDivElement>;\n children?: ReactNode;\n isMeasuring?: boolean;\n open: boolean;\n setOpen: Dispatch<SetStateAction<boolean>>;\n}\n\nconst withBaseName = makePrefixer(\"saltTabOverflow\");\n\nexport const TabOverflowList = forwardRef<HTMLDivElement, TabOverflowListProps>(\n function TabOverflowList(props, ref) {\n const {\n buttonRef,\n tabstripRef,\n children,\n isMeasuring,\n open,\n setOpen,\n ...rest\n } = props;\n\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-tabs-next-overflow-list\",\n css: tabOverflowListCss,\n window: targetWindow,\n });\n\n const { OverflowIcon } = useIcon();\n\n const { refs, x, y, strategy, context } = useFloatingUI({\n open: open,\n onOpenChange(open, _, reason) {\n if (reason === \"escape-key\") {\n queueMicrotask(() => {\n const allTabs =\n tabstripRef.current?.querySelectorAll<HTMLElement>(\n '[role=\"tab\"]:not([aria-hidden])',\n ) ?? [];\n const numberOfTabsInOverflow =\n listRef.current?.querySelectorAll<HTMLElement>('[role=\"tab\"]')\n .length ?? 0;\n\n allTabs[allTabs.length - numberOfTabsInOverflow - 1]?.focus({\n preventScroll: true,\n });\n });\n }\n\n setOpen(open);\n },\n placement: \"bottom-start\",\n middleware: [\n offset(1),\n size({\n apply({ elements, availableHeight }) {\n Object.assign(elements.floating.style, {\n maxHeight: `max(calc((var(--salt-size-base) + var(--salt-spacing-100)) * 5), calc(${availableHeight}px - var(--salt-spacing-100)))`,\n });\n },\n }),\n ],\n });\n\n const { getFloatingProps } = useInteractions([useDismiss(context)]);\n\n const rootRef = useRef<HTMLDivElement>(null);\n const handleRootRef = useForkRef(rootRef, ref);\n const listRef = useRef<HTMLDivElement>(null);\n const handleListRef = useForkRef<HTMLDivElement>(listRef, refs.setFloating);\n\n const handleFocusOutside = useCallback(() => {\n setOpen(false);\n }, [setOpen]);\n\n useFocusOutside(\n rootRef,\n handleFocusOutside,\n open,\n \"[data-floating-ui-portal]\",\n );\n\n const handleClick = () => {\n if (!open) {\n listRef.current\n ?.querySelectorAll<HTMLElement>('[role=\"tab\"]')[0]\n ?.focus({ preventScroll: true });\n } else {\n setOpen(false);\n }\n };\n\n const handleFocus = () => {\n setOpen(true);\n };\n\n const handleButtonRef = useForkRef<HTMLButtonElement>(\n buttonRef,\n refs.setReference,\n );\n\n const listId = useId();\n\n const childCount = Children.count(children);\n if (childCount === 0 && !isMeasuring) return null;\n\n return (\n <div className={withBaseName()} ref={handleRootRef} data-overflow>\n <Button\n data-overflowbutton\n tabIndex={-1}\n appearance=\"transparent\"\n sentiment=\"neutral\"\n onClick={handleClick}\n ref={handleButtonRef}\n aria-label={`Overflow menu. ${childCount} tabs hidden`}\n aria-expanded={open}\n aria-controls={listId}\n aria-hidden=\"true\"\n role=\"tab\"\n aria-haspopup\n {...rest}\n >\n <OverflowIcon aria-hidden />\n </Button>\n <FloatingTree>\n <div\n ref={handleListRef}\n {...getFloatingProps({\n onFocus: handleFocus,\n role: \"presentation\",\n })}\n className={withBaseName(\"list\")}\n data-hidden={!open}\n style={\n open\n ? { left: x ?? 0, top: y ?? 0, position: strategy }\n : undefined\n }\n id={listId}\n >\n <div className={withBaseName(\"listContainer\")}>{children}</div>\n </div>\n </FloatingTree>\n </div>\n );\n },\n);\n"],"names":["makePrefixer","forwardRef","TabOverflowList","useWindow","useComponentCssInjection","tabOverflowListCss","useIcon","useFloatingUI","open","offset","size","useInteractions","useDismiss","useRef","useForkRef","useCallback","useFocusOutside","useId","Children","jsxs","jsx","Button","FloatingTree"],"mappings":";;;;;;;;;;;AAyCA,MAAM,YAAA,GAAeA,kBAAa,iBAAiB,CAAA;AAE5C,MAAM,eAAkB,GAAAC,gBAAA;AAAA,EAC7B,SAASC,gBAAgB,CAAA,KAAA,EAAO,GAAK,EAAA;AACnC,IAAM,MAAA;AAAA,MACJ,SAAA;AAAA,MACA,WAAA;AAAA,MACA,QAAA;AAAA,MACA,WAAA;AAAA,MACA,IAAA;AAAA,MACA,OAAA;AAAA,MACA,GAAG;AAAA,KACD,GAAA,KAAA;AAEJ,IAAA,MAAM,eAAeC,gBAAU,EAAA;AAC/B,IAAyBC,+BAAA,CAAA;AAAA,MACvB,MAAQ,EAAA,8BAAA;AAAA,MACR,GAAK,EAAAC,iBAAA;AAAA,MACL,MAAQ,EAAA;AAAA,KACT,CAAA;AAED,IAAM,MAAA,EAAE,YAAa,EAAA,GAAIC,YAAQ,EAAA;AAEjC,IAAA,MAAM,EAAE,IAAM,EAAA,CAAA,EAAG,GAAG,QAAU,EAAA,OAAA,KAAYC,kBAAc,CAAA;AAAA,MACtD,IAAA;AAAA,MACA,YAAA,CAAaC,KAAM,EAAA,CAAA,EAAG,MAAQ,EAAA;AAC5B,QAAA,IAAI,WAAW,YAAc,EAAA;AAC3B,UAAA,cAAA,CAAe,MAAM;AApE/B,YAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AAqEY,YAAM,MAAA,OAAA,GAAA,CAAA,CACJ,EAAY,GAAA,WAAA,CAAA,OAAA,KAAZ,IAAqB,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,gBAAA;AAAA,cACnB;AAAA,aAAA,KACG,EAAC;AACR,YAAA,MAAM,2BACJ,EAAQ,GAAA,OAAA,CAAA,OAAA,KAAR,IAAiB,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,gBAAA,CAA8B,gBAC5C,MAAU,KAAA,CAAA;AAEf,YAAA,CAAA,EAAA,GAAA,OAAA,CAAQ,QAAQ,MAAS,GAAA,sBAAA,GAAyB,CAAC,CAAA,KAAnD,mBAAsD,KAAM,CAAA;AAAA,cAC1D,aAAe,EAAA;AAAA,aACjB,CAAA;AAAA,WACD,CAAA;AAAA;AAGH,QAAA,OAAA,CAAQA,KAAI,CAAA;AAAA,OACd;AAAA,MACA,SAAW,EAAA,cAAA;AAAA,MACX,UAAY,EAAA;AAAA,QACVC,eAAO,CAAC,CAAA;AAAA,QACRC,YAAK,CAAA;AAAA,UACH,KAAM,CAAA,EAAE,QAAU,EAAA,eAAA,EAAmB,EAAA;AACnC,YAAO,MAAA,CAAA,MAAA,CAAO,QAAS,CAAA,QAAA,CAAS,KAAO,EAAA;AAAA,cACrC,SAAA,EAAW,yEAAyE,eAAe,CAAA,8BAAA;AAAA,aACpG,CAAA;AAAA;AACH,SACD;AAAA;AACH,KACD,CAAA;AAED,IAAM,MAAA,EAAE,kBAAqB,GAAAC,uBAAA,CAAgB,CAACC,kBAAW,CAAA,OAAO,CAAC,CAAC,CAAA;AAElE,IAAM,MAAA,OAAA,GAAUC,aAAuB,IAAI,CAAA;AAC3C,IAAM,MAAA,aAAA,GAAgBC,eAAW,CAAA,OAAA,EAAS,GAAG,CAAA;AAC7C,IAAM,MAAA,OAAA,GAAUD,aAAuB,IAAI,CAAA;AAC3C,IAAA,MAAM,aAAgB,GAAAC,eAAA,CAA2B,OAAS,EAAA,IAAA,CAAK,WAAW,CAAA;AAE1E,IAAM,MAAA,kBAAA,GAAqBC,kBAAY,MAAM;AAC3C,MAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,KACf,EAAG,CAAC,OAAO,CAAC,CAAA;AAEZ,IAAAC,+BAAA;AAAA,MACE,OAAA;AAAA,MACA,kBAAA;AAAA,MACA,IAAA;AAAA,MACA;AAAA,KACF;AAEA,IAAA,MAAM,cAAc,MAAM;AApH9B,MAAA,IAAA,EAAA,EAAA,EAAA;AAqHM,MAAA,IAAI,CAAC,IAAM,EAAA;AACT,QAAQ,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,OAAA,CAAA,OAAA,KAAR,mBACI,gBAA8B,CAAA,cAAA,CAAA,CAAgB,OADlD,IAEI,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,KAAA,CAAM,EAAE,aAAA,EAAe,IAAK,EAAA,CAAA;AAAA,OAC3B,MAAA;AACL,QAAA,OAAA,CAAQ,KAAK,CAAA;AAAA;AACf,KACF;AAEA,IAAA,MAAM,cAAc,MAAM;AACxB,MAAA,OAAA,CAAQ,IAAI,CAAA;AAAA,KACd;AAEA,IAAA,MAAM,eAAkB,GAAAF,eAAA;AAAA,MACtB,SAAA;AAAA,MACA,IAAK,CAAA;AAAA,KACP;AAEA,IAAA,MAAM,SAASG,UAAM,EAAA;AAErB,IAAM,MAAA,UAAA,GAAaC,cAAS,CAAA,KAAA,CAAM,QAAQ,CAAA;AAC1C,IAAA,IAAI,UAAe,KAAA,CAAA,IAAK,CAAC,WAAA,EAAoB,OAAA,IAAA;AAE7C,IACE,uBAAAC,eAAA,CAAC,SAAI,SAAW,EAAA,YAAA,IAAgB,GAAK,EAAA,aAAA,EAAe,iBAAa,IAC/D,EAAA,QAAA,EAAA;AAAA,sBAAAC,cAAA;AAAA,QAACC,WAAA;AAAA,QAAA;AAAA,UACC,qBAAmB,EAAA,IAAA;AAAA,UACnB,QAAU,EAAA,CAAA,CAAA;AAAA,UACV,UAAW,EAAA,aAAA;AAAA,UACX,SAAU,EAAA,SAAA;AAAA,UACV,OAAS,EAAA,WAAA;AAAA,UACT,GAAK,EAAA,eAAA;AAAA,UACL,YAAA,EAAY,kBAAkB,UAAU,CAAA,YAAA,CAAA;AAAA,UACxC,eAAe,EAAA,IAAA;AAAA,UACf,eAAe,EAAA,MAAA;AAAA,UACf,aAAY,EAAA,MAAA;AAAA,UACZ,IAAK,EAAA,KAAA;AAAA,UACL,eAAa,EAAA,IAAA;AAAA,UACZ,GAAG,IAAA;AAAA,UAEJ,QAAA,kBAAAD,cAAA,CAAC,YAAa,EAAA,EAAA,aAAA,EAAW,IAAC,EAAA;AAAA;AAAA,OAC5B;AAAA,qCACCE,oBACC,EAAA,EAAA,QAAA,kBAAAF,cAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UACC,GAAK,EAAA,aAAA;AAAA,UACJ,GAAG,gBAAiB,CAAA;AAAA,YACnB,OAAS,EAAA,WAAA;AAAA,YACT,IAAM,EAAA;AAAA,WACP,CAAA;AAAA,UACD,SAAA,EAAW,aAAa,MAAM,CAAA;AAAA,UAC9B,eAAa,CAAC,IAAA;AAAA,UACd,KAAA,EACE,IACI,GAAA,EAAE,IAAM,EAAA,CAAA,IAAK,CAAG,EAAA,GAAA,EAAK,CAAK,IAAA,CAAA,EAAG,QAAU,EAAA,QAAA,EACvC,GAAA,KAAA,CAAA;AAAA,UAEN,EAAI,EAAA,MAAA;AAAA,UAEJ,yCAAC,KAAI,EAAA,EAAA,SAAA,EAAW,YAAa,CAAA,eAAe,GAAI,QAAS,EAAA;AAAA;AAAA,OAE7D,EAAA;AAAA,KACF,EAAA,CAAA;AAAA;AAGN;;;;"}
@@ -27,7 +27,7 @@ const TabsNext = react.forwardRef(
27
27
  items
28
28
  } = useCollection.useCollection({ wrap: true });
29
29
  const activeTab = react.useRef();
30
- const returnFocus = react.useRef(void 0);
30
+ const removedActiveTabRef = react.useRef(void 0);
31
31
  const [menuOpen, setMenuOpen] = react.useState(false);
32
32
  const [selected, setSelectedState] = core.useControlled({
33
33
  controlled: value,
@@ -35,10 +35,6 @@ const TabsNext = react.forwardRef(
35
35
  name: "TabListNext",
36
36
  state: "selected"
37
37
  });
38
- const selectedRef = react.useRef(void 0);
39
- core.useIsomorphicLayoutEffect(() => {
40
- selectedRef.current = selected;
41
- }, [selected]);
42
38
  const setSelected = react.useCallback(
43
39
  (event, value2) => {
44
40
  setMenuOpen(false);
@@ -55,7 +51,7 @@ const TabsNext = react.forwardRef(
55
51
  });
56
52
  return () => {
57
53
  var _a;
58
- const items2 = cleanup();
54
+ cleanup();
59
55
  setValueToIdMap(({ map }) => {
60
56
  map.delete(item2.value);
61
57
  return { map };
@@ -63,50 +59,7 @@ const TabsNext = react.forwardRef(
63
59
  if (((_a = activeTab.current) == null ? void 0 : _a.value) !== item2.value) {
64
60
  return;
65
61
  }
66
- returnFocus.current = item2.value;
67
- const containFocus = () => {
68
- var _a2;
69
- const activeIndex = items2.current.findIndex(
70
- (i) => item2.value === i.value
71
- );
72
- const nextIndex = activeIndex === items2.current.length - 1 ? items2.current.length - 2 : activeIndex + 1;
73
- const nextActive = items2.current[nextIndex];
74
- returnFocus.current = nextActive.value;
75
- if (selectedRef.current === item2.value) {
76
- setSelected(null, nextActive.value);
77
- }
78
- (_a2 = nextActive == null ? void 0 : nextActive.element) == null ? void 0 : _a2.focus();
79
- };
80
- if (document.activeElement === document.body) {
81
- requestAnimationFrame(() => {
82
- if (document.activeElement === document.body) {
83
- containFocus();
84
- }
85
- });
86
- } else {
87
- const handleFocusOut = (event) => {
88
- if (!event.relatedTarget) {
89
- requestAnimationFrame(() => {
90
- if (document.activeElement === document.body) {
91
- containFocus();
92
- }
93
- });
94
- }
95
- };
96
- item2.element.ownerDocument.addEventListener(
97
- "focusout",
98
- handleFocusOut,
99
- {
100
- once: true
101
- }
102
- );
103
- setTimeout(() => {
104
- item2.element.ownerDocument.removeEventListener(
105
- "focusout",
106
- handleFocusOut
107
- );
108
- }, 1e3);
109
- }
62
+ removedActiveTabRef.current = item2.value;
110
63
  };
111
64
  });
112
65
  const registerPanel = react.useCallback((id, value2) => {
@@ -150,7 +103,7 @@ const TabsNext = react.forwardRef(
150
103
  activeTab,
151
104
  menuOpen,
152
105
  setMenuOpen,
153
- returnFocus
106
+ removedActiveTabRef
154
107
  }),
155
108
  [
156
109
  registerPanel,
@@ -1 +1 @@
1
- {"version":3,"file":"TabsNext.js","sources":["../src/tabs-next/TabsNext.tsx"],"sourcesContent":["import {\n type ComponentPropsWithoutRef,\n type ReactNode,\n type SyntheticEvent,\n forwardRef,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport {\n makePrefixer,\n useControlled,\n useEventCallback,\n useIsomorphicLayoutEffect,\n} from \"@salt-ds/core\";\nimport { clsx } from \"clsx\";\nimport { type Item, TabsNextContext } from \"./TabsNextContext\";\nimport { useCollection } from \"./hooks/useCollection\";\n\nexport interface TabsNextProps\n extends Omit<ComponentPropsWithoutRef<\"div\">, \"onChange\"> {\n children?: ReactNode;\n /**\n * The default value. Use when the component is not controlled.\n */\n defaultValue?: string;\n /**\n * The value. Use when the component is controlled.\n */\n value?: string;\n /**\n * Callback fired when the selection changes. The event will be null when selection is moved automatically.\n */\n onChange?: (event: SyntheticEvent | null, value: string) => void;\n}\n\nconst withBaseName = makePrefixer(\"saltTabsNext\");\n\nexport const TabsNext = forwardRef<HTMLDivElement, TabsNextProps>(\n function TabsNext(props, ref) {\n const { className, children, value, defaultValue, onChange, ...rest } =\n props;\n\n const [valueToTabIdMap, setValueToIdMap] = useState({\n map: new Map<string, string>(),\n });\n const [valueToPanelIdMap, setValueToPanelIdMap] = useState({\n map: new Map<string, string>(),\n });\n\n const {\n registerItem,\n item,\n getNext,\n getPrevious,\n getFirst,\n getLast,\n items,\n } = useCollection({ wrap: true });\n\n const activeTab = useRef<Pick<Item, \"id\" | \"value\">>();\n const returnFocus = useRef<string | undefined>(undefined);\n\n const [menuOpen, setMenuOpen] = useState(false);\n\n const [selected, setSelectedState] = useControlled({\n controlled: value,\n default: defaultValue,\n name: \"TabListNext\",\n state: \"selected\",\n });\n\n // This ref is needed so we can read the current selected item in the containFocus() function.\n const selectedRef = useRef<string | undefined>(undefined);\n useIsomorphicLayoutEffect(() => {\n selectedRef.current = selected;\n }, [selected]);\n\n const setSelected = useCallback(\n (event: SyntheticEvent | null, value: string) => {\n setMenuOpen(false);\n setSelectedState(value);\n onChange?.(event, value);\n },\n [onChange],\n );\n\n const registerTab = useEventCallback((item: Item) => {\n const cleanup = registerItem(item);\n setValueToIdMap(({ map }) => {\n map.set(item.value, item.id);\n return { map };\n });\n\n return () => {\n const items = cleanup();\n setValueToIdMap(({ map }) => {\n map.delete(item.value);\n return { map };\n });\n\n if (activeTab.current?.value !== item.value) {\n return;\n }\n\n returnFocus.current = item.value;\n\n const containFocus = () => {\n const activeIndex = items.current.findIndex(\n (i) => item.value === i.value,\n );\n\n const nextIndex =\n activeIndex === items.current.length - 1\n ? items.current.length - 2\n : activeIndex + 1;\n\n const nextActive = items.current[nextIndex];\n\n returnFocus.current = nextActive.value;\n\n if (selectedRef.current === item.value) {\n setSelected(null, nextActive.value);\n }\n\n nextActive?.element?.focus();\n };\n\n if (document.activeElement === document.body) {\n requestAnimationFrame(() => {\n if (document.activeElement === document.body) {\n containFocus();\n }\n });\n } else {\n const handleFocusOut = (event: FocusEvent) => {\n if (!event.relatedTarget) {\n requestAnimationFrame(() => {\n if (document.activeElement === document.body) {\n containFocus();\n }\n });\n }\n };\n\n item.element.ownerDocument.addEventListener(\n \"focusout\",\n handleFocusOut,\n {\n once: true,\n },\n );\n\n setTimeout(() => {\n item.element.ownerDocument.removeEventListener(\n \"focusout\",\n handleFocusOut,\n );\n }, 1000);\n }\n };\n });\n\n const registerPanel = useCallback((id: string, value: string) => {\n setValueToPanelIdMap(({ map }) => {\n map.set(value, id);\n return { map };\n });\n return () => {\n setValueToIdMap(({ map }) => {\n map.delete(value);\n return { map };\n });\n };\n }, []);\n\n const getPanelId = useCallback(\n (value: string) => {\n return valueToPanelIdMap.map.get(value);\n },\n [valueToPanelIdMap],\n );\n\n const getTabId = useCallback(\n (value: string) => {\n return valueToTabIdMap.map.get(value);\n },\n [valueToTabIdMap],\n );\n\n const context = useMemo(\n () => ({\n registerTab,\n registerPanel,\n getPanelId,\n getTabId,\n selected,\n setSelected,\n item,\n getNext,\n getPrevious,\n getFirst,\n getLast,\n items,\n activeTab,\n menuOpen,\n setMenuOpen,\n returnFocus,\n }),\n [\n registerPanel,\n registerTab,\n getPanelId,\n getTabId,\n selected,\n setSelected,\n item,\n getNext,\n getPrevious,\n getFirst,\n getLast,\n items,\n menuOpen,\n ],\n );\n\n return (\n <TabsNextContext.Provider value={context}>\n <div className={clsx(withBaseName(), className)} ref={ref} {...rest}>\n {children}\n </div>\n </TabsNextContext.Provider>\n );\n },\n);\n"],"names":["makePrefixer","forwardRef","TabsNext","useState","useCollection","useRef","useControlled","useIsomorphicLayoutEffect","useCallback","value","useEventCallback","item","items","_a","useMemo","TabsNextContext","clsx"],"mappings":"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"}
1
+ {"version":3,"file":"TabsNext.js","sources":["../src/tabs-next/TabsNext.tsx"],"sourcesContent":["import {\n type ComponentPropsWithoutRef,\n type ReactNode,\n type SyntheticEvent,\n forwardRef,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport { makePrefixer, useControlled, useEventCallback } from \"@salt-ds/core\";\nimport { clsx } from \"clsx\";\nimport { type Item, TabsNextContext } from \"./TabsNextContext\";\nimport { useCollection } from \"./hooks/useCollection\";\n\nexport interface TabsNextProps\n extends Omit<ComponentPropsWithoutRef<\"div\">, \"onChange\"> {\n children?: ReactNode;\n /**\n * The default value. Use when the component is not controlled.\n */\n defaultValue?: string;\n /**\n * The value. Use when the component is controlled.\n */\n value?: string;\n /**\n * Callback fired when the selection changes. The event will be null when selection is moved automatically.\n */\n onChange?: (event: SyntheticEvent | null, value: string) => void;\n}\n\nconst withBaseName = makePrefixer(\"saltTabsNext\");\n\nexport const TabsNext = forwardRef<HTMLDivElement, TabsNextProps>(\n function TabsNext(props, ref) {\n const { className, children, value, defaultValue, onChange, ...rest } =\n props;\n\n const [valueToTabIdMap, setValueToIdMap] = useState({\n map: new Map<string, string>(),\n });\n const [valueToPanelIdMap, setValueToPanelIdMap] = useState({\n map: new Map<string, string>(),\n });\n\n const {\n registerItem,\n item,\n getNext,\n getPrevious,\n getFirst,\n getLast,\n items,\n } = useCollection({ wrap: true });\n\n const activeTab = useRef<Pick<Item, \"id\" | \"value\">>();\n const removedActiveTabRef = useRef<string | undefined>(undefined);\n\n const [menuOpen, setMenuOpen] = useState(false);\n\n const [selected, setSelectedState] = useControlled({\n controlled: value,\n default: defaultValue,\n name: \"TabListNext\",\n state: \"selected\",\n });\n\n const setSelected = useCallback(\n (event: SyntheticEvent | null, value: string) => {\n setMenuOpen(false);\n setSelectedState(value);\n onChange?.(event, value);\n },\n [onChange],\n );\n\n const registerTab = useEventCallback((item: Item) => {\n const cleanup = registerItem(item);\n setValueToIdMap(({ map }) => {\n map.set(item.value, item.id);\n return { map };\n });\n\n return () => {\n cleanup();\n setValueToIdMap(({ map }) => {\n map.delete(item.value);\n return { map };\n });\n\n if (activeTab.current?.value !== item.value) {\n return;\n }\n\n removedActiveTabRef.current = item.value;\n };\n });\n\n const registerPanel = useCallback((id: string, value: string) => {\n setValueToPanelIdMap(({ map }) => {\n map.set(value, id);\n return { map };\n });\n return () => {\n setValueToIdMap(({ map }) => {\n map.delete(value);\n return { map };\n });\n };\n }, []);\n\n const getPanelId = useCallback(\n (value: string) => {\n return valueToPanelIdMap.map.get(value);\n },\n [valueToPanelIdMap],\n );\n\n const getTabId = useCallback(\n (value: string) => {\n return valueToTabIdMap.map.get(value);\n },\n [valueToTabIdMap],\n );\n\n const context = useMemo(\n () => ({\n registerTab,\n registerPanel,\n getPanelId,\n getTabId,\n selected,\n setSelected,\n item,\n getNext,\n getPrevious,\n getFirst,\n getLast,\n items,\n activeTab,\n menuOpen,\n setMenuOpen,\n removedActiveTabRef,\n }),\n [\n registerPanel,\n registerTab,\n getPanelId,\n getTabId,\n selected,\n setSelected,\n item,\n getNext,\n getPrevious,\n getFirst,\n getLast,\n items,\n menuOpen,\n ],\n );\n\n return (\n <TabsNextContext.Provider value={context}>\n <div className={clsx(withBaseName(), className)} ref={ref} {...rest}>\n {children}\n </div>\n </TabsNextContext.Provider>\n );\n },\n);\n"],"names":["makePrefixer","forwardRef","TabsNext","useState","useCollection","useRef","useControlled","useCallback","value","useEventCallback","item","useMemo","TabsNextContext","clsx"],"mappings":";;;;;;;;;AAiCA,MAAM,YAAA,GAAeA,kBAAa,cAAc,CAAA;AAEzC,MAAM,QAAW,GAAAC,gBAAA;AAAA,EACtB,SAASC,SAAS,CAAA,KAAA,EAAO,GAAK,EAAA;AAC5B,IAAM,MAAA,EAAE,WAAW,QAAU,EAAA,KAAA,EAAO,cAAc,QAAU,EAAA,GAAG,MAC7D,GAAA,KAAA;AAEF,IAAA,MAAM,CAAC,eAAA,EAAiB,eAAe,CAAA,GAAIC,cAAS,CAAA;AAAA,MAClD,GAAA,sBAAS,GAAoB;AAAA,KAC9B,CAAA;AACD,IAAA,MAAM,CAAC,iBAAA,EAAmB,oBAAoB,CAAA,GAAIA,cAAS,CAAA;AAAA,MACzD,GAAA,sBAAS,GAAoB;AAAA,KAC9B,CAAA;AAED,IAAM,MAAA;AAAA,MACJ,YAAA;AAAA,MACA,IAAA;AAAA,MACA,OAAA;AAAA,MACA,WAAA;AAAA,MACA,QAAA;AAAA,MACA,OAAA;AAAA,MACA;AAAA,KACE,GAAAC,2BAAA,CAAc,EAAE,IAAA,EAAM,MAAM,CAAA;AAEhC,IAAA,MAAM,YAAYC,YAAmC,EAAA;AACrD,IAAM,MAAA,mBAAA,GAAsBA,aAA2B,KAAS,CAAA,CAAA;AAEhE,IAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAIF,eAAS,KAAK,CAAA;AAE9C,IAAA,MAAM,CAAC,QAAA,EAAU,gBAAgB,CAAA,GAAIG,kBAAc,CAAA;AAAA,MACjD,UAAY,EAAA,KAAA;AAAA,MACZ,OAAS,EAAA,YAAA;AAAA,MACT,IAAM,EAAA,aAAA;AAAA,MACN,KAAO,EAAA;AAAA,KACR,CAAA;AAED,IAAA,MAAM,WAAc,GAAAC,iBAAA;AAAA,MAClB,CAAC,OAA8BC,MAAkB,KAAA;AAC/C,QAAA,WAAA,CAAY,KAAK,CAAA;AACjB,QAAA,gBAAA,CAAiBA,MAAK,CAAA;AACtB,QAAA,QAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,QAAA,CAAW,KAAOA,EAAAA,MAAAA,CAAAA;AAAA,OACpB;AAAA,MACA,CAAC,QAAQ;AAAA,KACX;AAEA,IAAM,MAAA,WAAA,GAAcC,qBAAiB,CAAA,CAACC,KAAe,KAAA;AACnD,MAAM,MAAA,OAAA,GAAU,aAAaA,KAAI,CAAA;AACjC,MAAgB,eAAA,CAAA,CAAC,EAAE,GAAA,EAAU,KAAA;AAC3B,QAAA,GAAA,CAAI,GAAIA,CAAAA,KAAAA,CAAK,KAAOA,EAAAA,KAAAA,CAAK,EAAE,CAAA;AAC3B,QAAA,OAAO,EAAE,GAAI,EAAA;AAAA,OACd,CAAA;AAED,MAAA,OAAO,MAAM;AArFnB,QAAA,IAAA,EAAA;AAsFQ,QAAQ,OAAA,EAAA;AACR,QAAgB,eAAA,CAAA,CAAC,EAAE,GAAA,EAAU,KAAA;AAC3B,UAAI,GAAA,CAAA,MAAA,CAAOA,MAAK,KAAK,CAAA;AACrB,UAAA,OAAO,EAAE,GAAI,EAAA;AAAA,SACd,CAAA;AAED,QAAA,IAAA,CAAA,CAAI,EAAU,GAAA,SAAA,CAAA,OAAA,KAAV,IAAmB,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,KAAA,MAAUA,MAAK,KAAO,EAAA;AAC3C,UAAA;AAAA;AAGF,QAAA,mBAAA,CAAoB,UAAUA,KAAK,CAAA,KAAA;AAAA,OACrC;AAAA,KACD,CAAA;AAED,IAAA,MAAM,aAAgB,GAAAH,iBAAA,CAAY,CAAC,EAAA,EAAYC,MAAkB,KAAA;AAC/D,MAAqB,oBAAA,CAAA,CAAC,EAAE,GAAA,EAAU,KAAA;AAChC,QAAI,GAAA,CAAA,GAAA,CAAIA,QAAO,EAAE,CAAA;AACjB,QAAA,OAAO,EAAE,GAAI,EAAA;AAAA,OACd,CAAA;AACD,MAAA,OAAO,MAAM;AACX,QAAgB,eAAA,CAAA,CAAC,EAAE,GAAA,EAAU,KAAA;AAC3B,UAAA,GAAA,CAAI,OAAOA,MAAK,CAAA;AAChB,UAAA,OAAO,EAAE,GAAI,EAAA;AAAA,SACd,CAAA;AAAA,OACH;AAAA,KACF,EAAG,EAAE,CAAA;AAEL,IAAA,MAAM,UAAa,GAAAD,iBAAA;AAAA,MACjB,CAACC,MAAkB,KAAA;AACjB,QAAO,OAAA,iBAAA,CAAkB,GAAI,CAAA,GAAA,CAAIA,MAAK,CAAA;AAAA,OACxC;AAAA,MACA,CAAC,iBAAiB;AAAA,KACpB;AAEA,IAAA,MAAM,QAAW,GAAAD,iBAAA;AAAA,MACf,CAACC,MAAkB,KAAA;AACjB,QAAO,OAAA,eAAA,CAAgB,GAAI,CAAA,GAAA,CAAIA,MAAK,CAAA;AAAA,OACtC;AAAA,MACA,CAAC,eAAe;AAAA,KAClB;AAEA,IAAA,MAAM,OAAU,GAAAG,aAAA;AAAA,MACd,OAAO;AAAA,QACL,WAAA;AAAA,QACA,aAAA;AAAA,QACA,UAAA;AAAA,QACA,QAAA;AAAA,QACA,QAAA;AAAA,QACA,WAAA;AAAA,QACA,IAAA;AAAA,QACA,OAAA;AAAA,QACA,WAAA;AAAA,QACA,QAAA;AAAA,QACA,OAAA;AAAA,QACA,KAAA;AAAA,QACA,SAAA;AAAA,QACA,QAAA;AAAA,QACA,WAAA;AAAA,QACA;AAAA,OACF,CAAA;AAAA,MACA;AAAA,QACE,aAAA;AAAA,QACA,WAAA;AAAA,QACA,UAAA;AAAA,QACA,QAAA;AAAA,QACA,QAAA;AAAA,QACA,WAAA;AAAA,QACA,IAAA;AAAA,QACA,OAAA;AAAA,QACA,WAAA;AAAA,QACA,QAAA;AAAA,QACA,OAAA;AAAA,QACA,KAAA;AAAA,QACA;AAAA;AACF,KACF;AAEA,IAAA,sCACGC,+BAAgB,CAAA,QAAA,EAAhB,EAAyB,KAAO,EAAA,OAAA,EAC/B,yCAAC,KAAI,EAAA,EAAA,SAAA,EAAWC,SAAK,CAAA,YAAA,IAAgB,SAAS,CAAA,EAAG,KAAW,GAAG,IAAA,EAC5D,UACH,CACF,EAAA,CAAA;AAAA;AAGN;;;;"}
@@ -19,7 +19,7 @@ const TabsNextContext = core.createContext(
19
19
  getTabId: () => void 0,
20
20
  setSelected: () => void 0,
21
21
  activeTab: { current: void 0 },
22
- returnFocus: { current: void 0 },
22
+ removedActiveTabRef: { current: void 0 },
23
23
  menuOpen: false,
24
24
  setMenuOpen: () => void 0
25
25
  }
@@ -1 +1 @@
1
- {"version":3,"file":"TabsNextContext.js","sources":["../src/tabs-next/TabsNextContext.tsx"],"sourcesContent":["import { createContext } from \"@salt-ds/core\";\nimport {\n type Dispatch,\n type MutableRefObject,\n type SetStateAction,\n type SyntheticEvent,\n useContext,\n} from \"react\";\nimport type { useCollection } from \"./hooks/useCollection\";\n\nexport interface Item {\n id: string;\n value: string;\n element: HTMLElement;\n}\n\nexport interface TabsNextContextValue\n extends Omit<ReturnType<typeof useCollection>, \"registerItem\"> {\n registerTab: (item: Item) => () => void;\n registerPanel: (id: string, value: string) => () => void;\n getPanelId: (value: string) => string | undefined;\n getTabId: (value: string) => string | undefined;\n selected?: string;\n setSelected: (event: SyntheticEvent, value: string) => void;\n activeTab: MutableRefObject<Pick<Item, \"id\" | \"value\"> | undefined>;\n returnFocus: MutableRefObject<string | undefined>;\n menuOpen: boolean;\n setMenuOpen: Dispatch<SetStateAction<boolean>>;\n}\n\nexport const TabsNextContext = createContext<TabsNextContextValue>(\n \"TabsNextContext\",\n {\n getFirst: () => null,\n getLast: () => null,\n getNext: () => null,\n getPrevious: () => null,\n item: () => null,\n items: [],\n selected: undefined,\n registerTab: () => () => undefined,\n registerPanel: () => () => undefined,\n getPanelId: () => undefined,\n getTabId: () => undefined,\n setSelected: () => undefined,\n activeTab: { current: undefined },\n returnFocus: { current: undefined },\n menuOpen: false,\n setMenuOpen: () => undefined,\n },\n);\n\nexport function useTabsNext() {\n return useContext(TabsNextContext);\n}\n"],"names":["createContext","useContext"],"mappings":";;;;;AA8BO,MAAM,eAAkB,GAAAA,kBAAA;AAAA,EAC7B,iBAAA;AAAA,EACA;AAAA,IACE,UAAU,MAAM,IAAA;AAAA,IAChB,SAAS,MAAM,IAAA;AAAA,IACf,SAAS,MAAM,IAAA;AAAA,IACf,aAAa,MAAM,IAAA;AAAA,IACnB,MAAM,MAAM,IAAA;AAAA,IACZ,OAAO,EAAC;AAAA,IACR,QAAU,EAAA,KAAA,CAAA;AAAA,IACV,WAAA,EAAa,MAAM,MAAM,KAAA,CAAA;AAAA,IACzB,aAAA,EAAe,MAAM,MAAM,KAAA,CAAA;AAAA,IAC3B,YAAY,MAAM,KAAA,CAAA;AAAA,IAClB,UAAU,MAAM,KAAA,CAAA;AAAA,IAChB,aAAa,MAAM,KAAA,CAAA;AAAA,IACnB,SAAA,EAAW,EAAE,OAAA,EAAS,KAAU,CAAA,EAAA;AAAA,IAChC,WAAA,EAAa,EAAE,OAAA,EAAS,KAAU,CAAA,EAAA;AAAA,IAClC,QAAU,EAAA,KAAA;AAAA,IACV,aAAa,MAAM,KAAA;AAAA;AAEvB;AAEO,SAAS,WAAc,GAAA;AAC5B,EAAA,OAAOC,iBAAW,eAAe,CAAA;AACnC;;;;;"}
1
+ {"version":3,"file":"TabsNextContext.js","sources":["../src/tabs-next/TabsNextContext.tsx"],"sourcesContent":["import { createContext } from \"@salt-ds/core\";\nimport {\n type Dispatch,\n type MutableRefObject,\n type SetStateAction,\n type SyntheticEvent,\n useContext,\n} from \"react\";\nimport type { useCollection } from \"./hooks/useCollection\";\n\nexport interface Item {\n id: string;\n value: string;\n element: HTMLElement;\n}\n\nexport interface TabsNextContextValue\n extends Omit<ReturnType<typeof useCollection>, \"registerItem\"> {\n registerTab: (item: Item) => () => void;\n registerPanel: (id: string, value: string) => () => void;\n getPanelId: (value: string) => string | undefined;\n getTabId: (value: string) => string | undefined;\n selected?: string;\n setSelected: (event: SyntheticEvent, value: string) => void;\n activeTab: MutableRefObject<Pick<Item, \"id\" | \"value\"> | undefined>;\n removedActiveTabRef: MutableRefObject<string | undefined>;\n menuOpen: boolean;\n setMenuOpen: Dispatch<SetStateAction<boolean>>;\n}\n\nexport const TabsNextContext = createContext<TabsNextContextValue>(\n \"TabsNextContext\",\n {\n getFirst: () => null,\n getLast: () => null,\n getNext: () => null,\n getPrevious: () => null,\n item: () => null,\n items: [],\n selected: undefined,\n registerTab: () => () => undefined,\n registerPanel: () => () => undefined,\n getPanelId: () => undefined,\n getTabId: () => undefined,\n setSelected: () => undefined,\n activeTab: { current: undefined },\n removedActiveTabRef: { current: undefined },\n menuOpen: false,\n setMenuOpen: () => undefined,\n },\n);\n\nexport function useTabsNext() {\n return useContext(TabsNextContext);\n}\n"],"names":["createContext","useContext"],"mappings":";;;;;AA8BO,MAAM,eAAkB,GAAAA,kBAAA;AAAA,EAC7B,iBAAA;AAAA,EACA;AAAA,IACE,UAAU,MAAM,IAAA;AAAA,IAChB,SAAS,MAAM,IAAA;AAAA,IACf,SAAS,MAAM,IAAA;AAAA,IACf,aAAa,MAAM,IAAA;AAAA,IACnB,MAAM,MAAM,IAAA;AAAA,IACZ,OAAO,EAAC;AAAA,IACR,QAAU,EAAA,KAAA,CAAA;AAAA,IACV,WAAA,EAAa,MAAM,MAAM,KAAA,CAAA;AAAA,IACzB,aAAA,EAAe,MAAM,MAAM,KAAA,CAAA;AAAA,IAC3B,YAAY,MAAM,KAAA,CAAA;AAAA,IAClB,UAAU,MAAM,KAAA,CAAA;AAAA,IAChB,aAAa,MAAM,KAAA,CAAA;AAAA,IACnB,SAAA,EAAW,EAAE,OAAA,EAAS,KAAU,CAAA,EAAA;AAAA,IAChC,mBAAA,EAAqB,EAAE,OAAA,EAAS,KAAU,CAAA,EAAA;AAAA,IAC1C,QAAU,EAAA,KAAA;AAAA,IACV,aAAa,MAAM,KAAA;AAAA;AAEvB;AAEO,SAAS,WAAc,GAAA;AAC5B,EAAA,OAAOC,iBAAW,eAAe,CAAA;AACnC;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"useCollection.js","sources":["../src/tabs-next/hooks/useCollection.tsx"],"sourcesContent":["import { useCallback, useRef, useState } from \"react\";\n\nexport interface Item {\n id: string;\n element?: HTMLElement | null;\n value: string;\n}\n\nfunction sortBasedOnDOMPosition(items: Item[]): Item[] {\n const indexedItems = items.map((item, index) => [index, item] as const);\n let orderChanged = false;\n indexedItems.sort(([itemAIndex, itemA], [itemBIndex, itemB]) => {\n const itemAElement = itemA.element;\n const itemBElement = itemB.element;\n if (itemAElement === itemBElement) return 0;\n if (!itemAElement || !itemBElement) return 0;\n\n if (\n itemAElement.compareDocumentPosition(itemBElement) &\n Node.DOCUMENT_POSITION_FOLLOWING\n ) {\n if (itemAIndex > itemBIndex) {\n orderChanged = true;\n }\n return -1;\n }\n\n if (itemAIndex < itemBIndex) {\n orderChanged = true;\n }\n return 1;\n });\n\n if (orderChanged) {\n return indexedItems.map(([_, item]) => item);\n }\n return items;\n}\n\ninterface UseCollectionProps {\n wrap: boolean;\n}\n\nexport function useCollection({ wrap }: UseCollectionProps) {\n const [items, setItems] = useState<Item[]>([]);\n const itemsRef = useRef<Item[]>([]);\n const itemMap = useRef<Map<string, Item>>(new Map());\n\n const registerItem = useCallback((item: Item) => {\n setItems((old) => {\n const newItems = old.slice();\n const index = newItems.findIndex(({ id }) => id === item.id);\n if (index !== -1) {\n const newItem = { ...newItems[index], ...item };\n newItems[index] = newItem;\n itemMap.current.set(item.id, newItem);\n } else {\n newItems.push(item);\n itemMap.current.set(item.id, item);\n }\n const value = sortBasedOnDOMPosition(newItems);\n itemsRef.current = value;\n return value;\n });\n\n return () => {\n setItems((old) => {\n itemMap.current.delete(item.id);\n return old.filter(({ id }) => id !== item.id);\n });\n return itemsRef;\n };\n }, []);\n\n return {\n registerItem,\n item: (id?: string | null): Item | null => {\n if (!id) return null;\n let item = itemMap.current.get(id);\n if (!item) {\n item = items.find((item) => item.id === id);\n if (item) {\n itemMap.current.set(item.id, item);\n }\n }\n return item ?? null;\n },\n getNext: (current: string): Item | null => {\n const index = items.findIndex(({ id }) => id === current);\n\n const newIndex = wrap\n ? (index + 1) % items.length\n : Math.min(index + 1, items.length - 1);\n\n return items[newIndex] ?? null;\n },\n getPrevious: (current: string): Item | null => {\n const index = items.findIndex(({ id }) => id === current);\n\n const newIndex = wrap\n ? (index - 1 + items.length) % items.length\n : Math.max(index - 1, 0);\n\n return items[newIndex] ?? null;\n },\n getFirst: (): Item | null => {\n return items[0] ?? null;\n },\n getLast: (): Item | null => {\n return items[items.length - 1] ?? null;\n },\n items,\n };\n}\n"],"names":["useState","useRef","useCallback","item"],"mappings":"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"}
1
+ {"version":3,"file":"useCollection.js","sources":["../src/tabs-next/hooks/useCollection.ts"],"sourcesContent":["import { useCallback, useRef, useState } from \"react\";\n\nexport interface Item {\n id: string;\n element?: HTMLElement | null;\n value: string;\n}\n\nfunction sortBasedOnDOMPosition(items: Item[]): Item[] {\n const indexedItems = items.map((item, index) => [index, item] as const);\n let orderChanged = false;\n indexedItems.sort(([itemAIndex, itemA], [itemBIndex, itemB]) => {\n const itemAElement = itemA.element;\n const itemBElement = itemB.element;\n if (itemAElement === itemBElement) return 0;\n if (!itemAElement || !itemBElement) return 0;\n\n if (\n itemAElement.compareDocumentPosition(itemBElement) &\n Node.DOCUMENT_POSITION_FOLLOWING\n ) {\n if (itemAIndex > itemBIndex) {\n orderChanged = true;\n }\n return -1;\n }\n\n if (itemAIndex < itemBIndex) {\n orderChanged = true;\n }\n return 1;\n });\n\n if (orderChanged) {\n return indexedItems.map(([_, item]) => item);\n }\n return items;\n}\n\ninterface UseCollectionProps {\n wrap: boolean;\n}\n\nexport function useCollection({ wrap }: UseCollectionProps) {\n const [items, setItems] = useState<Item[]>([]);\n const itemsRef = useRef<Item[]>([]);\n const itemMap = useRef<Map<string, Item>>(new Map());\n\n const registerItem = useCallback((item: Item) => {\n setItems((old) => {\n const newItems = old.slice();\n const index = newItems.findIndex(({ id }) => id === item.id);\n if (index !== -1) {\n const newItem = { ...newItems[index], ...item };\n newItems[index] = newItem;\n itemMap.current.set(item.id, newItem);\n } else {\n newItems.push(item);\n itemMap.current.set(item.id, item);\n }\n const value = sortBasedOnDOMPosition(newItems);\n itemsRef.current = value;\n return value;\n });\n\n return () => {\n setItems((old) => {\n itemMap.current.delete(item.id);\n return old.filter(({ id }) => id !== item.id);\n });\n return itemsRef;\n };\n }, []);\n\n return {\n registerItem,\n item: (id?: string | null): Item | null => {\n if (!id) return null;\n let item = itemMap.current.get(id);\n if (!item) {\n item = items.find((item) => item.id === id);\n if (item) {\n itemMap.current.set(item.id, item);\n }\n }\n return item ?? null;\n },\n getNext: (current: string): Item | null => {\n const index = items.findIndex(({ id }) => id === current);\n\n const newIndex = wrap\n ? (index + 1) % items.length\n : Math.min(index + 1, items.length - 1);\n\n return items[newIndex] ?? null;\n },\n getPrevious: (current: string): Item | null => {\n const index = items.findIndex(({ id }) => id === current);\n\n const newIndex = wrap\n ? (index - 1 + items.length) % items.length\n : Math.max(index - 1, 0);\n\n return items[newIndex] ?? null;\n },\n getFirst: (): Item | null => {\n return items[0] ?? null;\n },\n getLast: (): Item | null => {\n return items[items.length - 1] ?? null;\n },\n items,\n };\n}\n"],"names":["useState","useRef","useCallback","item"],"mappings":";;;;AAQA,SAAS,uBAAuB,KAAuB,EAAA;AACrD,EAAM,MAAA,YAAA,GAAe,MAAM,GAAI,CAAA,CAAC,MAAM,KAAU,KAAA,CAAC,KAAO,EAAA,IAAI,CAAU,CAAA;AACtE,EAAA,IAAI,YAAe,GAAA,KAAA;AACnB,EAAa,YAAA,CAAA,IAAA,CAAK,CAAC,CAAC,UAAA,EAAY,KAAK,CAAG,EAAA,CAAC,UAAY,EAAA,KAAK,CAAM,KAAA;AAC9D,IAAA,MAAM,eAAe,KAAM,CAAA,OAAA;AAC3B,IAAA,MAAM,eAAe,KAAM,CAAA,OAAA;AAC3B,IAAI,IAAA,YAAA,KAAiB,cAAqB,OAAA,CAAA;AAC1C,IAAA,IAAI,CAAC,YAAA,IAAgB,CAAC,YAAA,EAAqB,OAAA,CAAA;AAE3C,IAAA,IACE,YAAa,CAAA,uBAAA,CAAwB,YAAY,CAAA,GACjD,KAAK,2BACL,EAAA;AACA,MAAA,IAAI,aAAa,UAAY,EAAA;AAC3B,QAAe,YAAA,GAAA,IAAA;AAAA;AAEjB,MAAO,OAAA,CAAA,CAAA;AAAA;AAGT,IAAA,IAAI,aAAa,UAAY,EAAA;AAC3B,MAAe,YAAA,GAAA,IAAA;AAAA;AAEjB,IAAO,OAAA,CAAA;AAAA,GACR,CAAA;AAED,EAAA,IAAI,YAAc,EAAA;AAChB,IAAA,OAAO,aAAa,GAAI,CAAA,CAAC,CAAC,CAAG,EAAA,IAAI,MAAM,IAAI,CAAA;AAAA;AAE7C,EAAO,OAAA,KAAA;AACT;AAMgB,SAAA,aAAA,CAAc,EAAE,IAAA,EAA4B,EAAA;AAC1D,EAAA,MAAM,CAAC,KAAO,EAAA,QAAQ,CAAI,GAAAA,cAAA,CAAiB,EAAE,CAAA;AAC7C,EAAM,MAAA,QAAA,GAAWC,YAAe,CAAA,EAAE,CAAA;AAClC,EAAA,MAAM,OAAU,GAAAA,YAAA,iBAA8B,IAAA,GAAA,EAAK,CAAA;AAEnD,EAAM,MAAA,YAAA,GAAeC,iBAAY,CAAA,CAAC,IAAe,KAAA;AAC/C,IAAA,QAAA,CAAS,CAAC,GAAQ,KAAA;AAChB,MAAM,MAAA,QAAA,GAAW,IAAI,KAAM,EAAA;AAC3B,MAAM,MAAA,KAAA,GAAQ,SAAS,SAAU,CAAA,CAAC,EAAE,EAAG,EAAA,KAAM,EAAO,KAAA,IAAA,CAAK,EAAE,CAAA;AAC3D,MAAA,IAAI,UAAU,CAAI,CAAA,EAAA;AAChB,QAAA,MAAM,UAAU,EAAE,GAAG,SAAS,KAAK,CAAA,EAAG,GAAG,IAAK,EAAA;AAC9C,QAAA,QAAA,CAAS,KAAK,CAAI,GAAA,OAAA;AAClB,QAAA,OAAA,CAAQ,OAAQ,CAAA,GAAA,CAAI,IAAK,CAAA,EAAA,EAAI,OAAO,CAAA;AAAA,OAC/B,MAAA;AACL,QAAA,QAAA,CAAS,KAAK,IAAI,CAAA;AAClB,QAAA,OAAA,CAAQ,OAAQ,CAAA,GAAA,CAAI,IAAK,CAAA,EAAA,EAAI,IAAI,CAAA;AAAA;AAEnC,MAAM,MAAA,KAAA,GAAQ,uBAAuB,QAAQ,CAAA;AAC7C,MAAA,QAAA,CAAS,OAAU,GAAA,KAAA;AACnB,MAAO,OAAA,KAAA;AAAA,KACR,CAAA;AAED,IAAA,OAAO,MAAM;AACX,MAAA,QAAA,CAAS,CAAC,GAAQ,KAAA;AAChB,QAAQ,OAAA,CAAA,OAAA,CAAQ,MAAO,CAAA,IAAA,CAAK,EAAE,CAAA;AAC9B,QAAO,OAAA,GAAA,CAAI,OAAO,CAAC,EAAE,IAAS,KAAA,EAAA,KAAO,KAAK,EAAE,CAAA;AAAA,OAC7C,CAAA;AACD,MAAO,OAAA,QAAA;AAAA,KACT;AAAA,GACF,EAAG,EAAE,CAAA;AAEL,EAAO,OAAA;AAAA,IACL,YAAA;AAAA,IACA,IAAA,EAAM,CAAC,EAAoC,KAAA;AACzC,MAAI,IAAA,CAAC,IAAW,OAAA,IAAA;AAChB,MAAA,IAAI,IAAO,GAAA,OAAA,CAAQ,OAAQ,CAAA,GAAA,CAAI,EAAE,CAAA;AACjC,MAAA,IAAI,CAAC,IAAM,EAAA;AACT,QAAA,IAAA,GAAO,MAAM,IAAK,CAAA,CAACC,KAASA,KAAAA,KAAAA,CAAK,OAAO,EAAE,CAAA;AAC1C,QAAA,IAAI,IAAM,EAAA;AACR,UAAA,OAAA,CAAQ,OAAQ,CAAA,GAAA,CAAI,IAAK,CAAA,EAAA,EAAI,IAAI,CAAA;AAAA;AACnC;AAEF,MAAA,OAAO,IAAQ,IAAA,IAAA;AAAA,KACjB;AAAA,IACA,OAAA,EAAS,CAAC,OAAiC,KAAA;AACzC,MAAM,MAAA,KAAA,GAAQ,MAAM,SAAU,CAAA,CAAC,EAAE,EAAG,EAAA,KAAM,OAAO,OAAO,CAAA;AAExD,MAAA,MAAM,QAAW,GAAA,IAAA,GAAA,CACZ,KAAQ,GAAA,CAAA,IAAK,KAAM,CAAA,MAAA,GACpB,IAAK,CAAA,GAAA,CAAI,KAAQ,GAAA,CAAA,EAAG,KAAM,CAAA,MAAA,GAAS,CAAC,CAAA;AAExC,MAAO,OAAA,KAAA,CAAM,QAAQ,CAAK,IAAA,IAAA;AAAA,KAC5B;AAAA,IACA,WAAA,EAAa,CAAC,OAAiC,KAAA;AAC7C,MAAM,MAAA,KAAA,GAAQ,MAAM,SAAU,CAAA,CAAC,EAAE,EAAG,EAAA,KAAM,OAAO,OAAO,CAAA;AAExD,MAAA,MAAM,QAAW,GAAA,IAAA,GAAA,CACZ,KAAQ,GAAA,CAAA,GAAI,KAAM,CAAA,MAAA,IAAU,KAAM,CAAA,MAAA,GACnC,IAAK,CAAA,GAAA,CAAI,KAAQ,GAAA,CAAA,EAAG,CAAC,CAAA;AAEzB,MAAO,OAAA,KAAA,CAAM,QAAQ,CAAK,IAAA,IAAA;AAAA,KAC5B;AAAA,IACA,UAAU,MAAmB;AAC3B,MAAO,OAAA,KAAA,CAAM,CAAC,CAAK,IAAA,IAAA;AAAA,KACrB;AAAA,IACA,SAAS,MAAmB;AAC1B,MAAA,OAAO,KAAM,CAAA,KAAA,CAAM,MAAS,GAAA,CAAC,CAAK,IAAA,IAAA;AAAA,KACpC;AAAA,IACA;AAAA,GACF;AACF;;;;"}
@@ -20,6 +20,7 @@ function useOverflow({
20
20
  isMeasuring: false
21
21
  });
22
22
  const targetWindow = window.useWindow();
23
+ const realSelectedIndex = react.useRef(-1);
23
24
  const updateOverflow = core.useEventCallback(() => {
24
25
  const computeVisible = (visibleCount2) => {
25
26
  var _a;
@@ -71,7 +72,7 @@ function useOverflow({
71
72
  newVisibleCount--;
72
73
  }
73
74
  }
74
- return Math.max(1, newVisibleCount);
75
+ return Math.max(0, newVisibleCount);
75
76
  }
76
77
  return visibleCount2;
77
78
  };
@@ -97,6 +98,15 @@ function useOverflow({
97
98
  core.useIsomorphicLayoutEffect(() => {
98
99
  updateOverflow();
99
100
  }, [selected]);
101
+ react.useEffect(() => {
102
+ const handleWindowResize = () => {
103
+ updateOverflow();
104
+ };
105
+ targetWindow == null ? void 0 : targetWindow.addEventListener("resize", handleWindowResize);
106
+ return () => {
107
+ targetWindow == null ? void 0 : targetWindow.removeEventListener("resize", handleWindowResize);
108
+ };
109
+ }, [updateOverflow, targetWindow]);
100
110
  react.useEffect(() => {
101
111
  const element = container == null ? void 0 : container.current;
102
112
  if (!element) return;
@@ -117,9 +127,31 @@ function useOverflow({
117
127
  }
118
128
  };
119
129
  }, [container, updateOverflow]);
130
+ react.useEffect(() => {
131
+ const element = container == null ? void 0 : container.current;
132
+ if (!element || isMeasuring) return;
133
+ const win = core.ownerWindow(element);
134
+ const mutationObserver = new win.MutationObserver(() => {
135
+ requestAnimationFrame(() => {
136
+ updateOverflow();
137
+ });
138
+ });
139
+ mutationObserver.observe(element, {
140
+ childList: true
141
+ });
142
+ return () => {
143
+ mutationObserver.disconnect();
144
+ };
145
+ }, [container, updateOverflow, isMeasuring]);
120
146
  const childArray = react.useMemo(() => react.Children.toArray(children), [children]);
121
- const visible = childArray.slice(0, visibleCount || 1);
122
- const hidden = childArray.slice(visibleCount || 1);
147
+ const visible = react.useMemo(
148
+ () => childArray.slice(0, visibleCount),
149
+ [visibleCount, childArray]
150
+ );
151
+ const hidden = react.useMemo(
152
+ () => childArray.slice(visibleCount),
153
+ [childArray, visibleCount]
154
+ );
123
155
  const hiddenSelectedIndex = hidden.findIndex(
124
156
  // @ts-ignore
125
157
  (child) => {
@@ -127,14 +159,25 @@ function useOverflow({
127
159
  return ((_a = child == null ? void 0 : child.props) == null ? void 0 : _a.value) === selected;
128
160
  }
129
161
  );
162
+ core.useIsomorphicLayoutEffect(() => {
163
+ if (visibleCount === childArray.length) {
164
+ realSelectedIndex.current = childArray.findIndex(
165
+ // @ts-ignore
166
+ (child) => {
167
+ var _a;
168
+ return ((_a = child == null ? void 0 : child.props) == null ? void 0 : _a.value) === selected;
169
+ }
170
+ );
171
+ }
172
+ }, [visibleCount, childArray, selected]);
130
173
  if (selected && hiddenSelectedIndex !== -1) {
131
174
  const removed = hidden.splice(hiddenSelectedIndex, 1);
132
175
  visible.push(removed[0]);
133
176
  }
134
177
  if (isMeasuring) {
135
- return [childArray, [], isMeasuring];
178
+ return [childArray, [], isMeasuring, realSelectedIndex];
136
179
  }
137
- return [visible, hidden, isMeasuring];
180
+ return [visible, hidden, isMeasuring, realSelectedIndex];
138
181
  }
139
182
 
140
183
  exports.useOverflow = useOverflow;
@@ -1 +1 @@
1
- {"version":3,"file":"useOverflow.js","sources":["../src/tabs-next/hooks/useOverflow.ts"],"sourcesContent":["import {\n ownerWindow,\n useEventCallback,\n useIsomorphicLayoutEffect,\n useValueEffect,\n} from \"@salt-ds/core\";\nimport { useWindow } from \"@salt-ds/window\";\nimport {\n Children,\n type ReactNode,\n type RefObject,\n useEffect,\n useMemo,\n} from \"react\";\nimport type { Item } from \"./useCollection\";\n\ninterface UseOverflowProps {\n container: RefObject<HTMLElement>;\n selected?: string;\n children: ReactNode;\n tabs: Item[];\n overflowButton: RefObject<HTMLButtonElement>;\n}\n\nfunction getTabWidth(element: HTMLElement) {\n const { width } = element.getBoundingClientRect();\n return Math.ceil(width);\n}\n\nexport function useOverflow({\n tabs,\n container,\n overflowButton,\n children,\n selected,\n}: UseOverflowProps) {\n const [{ visibleCount, isMeasuring }, setVisibleItems] = useValueEffect({\n visibleCount: tabs.length,\n isMeasuring: false,\n });\n const targetWindow = useWindow();\n\n const updateOverflow = useEventCallback(() => {\n const computeVisible = (visibleCount: number) => {\n if (container.current && targetWindow) {\n const items = Array.from(\n container.current.querySelectorAll<HTMLElement>(\n \"[data-overflowitem]\",\n ),\n );\n const selectedTab = container.current.querySelector<HTMLElement>(\n \"[role=tab][aria-selected=true]\",\n )?.parentElement;\n\n let maxWidth = container.current.clientWidth ?? 0;\n\n const containerStyles = targetWindow.getComputedStyle(\n container.current,\n );\n const gap = Number.parseInt(containerStyles.gap || \"0\");\n\n let currentWidth = 0;\n let newVisibleCount = 0;\n\n const visible = [];\n\n while (newVisibleCount < items.length) {\n const element = items[newVisibleCount];\n if (element) {\n if (currentWidth + getTabWidth(element) + gap > maxWidth) {\n break;\n }\n currentWidth += getTabWidth(element) + gap;\n visible.push(element);\n }\n newVisibleCount++;\n }\n\n if (newVisibleCount >= items.length) {\n return newVisibleCount;\n }\n\n const overflowButtonWidth = overflowButton.current\n ? overflowButton.current.offsetWidth + gap\n : 0;\n maxWidth -= overflowButtonWidth;\n\n while (currentWidth > maxWidth) {\n const removed = visible.pop();\n if (!removed) break;\n currentWidth -= getTabWidth(removed) + gap;\n newVisibleCount--;\n }\n\n if (selectedTab && !visible.includes(selectedTab)) {\n const selectedTabWidth = getTabWidth(selectedTab) + gap;\n while (currentWidth + selectedTabWidth > maxWidth) {\n const removed = visible.pop();\n if (!removed) break;\n currentWidth -= getTabWidth(selectedTab) + gap;\n newVisibleCount--;\n }\n }\n\n return Math.max(1, newVisibleCount);\n }\n return visibleCount;\n };\n\n setVisibleItems(function* () {\n // Show all\n yield {\n visibleCount: tabs.length,\n isMeasuring: true,\n };\n\n // Measure the visible count\n const newVisibleCount = computeVisible(tabs.length);\n const isMeasuring = newVisibleCount < tabs.length && newVisibleCount > 0;\n yield {\n visibleCount: newVisibleCount,\n isMeasuring,\n };\n\n // ensure the visible count is correct\n if (isMeasuring) {\n yield {\n visibleCount: computeVisible(newVisibleCount),\n isMeasuring: false,\n };\n }\n });\n });\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: we want to update when selected changes.\n useIsomorphicLayoutEffect(() => {\n updateOverflow();\n }, [selected]);\n\n useEffect(() => {\n const element = container?.current;\n if (!element) return;\n\n const win = ownerWindow(element);\n\n const resizeObserver = new win.ResizeObserver((entries) => {\n requestAnimationFrame(() => {\n if (entries.length === 0) return;\n\n updateOverflow();\n });\n });\n resizeObserver.observe(element);\n if (element.parentElement) {\n resizeObserver.observe(element.parentElement);\n }\n\n return () => {\n if (element) {\n resizeObserver.unobserve(element);\n }\n };\n }, [container, updateOverflow]);\n\n const childArray = useMemo(() => Children.toArray(children), [children]);\n const visible = childArray.slice(0, visibleCount || 1);\n const hidden = childArray.slice(visibleCount || 1);\n\n const hiddenSelectedIndex = hidden.findIndex(\n // @ts-ignore\n (child) => child?.props?.value === selected,\n );\n\n if (selected && hiddenSelectedIndex !== -1) {\n const removed = hidden.splice(hiddenSelectedIndex, 1);\n visible.push(removed[0]);\n }\n\n if (isMeasuring) {\n return [childArray, [], isMeasuring] as const;\n }\n\n return [visible, hidden, isMeasuring] as const;\n}\n"],"names":["useValueEffect","useWindow","useEventCallback","visibleCount","visible","isMeasuring","useIsomorphicLayoutEffect","useEffect","ownerWindow","useMemo","Children"],"mappings":"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"}
1
+ {"version":3,"file":"useOverflow.js","sources":["../src/tabs-next/hooks/useOverflow.ts"],"sourcesContent":["import {\n ownerWindow,\n useEventCallback,\n useIsomorphicLayoutEffect,\n useValueEffect,\n} from \"@salt-ds/core\";\nimport { useWindow } from \"@salt-ds/window\";\nimport {\n Children,\n type ReactNode,\n type RefObject,\n useEffect,\n useMemo,\n useRef,\n} from \"react\";\nimport type { Item } from \"./useCollection\";\n\ninterface UseOverflowProps {\n container: RefObject<HTMLElement>;\n selected?: string;\n children: ReactNode;\n tabs: Item[];\n overflowButton: RefObject<HTMLButtonElement>;\n}\n\nfunction getTabWidth(element: HTMLElement) {\n const { width } = element.getBoundingClientRect();\n return Math.ceil(width);\n}\n\nexport function useOverflow({\n tabs,\n container,\n overflowButton,\n children,\n selected,\n}: UseOverflowProps) {\n /**\n * `visibleCount` doesn't include newly selected tab from overflow menu, which is removed in `computeVisible`\n */\n const [{ visibleCount, isMeasuring }, setVisibleItems] = useValueEffect({\n visibleCount: tabs.length,\n isMeasuring: false,\n });\n const targetWindow = useWindow();\n const realSelectedIndex = useRef<number>(-1);\n\n const updateOverflow = useEventCallback(() => {\n const computeVisible = (visibleCount: number) => {\n if (container.current && targetWindow) {\n const items = Array.from(\n container.current.querySelectorAll<HTMLElement>(\n \"[data-overflowitem]\",\n ),\n );\n const selectedTab = container.current.querySelector<HTMLElement>(\n \"[role=tab][aria-selected=true]\",\n )?.parentElement;\n\n let maxWidth = container.current.clientWidth ?? 0;\n\n const containerStyles = targetWindow.getComputedStyle(\n container.current,\n );\n const gap = Number.parseInt(containerStyles.gap || \"0\");\n\n let currentWidth = 0;\n let newVisibleCount = 0;\n\n const visible = [];\n\n while (newVisibleCount < items.length) {\n const element = items[newVisibleCount];\n if (element) {\n if (currentWidth + getTabWidth(element) + gap > maxWidth) {\n break;\n }\n currentWidth += getTabWidth(element) + gap;\n visible.push(element);\n }\n newVisibleCount++;\n }\n\n if (newVisibleCount >= items.length) {\n return newVisibleCount;\n }\n\n const overflowButtonWidth = overflowButton.current\n ? overflowButton.current.offsetWidth + gap\n : 0;\n maxWidth -= overflowButtonWidth;\n\n while (currentWidth > maxWidth) {\n const removed = visible.pop();\n if (!removed) break;\n currentWidth -= getTabWidth(removed) + gap;\n newVisibleCount--;\n }\n\n if (selectedTab && !visible.includes(selectedTab)) {\n const selectedTabWidth = getTabWidth(selectedTab) + gap;\n while (currentWidth + selectedTabWidth > maxWidth) {\n const removed = visible.pop();\n if (!removed) break;\n currentWidth -= getTabWidth(selectedTab) + gap;\n newVisibleCount--;\n }\n }\n\n // minimal count should be 0, if there is no space for any tab apart from selected tab from the overflow menu\n return Math.max(0, newVisibleCount);\n }\n return visibleCount;\n };\n\n setVisibleItems(function* () {\n // Show all\n yield {\n visibleCount: tabs.length,\n isMeasuring: true,\n };\n\n // Measure the visible count\n const newVisibleCount = computeVisible(tabs.length);\n const isMeasuring = newVisibleCount < tabs.length && newVisibleCount > 0;\n yield {\n visibleCount: newVisibleCount,\n isMeasuring,\n };\n\n // ensure the visible count is correct\n if (isMeasuring) {\n yield {\n visibleCount: computeVisible(newVisibleCount),\n isMeasuring: false,\n };\n }\n });\n });\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: we want to update when selected changes.\n useIsomorphicLayoutEffect(() => {\n updateOverflow();\n }, [selected]);\n\n useEffect(() => {\n const handleWindowResize = () => {\n updateOverflow();\n };\n\n targetWindow?.addEventListener(\"resize\", handleWindowResize);\n\n return () => {\n targetWindow?.removeEventListener(\"resize\", handleWindowResize);\n };\n }, [updateOverflow, targetWindow]);\n\n useEffect(() => {\n const element = container?.current;\n if (!element) return;\n\n const win = ownerWindow(element);\n\n const resizeObserver = new win.ResizeObserver((entries) => {\n requestAnimationFrame(() => {\n if (entries.length === 0) return;\n\n updateOverflow();\n });\n });\n resizeObserver.observe(element);\n if (element.parentElement) {\n resizeObserver.observe(element.parentElement);\n }\n\n return () => {\n if (element) {\n resizeObserver.unobserve(element);\n }\n };\n }, [container, updateOverflow]);\n\n useEffect(() => {\n const element = container?.current;\n if (!element || isMeasuring) return;\n\n const win = ownerWindow(element);\n\n const mutationObserver = new win.MutationObserver(() => {\n requestAnimationFrame(() => {\n updateOverflow();\n });\n });\n\n mutationObserver.observe(element, {\n childList: true,\n });\n\n return () => {\n mutationObserver.disconnect();\n };\n }, [container, updateOverflow, isMeasuring]);\n\n const childArray = useMemo(() => Children.toArray(children), [children]);\n const visible = useMemo(\n () => childArray.slice(0, visibleCount),\n [visibleCount, childArray],\n );\n const hidden = useMemo(\n () => childArray.slice(visibleCount),\n [childArray, visibleCount],\n );\n\n const hiddenSelectedIndex = hidden.findIndex(\n // @ts-ignore\n (child) => child?.props?.value === selected,\n );\n\n useIsomorphicLayoutEffect(() => {\n if (visibleCount === childArray.length) {\n realSelectedIndex.current = childArray.findIndex(\n // @ts-ignore\n (child) => child?.props?.value === selected,\n );\n }\n }, [visibleCount, childArray, selected]);\n\n if (selected && hiddenSelectedIndex !== -1) {\n const removed = hidden.splice(hiddenSelectedIndex, 1);\n visible.push(removed[0]);\n }\n\n if (isMeasuring) {\n return [childArray, [], isMeasuring, realSelectedIndex] as const;\n }\n\n return [visible, hidden, isMeasuring, realSelectedIndex] as const;\n}\n"],"names":["useValueEffect","useWindow","useRef","useEventCallback","visibleCount","visible","isMeasuring","useIsomorphicLayoutEffect","useEffect","ownerWindow","useMemo","Children"],"mappings":"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"}
@@ -0,0 +1,93 @@
1
+ 'use strict';
2
+
3
+ var core = require('@salt-ds/core');
4
+ var react = require('react');
5
+
6
+ function useRestoreActiveTab({
7
+ container,
8
+ tabs,
9
+ realSelectedIndex,
10
+ removedActiveTabRef
11
+ }) {
12
+ const tabsRef = react.useRef(tabs);
13
+ const previousTabsRef = react.useRef(tabs);
14
+ core.useIsomorphicLayoutEffect(() => {
15
+ tabsRef.current = tabs;
16
+ return () => {
17
+ previousTabsRef.current = tabs;
18
+ };
19
+ }, [tabs]);
20
+ react.useEffect(() => {
21
+ if (!container.current) return;
22
+ const win = core.ownerWindow(container.current);
23
+ const mutationObserver = new win.MutationObserver((mutations) => {
24
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
25
+ for (const mutation of mutations) {
26
+ const removedItem = mutation.removedNodes[0] instanceof HTMLElement ? mutation.removedNodes[0] : null;
27
+ const removedItemWasTab = removedActiveTabRef.current && ((_a = removedItem == null ? void 0 : removedItem.dataset) == null ? void 0 : _a.overflowitem);
28
+ const activeTabWasRemoved = removedItemWasTab && !tabsRef.current.find(
29
+ ({ value }) => value === removedActiveTabRef.current
30
+ );
31
+ if (activeTabWasRemoved) {
32
+ const removedTab = removedItem == null ? void 0 : removedItem.querySelector('[role="tab"]');
33
+ let nextTab = null;
34
+ if ((removedTab == null ? void 0 : removedTab.ariaSelected) === "true" && realSelectedIndex.current != null && realSelectedIndex.current >= 0) {
35
+ nextTab = (_b = tabsRef.current[Math.min(realSelectedIndex.current, tabsRef.current.length - 1)]) == null ? void 0 : _b.element;
36
+ }
37
+ if (!nextTab) {
38
+ const previousTab = mutation.previousSibling instanceof HTMLElement ? mutation.previousSibling.querySelector(
39
+ '[role="tab"]'
40
+ ) : null;
41
+ if (!previousTab) {
42
+ nextTab = mutation.nextSibling instanceof HTMLElement ? (_c = mutation.nextSibling) == null ? void 0 : _c.querySelector(
43
+ '[role="tab"]'
44
+ ) : null;
45
+ } else {
46
+ const nextTabIndex = previousTab ? tabsRef.current.findIndex(
47
+ ({ element }) => element === previousTab
48
+ ) + 1 : -1;
49
+ nextTab = (_d = tabsRef.current[Math.min(nextTabIndex, tabsRef.current.length - 1)]) == null ? void 0 : _d.element;
50
+ }
51
+ }
52
+ if (!((_e = container.current) == null ? void 0 : _e.querySelector(
53
+ '[role="tab"][aria-selected="true"]'
54
+ ))) {
55
+ nextTab == null ? void 0 : nextTab.click();
56
+ }
57
+ if (!((_f = container.current) == null ? void 0 : _f.contains(win.document.activeElement))) {
58
+ if (nextTab == null ? void 0 : nextTab.isConnected) {
59
+ nextTab == null ? void 0 : nextTab.focus({ preventScroll: true });
60
+ } else {
61
+ (_h = (_g = container.current) == null ? void 0 : _g.querySelector(
62
+ '[role="tab"][aria-selected="true"]'
63
+ )) == null ? void 0 : _h.focus({ preventScroll: true });
64
+ }
65
+ }
66
+ removedActiveTabRef.current = void 0;
67
+ }
68
+ if (removedActiveTabRef.current) {
69
+ if (removedItemWasTab) {
70
+ const tabElement = (_i = tabsRef.current.find(
71
+ ({ value }) => value === removedActiveTabRef.current
72
+ )) == null ? void 0 : _i.element;
73
+ if (win.document.activeElement === win.document.body) {
74
+ tabElement == null ? void 0 : tabElement.focus();
75
+ }
76
+ } else if (removedItem == null ? void 0 : removedItem.dataset.overflow) {
77
+ (_k = (_j = tabsRef.current[tabsRef.current.length - 1]) == null ? void 0 : _j.element) == null ? void 0 : _k.focus();
78
+ }
79
+ }
80
+ }
81
+ });
82
+ mutationObserver.observe(container.current, {
83
+ childList: true,
84
+ subtree: true
85
+ });
86
+ return () => {
87
+ mutationObserver.disconnect();
88
+ };
89
+ }, [container, realSelectedIndex, removedActiveTabRef]);
90
+ }
91
+
92
+ exports.useRestoreActiveTab = useRestoreActiveTab;
93
+ //# sourceMappingURL=useRestoreActiveTab.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useRestoreActiveTab.js","sources":["../src/tabs-next/hooks/useRestoreActiveTab.ts"],"sourcesContent":["import { ownerWindow, useIsomorphicLayoutEffect } from \"@salt-ds/core\";\nimport {\n type MutableRefObject,\n type RefObject,\n useEffect,\n useRef,\n} from \"react\";\nimport type { Item } from \"./useCollection\";\n\ninterface UseHandleRemovalProps {\n container: RefObject<HTMLElement>;\n tabs: Item[];\n realSelectedIndex: RefObject<number>;\n removedActiveTabRef: MutableRefObject<string | undefined>;\n}\n\nexport function useRestoreActiveTab({\n container,\n tabs,\n realSelectedIndex,\n removedActiveTabRef,\n}: UseHandleRemovalProps) {\n const tabsRef = useRef(tabs);\n const previousTabsRef = useRef(tabs);\n\n useIsomorphicLayoutEffect(() => {\n tabsRef.current = tabs;\n\n return () => {\n previousTabsRef.current = tabs;\n };\n }, [tabs]);\n\n useEffect(() => {\n if (!container.current) return;\n\n const win = ownerWindow(container.current);\n\n const mutationObserver = new win.MutationObserver((mutations) => {\n for (const mutation of mutations) {\n const removedItem =\n mutation.removedNodes[0] instanceof HTMLElement\n ? mutation.removedNodes[0]\n : null;\n\n const removedItemWasTab =\n removedActiveTabRef.current && removedItem?.dataset?.overflowitem;\n\n const activeTabWasRemoved =\n removedItemWasTab &&\n !tabsRef.current.find(\n ({ value }) => value === removedActiveTabRef.current,\n );\n\n if (activeTabWasRemoved) {\n const removedTab =\n removedItem?.querySelector<HTMLElement>('[role=\"tab\"]');\n\n let nextTab: HTMLElement | null | undefined = null;\n\n if (\n removedTab?.ariaSelected === \"true\" &&\n realSelectedIndex.current != null &&\n realSelectedIndex.current >= 0\n ) {\n nextTab =\n tabsRef.current[\n Math.min(realSelectedIndex.current, tabsRef.current.length - 1)\n ]?.element;\n }\n\n if (!nextTab) {\n const previousTab =\n mutation.previousSibling instanceof HTMLElement\n ? mutation.previousSibling.querySelector<HTMLElement>(\n '[role=\"tab\"]',\n )\n : null;\n\n if (!previousTab) {\n nextTab =\n mutation.nextSibling instanceof HTMLElement\n ? mutation.nextSibling?.querySelector<HTMLElement>(\n '[role=\"tab\"]',\n )\n : null;\n } else {\n const nextTabIndex = previousTab\n ? tabsRef.current.findIndex(\n ({ element }) => element === previousTab,\n ) + 1\n : -1;\n\n nextTab =\n tabsRef.current[\n Math.min(nextTabIndex, tabsRef.current.length - 1)\n ]?.element;\n }\n }\n\n if (\n !container.current?.querySelector<HTMLElement>(\n '[role=\"tab\"][aria-selected=\"true\"]',\n )\n ) {\n nextTab?.click();\n }\n\n if (!container.current?.contains(win.document.activeElement)) {\n if (nextTab?.isConnected) {\n nextTab?.focus({ preventScroll: true });\n } else {\n container.current\n ?.querySelector<HTMLElement>(\n '[role=\"tab\"][aria-selected=\"true\"]',\n )\n ?.focus({ preventScroll: true });\n }\n }\n\n removedActiveTabRef.current = undefined;\n }\n\n // Focus the tab if it was moved from the overflow menu into the visible tabs\n if (removedActiveTabRef.current) {\n if (removedItemWasTab) {\n const tabElement = tabsRef.current.find(\n ({ value }) => value === removedActiveTabRef.current,\n )?.element;\n\n if (win.document.activeElement === win.document.body) {\n tabElement?.focus();\n }\n } else if (removedItem?.dataset.overflow) {\n tabsRef.current[tabsRef.current.length - 1]?.element?.focus();\n }\n }\n }\n });\n\n mutationObserver.observe(container.current, {\n childList: true,\n subtree: true,\n });\n\n return () => {\n mutationObserver.disconnect();\n };\n }, [container, realSelectedIndex, removedActiveTabRef]);\n}\n"],"names":["useRef","useIsomorphicLayoutEffect","useEffect","ownerWindow"],"mappings":"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"}