@frontify/fondue 12.0.0-beta.248 → 12.0.0-beta.249

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.
@@ -13,16 +13,16 @@ const J = {
13
13
  Small: "tw-pl-s",
14
14
  Medium: "tw-pl-m",
15
15
  Large: "tw-pl-l"
16
- }, Q = ({
16
+ }, P = ({
17
17
  paddingX: l,
18
18
  size: y,
19
- activeItemId: i,
19
+ activeItemId: a,
20
20
  children: E,
21
21
  onChange: h,
22
22
  maxHeight: B,
23
23
  minHeight: C
24
24
  }) => {
25
- const M = Y(), v = K(null), [k, R] = b(!1), [w, c] = b(!1), p = O.map(E, (e) => A(e) ? e == null ? void 0 : e.props : null) ?? [], [T, D] = b([0]), a = z(() => {
25
+ const M = Y(), v = K(null), [k, R] = b(!1), [w, c] = b(!1), p = O.map(E, (e) => A(e) ? e == null ? void 0 : e.props : null) ?? [], [T, D] = b([0]), i = z(() => {
26
26
  const e = v.current;
27
27
  R((e && e.scrollWidth > e.clientWidth) ?? !1);
28
28
  const r = [];
@@ -35,9 +35,10 @@ const J = {
35
35
  D(o);
36
36
  }
37
37
  }, []), g = () => T.map((e) => p[e]), N = (e, r) => {
38
- const o = e.findIndex((t) => t.id === i);
38
+ const o = e.findIndex((t) => t.id === a);
39
39
  return e.filter((t, s) => r === "next" && s > o && !t.disabled || r === "previous" && s < o && !t.disabled ? t : !1);
40
40
  }, S = (e) => {
41
+ e.stopPropagation();
41
42
  const r = g(), o = e.target, t = o.id.includes("-m"), s = o.id.replace("-btn-m", ""), m = t ? r : p, f = N(m, "next"), x = N(m, "previous");
42
43
  (e.key === "ArrowRight" || e.key === "ArrowDown") && f.length > 0 && d(f[0].id, t), (e.key === "ArrowLeft" || e.key === "ArrowUp") && x.length > 0 && d(x[x.length - 1].id, t), e.key === "Enter" && t && (d(s, !0), c(!1), document.getElementById(`${s}-content`).focus()), o.id.includes("-m") || c(!1);
43
44
  }, d = (e, r) => {
@@ -50,7 +51,7 @@ const J = {
50
51
  throw o.message;
51
52
  }
52
53
  }, F = (e) => {
53
- a();
54
+ i();
54
55
  const r = g();
55
56
  if (e.key === "Enter" && !w && r.length > 0) {
56
57
  const o = document.getElementById(`${r[0].id}-btn-m`);
@@ -59,10 +60,10 @@ const J = {
59
60
  w && (e.key === "ArrowRight" || e.key === "ArrowDown") && d(r[0].id, !0);
60
61
  };
61
62
  L(() => {
62
- a();
63
- }, [a]), L(() => (window.addEventListener("resize", a), () => {
64
- window.removeEventListener("resize", a);
65
- }), [a]);
63
+ i();
64
+ }, [i]), L(() => (window.addEventListener("resize", i), () => {
65
+ window.removeEventListener("resize", i);
66
+ }), [i]);
66
67
  const { isFocusVisible: I, focusProps: j } = W();
67
68
  return /* @__PURE__ */ n.createElement(n.Fragment, null, /* @__PURE__ */ n.createElement("div", { "data-test-id": "tabs", className: "tw-flex tw-relative tw-border-b tw-border-line" }, /* @__PURE__ */ n.createElement(
68
69
  "div",
@@ -84,16 +85,16 @@ const J = {
84
85
  "data-test-id": "tab-item",
85
86
  role: "tab",
86
87
  type: "button",
87
- "aria-selected": e.id === i,
88
+ "aria-selected": e.id === a,
88
89
  "aria-controls": `${e.id}-content`,
89
90
  "aria-hidden": e.disabled,
90
- tabIndex: e.id === i ? 0 : -1,
91
+ tabIndex: e.id === a ? 0 : -1,
91
92
  id: `${e.id}-btn`,
92
93
  className: u([
93
94
  "tw-group tw-relative tw-mx-0 tw-py-4 tw-px-2 tw-w-max tw-cursor-pointer tw-flex tw-items-center tw-justify-center tw-whitespace-nowrap",
94
95
  e.disabled && "tw-text-text-disabled",
95
96
  !e.disabled && "hover:tw-text-text",
96
- e.id === i ? "tw-font-medium tw-text-text" : "tw-text-text-weak",
97
+ e.id === a ? "tw-font-medium tw-text-text" : "tw-text-text-weak",
97
98
  y === "Small" ? "tw-text-sm" : "tw-text-md"
98
99
  ]),
99
100
  key: e.id,
@@ -105,11 +106,11 @@ const J = {
105
106
  e.decorator && /* @__PURE__ */ n.createElement("span", { className: "tw-mr-1.5" }, e.decorator),
106
107
  /* @__PURE__ */ n.createElement("span", null, e.label),
107
108
  e.badge && /* @__PURE__ */ n.createElement("span", { className: "tw-ml-1.5" }, /* @__PURE__ */ n.createElement($, { disabled: e.disabled, style: e.badge.style }, e.badge.children)),
108
- e.id === i && /* @__PURE__ */ n.createElement(
109
+ e.id === a && /* @__PURE__ */ n.createElement(
109
110
  U.div,
110
111
  {
111
112
  initial: !1,
112
- layoutDependency: i,
113
+ layoutDependency: a,
113
114
  "data-test-id": "tab-active-highlight",
114
115
  layoutId: M,
115
116
  className: "tw-absolute tw-h-[3px] tw-bg-box-selected-strong tw-rounded-t-x-large tw-w-full tw-bottom-0"
@@ -131,7 +132,7 @@ const J = {
131
132
  ]),
132
133
  type: "button",
133
134
  onClick: () => {
134
- a(), c(!w);
135
+ i(), c(!w);
135
136
  },
136
137
  onKeyDown: (e) => F(e),
137
138
  ...j
@@ -159,7 +160,7 @@ const J = {
159
160
  },
160
161
  role: "tab",
161
162
  type: "button",
162
- "aria-selected": e.id === i,
163
+ "aria-selected": e.id === a,
163
164
  "aria-controls": `${e.id}-content`,
164
165
  "aria-hidden": e.disabled,
165
166
  tabIndex: !e.disabled && w ? 0 : -1,
@@ -172,12 +173,12 @@ const J = {
172
173
  );
173
174
  })
174
175
  )
175
- )), /* @__PURE__ */ n.createElement("div", { "data-test-id": "tab-content", className: "tw-flex tw-flex-col tw-overflow-y-auto" }, /* @__PURE__ */ n.createElement("div", { className: "tw-mr-0", style: { maxHeight: B, minHeight: C } }, O.map(E, (e) => A(e) ? V(e, { ...e.props, active: e.props.id === i }) : null))));
176
+ )), /* @__PURE__ */ n.createElement("div", { "data-test-id": "tab-content", className: "tw-flex tw-flex-col tw-overflow-y-auto" }, /* @__PURE__ */ n.createElement("div", { className: "tw-mr-0", style: { maxHeight: B, minHeight: C } }, O.map(E, (e) => A(e) ? V(e, { ...e.props, active: e.props.id === a }) : null))));
176
177
  };
177
- Q.displayName = "FondueTabs";
178
+ P.displayName = "FondueTabs";
178
179
  export {
179
180
  G as TabSize,
180
- Q as Tabs,
181
+ P as Tabs,
181
182
  q as TabsPaddingX
182
183
  };
183
184
  //# sourceMappingURL=Tabs.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Tabs.es.js","sources":["../../../src/components/Tabs/Tabs.tsx"],"sourcesContent":["/* (c) Copyright Frontify Ltd., all rights reserved. */\n\nimport React, {\n Children,\n KeyboardEvent,\n ReactElement,\n ReactNode,\n cloneElement,\n isValidElement,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport { TabItemProps } from '@components/Tabs/TabItem';\nimport { merge } from '@utilities/merge';\nimport { IconDotsHorizontal } from '@foundation/Icon/Generated';\nimport { Badge } from '@components/Badge';\nimport { motion } from 'framer-motion';\nimport { useFocusRing } from '@react-aria/focus';\nimport { FOCUS_STYLE } from '@utilities/focusStyle';\nimport { useMemoizedId } from '@hooks/useMemoizedId';\nimport { DimensionUnity } from '@utilities/dimensions';\n\nexport enum TabsPaddingX {\n None = 'None',\n XSmall = 'XSmall',\n Small = 'Small',\n Medium = 'Medium',\n Large = 'Large',\n}\n\nexport enum TabSize {\n Small = 'Small',\n Large = 'Large',\n}\n\nexport type TabsProps = {\n paddingX?: TabsPaddingX;\n size?: TabSize;\n activeItemId: string;\n children: ReactNode;\n onChange?: (tabId: string) => void;\n maxHeight?: `${number}${DimensionUnity}`;\n minHeight?: `${number}${DimensionUnity}`;\n};\n\nconst paddingMap: Record<TabsPaddingX, string> = {\n [TabsPaddingX.None]: 'tw-pl-0',\n [TabsPaddingX.XSmall]: 'tw-pl-xs',\n [TabsPaddingX.Small]: 'tw-pl-s',\n [TabsPaddingX.Medium]: 'tw-pl-m',\n [TabsPaddingX.Large]: 'tw-pl-l',\n};\n\nexport const Tabs = ({\n paddingX,\n size,\n activeItemId,\n children,\n onChange,\n maxHeight,\n minHeight,\n}: TabsProps): ReactElement => {\n const groupId = useMemoizedId();\n const tabNavRef = useRef<HTMLDivElement | null>(null);\n const [isOverflowing, setIsOverflowing] = useState(false);\n const [isMenuOpened, setIsMenuOpened] = useState(false);\n\n const tabs: TabItemProps[] =\n Children.map(children, (child) => {\n if (!isValidElement<TabItemProps>(child)) {\n return null;\n }\n return child?.props;\n }) ?? [];\n\n const [overflowArray, setOverflowArray] = useState([0]);\n\n const checkIfOverflowing = useCallback(() => {\n const tabNav = tabNavRef.current;\n setIsOverflowing((tabNav && tabNav.scrollWidth > tabNav.clientWidth) ?? false);\n const overFlowIndex = [];\n if (tabNav) {\n for (const tabItem of tabNav.children) {\n const i = [...tabNav.children].indexOf(tabItem);\n const navPosition = tabNav.getBoundingClientRect();\n const tabPosition = tabItem.getBoundingClientRect();\n if (tabPosition.right > navPosition.right || tabPosition.left < navPosition.left) {\n overFlowIndex.push(i);\n }\n }\n\n const overFlowIndexInAscOrder = [...overFlowIndex].sort((a, b) => a - b);\n setOverflowArray(overFlowIndexInAscOrder);\n }\n }, []);\n\n const getOverflownTabs = () => {\n return overflowArray.map((i) => {\n return tabs[i];\n });\n };\n\n const filterTabList = (array: TabItemProps[], direction: string) => {\n const activeItemIndex = array.findIndex((tab) => tab.id === activeItemId);\n\n return array.filter((tab, index) => {\n if (direction === 'next') {\n if (index > activeItemIndex && !tab.disabled) {\n return tab;\n }\n }\n\n if (direction === 'previous') {\n if (index < activeItemIndex && !tab.disabled) {\n return tab;\n }\n }\n\n return false;\n });\n };\n\n const handleKeyboardTabChange = (event: KeyboardEvent<HTMLButtonElement>) => {\n const overflownTabs = getOverflownTabs();\n const target = event.target as HTMLElement;\n const fromOverflow = target.id.includes('-m');\n const currentTabId = target.id.replace('-btn-m', '');\n const currentTabsArray = fromOverflow ? overflownTabs : tabs;\n\n const nextTabs = filterTabList(currentTabsArray, 'next');\n const previousTabs = filterTabList(currentTabsArray, 'previous');\n\n if ((event.key === 'ArrowRight' || event.key === 'ArrowDown') && nextTabs.length > 0) {\n triggerTabButton(nextTabs[0].id, fromOverflow);\n }\n\n if ((event.key === 'ArrowLeft' || event.key === 'ArrowUp') && previousTabs.length > 0) {\n triggerTabButton(previousTabs[previousTabs.length - 1].id, fromOverflow);\n }\n\n if (event.key === 'Enter' && fromOverflow) {\n triggerTabButton(currentTabId, true);\n setIsMenuOpened(false);\n const contentSection = document.getElementById(`${currentTabId}-content`) as HTMLDivElement;\n contentSection.focus();\n }\n\n if (!target.id.includes('-m')) {\n setIsMenuOpened(false);\n }\n };\n\n const triggerTabButton = (elementId: string, fromOverflow: boolean) => {\n try {\n const tabElement = document.getElementById(`${elementId}-btn`) as HTMLButtonElement;\n const buttonElement = document.getElementById(\n fromOverflow ? `${elementId}-btn-m` : `${elementId}-btn`,\n ) as HTMLButtonElement;\n if (onChange) {\n onChange(elementId);\n }\n if (isOverflowing) {\n tabElement.scrollIntoView({ behavior: 'smooth', block: 'end', inline: 'end' });\n }\n buttonElement.focus();\n } catch (error) {\n throw (error as Error).message;\n }\n };\n\n const triggerOverflowMenu = (event: KeyboardEvent<HTMLButtonElement>) => {\n checkIfOverflowing();\n const overflownTabs = getOverflownTabs();\n\n if (event.key === 'Enter') {\n if (!isMenuOpened && overflownTabs.length > 0) {\n const buttonElement = document.getElementById(`${overflownTabs[0].id}-btn-m`) as HTMLButtonElement;\n if (buttonElement) {\n buttonElement.focus();\n }\n }\n }\n\n if (isMenuOpened && (event.key === 'ArrowRight' || event.key === 'ArrowDown')) {\n triggerTabButton(overflownTabs[0].id, true);\n }\n };\n\n // First render\n useEffect(() => {\n checkIfOverflowing();\n }, [checkIfOverflowing]);\n\n useEffect(() => {\n window.addEventListener('resize', checkIfOverflowing);\n return () => {\n window.removeEventListener('resize', checkIfOverflowing);\n };\n }, [checkIfOverflowing]);\n\n const { isFocusVisible, focusProps } = useFocusRing();\n\n return (\n <>\n <div data-test-id=\"tabs\" className=\"tw-flex tw-relative tw-border-b tw-border-line\">\n <div\n ref={tabNavRef}\n role=\"tablist\"\n className={merge([\n 'tw-overflow-x-hidden tw-flex-shrink-0 tw-h-full tw-w-full tw-flex tw-justify-start',\n paddingMap[paddingX ?? TabsPaddingX.Small],\n size === TabSize.Small ? 'tw-gap-xxs' : 'tw-gap-xs ',\n ])}\n >\n {tabs.map((tab) => {\n return (\n <button\n data-test-id=\"tab-item\"\n role=\"tab\"\n type=\"button\"\n aria-selected={tab.id === activeItemId}\n aria-controls={`${tab.id}-content`}\n aria-hidden={tab.disabled}\n tabIndex={tab.id === activeItemId ? 0 : -1}\n id={`${tab.id}-btn`}\n className={merge([\n 'tw-group tw-relative tw-mx-0 tw-py-4 tw-px-2 tw-w-max tw-cursor-pointer tw-flex tw-items-center tw-justify-center tw-whitespace-nowrap',\n tab.disabled && 'tw-text-text-disabled',\n !tab.disabled && 'hover:tw-text-text',\n tab.id === activeItemId ? 'tw-font-medium tw-text-text' : 'tw-text-text-weak',\n size === TabSize.Small ? 'tw-text-sm' : 'tw-text-md',\n ])}\n key={tab.id}\n onClick={() => {\n if (!tab.disabled) {\n triggerTabButton(tab.id, false);\n setIsMenuOpened(false);\n }\n }}\n onKeyDown={(event) => handleKeyboardTabChange(event)}\n >\n {tab.decorator && <span className=\"tw-mr-1.5\">{tab.decorator}</span>}\n\n <span>{tab.label}</span>\n\n {tab.badge && (\n <span className=\"tw-ml-1.5\">\n <Badge disabled={tab.disabled} style={tab.badge.style}>\n {tab.badge.children}\n </Badge>\n </span>\n )}\n {tab.id === activeItemId && (\n <motion.div\n initial={false}\n layoutDependency={activeItemId}\n data-test-id=\"tab-active-highlight\"\n layoutId={groupId}\n className=\"tw-absolute tw-h-[3px] tw-bg-box-selected-strong tw-rounded-t-x-large tw-w-full tw-bottom-0\"\n />\n )}\n </button>\n );\n })}\n </div>\n {isOverflowing && (\n <div\n data-test-id=\"tab-overflow\"\n className=\"tw-absolute tw-z-50 tw-right-3 tw-bottom-0 tw-top-0 tw-flex tw-justify-center tw-items-center\"\n >\n <button\n className={merge([\n 'tw-w-6 tw-h-6 tw-bg-box-neutral tw-rounded tw-flex tw-justify-center tw-items-center',\n isFocusVisible ? FOCUS_STYLE : '',\n ])}\n type=\"button\"\n onClick={() => {\n checkIfOverflowing();\n setIsMenuOpened(!isMenuOpened);\n }}\n onKeyDown={(event) => triggerOverflowMenu(event)}\n {...focusProps}\n >\n <IconDotsHorizontal />\n </button>\n {isMenuOpened && (\n <div\n className=\"tw-absolute tw-right-0 tw-top-11 tw-px-3 tw-pt-3 tw-bg-base tw-shadow tw-w-max\"\n role=\"dialog\"\n >\n {getOverflownTabs().map((tab) => {\n return (\n <button\n className={merge([\n 'tw-flex tw-items-center tw-w-full tw-mb-3 tw-text-left tw-text-text-weak',\n tab.disabled && 'tw-text-text-disabled',\n ])}\n key={tab.id}\n onClick={() => {\n if (!tab.disabled) {\n triggerTabButton(tab.id, true);\n setIsMenuOpened(false);\n }\n }}\n role=\"tab\"\n type=\"button\"\n aria-selected={tab.id === activeItemId}\n aria-controls={`${tab.id}-content`}\n aria-hidden={tab.disabled}\n tabIndex={!tab.disabled && isMenuOpened ? 0 : -1}\n id={`${tab.id}-btn-m`}\n onKeyDown={(event) => handleKeyboardTabChange(event)}\n >\n {tab.decorator}\n <span className=\"tw-mr-1 tw-ml-1.5\">{tab.label}</span>\n {tab.badge && (\n <Badge disabled={tab.disabled} style={tab.badge?.style}>\n {tab.badge?.children}\n </Badge>\n )}\n </button>\n );\n })}\n </div>\n )}\n </div>\n )}\n </div>\n\n <div data-test-id=\"tab-content\" className=\"tw-flex tw-flex-col tw-overflow-y-auto\">\n <div className=\"tw-mr-0\" style={{ maxHeight, minHeight }}>\n {Children.map(children, (child) => {\n if (!isValidElement(child)) {\n return null;\n }\n\n return cloneElement(child, { ...child.props, active: child.props.id === activeItemId });\n })}\n </div>\n </div>\n </>\n );\n};\nTabs.displayName = 'FondueTabs';\n"],"names":["TabsPaddingX","TabSize","paddingMap","Tabs","paddingX","size","activeItemId","children","onChange","maxHeight","minHeight","groupId","useMemoizedId","tabNavRef","useRef","isOverflowing","setIsOverflowing","useState","isMenuOpened","setIsMenuOpened","tabs","Children","child","isValidElement","overflowArray","setOverflowArray","checkIfOverflowing","useCallback","tabNav","overFlowIndex","tabItem","i","navPosition","tabPosition","overFlowIndexInAscOrder","a","b","getOverflownTabs","filterTabList","array","direction","activeItemIndex","tab","index","handleKeyboardTabChange","event","overflownTabs","target","fromOverflow","currentTabId","currentTabsArray","nextTabs","previousTabs","triggerTabButton","elementId","tabElement","buttonElement","error","triggerOverflowMenu","useEffect","isFocusVisible","focusProps","useFocusRing","React","merge","Badge","motion","FOCUS_STYLE","IconDotsHorizontal","_a","_b","cloneElement"],"mappings":"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"}
1
+ {"version":3,"file":"Tabs.es.js","sources":["../../../src/components/Tabs/Tabs.tsx"],"sourcesContent":["/* (c) Copyright Frontify Ltd., all rights reserved. */\n\nimport React, {\n Children,\n KeyboardEvent,\n ReactElement,\n ReactNode,\n cloneElement,\n isValidElement,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport { TabItemProps } from '@components/Tabs/TabItem';\nimport { merge } from '@utilities/merge';\nimport { IconDotsHorizontal } from '@foundation/Icon/Generated';\nimport { Badge } from '@components/Badge';\nimport { motion } from 'framer-motion';\nimport { useFocusRing } from '@react-aria/focus';\nimport { FOCUS_STYLE } from '@utilities/focusStyle';\nimport { useMemoizedId } from '@hooks/useMemoizedId';\nimport { DimensionUnity } from '@utilities/dimensions';\n\nexport enum TabsPaddingX {\n None = 'None',\n XSmall = 'XSmall',\n Small = 'Small',\n Medium = 'Medium',\n Large = 'Large',\n}\n\nexport enum TabSize {\n Small = 'Small',\n Large = 'Large',\n}\n\nexport type TabsProps = {\n paddingX?: TabsPaddingX;\n size?: TabSize;\n activeItemId: string;\n children: ReactNode;\n onChange?: (tabId: string) => void;\n maxHeight?: `${number}${DimensionUnity}`;\n minHeight?: `${number}${DimensionUnity}`;\n};\n\nconst paddingMap: Record<TabsPaddingX, string> = {\n [TabsPaddingX.None]: 'tw-pl-0',\n [TabsPaddingX.XSmall]: 'tw-pl-xs',\n [TabsPaddingX.Small]: 'tw-pl-s',\n [TabsPaddingX.Medium]: 'tw-pl-m',\n [TabsPaddingX.Large]: 'tw-pl-l',\n};\n\nexport const Tabs = ({\n paddingX,\n size,\n activeItemId,\n children,\n onChange,\n maxHeight,\n minHeight,\n}: TabsProps): ReactElement => {\n const groupId = useMemoizedId();\n const tabNavRef = useRef<HTMLDivElement | null>(null);\n const [isOverflowing, setIsOverflowing] = useState(false);\n const [isMenuOpened, setIsMenuOpened] = useState(false);\n\n const tabs: TabItemProps[] =\n Children.map(children, (child) => {\n if (!isValidElement<TabItemProps>(child)) {\n return null;\n }\n return child?.props;\n }) ?? [];\n\n const [overflowArray, setOverflowArray] = useState([0]);\n\n const checkIfOverflowing = useCallback(() => {\n const tabNav = tabNavRef.current;\n setIsOverflowing((tabNav && tabNav.scrollWidth > tabNav.clientWidth) ?? false);\n const overFlowIndex = [];\n if (tabNav) {\n for (const tabItem of tabNav.children) {\n const i = [...tabNav.children].indexOf(tabItem);\n const navPosition = tabNav.getBoundingClientRect();\n const tabPosition = tabItem.getBoundingClientRect();\n if (tabPosition.right > navPosition.right || tabPosition.left < navPosition.left) {\n overFlowIndex.push(i);\n }\n }\n\n const overFlowIndexInAscOrder = [...overFlowIndex].sort((a, b) => a - b);\n setOverflowArray(overFlowIndexInAscOrder);\n }\n }, []);\n\n const getOverflownTabs = () => {\n return overflowArray.map((i) => {\n return tabs[i];\n });\n };\n\n const filterTabList = (array: TabItemProps[], direction: string) => {\n const activeItemIndex = array.findIndex((tab) => tab.id === activeItemId);\n\n return array.filter((tab, index) => {\n if (direction === 'next') {\n if (index > activeItemIndex && !tab.disabled) {\n return tab;\n }\n }\n\n if (direction === 'previous') {\n if (index < activeItemIndex && !tab.disabled) {\n return tab;\n }\n }\n\n return false;\n });\n };\n\n const handleKeyboardTabChange = (event: KeyboardEvent<HTMLButtonElement>) => {\n event.stopPropagation();\n\n const overflownTabs = getOverflownTabs();\n const target = event.target as HTMLElement;\n const fromOverflow = target.id.includes('-m');\n const currentTabId = target.id.replace('-btn-m', '');\n const currentTabsArray = fromOverflow ? overflownTabs : tabs;\n\n const nextTabs = filterTabList(currentTabsArray, 'next');\n const previousTabs = filterTabList(currentTabsArray, 'previous');\n\n if ((event.key === 'ArrowRight' || event.key === 'ArrowDown') && nextTabs.length > 0) {\n triggerTabButton(nextTabs[0].id, fromOverflow);\n }\n\n if ((event.key === 'ArrowLeft' || event.key === 'ArrowUp') && previousTabs.length > 0) {\n triggerTabButton(previousTabs[previousTabs.length - 1].id, fromOverflow);\n }\n\n if (event.key === 'Enter' && fromOverflow) {\n triggerTabButton(currentTabId, true);\n setIsMenuOpened(false);\n const contentSection = document.getElementById(`${currentTabId}-content`) as HTMLDivElement;\n contentSection.focus();\n }\n\n if (!target.id.includes('-m')) {\n setIsMenuOpened(false);\n }\n };\n\n const triggerTabButton = (elementId: string, fromOverflow: boolean) => {\n try {\n const tabElement = document.getElementById(`${elementId}-btn`) as HTMLButtonElement;\n const buttonElement = document.getElementById(\n fromOverflow ? `${elementId}-btn-m` : `${elementId}-btn`,\n ) as HTMLButtonElement;\n if (onChange) {\n onChange(elementId);\n }\n if (isOverflowing) {\n tabElement.scrollIntoView({ behavior: 'smooth', block: 'end', inline: 'end' });\n }\n buttonElement.focus();\n } catch (error) {\n throw (error as Error).message;\n }\n };\n\n const triggerOverflowMenu = (event: KeyboardEvent<HTMLButtonElement>) => {\n checkIfOverflowing();\n const overflownTabs = getOverflownTabs();\n\n if (event.key === 'Enter') {\n if (!isMenuOpened && overflownTabs.length > 0) {\n const buttonElement = document.getElementById(`${overflownTabs[0].id}-btn-m`) as HTMLButtonElement;\n if (buttonElement) {\n buttonElement.focus();\n }\n }\n }\n\n if (isMenuOpened && (event.key === 'ArrowRight' || event.key === 'ArrowDown')) {\n triggerTabButton(overflownTabs[0].id, true);\n }\n };\n\n // First render\n useEffect(() => {\n checkIfOverflowing();\n }, [checkIfOverflowing]);\n\n useEffect(() => {\n window.addEventListener('resize', checkIfOverflowing);\n return () => {\n window.removeEventListener('resize', checkIfOverflowing);\n };\n }, [checkIfOverflowing]);\n\n const { isFocusVisible, focusProps } = useFocusRing();\n\n return (\n <>\n <div data-test-id=\"tabs\" className=\"tw-flex tw-relative tw-border-b tw-border-line\">\n <div\n ref={tabNavRef}\n role=\"tablist\"\n className={merge([\n 'tw-overflow-x-hidden tw-flex-shrink-0 tw-h-full tw-w-full tw-flex tw-justify-start',\n paddingMap[paddingX ?? TabsPaddingX.Small],\n size === TabSize.Small ? 'tw-gap-xxs' : 'tw-gap-xs ',\n ])}\n >\n {tabs.map((tab) => {\n return (\n <button\n data-test-id=\"tab-item\"\n role=\"tab\"\n type=\"button\"\n aria-selected={tab.id === activeItemId}\n aria-controls={`${tab.id}-content`}\n aria-hidden={tab.disabled}\n tabIndex={tab.id === activeItemId ? 0 : -1}\n id={`${tab.id}-btn`}\n className={merge([\n 'tw-group tw-relative tw-mx-0 tw-py-4 tw-px-2 tw-w-max tw-cursor-pointer tw-flex tw-items-center tw-justify-center tw-whitespace-nowrap',\n tab.disabled && 'tw-text-text-disabled',\n !tab.disabled && 'hover:tw-text-text',\n tab.id === activeItemId ? 'tw-font-medium tw-text-text' : 'tw-text-text-weak',\n size === TabSize.Small ? 'tw-text-sm' : 'tw-text-md',\n ])}\n key={tab.id}\n onClick={() => {\n if (!tab.disabled) {\n triggerTabButton(tab.id, false);\n setIsMenuOpened(false);\n }\n }}\n onKeyDown={(event) => handleKeyboardTabChange(event)}\n >\n {tab.decorator && <span className=\"tw-mr-1.5\">{tab.decorator}</span>}\n\n <span>{tab.label}</span>\n\n {tab.badge && (\n <span className=\"tw-ml-1.5\">\n <Badge disabled={tab.disabled} style={tab.badge.style}>\n {tab.badge.children}\n </Badge>\n </span>\n )}\n {tab.id === activeItemId && (\n <motion.div\n initial={false}\n layoutDependency={activeItemId}\n data-test-id=\"tab-active-highlight\"\n layoutId={groupId}\n className=\"tw-absolute tw-h-[3px] tw-bg-box-selected-strong tw-rounded-t-x-large tw-w-full tw-bottom-0\"\n />\n )}\n </button>\n );\n })}\n </div>\n {isOverflowing && (\n <div\n data-test-id=\"tab-overflow\"\n className=\"tw-absolute tw-z-50 tw-right-3 tw-bottom-0 tw-top-0 tw-flex tw-justify-center tw-items-center\"\n >\n <button\n className={merge([\n 'tw-w-6 tw-h-6 tw-bg-box-neutral tw-rounded tw-flex tw-justify-center tw-items-center',\n isFocusVisible ? FOCUS_STYLE : '',\n ])}\n type=\"button\"\n onClick={() => {\n checkIfOverflowing();\n setIsMenuOpened(!isMenuOpened);\n }}\n onKeyDown={(event) => triggerOverflowMenu(event)}\n {...focusProps}\n >\n <IconDotsHorizontal />\n </button>\n {isMenuOpened && (\n <div\n className=\"tw-absolute tw-right-0 tw-top-11 tw-px-3 tw-pt-3 tw-bg-base tw-shadow tw-w-max\"\n role=\"dialog\"\n >\n {getOverflownTabs().map((tab) => {\n return (\n <button\n className={merge([\n 'tw-flex tw-items-center tw-w-full tw-mb-3 tw-text-left tw-text-text-weak',\n tab.disabled && 'tw-text-text-disabled',\n ])}\n key={tab.id}\n onClick={() => {\n if (!tab.disabled) {\n triggerTabButton(tab.id, true);\n setIsMenuOpened(false);\n }\n }}\n role=\"tab\"\n type=\"button\"\n aria-selected={tab.id === activeItemId}\n aria-controls={`${tab.id}-content`}\n aria-hidden={tab.disabled}\n tabIndex={!tab.disabled && isMenuOpened ? 0 : -1}\n id={`${tab.id}-btn-m`}\n onKeyDown={(event) => handleKeyboardTabChange(event)}\n >\n {tab.decorator}\n <span className=\"tw-mr-1 tw-ml-1.5\">{tab.label}</span>\n {tab.badge && (\n <Badge disabled={tab.disabled} style={tab.badge?.style}>\n {tab.badge?.children}\n </Badge>\n )}\n </button>\n );\n })}\n </div>\n )}\n </div>\n )}\n </div>\n\n <div data-test-id=\"tab-content\" className=\"tw-flex tw-flex-col tw-overflow-y-auto\">\n <div className=\"tw-mr-0\" style={{ maxHeight, minHeight }}>\n {Children.map(children, (child) => {\n if (!isValidElement(child)) {\n return null;\n }\n\n return cloneElement(child, { ...child.props, active: child.props.id === activeItemId });\n })}\n </div>\n </div>\n </>\n );\n};\nTabs.displayName = 'FondueTabs';\n"],"names":["TabsPaddingX","TabSize","paddingMap","Tabs","paddingX","size","activeItemId","children","onChange","maxHeight","minHeight","groupId","useMemoizedId","tabNavRef","useRef","isOverflowing","setIsOverflowing","useState","isMenuOpened","setIsMenuOpened","tabs","Children","child","isValidElement","overflowArray","setOverflowArray","checkIfOverflowing","useCallback","tabNav","overFlowIndex","tabItem","i","navPosition","tabPosition","overFlowIndexInAscOrder","a","b","getOverflownTabs","filterTabList","array","direction","activeItemIndex","tab","index","handleKeyboardTabChange","event","overflownTabs","target","fromOverflow","currentTabId","currentTabsArray","nextTabs","previousTabs","triggerTabButton","elementId","tabElement","buttonElement","error","triggerOverflowMenu","useEffect","isFocusVisible","focusProps","useFocusRing","React","merge","Badge","motion","FOCUS_STYLE","IconDotsHorizontal","_a","_b","cloneElement"],"mappings":"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"}