@frontify/fondue 12.0.0-beta.243 → 12.0.0-beta.244
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.
- package/dist/components/ScrollWrapper/ScrollWrapper.d.ts +1 -1
- package/dist/components/ScrollWrapper/ScrollWrapper.es.js +20 -19
- package/dist/components/ScrollWrapper/ScrollWrapper.es.js.map +1 -1
- package/dist/components/ScrollWrapper/types.d.ts +1 -0
- package/dist/components/ScrollWrapper/types.es.js.map +1 -1
- package/dist/components/Tabs/Tabs.d.ts +2 -0
- package/dist/components/Tabs/Tabs.es.js +70 -68
- package/dist/components/Tabs/Tabs.es.js.map +1 -1
- package/dist/index.cjs.js +2 -2
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.umd.js +2 -2
- package/dist/index.umd.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ReactElement } from 'react';
|
|
2
2
|
import { ScrollWrapperProps } from './types';
|
|
3
3
|
export declare const ScrollWrapper: {
|
|
4
|
-
({ direction, children, "data-test-id": dataTestId, }: ScrollWrapperProps): ReactElement;
|
|
4
|
+
({ tabIndex, direction, children, "data-test-id": dataTestId, }: ScrollWrapperProps): ReactElement;
|
|
5
5
|
displayName: string;
|
|
6
6
|
};
|
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
import { useFocusRing as b } from "@react-aria/focus";
|
|
2
|
-
import e, { useRef as
|
|
2
|
+
import e, { useRef as f } from "react";
|
|
3
3
|
import "../../styles.css.es.js";
|
|
4
|
-
import { useScrollWrapper as
|
|
5
|
-
import { ScrollWrapperDirection as o, scrollWrapperDirections as
|
|
6
|
-
import { merge as
|
|
7
|
-
import { FOCUS_STYLE as
|
|
4
|
+
import { useScrollWrapper as g } from "./hooks/useScrollWrapper.es.js";
|
|
5
|
+
import { ScrollWrapperDirection as o, scrollWrapperDirections as h } from "./types.es.js";
|
|
6
|
+
import { merge as E } from "../../utilities/merge.es.js";
|
|
7
|
+
import { FOCUS_STYLE as x } from "../../utilities/focusStyle.es.js";
|
|
8
8
|
const i = {
|
|
9
9
|
bottom: "linear-gradient(180deg, rgba(232, 233, 233, 0) 0%, #E8E9E9 100%)",
|
|
10
10
|
top: "linear-gradient(0deg, rgba(232, 233, 233, 0) 0%, #E8E9E9 100%)"
|
|
11
|
-
},
|
|
11
|
+
}, S = ({
|
|
12
|
+
tabIndex: n = 0,
|
|
12
13
|
direction: r = o.Vertical,
|
|
13
|
-
children:
|
|
14
|
-
"data-test-id":
|
|
14
|
+
children: c,
|
|
15
|
+
"data-test-id": s = "scroll-wrapper"
|
|
15
16
|
}) => {
|
|
16
|
-
const t =
|
|
17
|
-
return /* @__PURE__ */ e.createElement("div", { "data-test-id":
|
|
17
|
+
const t = f(null), [{ showTopShadow: w, showBottomShadow: m }, d] = g(t), { isFocusVisible: p, focusProps: u } = b(), l = r === o.Vertical || r === o.Both, a = t.current ? t.current.clientWidth + 8 : "100%";
|
|
18
|
+
return /* @__PURE__ */ e.createElement("div", { "data-test-id": s, className: "tw-h-full tw-relative tw-flex-auto tw-flex tw-flex-col tw-min-h-0" }, l && w && /* @__PURE__ */ e.createElement(
|
|
18
19
|
"div",
|
|
19
20
|
{
|
|
20
21
|
className: "tw-h-3 tw-w-full tw-absolute tw-z-10 tw-top-0 tw-left-0 tw-mix-blend-darken tw-border-t tw-border-line",
|
|
@@ -27,19 +28,19 @@ const i = {
|
|
|
27
28
|
"div",
|
|
28
29
|
{
|
|
29
30
|
ref: t,
|
|
30
|
-
tabIndex:
|
|
31
|
+
tabIndex: n,
|
|
31
32
|
role: "region",
|
|
32
33
|
"aria-label": "Scrollable dialogue content",
|
|
33
|
-
className:
|
|
34
|
-
|
|
34
|
+
className: E([
|
|
35
|
+
h[r],
|
|
35
36
|
"tw-flex-auto tw-min-h-0 tw-outline-none tw-pt-px tw-pb-2 tw-px-2 tw--mx-2",
|
|
36
|
-
|
|
37
|
+
p && x
|
|
37
38
|
]),
|
|
38
39
|
...d,
|
|
39
|
-
...
|
|
40
|
+
...u
|
|
40
41
|
},
|
|
41
|
-
|
|
42
|
-
), l &&
|
|
42
|
+
c
|
|
43
|
+
), l && m && /* @__PURE__ */ e.createElement(
|
|
43
44
|
"div",
|
|
44
45
|
{
|
|
45
46
|
className: "tw-h-3 tw-absolute tw-z-10 tw-bottom-0 tw-left-0 tw-mix-blend-darken tw-border-b tw-border-line",
|
|
@@ -50,8 +51,8 @@ const i = {
|
|
|
50
51
|
}
|
|
51
52
|
));
|
|
52
53
|
};
|
|
53
|
-
|
|
54
|
+
S.displayName = "FondueScrollWrapper";
|
|
54
55
|
export {
|
|
55
|
-
|
|
56
|
+
S as ScrollWrapper
|
|
56
57
|
};
|
|
57
58
|
//# sourceMappingURL=ScrollWrapper.es.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ScrollWrapper.es.js","sources":["../../../src/components/ScrollWrapper/ScrollWrapper.tsx"],"sourcesContent":["/* (c) Copyright Frontify Ltd., all rights reserved. */\n\nimport { useFocusRing } from '@react-aria/focus';\nimport React, { ReactElement, useRef } from 'react';\nimport { FOCUS_STYLE, merge } from '../..';\nimport { useScrollWrapper } from './hooks/useScrollWrapper';\nimport { ScrollWrapperDirection, ScrollWrapperProps, scrollWrapperDirections } from './types';\n\nconst GRADIENTS = {\n bottom: 'linear-gradient(180deg, rgba(232, 233, 233, 0) 0%, #E8E9E9 100%)',\n top: 'linear-gradient(0deg, rgba(232, 233, 233, 0) 0%, #E8E9E9 100%)',\n};\n\nexport const ScrollWrapper = ({\n direction = ScrollWrapperDirection.Vertical,\n children,\n 'data-test-id': dataTestId = 'scroll-wrapper',\n}: ScrollWrapperProps): ReactElement => {\n const scrollingContainer = useRef<HTMLDivElement>(null);\n\n const [{ showTopShadow, showBottomShadow }, scrollDivProps] = useScrollWrapper(scrollingContainer);\n\n const { isFocusVisible, focusProps } = useFocusRing();\n\n const directionVertical =\n direction === ScrollWrapperDirection.Vertical || direction === ScrollWrapperDirection.Both;\n\n const gradientWidth = scrollingContainer.current ? scrollingContainer.current.clientWidth + 8 : '100%';\n\n return (\n <div data-test-id={dataTestId} className=\"tw-h-full tw-relative tw-flex-auto tw-flex tw-flex-col tw-min-h-0\">\n {directionVertical && showTopShadow && (\n <div\n className=\"tw-h-3 tw-w-full tw-absolute tw-z-10 tw-top-0 tw-left-0 tw-mix-blend-darken tw-border-t tw-border-line\"\n style={{\n background: GRADIENTS.top,\n width: gradientWidth,\n }}\n />\n )}\n <div\n ref={scrollingContainer}\n // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex\n tabIndex={
|
|
1
|
+
{"version":3,"file":"ScrollWrapper.es.js","sources":["../../../src/components/ScrollWrapper/ScrollWrapper.tsx"],"sourcesContent":["/* (c) Copyright Frontify Ltd., all rights reserved. */\n\nimport { useFocusRing } from '@react-aria/focus';\nimport React, { ReactElement, useRef } from 'react';\nimport { FOCUS_STYLE, merge } from '../..';\nimport { useScrollWrapper } from './hooks/useScrollWrapper';\nimport { ScrollWrapperDirection, ScrollWrapperProps, scrollWrapperDirections } from './types';\n\nconst GRADIENTS = {\n bottom: 'linear-gradient(180deg, rgba(232, 233, 233, 0) 0%, #E8E9E9 100%)',\n top: 'linear-gradient(0deg, rgba(232, 233, 233, 0) 0%, #E8E9E9 100%)',\n};\n\nexport const ScrollWrapper = ({\n tabIndex = 0,\n direction = ScrollWrapperDirection.Vertical,\n children,\n 'data-test-id': dataTestId = 'scroll-wrapper',\n}: ScrollWrapperProps): ReactElement => {\n const scrollingContainer = useRef<HTMLDivElement>(null);\n\n const [{ showTopShadow, showBottomShadow }, scrollDivProps] = useScrollWrapper(scrollingContainer);\n\n const { isFocusVisible, focusProps } = useFocusRing();\n\n const directionVertical =\n direction === ScrollWrapperDirection.Vertical || direction === ScrollWrapperDirection.Both;\n\n const gradientWidth = scrollingContainer.current ? scrollingContainer.current.clientWidth + 8 : '100%';\n\n return (\n <div data-test-id={dataTestId} className=\"tw-h-full tw-relative tw-flex-auto tw-flex tw-flex-col tw-min-h-0\">\n {directionVertical && showTopShadow && (\n <div\n className=\"tw-h-3 tw-w-full tw-absolute tw-z-10 tw-top-0 tw-left-0 tw-mix-blend-darken tw-border-t tw-border-line\"\n style={{\n background: GRADIENTS.top,\n width: gradientWidth,\n }}\n />\n )}\n <div\n ref={scrollingContainer}\n // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex\n tabIndex={tabIndex}\n role=\"region\"\n aria-label=\"Scrollable dialogue content\"\n className={merge([\n scrollWrapperDirections[direction],\n 'tw-flex-auto tw-min-h-0 tw-outline-none tw-pt-px tw-pb-2 tw-px-2 tw--mx-2',\n isFocusVisible && FOCUS_STYLE,\n ])}\n {...scrollDivProps}\n {...focusProps}\n >\n {children}\n </div>\n {directionVertical && showBottomShadow && (\n <div\n className=\"tw-h-3 tw-absolute tw-z-10 tw-bottom-0 tw-left-0 tw-mix-blend-darken tw-border-b tw-border-line\"\n style={{\n background: GRADIENTS.bottom,\n width: gradientWidth,\n }}\n />\n )}\n </div>\n );\n};\nScrollWrapper.displayName = 'FondueScrollWrapper';\n"],"names":["GRADIENTS","ScrollWrapper","tabIndex","direction","ScrollWrapperDirection","children","dataTestId","scrollingContainer","useRef","showTopShadow","showBottomShadow","scrollDivProps","useScrollWrapper","isFocusVisible","focusProps","useFocusRing","directionVertical","gradientWidth","React","merge","scrollWrapperDirections","FOCUS_STYLE"],"mappings":";;;;;;;AAQA,MAAMA,IAAY;AAAA,EACd,QAAQ;AAAA,EACR,KAAK;AACT,GAEaC,IAAgB,CAAC;AAAA,EAC1B,UAAAC,IAAW;AAAA,EACX,WAAAC,IAAYC,EAAuB;AAAA,EACnC,UAAAC;AAAA,EACA,gBAAgBC,IAAa;AACjC,MAAwC;AAC9B,QAAAC,IAAqBC,EAAuB,IAAI,GAEhD,CAAC,EAAE,eAAAC,GAAe,kBAAAC,EAAA,GAAoBC,CAAc,IAAIC,EAAiBL,CAAkB,GAE3F,EAAE,gBAAAM,GAAgB,YAAAC,EAAW,IAAIC,EAAa,GAE9CC,IACFb,MAAcC,EAAuB,YAAYD,MAAcC,EAAuB,MAEpFa,IAAgBV,EAAmB,UAAUA,EAAmB,QAAQ,cAAc,IAAI;AAEhG,yCACK,OAAI,EAAA,gBAAcD,GAAY,WAAU,oEAAA,GACpCU,KAAqBP,KAClB,gBAAAS,EAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACG,WAAU;AAAA,MACV,OAAO;AAAA,QACH,YAAYlB,EAAU;AAAA,QACtB,OAAOiB;AAAA,MACX;AAAA,IAAA;AAAA,EAGR,GAAA,gBAAAC,EAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACG,KAAKX;AAAA,MAEL,UAAAL;AAAA,MACA,MAAK;AAAA,MACL,cAAW;AAAA,MACX,WAAWiB,EAAM;AAAA,QACbC,EAAwBjB,CAAS;AAAA,QACjC;AAAA,QACAU,KAAkBQ;AAAA,MAAA,CACrB;AAAA,MACA,GAAGV;AAAA,MACH,GAAGG;AAAA,IAAA;AAAA,IAEHT;AAAA,EAAA,GAEJW,KAAqBN,KAClB,gBAAAQ,EAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACG,WAAU;AAAA,MACV,OAAO;AAAA,QACH,YAAYlB,EAAU;AAAA,QACtB,OAAOiB;AAAA,MACX;AAAA,IAAA;AAAA,EAAA,CAGZ;AAER;AACAhB,EAAc,cAAc;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.es.js","sources":["../../../src/components/ScrollWrapper/types.ts"],"sourcesContent":["/* (c) Copyright Frontify Ltd., all rights reserved. */\n\nimport { ReactElement } from 'react';\n\nexport enum ScrollWrapperDirection {\n Both = 'Both',\n Horizontal = 'Horizontal',\n Vertical = 'Vertical',\n}\n\nexport const scrollWrapperDirections: Record<ScrollWrapperDirection, string> = {\n [ScrollWrapperDirection.Both]: 'tw-w-full tw-h-full tw-overflow-auto',\n [ScrollWrapperDirection.Horizontal]: 'tw-w-full tw-overflow-x-auto tw-overflow-y-hidden',\n [ScrollWrapperDirection.Vertical]: 'tw-h-full tw-overflow-y-auto tw-overflow-x-hidden',\n};\n\nexport type ScrollWrapperProps = {\n direction?: ScrollWrapperDirection;\n children?: ReactElement | ReactElement[];\n 'data-test-id'?: string;\n};\n"],"names":["ScrollWrapperDirection","scrollWrapperDirections"],"mappings":"AAIY,IAAAA,sBAAAA,OACRA,EAAA,OAAO,QACPA,EAAA,aAAa,cACbA,EAAA,WAAW,YAHHA,IAAAA,KAAA,CAAA,CAAA;AAML,MAAMC,IAAkE;AAAA,EAC1E,MAA8B;AAAA,EAC9B,YAAoC;AAAA,EACpC,UAAkC;AACvC;"}
|
|
1
|
+
{"version":3,"file":"types.es.js","sources":["../../../src/components/ScrollWrapper/types.ts"],"sourcesContent":["/* (c) Copyright Frontify Ltd., all rights reserved. */\n\nimport { ReactElement } from 'react';\n\nexport enum ScrollWrapperDirection {\n Both = 'Both',\n Horizontal = 'Horizontal',\n Vertical = 'Vertical',\n}\n\nexport const scrollWrapperDirections: Record<ScrollWrapperDirection, string> = {\n [ScrollWrapperDirection.Both]: 'tw-w-full tw-h-full tw-overflow-auto',\n [ScrollWrapperDirection.Horizontal]: 'tw-w-full tw-overflow-x-auto tw-overflow-y-hidden',\n [ScrollWrapperDirection.Vertical]: 'tw-h-full tw-overflow-y-auto tw-overflow-x-hidden',\n};\n\nexport type ScrollWrapperProps = {\n direction?: ScrollWrapperDirection;\n children?: ReactElement | ReactElement[];\n 'data-test-id'?: string;\n tabIndex?: number;\n};\n"],"names":["ScrollWrapperDirection","scrollWrapperDirections"],"mappings":"AAIY,IAAAA,sBAAAA,OACRA,EAAA,OAAO,QACPA,EAAA,aAAa,cACbA,EAAA,WAAW,YAHHA,IAAAA,KAAA,CAAA,CAAA;AAML,MAAMC,IAAkE;AAAA,EAC1E,MAA8B;AAAA,EAC9B,YAAoC;AAAA,EACpC,UAAkC;AACvC;"}
|
|
@@ -1,118 +1,120 @@
|
|
|
1
|
-
import
|
|
1
|
+
import o, { useRef as I, useState as x, Children as O, isValidElement as A, useCallback as j, useEffect as L, cloneElement as K } from "react";
|
|
2
2
|
import { merge as f } from "../../utilities/merge.es.js";
|
|
3
|
-
import { motion as
|
|
4
|
-
import { useFocusRing as
|
|
3
|
+
import { motion as z } from "framer-motion";
|
|
4
|
+
import { useFocusRing as V } from "@react-aria/focus";
|
|
5
5
|
import { FOCUS_STYLE as U } from "../../utilities/focusStyle.es.js";
|
|
6
6
|
import { useMemoizedId as W } from "../../hooks/useMemoizedId.es.js";
|
|
7
7
|
import H from "../../foundation/Icon/Generated/IconDotsHorizontal.es.js";
|
|
8
|
-
import { Badge as
|
|
9
|
-
var
|
|
10
|
-
const
|
|
8
|
+
import { Badge as $ } from "../Badge/Badge.es.js";
|
|
9
|
+
var Y = /* @__PURE__ */ ((l) => (l.None = "None", l.XSmall = "XSmall", l.Small = "Small", l.Medium = "Medium", l.Large = "Large", l))(Y || {}), _ = /* @__PURE__ */ ((l) => (l.Small = "Small", l.Large = "Large", l))(_ || {});
|
|
10
|
+
const q = {
|
|
11
|
+
None: "tw-pl-0",
|
|
12
|
+
XSmall: "tw-pl-xs",
|
|
11
13
|
Small: "tw-pl-s",
|
|
12
14
|
Medium: "tw-pl-m",
|
|
13
15
|
Large: "tw-pl-l"
|
|
14
|
-
},
|
|
15
|
-
const
|
|
16
|
+
}, G = ({ paddingX: l, size: y, activeItemId: i, children: E, onChange: h }) => {
|
|
17
|
+
const B = W(), v = I(null), [k, C] = x(!1), [w, c] = x(!1), p = O.map(E, (e) => A(e) ? e == null ? void 0 : e.props : null) ?? [], [M, R] = x([0]), a = j(() => {
|
|
16
18
|
const e = v.current;
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
+
C((e && e.scrollWidth > e.clientWidth) ?? !1);
|
|
20
|
+
const n = [];
|
|
19
21
|
if (e) {
|
|
20
22
|
for (const t of e.children) {
|
|
21
|
-
const
|
|
22
|
-
(u.right > m.right || u.left < m.left) &&
|
|
23
|
+
const s = [...e.children].indexOf(t), m = e.getBoundingClientRect(), u = t.getBoundingClientRect();
|
|
24
|
+
(u.right > m.right || u.left < m.left) && n.push(s);
|
|
23
25
|
}
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
+
const r = [...n].sort((t, s) => t - s);
|
|
27
|
+
R(r);
|
|
26
28
|
}
|
|
27
|
-
}, []), g = () =>
|
|
28
|
-
const
|
|
29
|
-
return e.filter((t,
|
|
30
|
-
},
|
|
31
|
-
const
|
|
32
|
-
(e.key === "ArrowRight" || e.key === "ArrowDown") && u.length > 0 && d(u[0].id, t), (e.key === "ArrowLeft" || e.key === "ArrowUp") && b.length > 0 && d(b[b.length - 1].id, t), e.key === "Enter" && t && (d(
|
|
33
|
-
}, d = (e,
|
|
29
|
+
}, []), g = () => M.map((e) => p[e]), N = (e, n) => {
|
|
30
|
+
const r = e.findIndex((t) => t.id === i);
|
|
31
|
+
return e.filter((t, s) => n === "next" && s > r && !t.disabled || n === "previous" && s < r && !t.disabled ? t : !1);
|
|
32
|
+
}, S = (e) => {
|
|
33
|
+
const n = g(), r = e.target, t = r.id.includes("-m"), s = r.id.replace("-btn-m", ""), m = t ? n : p, u = N(m, "next"), b = N(m, "previous");
|
|
34
|
+
(e.key === "ArrowRight" || e.key === "ArrowDown") && u.length > 0 && d(u[0].id, t), (e.key === "ArrowLeft" || e.key === "ArrowUp") && b.length > 0 && d(b[b.length - 1].id, t), e.key === "Enter" && t && (d(s, !0), c(!1), document.getElementById(`${s}-content`).focus()), r.id.includes("-m") || c(!1);
|
|
35
|
+
}, d = (e, n) => {
|
|
34
36
|
try {
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
+
const r = document.getElementById(`${e}-btn`), t = document.getElementById(
|
|
38
|
+
n ? `${e}-btn-m` : `${e}-btn`
|
|
37
39
|
);
|
|
38
|
-
|
|
39
|
-
} catch (
|
|
40
|
-
throw
|
|
40
|
+
h && h(e), k && r.scrollIntoView({ behavior: "smooth", block: "end", inline: "end" }), t.focus();
|
|
41
|
+
} catch (r) {
|
|
42
|
+
throw r.message;
|
|
41
43
|
}
|
|
42
|
-
},
|
|
44
|
+
}, T = (e) => {
|
|
43
45
|
a();
|
|
44
|
-
const
|
|
45
|
-
if (e.key === "Enter" && !w &&
|
|
46
|
-
const
|
|
47
|
-
|
|
46
|
+
const n = g();
|
|
47
|
+
if (e.key === "Enter" && !w && n.length > 0) {
|
|
48
|
+
const r = document.getElementById(`${n[0].id}-btn-m`);
|
|
49
|
+
r && r.focus();
|
|
48
50
|
}
|
|
49
|
-
w && (e.key === "ArrowRight" || e.key === "ArrowDown") && d(
|
|
51
|
+
w && (e.key === "ArrowRight" || e.key === "ArrowDown") && d(n[0].id, !0);
|
|
50
52
|
};
|
|
51
53
|
L(() => {
|
|
52
54
|
a();
|
|
53
55
|
}, [a]), L(() => (window.addEventListener("resize", a), () => {
|
|
54
56
|
window.removeEventListener("resize", a);
|
|
55
57
|
}), [a]);
|
|
56
|
-
const { isFocusVisible: D, focusProps: F } =
|
|
57
|
-
return /* @__PURE__ */
|
|
58
|
+
const { isFocusVisible: D, focusProps: F } = V();
|
|
59
|
+
return /* @__PURE__ */ o.createElement(o.Fragment, null, /* @__PURE__ */ o.createElement("div", { "data-test-id": "tabs", className: "tw-flex tw-relative tw-border-b tw-border-line" }, /* @__PURE__ */ o.createElement(
|
|
58
60
|
"div",
|
|
59
61
|
{
|
|
60
62
|
ref: v,
|
|
61
63
|
role: "tablist",
|
|
62
64
|
className: f([
|
|
63
|
-
"tw-overflow-x-hidden tw-flex-shrink-0 tw-h-full tw-w-full tw-flex tw-justify-start
|
|
64
|
-
|
|
65
|
+
"tw-overflow-x-hidden tw-flex-shrink-0 tw-h-full tw-w-full tw-flex tw-justify-start",
|
|
66
|
+
q[
|
|
65
67
|
l ?? "Small"
|
|
66
68
|
/* Small */
|
|
67
69
|
],
|
|
68
70
|
y === "Small" ? "tw-gap-xxs" : "tw-gap-xs "
|
|
69
71
|
])
|
|
70
72
|
},
|
|
71
|
-
p.map((e) => /* @__PURE__ */
|
|
73
|
+
p.map((e) => /* @__PURE__ */ o.createElement(
|
|
72
74
|
"button",
|
|
73
75
|
{
|
|
74
76
|
"data-test-id": "tab-item",
|
|
75
77
|
role: "tab",
|
|
76
78
|
type: "button",
|
|
77
|
-
"aria-selected": e.id ===
|
|
79
|
+
"aria-selected": e.id === i,
|
|
78
80
|
"aria-controls": `${e.id}-content`,
|
|
79
81
|
"aria-hidden": e.disabled,
|
|
80
|
-
tabIndex: e.id ===
|
|
82
|
+
tabIndex: e.id === i ? 0 : -1,
|
|
81
83
|
id: `${e.id}-btn`,
|
|
82
84
|
className: f([
|
|
83
85
|
"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",
|
|
84
86
|
e.disabled && "tw-text-text-disabled",
|
|
85
|
-
e.
|
|
87
|
+
!e.disabled && "hover:tw-text-text",
|
|
88
|
+
e.id === i ? "tw-font-medium tw-text-text" : "tw-text-text-weak",
|
|
86
89
|
y === "Small" ? "tw-text-sm" : "tw-text-md"
|
|
87
90
|
]),
|
|
88
91
|
key: e.id,
|
|
89
92
|
onClick: () => {
|
|
90
93
|
e.disabled || (d(e.id, !1), c(!1));
|
|
91
94
|
},
|
|
92
|
-
onKeyDown: (
|
|
95
|
+
onKeyDown: (n) => S(n)
|
|
93
96
|
},
|
|
94
|
-
e.decorator && /* @__PURE__ */
|
|
95
|
-
/* @__PURE__ */
|
|
96
|
-
e.badge && /* @__PURE__ */
|
|
97
|
-
e.id ===
|
|
98
|
-
|
|
97
|
+
e.decorator && /* @__PURE__ */ o.createElement("span", { className: "tw-mr-1.5" }, e.decorator),
|
|
98
|
+
/* @__PURE__ */ o.createElement("span", null, e.label),
|
|
99
|
+
e.badge && /* @__PURE__ */ o.createElement("span", { className: "tw-ml-1.5" }, /* @__PURE__ */ o.createElement($, { disabled: e.disabled, style: e.badge.style }, e.badge.children)),
|
|
100
|
+
e.id === i && /* @__PURE__ */ o.createElement(
|
|
101
|
+
z.div,
|
|
99
102
|
{
|
|
100
103
|
initial: !1,
|
|
101
|
-
layoutDependency:
|
|
104
|
+
layoutDependency: i,
|
|
102
105
|
"data-test-id": "tab-active-highlight",
|
|
103
|
-
layoutId:
|
|
104
|
-
className: "tw-absolute tw-h-[3px] tw-bg-
|
|
106
|
+
layoutId: B,
|
|
107
|
+
className: "tw-absolute tw-h-[3px] tw-bg-box-selected-strong tw-rounded-t-x-large tw-w-full tw-bottom-0"
|
|
105
108
|
}
|
|
106
|
-
)
|
|
107
|
-
e.id !== s && !e.disabled && /* @__PURE__ */ n.createElement("div", { className: "group-hover:tw-absolute group-hover:tw-h-[3px] group-hover:tw-bg-box-neutral-hover group-hover:tw-rounded-t-x-large group-hover:tw-w-full group-hover:tw-bottom-0" })
|
|
109
|
+
)
|
|
108
110
|
))
|
|
109
|
-
), k && /* @__PURE__ */
|
|
111
|
+
), k && /* @__PURE__ */ o.createElement(
|
|
110
112
|
"div",
|
|
111
113
|
{
|
|
112
114
|
"data-test-id": "tab-overflow",
|
|
113
|
-
className: "tw-absolute tw-right-3 tw-bottom-0 tw-top-0 tw-flex tw-justify-center tw-items-center"
|
|
115
|
+
className: "tw-absolute tw-z-50 tw-right-3 tw-bottom-0 tw-top-0 tw-flex tw-justify-center tw-items-center"
|
|
114
116
|
},
|
|
115
|
-
/* @__PURE__ */
|
|
117
|
+
/* @__PURE__ */ o.createElement(
|
|
116
118
|
"button",
|
|
117
119
|
{
|
|
118
120
|
className: f([
|
|
@@ -123,20 +125,20 @@ const _ = {
|
|
|
123
125
|
onClick: () => {
|
|
124
126
|
a(), c(!w);
|
|
125
127
|
},
|
|
126
|
-
onKeyDown: (e) =>
|
|
128
|
+
onKeyDown: (e) => T(e),
|
|
127
129
|
...F
|
|
128
130
|
},
|
|
129
|
-
/* @__PURE__ */
|
|
131
|
+
/* @__PURE__ */ o.createElement(H, null)
|
|
130
132
|
),
|
|
131
|
-
w && /* @__PURE__ */
|
|
133
|
+
w && /* @__PURE__ */ o.createElement(
|
|
132
134
|
"div",
|
|
133
135
|
{
|
|
134
136
|
className: "tw-absolute tw-right-0 tw-top-11 tw-px-3 tw-pt-3 tw-bg-base tw-shadow tw-w-max",
|
|
135
137
|
role: "dialog"
|
|
136
138
|
},
|
|
137
139
|
g().map((e) => {
|
|
138
|
-
var
|
|
139
|
-
return /* @__PURE__ */
|
|
140
|
+
var n, r;
|
|
141
|
+
return /* @__PURE__ */ o.createElement(
|
|
140
142
|
"button",
|
|
141
143
|
{
|
|
142
144
|
className: f([
|
|
@@ -149,25 +151,25 @@ const _ = {
|
|
|
149
151
|
},
|
|
150
152
|
role: "tab",
|
|
151
153
|
type: "button",
|
|
152
|
-
"aria-selected": e.id ===
|
|
154
|
+
"aria-selected": e.id === i,
|
|
153
155
|
"aria-controls": `${e.id}-content`,
|
|
154
156
|
"aria-hidden": e.disabled,
|
|
155
157
|
tabIndex: !e.disabled && w ? 0 : -1,
|
|
156
158
|
id: `${e.id}-btn-m`,
|
|
157
|
-
onKeyDown: (t) =>
|
|
159
|
+
onKeyDown: (t) => S(t)
|
|
158
160
|
},
|
|
159
161
|
e.decorator,
|
|
160
|
-
/* @__PURE__ */
|
|
161
|
-
e.badge && /* @__PURE__ */
|
|
162
|
+
/* @__PURE__ */ o.createElement("span", { className: "tw-mr-1 tw-ml-1.5" }, e.label),
|
|
163
|
+
e.badge && /* @__PURE__ */ o.createElement($, { disabled: e.disabled, style: (n = e.badge) == null ? void 0 : n.style }, (r = e.badge) == null ? void 0 : r.children)
|
|
162
164
|
);
|
|
163
165
|
})
|
|
164
166
|
)
|
|
165
|
-
)), /* @__PURE__ */
|
|
167
|
+
)), /* @__PURE__ */ o.createElement("div", { "data-test-id": "tab-content" }, O.map(E, (e) => A(e) ? K(e, { ...e.props, active: e.props.id === i }) : null)));
|
|
166
168
|
};
|
|
167
|
-
|
|
169
|
+
G.displayName = "FondueTabs";
|
|
168
170
|
export {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
171
|
+
_ as TabSize,
|
|
172
|
+
G as Tabs,
|
|
173
|
+
Y as TabsPaddingX
|
|
172
174
|
};
|
|
173
175
|
//# 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';\n\nexport enum TabsPaddingX {\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};\n\nconst paddingMap: Record<TabsPaddingX, string> = {\n [TabsPaddingX.Small]: 'tw-pl-s',\n [TabsPaddingX.Medium]: 'tw-pl-m',\n [TabsPaddingX.Large]: 'tw-pl-l',\n};\n\nexport const Tabs = ({ paddingX, size, activeItemId, children, onChange }: 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 tw-pr-8',\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.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 <Badge disabled={tab.disabled} style={tab.badge.style}>\n {tab.badge.children}\n </Badge>\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-violet-60 tw-rounded-t-x-large tw-w-full tw-bottom-0\"\n />\n )}\n {tab.id !== activeItemId && !tab.disabled && (\n <div className=\"group-hover:tw-absolute group-hover:tw-h-[3px] group-hover:tw-bg-box-neutral-hover group-hover:tw-rounded-t-x-large group-hover:tw-w-full group-hover:tw-bottom-0\" />\n )}\n </button>\n );\n })}\n </div>\n {isOverflowing && (\n <div\n data-test-id=\"tab-overflow\"\n className=\"tw-absolute 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\">\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 </>\n );\n};\nTabs.displayName = 'FondueTabs';\n"],"names":["TabsPaddingX","TabSize","paddingMap","Tabs","paddingX","size","activeItemId","children","onChange","groupId","useMemoizedId","tabNavRef","useRef","isOverflowing","setIsOverflowing","useState","isMenuOpened","setIsMenuOpened","tabs","Children","child","isValidElement","overflowArray","setOverflowArray","checkIfOverflowing","useCallback","tabNav","overFlowIndex","tabItem","navPosition","tabPosition","overFlowIndexInAscOrder","a","b","getOverflownTabs","i","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';\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};\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 = ({ paddingX, size, activeItemId, children, onChange }: 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\">\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 </>\n );\n};\nTabs.displayName = 'FondueTabs';\n"],"names":["TabsPaddingX","TabSize","paddingMap","Tabs","paddingX","size","activeItemId","children","onChange","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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"}
|