@frontify/fondue 12.0.0-beta.44 → 12.0.0-beta.46
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/Slider/Slider.d.ts +1 -1
- package/dist/components/Slider/Slider.es.js +1 -0
- package/dist/components/Slider/Slider.es.js.map +1 -1
- package/dist/components/Tabs/Tabs.es.js +19 -18
- 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 +8 -8
|
@@ -13,7 +13,7 @@ export declare type TextOrNumberItem = {
|
|
|
13
13
|
export declare type SliderProps = {
|
|
14
14
|
id?: string;
|
|
15
15
|
items: (TextOrNumberItem | IconItem)[];
|
|
16
|
-
activeItemId
|
|
16
|
+
activeItemId?: string;
|
|
17
17
|
onChange: (id: string) => void;
|
|
18
18
|
ariaLabel?: string;
|
|
19
19
|
disabled?: boolean;
|
|
@@ -82,6 +82,7 @@ const u = (s) => s.icon !== void 0, G = (s) => {
|
|
|
82
82
|
style: {
|
|
83
83
|
width: `${100 / i.length}%`
|
|
84
84
|
},
|
|
85
|
+
hidden: !e,
|
|
85
86
|
className: f([
|
|
86
87
|
"tw-absolute tw--inset-px tw-h-full tw-box-content tw-border tw-rounded tw-pointer-events-none",
|
|
87
88
|
r ? "tw-border-line-x-strong tw-border-opacity-30 tw-bg-black-0" : "tw-border-black tw-bg-white"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Slider.es.js","sources":["../../../src/components/Slider/Slider.tsx"],"sourcesContent":["/* (c) Copyright Frontify Ltd., all rights reserved. */\n\nimport { IconProps } from '@foundation/Icon/IconProps';\nimport { useMemoizedId } from '@hooks/useMemoizedId';\nimport { useFocusRing } from '@react-aria/focus';\nimport { setInteractionModality } from '@react-aria/interactions';\nimport { useRadio, useRadioGroup } from '@react-aria/radio';\nimport { VisuallyHidden } from '@react-aria/visually-hidden';\nimport { RadioGroupState, useRadioGroupState } from '@react-stately/radio';\nimport { FOCUS_STYLE } from '@utilities/focusStyle';\nimport { merge } from '@utilities/merge';\nimport { motion } from 'framer-motion';\nimport React, { FC, ReactElement, useMemo, useRef } from 'react';\n\nexport type IconItem = {\n id: string;\n icon: ReactElement<IconProps>;\n value?: string;\n ariaLabel: string;\n};\n\nexport type TextOrNumberItem = {\n id: string;\n value: string | number;\n};\n\nexport type SliderProps = {\n id?: string;\n items: (TextOrNumberItem | IconItem)[];\n activeItemId
|
|
1
|
+
{"version":3,"file":"Slider.es.js","sources":["../../../src/components/Slider/Slider.tsx"],"sourcesContent":["/* (c) Copyright Frontify Ltd., all rights reserved. */\n\nimport { IconProps } from '@foundation/Icon/IconProps';\nimport { useMemoizedId } from '@hooks/useMemoizedId';\nimport { useFocusRing } from '@react-aria/focus';\nimport { setInteractionModality } from '@react-aria/interactions';\nimport { useRadio, useRadioGroup } from '@react-aria/radio';\nimport { VisuallyHidden } from '@react-aria/visually-hidden';\nimport { RadioGroupState, useRadioGroupState } from '@react-stately/radio';\nimport { FOCUS_STYLE } from '@utilities/focusStyle';\nimport { merge } from '@utilities/merge';\nimport { motion } from 'framer-motion';\nimport React, { FC, ReactElement, useMemo, useRef } from 'react';\n\nexport type IconItem = {\n id: string;\n icon: ReactElement<IconProps>;\n value?: string;\n ariaLabel: string;\n};\n\nexport type TextOrNumberItem = {\n id: string;\n value: string | number;\n};\n\nexport type SliderProps = {\n id?: string;\n items: (TextOrNumberItem | IconItem)[];\n activeItemId?: string;\n onChange: (id: string) => void;\n ariaLabel?: string;\n disabled?: boolean;\n};\n\nconst isIconItem = (item: TextOrNumberItem | IconItem): item is IconItem => (item as IconItem).icon !== undefined;\n\ninterface SliderItemProps {\n id: string;\n item: TextOrNumberItem | IconItem;\n disabled: boolean;\n radioGroupState: RadioGroupState;\n}\n\nconst SliderItem = (props: SliderItemProps) => {\n const { id, item, disabled, radioGroupState } = props;\n const ref = useRef<HTMLInputElement | null>(null);\n const isActive = item.id === radioGroupState.selectedValue;\n const { inputProps } = useRadio(\n {\n value: item.id,\n 'aria-label': isIconItem(item) ? item.ariaLabel : item.value.toString(),\n isDisabled: disabled,\n id: isActive ? id : undefined,\n },\n radioGroupState,\n ref,\n );\n const { isFocusVisible, focusProps } = useFocusRing();\n\n const handleMockLabelClick = () => {\n if (!disabled) {\n radioGroupState.setSelectedValue(item.id);\n ref.current?.focus();\n setInteractionModality('pointer');\n }\n };\n\n const getSliderItemTestId = () => {\n switch (true) {\n case isIconItem(item):\n return 'slider-item-icon';\n case typeof item.value === 'string':\n return 'slider-item-text';\n default:\n return 'slider-item-number';\n }\n };\n\n return (\n <li key={item.id} className={merge(['tw-relative', isFocusVisible && FOCUS_STYLE])}>\n <div\n // TODO: Change element back to label when bug #2380 from @react-aria is fixed\n // https://github.com/adobe/react-spectrum/issues/2380\n role=\"none\"\n onClick={handleMockLabelClick}\n data-test-id={getSliderItemTestId()}\n className={merge([\n 'tw-relative tw-w-full tw-inline-flex tw-justify-center tw-items-center tw-font-sans tw-font-normal tw-h-full tw-text-center',\n isActive && !disabled ? 'tw-text-black' : 'tw-text-black-80',\n !disabled ? 'hover:tw-text-black hover:tw-cursor-pointer' : '',\n ])}\n >\n <VisuallyHidden>\n <input {...inputProps} {...focusProps} data-test-id=\"slider-input\" ref={ref} />\n </VisuallyHidden>\n <span className=\"tw-overflow-hidden tw-text-ellipsis tw-whitespace-nowrap tw-flex\">\n {isIconItem(item) && <span aria-label={item.ariaLabel}>{item.icon}</span>}\n {item.value && <span className={isIconItem(item) ? 'tw-ml-2' : ''}>{item.value.toString()}</span>}\n </span>\n </div>\n </li>\n );\n};\n\nexport const Slider: FC<SliderProps> = ({\n id: propId,\n items,\n activeItemId,\n onChange,\n ariaLabel = 'Slider',\n disabled = false,\n}) => {\n const id = useMemoizedId(propId);\n const groupProps = { onChange, value: activeItemId, label: ariaLabel, isDisabled: disabled };\n const radioGroupState = useRadioGroupState(groupProps);\n const { radioGroupProps } = useRadioGroup(groupProps, radioGroupState);\n const itemElements = useMemo(() => {\n return items.map((item, i) => (\n <SliderItem\n id={id}\n item={item}\n disabled={disabled}\n radioGroupState={radioGroupState}\n key={`slider-${id}-item-${i}`}\n />\n ));\n }, [items, id, disabled, radioGroupState]);\n const selectedIndex = items.findIndex((item) => item.id === radioGroupState.selectedValue);\n\n return (\n <ul\n {...radioGroupProps}\n data-test-id=\"slider\"\n className=\"tw-relative tw-h-9 tw-w-full tw-grid tw-grid-flow-col tw-auto-cols-fr tw-justify-evenly tw-p-0 tw-border tw-border-black-20 tw-m-0 tw-bg-black-0 tw-rounded tw-font-sans tw-text-s tw-list-none tw-select-none\"\n >\n <motion.div\n aria-hidden=\"true\"\n // div border is not included in width so it must be subtracted from translation.\n animate={{ x: `calc(${100 * selectedIndex}% - ${2 * selectedIndex}px)` }}\n initial={false}\n transition={{ type: 'tween', duration: 0.3 }}\n style={{\n width: `${100 / items.length}%`,\n }}\n hidden={!activeItemId}\n className={merge([\n 'tw-absolute tw--inset-px tw-h-full tw-box-content tw-border tw-rounded tw-pointer-events-none',\n disabled\n ? 'tw-border-line-x-strong tw-border-opacity-30 tw-bg-black-0'\n : 'tw-border-black tw-bg-white',\n ])}\n />\n {itemElements}\n </ul>\n );\n};\n"],"names":["isIconItem","item","SliderItem","props","id","disabled","radioGroupState","ref","useRef","isActive","inputProps","useRadio","isFocusVisible","focusProps","useFocusRing","handleMockLabelClick","_a","setInteractionModality","getSliderItemTestId","React","merge","FOCUS_STYLE","VisuallyHidden","Slider","propId","items","activeItemId","onChange","ariaLabel","useMemoizedId","groupProps","useRadioGroupState","radioGroupProps","useRadioGroup","itemElements","useMemo","i","selectedIndex","motion"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import o, { useRef as K, useState as x, Children as L, isValidElement as A, useCallback as V, useEffect as T, cloneElement as U } from "react";
|
|
2
|
-
import { merge as
|
|
2
|
+
import { merge as g } from "../../utilities/merge.es.js";
|
|
3
3
|
import { motion as _ } from "framer-motion";
|
|
4
4
|
import { useFocusRing as z } from "@react-aria/focus";
|
|
5
5
|
import { FOCUS_VISIBLE_STYLE as W, FOCUS_STYLE as Y } from "../../utilities/focusStyle.es.js";
|
|
@@ -13,7 +13,7 @@ const I = {
|
|
|
13
13
|
Large: "tw-pl-l"
|
|
14
14
|
}, le = ({ paddingX: n, size: y, activeItemId: l, children: h, onChange: E }) => {
|
|
15
15
|
var O;
|
|
16
|
-
const C = H(), v = K(null), [k, $] = x(!1), [
|
|
16
|
+
const C = H(), v = K(null), [k, $] = x(!1), [u, m] = x(!1), p = (O = L.map(h, (e) => A(e) ? e == null ? void 0 : e.props : null)) != null ? O : [], [M, R] = x([0]), i = V(() => {
|
|
17
17
|
var t;
|
|
18
18
|
const e = v.current;
|
|
19
19
|
$((t = e && e.scrollWidth > e.clientWidth) != null ? t : !1);
|
|
@@ -26,9 +26,9 @@ const I = {
|
|
|
26
26
|
const s = [...r].sort((a, d) => a - d);
|
|
27
27
|
R(s);
|
|
28
28
|
}
|
|
29
|
-
}, []), b = () => M.map((e) =>
|
|
30
|
-
const r = b(), t = e.target, s = t.id.includes("-m"), a = t.id.replace("-btn-m", ""), d = s ? r :
|
|
31
|
-
(e.key === "ArrowRight" || e.key === "ArrowDown") && f.length > 0 && w(f[0].id, s), (e.key === "ArrowLeft" || e.key === "ArrowUp") && c.length > 0 && w(c[c.length - 1].id, s), e.key === "Enter" && s && (w(a, !0),
|
|
29
|
+
}, []), b = () => M.map((e) => p[e]), S = (e, r) => e.filter((t) => r === "next" && t.id > l && !t.disabled || r === "previous" && t.id < l && !t.disabled ? t : !1), N = (e) => {
|
|
30
|
+
const r = b(), t = e.target, s = t.id.includes("-m"), a = t.id.replace("-btn-m", ""), d = s ? r : p, f = S(d, "next"), c = S(d, "previous");
|
|
31
|
+
(e.key === "ArrowRight" || e.key === "ArrowDown") && f.length > 0 && w(f[0].id, s), (e.key === "ArrowLeft" || e.key === "ArrowUp") && c.length > 0 && w(c[c.length - 1].id, s), e.key === "Enter" && s && (w(a, !0), m(!1), document.getElementById(`${a}-content`).focus()), t.id.includes("-m") || m(!1);
|
|
32
32
|
}, w = (e, r) => {
|
|
33
33
|
try {
|
|
34
34
|
const t = document.getElementById(`${e}-btn`), s = document.getElementById(
|
|
@@ -41,11 +41,11 @@ const I = {
|
|
|
41
41
|
}, D = (e) => {
|
|
42
42
|
i();
|
|
43
43
|
const r = b();
|
|
44
|
-
if (e.key === "Enter" && !
|
|
44
|
+
if (e.key === "Enter" && !u && r.length > 0) {
|
|
45
45
|
const t = document.getElementById(`${r[0].id}-btn-m`);
|
|
46
46
|
t && t.focus();
|
|
47
47
|
}
|
|
48
|
-
|
|
48
|
+
u && (e.key === "ArrowRight" || e.key === "ArrowDown") && w(r[0].id, !0);
|
|
49
49
|
};
|
|
50
50
|
T(() => {
|
|
51
51
|
i();
|
|
@@ -59,12 +59,12 @@ const I = {
|
|
|
59
59
|
}, /* @__PURE__ */ o.createElement("div", {
|
|
60
60
|
ref: v,
|
|
61
61
|
role: "tablist",
|
|
62
|
-
className:
|
|
63
|
-
"tw-overflow-x-hidden tw-flex-shrink-0 tw-h-full tw-w-full tw-flex tw-justify-start tw-pr-8
|
|
62
|
+
className: g([
|
|
63
|
+
"tw-overflow-x-hidden tw-flex-shrink-0 tw-h-full tw-w-full tw-flex tw-justify-start tw-pr-8",
|
|
64
64
|
I[n != null ? n : "Small"],
|
|
65
65
|
y === "Small" ? "tw-gap-xxs" : "tw-gap-xs "
|
|
66
66
|
])
|
|
67
|
-
},
|
|
67
|
+
}, p.map((e) => /* @__PURE__ */ o.createElement("button", {
|
|
68
68
|
"data-test-id": "tab-item",
|
|
69
69
|
role: "tab",
|
|
70
70
|
type: "button",
|
|
@@ -73,16 +73,17 @@ const I = {
|
|
|
73
73
|
"aria-hidden": e.disabled,
|
|
74
74
|
tabIndex: e.id === l ? 0 : -1,
|
|
75
75
|
id: `${e.id}-btn`,
|
|
76
|
-
className:
|
|
76
|
+
className: g([
|
|
77
77
|
"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",
|
|
78
78
|
W,
|
|
79
|
+
"tw-ring-inset",
|
|
79
80
|
e.disabled && "tw-text-text-disabled",
|
|
80
81
|
e.id === l ? "tw-font-medium tw-text-text" : "tw-text-text-weak",
|
|
81
82
|
y === "Small" ? "tw-text-sm" : "tw-text-md"
|
|
82
83
|
]),
|
|
83
84
|
key: e.id,
|
|
84
85
|
onClick: () => {
|
|
85
|
-
e.disabled || (w(e.id, !1),
|
|
86
|
+
e.disabled || (w(e.id, !1), m(!1));
|
|
86
87
|
},
|
|
87
88
|
onKeyDown: (r) => N(r)
|
|
88
89
|
}, e.decorator && /* @__PURE__ */ o.createElement("span", {
|
|
@@ -102,36 +103,36 @@ const I = {
|
|
|
102
103
|
"data-test-id": "tab-overflow",
|
|
103
104
|
className: "tw-absolute tw-right-3 tw-bottom-0 tw-top-0 tw-flex tw-justify-center tw-items-center"
|
|
104
105
|
}, /* @__PURE__ */ o.createElement("button", {
|
|
105
|
-
className:
|
|
106
|
+
className: g([
|
|
106
107
|
"tw-w-6 tw-h-6 tw-bg-box-neutral tw-rounded tw-flex tw-justify-center tw-items-center",
|
|
107
108
|
F ? Y : ""
|
|
108
109
|
]),
|
|
109
110
|
type: "button",
|
|
110
111
|
onClick: () => {
|
|
111
|
-
i(),
|
|
112
|
+
i(), m(!u);
|
|
112
113
|
},
|
|
113
114
|
onKeyDown: (e) => D(e),
|
|
114
115
|
...j
|
|
115
|
-
}, /* @__PURE__ */ o.createElement(P, null)),
|
|
116
|
+
}, /* @__PURE__ */ o.createElement(P, null)), u && /* @__PURE__ */ o.createElement("div", {
|
|
116
117
|
className: "tw-absolute tw-right-0 tw-top-11 tw-px-3 tw-pt-3 tw-bg-base tw-shadow tw-w-max",
|
|
117
118
|
role: "dialog"
|
|
118
119
|
}, b().map((e) => {
|
|
119
120
|
var r, t;
|
|
120
121
|
return /* @__PURE__ */ o.createElement("button", {
|
|
121
|
-
className:
|
|
122
|
+
className: g([
|
|
122
123
|
"tw-flex tw-items-center tw-w-full tw-mb-3 tw-text-left tw-text-text-weak",
|
|
123
124
|
e.disabled && "tw-text-text-disabled"
|
|
124
125
|
]),
|
|
125
126
|
key: e.id,
|
|
126
127
|
onClick: () => {
|
|
127
|
-
e.disabled || (w(e.id, !0),
|
|
128
|
+
e.disabled || (w(e.id, !0), m(!1));
|
|
128
129
|
},
|
|
129
130
|
role: "tab",
|
|
130
131
|
type: "button",
|
|
131
132
|
"aria-selected": e.id === l,
|
|
132
133
|
"aria-controls": `${e.id}-content`,
|
|
133
134
|
"aria-hidden": e.disabled,
|
|
134
|
-
tabIndex: !e.disabled &&
|
|
135
|
+
tabIndex: !e.disabled && u ? 0 : -1,
|
|
135
136
|
id: `${e.id}-btn-m`,
|
|
136
137
|
onKeyDown: (s) => N(s)
|
|
137
138
|
}, e.decorator, /* @__PURE__ */ o.createElement("span", {
|
|
@@ -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 FC,\n KeyboardEvent,\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';\nimport { Badge } from '@components/Badge';\nimport { motion } from 'framer-motion';\nimport { useFocusRing } from '@react-aria/focus';\nimport { FOCUS_STYLE, FOCUS_VISIBLE_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: FC<TabsProps> = ({ paddingX, size, activeItemId, children, onChange }) => {\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 return array.filter((tab) => {\n if (direction === 'next') {\n if (tab.id > activeItemId && !tab.disabled) {\n return tab;\n }\n }\n\n if (direction === 'previous') {\n if (tab.id < activeItemId && !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 tw-py-2 tw--my-2',\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 FOCUS_VISIBLE_STYLE,\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};\n"],"names":["TabsPaddingX","TabSize","paddingMap","Tabs","paddingX","size","activeItemId","children","onChange","groupId","useMemoizedId","tabNavRef","useRef","isOverflowing","setIsOverflowing","useState","isMenuOpened","setIsMenuOpened","tabs","_a","Children","child","isValidElement","overflowArray","setOverflowArray","checkIfOverflowing","useCallback","tabNav","overFlowIndex","tabItem","i","navPosition","tabPosition","overFlowIndexInAscOrder","b","getOverflownTabs","filterTabList","array","direction","tab","handleKeyboardTabChange","event","overflownTabs","target","fromOverflow","currentTabId","currentTabsArray","nextTabs","previousTabs","triggerTabButton","elementId","tabElement","buttonElement","error","triggerOverflowMenu","useEffect","isFocusVisible","focusProps","useFocusRing","React","merge","FOCUS_VISIBLE_STYLE","Badge","motion","FOCUS_STYLE","IconDotsHorizontal","_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 FC,\n KeyboardEvent,\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';\nimport { Badge } from '@components/Badge';\nimport { motion } from 'framer-motion';\nimport { useFocusRing } from '@react-aria/focus';\nimport { FOCUS_STYLE, FOCUS_VISIBLE_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: FC<TabsProps> = ({ paddingX, size, activeItemId, children, onChange }) => {\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 return array.filter((tab) => {\n if (direction === 'next') {\n if (tab.id > activeItemId && !tab.disabled) {\n return tab;\n }\n }\n\n if (direction === 'previous') {\n if (tab.id < activeItemId && !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 FOCUS_VISIBLE_STYLE,\n 'tw-ring-inset',\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};\n"],"names":["TabsPaddingX","TabSize","paddingMap","Tabs","paddingX","size","activeItemId","children","onChange","groupId","useMemoizedId","tabNavRef","useRef","isOverflowing","setIsOverflowing","useState","isMenuOpened","setIsMenuOpened","tabs","_a","Children","child","isValidElement","overflowArray","setOverflowArray","checkIfOverflowing","useCallback","tabNav","overFlowIndex","tabItem","i","navPosition","tabPosition","overFlowIndexInAscOrder","b","getOverflownTabs","filterTabList","array","direction","tab","handleKeyboardTabChange","event","overflownTabs","target","fromOverflow","currentTabId","currentTabsArray","nextTabs","previousTabs","triggerTabButton","elementId","tabElement","buttonElement","error","triggerOverflowMenu","useEffect","isFocusVisible","focusProps","useFocusRing","React","merge","FOCUS_VISIBLE_STYLE","Badge","motion","FOCUS_STYLE","IconDotsHorizontal","_b","cloneElement"],"mappings":"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"}
|