@clubmed/trident-ui 2.0.0-beta.65 → 2.0.0-beta.66
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/package.json +1 -1
- package/styles/index.css +0 -1
- package/styles/ui/tabs.css +0 -19
- package/ui/tabs/Tabs.js +88 -78
- package/ui/tabs/Tabs.js.map +1 -1
package/package.json
CHANGED
package/styles/index.css
CHANGED
package/styles/ui/tabs.css
CHANGED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
@layer components {
|
|
2
|
-
.tab-focus-pill {
|
|
3
|
-
transform: translateX(
|
|
4
|
-
calc(
|
|
5
|
-
var(--tab-index, 0) * -100% + var(--active-tab, 0) * 100% -
|
|
6
|
-
(var(--spacing) * 4 * (var(--tab-index) - var(--active-tab, 0)))
|
|
7
|
-
)
|
|
8
|
-
);
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
[dir='rtl'] .tab-focus-pill {
|
|
12
|
-
transform: translateX(
|
|
13
|
-
calc(
|
|
14
|
-
var(--tab-index) * 100% + var(--active-tab) * -100% +
|
|
15
|
-
(var(--spacing) * 4 * (var(--tab-index) - var(--active-tab)))
|
|
16
|
-
)
|
|
17
|
-
);
|
|
18
|
-
}
|
|
19
|
-
}
|
package/ui/tabs/Tabs.js
CHANGED
|
@@ -5,22 +5,22 @@ import { TabsProvider as n } from "../contexts/TabControl.js";
|
|
|
5
5
|
import { useActiveTab as r, useActiveTabControl as i, useRegisterTabControl as a, useTabDispatch as o, useTabsUid as s } from "../hooks/tabControl.js";
|
|
6
6
|
import { useKeyboardControls as c } from "../hooks/useKeyboardControls.js";
|
|
7
7
|
import { cn as l } from "../helpers/cn.js";
|
|
8
|
-
import { useCallback as u, useEffect as d,
|
|
9
|
-
import { jsx as
|
|
8
|
+
import { useCallback as u, useEffect as d, useMemo as f, useRef as p, useState as m } from "react";
|
|
9
|
+
import { jsx as h, jsxs as g } from "react/jsx-runtime";
|
|
10
10
|
//#region lib/ui/tabs/Tabs.tsx
|
|
11
|
-
var
|
|
11
|
+
var _ = ({ className: e, compacted: t = !1, selected: r, children: i }) => /* @__PURE__ */ h("div", {
|
|
12
12
|
className: l("flex flex-col", { "sm:gap-y-20": !t }, e),
|
|
13
13
|
"data-name": "Tabs",
|
|
14
|
-
children: /* @__PURE__ */
|
|
14
|
+
children: /* @__PURE__ */ h(n, {
|
|
15
15
|
selected: r,
|
|
16
16
|
children: i
|
|
17
17
|
})
|
|
18
|
-
}),
|
|
18
|
+
}), v = ({ className: e, children: t }) => /* @__PURE__ */ h("div", {
|
|
19
19
|
"data-name": "TabsBody",
|
|
20
20
|
className: l("grid grid-rows-1 overflow-hidden", e),
|
|
21
21
|
children: t
|
|
22
|
-
}),
|
|
23
|
-
let o = s(), c =
|
|
22
|
+
}), y = ({ value: e, className: t, onSelect: n, children: i, ...a }) => {
|
|
23
|
+
let o = s(), c = p(!1), u = r() === e;
|
|
24
24
|
return d(() => {
|
|
25
25
|
if (!c.current) {
|
|
26
26
|
c.current = !0;
|
|
@@ -31,7 +31,7 @@ var g = ({ className: e, compacted: t = !1, selected: r, children: i }) => /* @_
|
|
|
31
31
|
u,
|
|
32
32
|
e,
|
|
33
33
|
n
|
|
34
|
-
]), /* @__PURE__ */
|
|
34
|
+
]), /* @__PURE__ */ h("div", {
|
|
35
35
|
...a,
|
|
36
36
|
"aria-hidden": !u,
|
|
37
37
|
className: l("relative col-start-1 row-start-1 transition-opacity duration-500", {
|
|
@@ -46,20 +46,27 @@ var g = ({ className: e, compacted: t = !1, selected: r, children: i }) => /* @_
|
|
|
46
46
|
"aria-labelledby": `Tab_${e}_${o}`,
|
|
47
47
|
children: i
|
|
48
48
|
});
|
|
49
|
-
},
|
|
50
|
-
let a =
|
|
49
|
+
}, b = ({ className: t, constrained: n = !1, children: r }) => {
|
|
50
|
+
let a = p(null), o = p(null), [, c] = i(), _ = s(), [v, y] = m(!1), [b, x] = m(!1), S = `--tab-pill-${_}`, C = f(() => ({
|
|
51
|
+
positionAnchor: S,
|
|
52
|
+
top: "anchor(top)",
|
|
53
|
+
bottom: "anchor(bottom)",
|
|
54
|
+
left: "anchor(left)",
|
|
55
|
+
right: "anchor(right)",
|
|
56
|
+
position: "absolute"
|
|
57
|
+
}), [S]), w = u(() => {
|
|
51
58
|
let e = a.current;
|
|
52
|
-
e && (
|
|
59
|
+
e && (y(e.scrollLeft > 0), x(Math.ceil(e.scrollLeft) < e.scrollWidth - e.clientWidth));
|
|
53
60
|
}, []);
|
|
54
61
|
d(() => {
|
|
55
62
|
let e = a.current;
|
|
56
63
|
if (!e) return;
|
|
57
|
-
|
|
58
|
-
let t = new ResizeObserver(
|
|
59
|
-
return t.observe(e), e.addEventListener("scroll",
|
|
60
|
-
t.disconnect(), e.removeEventListener("scroll",
|
|
64
|
+
w();
|
|
65
|
+
let t = new ResizeObserver(w);
|
|
66
|
+
return t.observe(e), e.addEventListener("scroll", w, { passive: !0 }), () => {
|
|
67
|
+
t.disconnect(), e.removeEventListener("scroll", w);
|
|
61
68
|
};
|
|
62
|
-
}, [
|
|
69
|
+
}, [w]), d(() => {
|
|
63
70
|
if (!c?.current || !a.current) return;
|
|
64
71
|
let e = o.current.offsetWidth ?? 0, t = c.current.getBoundingClientRect(), n = a.current.getBoundingClientRect();
|
|
65
72
|
a.current.scrollBy({
|
|
@@ -67,81 +74,85 @@ var g = ({ className: e, compacted: t = !1, selected: r, children: i }) => /* @_
|
|
|
67
74
|
behavior: "smooth"
|
|
68
75
|
});
|
|
69
76
|
}, [c]);
|
|
70
|
-
let
|
|
71
|
-
|
|
72
|
-
}, []),
|
|
73
|
-
if (
|
|
77
|
+
let T = p(null), E = u(() => {
|
|
78
|
+
T.current !== null && (cancelAnimationFrame(T.current), T.current = null);
|
|
79
|
+
}, []), D = u((e) => {
|
|
80
|
+
if (T.current !== null) return;
|
|
74
81
|
let t = () => {
|
|
75
|
-
a.current?.scrollBy({ left: e * 6 }),
|
|
82
|
+
a.current?.scrollBy({ left: e * 6 }), T.current = requestAnimationFrame(t);
|
|
76
83
|
};
|
|
77
|
-
|
|
78
|
-
}, []),
|
|
79
|
-
(e.key === " " || e.key === "Enter") &&
|
|
80
|
-
}, [
|
|
81
|
-
(e.key === " " || e.key === "Enter") && (e.preventDefault(),
|
|
82
|
-
}, [
|
|
83
|
-
(e.key === " " || e.key === "Enter") && (e.preventDefault(),
|
|
84
|
-
}, [
|
|
85
|
-
d(() =>
|
|
86
|
-
let
|
|
87
|
-
return /* @__PURE__ */
|
|
84
|
+
T.current = requestAnimationFrame(t);
|
|
85
|
+
}, []), O = u((e) => {
|
|
86
|
+
(e.key === " " || e.key === "Enter") && E();
|
|
87
|
+
}, [E]), k = u((e) => {
|
|
88
|
+
(e.key === " " || e.key === "Enter") && (e.preventDefault(), D(-1));
|
|
89
|
+
}, [D]), A = u((e) => {
|
|
90
|
+
(e.key === " " || e.key === "Enter") && (e.preventDefault(), D(1));
|
|
91
|
+
}, [D]);
|
|
92
|
+
d(() => E, [E]);
|
|
93
|
+
let j = v || b;
|
|
94
|
+
return /* @__PURE__ */ g("div", {
|
|
88
95
|
className: "relative",
|
|
89
96
|
"data-name": "TabsHeader",
|
|
90
97
|
children: [
|
|
91
|
-
|
|
98
|
+
j && /* @__PURE__ */ h("div", {
|
|
92
99
|
className: "pointer-events-none absolute inset-y-0 left-0 z-10 flex items-center",
|
|
93
|
-
children: /* @__PURE__ */
|
|
100
|
+
children: /* @__PURE__ */ h(e, {
|
|
94
101
|
icon: "ArrowDefaultLeft",
|
|
95
102
|
size: "small",
|
|
96
|
-
className: l("pointer-events-auto transition-opacity duration-200 focus-visible:ring-
|
|
97
|
-
onMouseDown: () =>
|
|
98
|
-
onMouseUp:
|
|
99
|
-
onMouseLeave:
|
|
100
|
-
onKeyDown:
|
|
101
|
-
onKeyUp:
|
|
102
|
-
inert: !
|
|
103
|
-
tabIndex:
|
|
103
|
+
className: l("pointer-events-auto transition-opacity duration-200 focus-visible:ring-4 focus-visible:ring-black focus-visible:ring-offset-2", v ? "opacity-100" : "pointer-events-none opacity-0"),
|
|
104
|
+
onMouseDown: () => D(-1),
|
|
105
|
+
onMouseUp: E,
|
|
106
|
+
onMouseLeave: E,
|
|
107
|
+
onKeyDown: k,
|
|
108
|
+
onKeyUp: O,
|
|
109
|
+
inert: !v,
|
|
110
|
+
tabIndex: v ? 0 : -1,
|
|
104
111
|
children: "Scroll tabs left"
|
|
105
112
|
})
|
|
106
113
|
}),
|
|
107
|
-
/* @__PURE__ */
|
|
114
|
+
/* @__PURE__ */ h("div", {
|
|
108
115
|
className: l("scrollbar-hidden relative isolate flex max-w-full overflow-x-auto py-20", t),
|
|
109
116
|
ref: a,
|
|
110
|
-
children: /* @__PURE__ */
|
|
117
|
+
children: /* @__PURE__ */ g("div", {
|
|
111
118
|
role: "tablist",
|
|
112
|
-
className: "flex flex-row",
|
|
113
|
-
style: D,
|
|
119
|
+
className: "relative flex flex-row",
|
|
114
120
|
children: [
|
|
115
|
-
/* @__PURE__ */
|
|
121
|
+
/* @__PURE__ */ h("span", {
|
|
122
|
+
"aria-hidden": "true",
|
|
123
|
+
className: "pointer-events-none absolute rounded-pill bg-black transition-all duration-300",
|
|
124
|
+
style: C
|
|
125
|
+
}),
|
|
126
|
+
/* @__PURE__ */ h("div", {
|
|
116
127
|
ref: o,
|
|
117
128
|
className: l("shrink-0", { "w-16 lg:w-[max(calc((100vw-1212px)/2),116px)] xl:w-[max(calc((100vw-1212px)/2),156px)]": !n })
|
|
118
129
|
}),
|
|
119
130
|
r,
|
|
120
|
-
/* @__PURE__ */
|
|
131
|
+
/* @__PURE__ */ h("div", { className: l("shrink-0", { "w-16 lg:w-[max(calc((100vw-1212px)/2),116px)] xl:w-[max(calc((100vw-1212px)/2),156px)]": !n }) })
|
|
121
132
|
]
|
|
122
133
|
})
|
|
123
134
|
}),
|
|
124
|
-
|
|
135
|
+
j && /* @__PURE__ */ h("div", {
|
|
125
136
|
className: "pointer-events-none absolute inset-y-0 right-0 z-10 flex items-center",
|
|
126
|
-
children: /* @__PURE__ */
|
|
137
|
+
children: /* @__PURE__ */ h(e, {
|
|
127
138
|
icon: "ArrowDefaultRight",
|
|
128
139
|
size: "small",
|
|
129
|
-
className: l("pointer-events-auto transition-opacity duration-200 focus-visible:ring-
|
|
130
|
-
onMouseDown: () =>
|
|
131
|
-
onMouseUp:
|
|
132
|
-
onMouseLeave:
|
|
133
|
-
onKeyDown:
|
|
134
|
-
onKeyUp:
|
|
135
|
-
inert: !
|
|
136
|
-
tabIndex:
|
|
140
|
+
className: l("pointer-events-auto transition-opacity duration-200 focus-visible:ring-4 focus-visible:ring-black focus-visible:ring-offset-2", b ? "opacity-100" : "pointer-events-none opacity-0"),
|
|
141
|
+
onMouseDown: () => D(1),
|
|
142
|
+
onMouseUp: E,
|
|
143
|
+
onMouseLeave: E,
|
|
144
|
+
onKeyDown: A,
|
|
145
|
+
onKeyUp: O,
|
|
146
|
+
inert: !b,
|
|
147
|
+
tabIndex: b ? 0 : -1,
|
|
137
148
|
children: "Scroll tabs right"
|
|
138
149
|
})
|
|
139
150
|
})
|
|
140
151
|
]
|
|
141
152
|
});
|
|
142
|
-
},
|
|
153
|
+
}, x = ({ items: e, className: n, "aria-label": i = "Select tab" }) => {
|
|
143
154
|
let a = r(), s = o();
|
|
144
|
-
return /* @__PURE__ */
|
|
155
|
+
return /* @__PURE__ */ h(t, {
|
|
145
156
|
value: (a === -1 ? void 0 : a)?.toString(),
|
|
146
157
|
onChange: (e, t) => {
|
|
147
158
|
s({
|
|
@@ -151,18 +162,18 @@ var g = ({ className: e, compacted: t = !1, selected: r, children: i }) => /* @_
|
|
|
151
162
|
},
|
|
152
163
|
name: i,
|
|
153
164
|
className: l(n),
|
|
154
|
-
children: e.map((e) => /* @__PURE__ */
|
|
165
|
+
children: e.map((e) => /* @__PURE__ */ h("option", {
|
|
155
166
|
value: e.value,
|
|
156
167
|
children: e.label
|
|
157
168
|
}, e.value))
|
|
158
169
|
});
|
|
159
|
-
},
|
|
160
|
-
let v =
|
|
170
|
+
}, S = ({ as: e = "h2", label: t, children: n, value: i, onSelect: o, className: f, notification: m, ..._ }) => {
|
|
171
|
+
let v = p(null), y = r(), b = s(), x = a({
|
|
161
172
|
value: i,
|
|
162
173
|
ref: v
|
|
163
|
-
}), S =
|
|
174
|
+
}), S = p(y), C = p(y === i);
|
|
164
175
|
C.current = y === i;
|
|
165
|
-
let w =
|
|
176
|
+
let w = `--tab-pill-${b}`;
|
|
166
177
|
d(() => {
|
|
167
178
|
S.current !== y && i === y && (v.current?.focus(), o?.({
|
|
168
179
|
value: i,
|
|
@@ -206,7 +217,7 @@ var g = ({ className: e, compacted: t = !1, selected: r, children: i }) => /* @_
|
|
|
206
217
|
payload: i
|
|
207
218
|
});
|
|
208
219
|
};
|
|
209
|
-
return /* @__PURE__ */
|
|
220
|
+
return /* @__PURE__ */ h("div", {
|
|
210
221
|
..._,
|
|
211
222
|
id: _.id || `Tab_${i}_${b}`,
|
|
212
223
|
"data-name": "Tab",
|
|
@@ -215,30 +226,29 @@ var g = ({ className: e, compacted: t = !1, selected: r, children: i }) => /* @_
|
|
|
215
226
|
"aria-selected": C.current,
|
|
216
227
|
"aria-controls": `TabPanel_${i}_${b}`,
|
|
217
228
|
tabIndex: C.current ? 0 : -1,
|
|
218
|
-
className: l("group/tab text-b3 inline-block cursor-pointer overflow-hidden bg-transparent
|
|
229
|
+
className: l("group/tab text-b3 inline-block cursor-pointer overflow-hidden bg-transparent align-middle font-semibold whitespace-nowrap outline-none focus-visible:ring-4 focus-visible:ring-black focus-visible:ring-offset-2 rounded-pill", {
|
|
219
230
|
"text-white": C.current,
|
|
220
231
|
"text-black": !C.current,
|
|
221
|
-
"transition-transform active:scale-[1.03]": C.current
|
|
232
|
+
"transition-transform active:scale-[1.03]": C.current,
|
|
233
|
+
"[@supports(not(anchor-name:--x))]:bg-black": C.current
|
|
222
234
|
}),
|
|
223
235
|
onKeyDown: E,
|
|
224
236
|
onClick: D,
|
|
225
237
|
children: /* @__PURE__ */ h(e, {
|
|
226
|
-
className: l("relative inline-block px-20 py-12", "before:rounded-pill before:transition-colors/opacity before:absolute before:inset-0 before:-z-1 before:duration-300 group-focus-within/tab:before:bg-(--color-pearl) group-hover/tab:before:bg-(--color-pearl) group/tab-focus:before:bg-(--color-pearl)",
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
style: w
|
|
231
|
-
}), /* @__PURE__ */ h("span", {
|
|
238
|
+
className: l("relative inline-block px-20 py-12", !C.current && "before:rounded-pill before:transition-colors/opacity before:absolute before:inset-0 before:-z-1 before:duration-300 group-focus-within/tab:before:bg-(--color-pearl) group-hover/tab:before:bg-(--color-pearl) group/tab-focus:before:bg-(--color-pearl)", f),
|
|
239
|
+
style: C.current ? { anchorName: w } : void 0,
|
|
240
|
+
...C.current ? {} : { role: "presentation" },
|
|
241
|
+
children: /* @__PURE__ */ g("span", {
|
|
232
242
|
className: "flex items-center gap-8",
|
|
233
|
-
children: [n ?? t,
|
|
243
|
+
children: [n ?? t, m && /* @__PURE__ */ h("div", {
|
|
234
244
|
className: l("size-18 flex items-center justify-center text-b5 rounded-full bg-saffron text-black transition-colors duration-300", { "group-focus-within/tab:bg-darkGrey group-hover/tab:bg-darkGrey group-focus-within/tab:text-pearl group-hover/tab:text-pearl": !C.current }),
|
|
235
|
-
children:
|
|
245
|
+
children: m
|
|
236
246
|
})]
|
|
237
|
-
})
|
|
247
|
+
})
|
|
238
248
|
})
|
|
239
249
|
});
|
|
240
250
|
};
|
|
241
251
|
//#endregion
|
|
242
|
-
export {
|
|
252
|
+
export { S as Tab, b as TabList, y as TabPanel, x as TabSelect, _ as Tabs, v as TabsBody };
|
|
243
253
|
|
|
244
254
|
//# sourceMappingURL=Tabs.js.map
|
package/ui/tabs/Tabs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tabs.js","names":[],"sources":["../../../lib/ui/tabs/Tabs.tsx"],"sourcesContent":["'use client';\n\nimport {\n type ComponentProps,\n type ComponentPropsWithoutRef,\n type CSSProperties,\n type FunctionComponent,\n type PropsWithChildren,\n type RefObject,\n type KeyboardEvent,\n type ReactNode,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\n\nimport { TabsProvider } from '../contexts/TabControl';\nimport {\n useActiveTab,\n useActiveTabControl,\n useRegisterTabControl,\n useTabDispatch,\n useTabsUid,\n} from '../hooks/tabControl';\nimport { useKeyboardControls } from '../hooks/useKeyboardControls';\nimport { Select } from '../forms/Select';\nimport { cn } from '../helpers/cn';\nimport { ArrowButton } from '../buttons/ArrowButton';\n\ntype ProviderProps = ComponentProps<typeof TabsProvider>;\n\ninterface Props extends ProviderProps {\n className?: string;\n /**\n * Shrink the spacing between tabs and panels\n */\n compacted?: boolean;\n}\n\nexport const Tabs: FunctionComponent<PropsWithChildren<Props>> = ({\n className,\n compacted = false,\n selected,\n children,\n}) => {\n return (\n <div\n className={cn(\n 'flex flex-col',\n {\n 'sm:gap-y-20': !compacted,\n },\n className,\n )}\n data-name=\"Tabs\"\n >\n <TabsProvider selected={selected}>{children}</TabsProvider>\n </div>\n );\n};\n\ninterface TabsBodyProps {\n className?: string;\n}\n\nexport const TabsBody: FunctionComponent<PropsWithChildren<TabsBodyProps>> = ({\n className,\n children,\n}) => {\n return (\n <div data-name=\"TabsBody\" className={cn('grid grid-rows-1 overflow-hidden', className)}>\n {children}\n </div>\n );\n};\n\ninterface TabPanelProps {\n className?: string;\n /**\n * Tab panel index<br/>\n * _Can be **0** or **1** indexed_\n */\n value: number;\n /**\n * on panel select handler\n */\n onSelect?: (context: { value: TabPanelProps['value'] }) => void;\n}\n\nexport const TabPanel: FunctionComponent<PropsWithChildren<TabPanelProps>> = ({\n value,\n className,\n onSelect,\n children,\n ...attrs\n}) => {\n const uid = useTabsUid();\n const mounted = useRef(false);\n const tabSelected = useActiveTab();\n const isActive = tabSelected === value;\n\n useEffect(() => {\n if (!mounted.current) {\n mounted.current = true;\n return;\n }\n\n if (isActive) {\n onSelect?.({ value });\n }\n }, [isActive, value, onSelect]);\n\n return (\n <div\n {...attrs}\n aria-hidden={!isActive}\n className={cn(\n 'relative col-start-1 row-start-1 transition-opacity duration-500',\n {\n 'pointer-events-none z-0 h-0 opacity-0': !isActive,\n 'pointer-events-auto z-1 h-auto opacity-100': isActive,\n },\n className,\n )}\n inert={isActive ? undefined : true}\n tabIndex={isActive ? 0 : -1}\n id={`TabPanel_${value}_${uid}`}\n data-name={`TabPanel_${value}`}\n role=\"tabpanel\"\n aria-labelledby={`Tab_${value}_${uid}`}\n >\n {children}\n </div>\n );\n};\n\ninterface TabListProps {\n className?: string;\n /**\n * Remove filler placeholders\n */\n constrained?: boolean;\n}\n\nexport const TabList: FunctionComponent<PropsWithChildren<TabListProps>> = ({\n className,\n constrained = false,\n children,\n}) => {\n const ref = useRef<HTMLDivElement>(null);\n const spacerRef = useRef<HTMLDivElement>(null);\n const [currentTab, currentControl] = useActiveTabControl();\n const [canScrollLeft, setCanScrollLeft] = useState(false);\n const [canScrollRight, setCanScrollRight] = useState(false);\n\n const updateScrollState = useCallback(() => {\n const el = ref.current;\n if (!el) return;\n setCanScrollLeft(el.scrollLeft > 0);\n setCanScrollRight(Math.ceil(el.scrollLeft) < el.scrollWidth - el.clientWidth);\n }, []);\n\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n\n updateScrollState();\n\n const observer = new ResizeObserver(updateScrollState);\n observer.observe(el);\n el.addEventListener('scroll', updateScrollState, { passive: true });\n\n return () => {\n observer.disconnect();\n el.removeEventListener('scroll', updateScrollState);\n };\n }, [updateScrollState]);\n\n useEffect(() => {\n if (!currentControl?.current || !ref.current) {\n return;\n }\n\n const spacerWidth = spacerRef.current!.offsetWidth ?? 0;\n const currentRect = currentControl.current.getBoundingClientRect();\n const containerRect = ref.current!.getBoundingClientRect();\n\n ref.current.scrollBy({\n left: currentRect.left - containerRect.left - spacerWidth,\n behavior: 'smooth',\n });\n }, [currentControl]);\n\n const scrollRafRef = useRef<number | null>(null);\n\n const stopScroll = useCallback(() => {\n if (scrollRafRef.current !== null) {\n cancelAnimationFrame(scrollRafRef.current);\n scrollRafRef.current = null;\n }\n }, []);\n\n const startScroll = useCallback((direction: -1 | 1) => {\n if (scrollRafRef.current !== null) return;\n const step = () => {\n ref.current?.scrollBy({ left: direction * 6 });\n scrollRafRef.current = requestAnimationFrame(step);\n };\n scrollRafRef.current = requestAnimationFrame(step);\n }, []);\n\n const handleScrollKeyUp = useCallback(\n (e: KeyboardEvent<HTMLButtonElement>) => {\n if (e.key === ' ' || e.key === 'Enter') stopScroll();\n },\n [stopScroll],\n );\n\n const handleScrollLeftKeyDown = useCallback(\n (e: KeyboardEvent<HTMLButtonElement>) => {\n if (e.key === ' ' || e.key === 'Enter') {\n e.preventDefault();\n startScroll(-1);\n }\n },\n [startScroll],\n );\n\n const handleScrollRightKeyDown = useCallback(\n (e: KeyboardEvent<HTMLButtonElement>) => {\n if (e.key === ' ' || e.key === 'Enter') {\n e.preventDefault();\n startScroll(1);\n }\n },\n [startScroll],\n );\n\n useEffect(() => stopScroll, [stopScroll]);\n\n const style = { '--active-tab': currentTab } as CSSProperties;\n const isScrollable = canScrollLeft || canScrollRight;\n\n return (\n <div className=\"relative\" data-name=\"TabsHeader\">\n {isScrollable && (\n <div className=\"pointer-events-none absolute inset-y-0 left-0 z-10 flex items-center\">\n <ArrowButton\n icon=\"ArrowDefaultLeft\"\n size=\"small\"\n className={cn(\n 'pointer-events-auto transition-opacity duration-200 focus-visible:ring-8 focus-visible:ring-lavender/20',\n canScrollLeft ? 'opacity-100' : 'pointer-events-none opacity-0',\n )}\n onMouseDown={() => startScroll(-1)}\n onMouseUp={stopScroll}\n onMouseLeave={stopScroll}\n onKeyDown={handleScrollLeftKeyDown}\n onKeyUp={handleScrollKeyUp}\n inert={!canScrollLeft}\n tabIndex={canScrollLeft ? 0 : -1}\n >\n Scroll tabs left\n </ArrowButton>\n </div>\n )}\n <div\n className={cn(\n 'scrollbar-hidden relative isolate flex max-w-full overflow-x-auto py-20',\n className,\n )}\n ref={ref}\n >\n <div role=\"tablist\" className=\"flex flex-row\" style={style}>\n <div\n ref={spacerRef}\n className={cn('shrink-0', {\n 'w-16 lg:w-[max(calc((100vw-1212px)/2),116px)] xl:w-[max(calc((100vw-1212px)/2),156px)]':\n !constrained,\n })}\n />\n {children}\n <div\n className={cn('shrink-0', {\n 'w-16 lg:w-[max(calc((100vw-1212px)/2),116px)] xl:w-[max(calc((100vw-1212px)/2),156px)]':\n !constrained,\n })}\n />\n </div>\n </div>\n {isScrollable && (\n <div className=\"pointer-events-none absolute inset-y-0 right-0 z-10 flex items-center\">\n <ArrowButton\n icon=\"ArrowDefaultRight\"\n size=\"small\"\n className={cn(\n 'pointer-events-auto transition-opacity duration-200 focus-visible:ring-8 focus-visible:ring-lavender/20',\n canScrollRight ? 'opacity-100' : 'pointer-events-none opacity-0',\n )}\n onMouseDown={() => startScroll(1)}\n onMouseUp={stopScroll}\n onMouseLeave={stopScroll}\n onKeyDown={handleScrollRightKeyDown}\n onKeyUp={handleScrollKeyUp}\n inert={!canScrollRight}\n tabIndex={canScrollRight ? 0 : -1}\n >\n Scroll tabs right\n </ArrowButton>\n </div>\n )}\n </div>\n );\n};\n\nexport interface TabSelectProps {\n items: { label: string; value: number }[];\n className?: string;\n 'aria-label'?: string;\n}\n\nexport const TabSelect: FunctionComponent<TabSelectProps> = ({\n items,\n className,\n 'aria-label': ariaLabel = 'Select tab',\n}) => {\n const activeTab = useActiveTab();\n const dispatch = useTabDispatch();\n\n const handleChange = (_event: Event, value: string) => {\n dispatch({ type: 'update', payload: Number(value) });\n };\n\n const selectValue = activeTab === -1 ? undefined : activeTab;\n\n return (\n <Select\n value={selectValue?.toString()}\n onChange={handleChange}\n name={ariaLabel}\n className={cn(className)}\n >\n {items.map((item) => (\n <option key={item.value} value={item.value}>\n {item.label}\n </option>\n ))}\n </Select>\n );\n};\n\ninterface TabProps extends Omit<ComponentPropsWithoutRef<'div'>, 'onSelect'> {\n /**\n * Notification content\n */\n notification?: ReactNode;\n /**\n * Tab Heading text\n */\n label?: string;\n /**\n * Tab heading index<br/>\n * _Can be **0** or **1** indexed_\n */\n value: number;\n /**\n * on tab select handler\n */\n onSelect?: (context: { value: TabProps['value']; label: TabProps['label'] }) => void;\n /**\n * Heading type\n * _default: **h2**_\n */\n as?: 'div' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5';\n}\n\nexport const Tab: FunctionComponent<PropsWithChildren<TabProps>> = ({\n as: TagName = 'h2',\n label,\n children,\n value,\n onSelect,\n className,\n notification,\n ...attr\n}) => {\n const ref = useRef<HTMLDivElement>(null);\n const activeTab = useActiveTab();\n const uid = useTabsUid();\n const dispatch = useRegisterTabControl({ value, ref: ref as RefObject<HTMLDivElement> });\n const previousActiveTab = useRef(activeTab);\n\n const isActive = useRef(activeTab === value);\n isActive.current = activeTab === value;\n\n const pillStyle = { '--tab-index': value } as CSSProperties;\n\n useEffect(() => {\n if (previousActiveTab.current !== activeTab && value === activeTab) {\n ref.current?.focus();\n onSelect?.({ value, label });\n }\n if (previousActiveTab.current !== activeTab) {\n previousActiveTab.current = activeTab;\n }\n }, [label, value, onSelect, activeTab]);\n\n const start = useCallback(() => {\n dispatch({ type: 'start' });\n }, [dispatch]);\n\n const end = useCallback(() => {\n dispatch({ type: 'end' });\n }, [dispatch]);\n\n const up = useCallback(() => {\n dispatch({ type: 'previous' });\n }, [dispatch]);\n\n const down = useCallback(() => {\n dispatch({ type: 'next' });\n }, [dispatch]);\n\n const left = useCallback(() => {\n const isRTL = document.documentElement.dir === 'rtl';\n\n dispatch({ type: isRTL ? 'next' : 'previous' });\n }, [dispatch]);\n\n const right = useCallback(() => {\n const isRTL = document.documentElement.dir === 'rtl';\n\n dispatch({ type: isRTL ? 'previous' : 'next' });\n }, [dispatch]);\n\n const keyboardHandler = useKeyboardControls({\n start,\n end,\n up,\n down,\n left,\n right,\n });\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLDivElement>) => {\n const isSpace = e.key === ' ' || e.key === 'Spacebar' || e.code === 'Space';\n const isEnter = e.key === 'Enter' || e.code === 'Enter';\n\n if (isActive.current && (isSpace || isEnter)) {\n e.preventDefault();\n return;\n }\n\n keyboardHandler(e);\n },\n [keyboardHandler],\n );\n\n const handleClick = () => {\n if (isActive.current) {\n return;\n }\n\n dispatch({ type: 'update', payload: value });\n };\n\n return (\n <div\n {...attr}\n id={attr.id || `Tab_${value}_${uid}`}\n data-name=\"Tab\"\n ref={ref}\n role=\"tab\"\n aria-selected={isActive.current}\n aria-controls={`TabPanel_${value}_${uid}`}\n tabIndex={isActive.current ? 0 : -1}\n className={cn(\n 'group/tab text-b3 inline-block cursor-pointer overflow-hidden bg-transparent pe-4 align-middle font-semibold whitespace-nowrap outline-none',\n {\n 'text-white': isActive.current,\n 'text-black': !isActive.current,\n 'transition-transform active:scale-[1.03]': isActive.current,\n },\n )}\n onKeyDown={handleKeyDown}\n onClick={handleClick}\n >\n <TagName\n className={cn(\n 'relative inline-block px-20 py-12',\n 'before:rounded-pill before:transition-colors/opacity before:absolute before:inset-0 before:-z-1 before:duration-300 group-focus-within/tab:before:bg-(--color-pearl) group-hover/tab:before:bg-(--color-pearl) group/tab-focus:before:bg-(--color-pearl)',\n className,\n )}\n {...(!isActive ? { role: 'presentation' } : {})}\n >\n <span\n className={cn(\n 'tab-focus-pill ease transition-transform/colors',\n 'rounded-pill absolute inset-0 -z-1 duration-300',\n 'bg-black',\n )}\n style={pillStyle}\n />\n <span className=\"flex items-center gap-8\">\n {children ?? label}\n {notification && (\n <div\n className={cn(\n 'size-18 flex items-center justify-center text-b5 rounded-full bg-saffron text-black transition-colors duration-300',\n {\n 'group-focus-within/tab:bg-darkGrey group-hover/tab:bg-darkGrey group-focus-within/tab:text-pearl group-hover/tab:text-pearl':\n !isActive.current,\n },\n )}\n >\n {notification}\n </div>\n )}\n </span>\n </TagName>\n </div>\n );\n};\n"],"mappings":";;;;;;;;;;AAwCA,IAAa,KAAqD,EAChE,cACA,eAAY,IACZ,aACA,kBAGE,kBAAC,OAAD;CACE,WAAW,EACT,iBACA,EACE,eAAe,CAAC,GACjB,EACD,EACD;CACD,aAAU;WAEV,kBAAC,GAAD;EAAwB;EAAW;EAAwB,CAAA;CACvD,CAAA,EAQG,KAAiE,EAC5E,cACA,kBAGE,kBAAC,OAAD;CAAK,aAAU;CAAW,WAAW,EAAG,oCAAoC,EAAU;CACnF;CACG,CAAA,EAiBG,KAAiE,EAC5E,UACA,cACA,aACA,aACA,GAAG,QACC;CACJ,IAAM,IAAM,GAAY,EAClB,IAAU,EAAO,GAAM,EAEvB,IADc,GAAc,KACD;AAajC,QAXA,QAAgB;AACd,MAAI,CAAC,EAAQ,SAAS;AACpB,KAAQ,UAAU;AAClB;;AAGF,EAAI,KACF,IAAW,EAAE,UAAO,CAAC;IAEtB;EAAC;EAAU;EAAO;EAAS,CAAC,EAG7B,kBAAC,OAAD;EACE,GAAI;EACJ,eAAa,CAAC;EACd,WAAW,EACT,oEACA;GACE,yCAAyC,CAAC;GAC1C,8CAA8C;GAC/C,EACD,EACD;EACD,OAAO,IAAW,KAAA,IAAY;EAC9B,UAAU,IAAW,IAAI;EACzB,IAAI,YAAY,EAAM,GAAG;EACzB,aAAW,YAAY;EACvB,MAAK;EACL,mBAAiB,OAAO,EAAM,GAAG;EAEhC;EACG,CAAA;GAYG,KAA+D,EAC1E,cACA,iBAAc,IACd,kBACI;CACJ,IAAM,IAAM,EAAuB,KAAK,EAClC,IAAY,EAAuB,KAAK,EACxC,CAAC,GAAY,KAAkB,GAAqB,EACpD,CAAC,GAAe,KAAoB,EAAS,GAAM,EACnD,CAAC,GAAgB,KAAqB,EAAS,GAAM,EAErD,IAAoB,QAAkB;EAC1C,IAAM,IAAK,EAAI;AACV,QACL,EAAiB,EAAG,aAAa,EAAE,EACnC,EAAkB,KAAK,KAAK,EAAG,WAAW,GAAG,EAAG,cAAc,EAAG,YAAY;IAC5E,EAAE,CAAC;AAkBN,CAhBA,QAAgB;EACd,IAAM,IAAK,EAAI;AACf,MAAI,CAAC,EAAI;AAET,KAAmB;EAEnB,IAAM,IAAW,IAAI,eAAe,EAAkB;AAItD,SAHA,EAAS,QAAQ,EAAG,EACpB,EAAG,iBAAiB,UAAU,GAAmB,EAAE,SAAS,IAAM,CAAC,QAEtD;AAEX,GADA,EAAS,YAAY,EACrB,EAAG,oBAAoB,UAAU,EAAkB;;IAEpD,CAAC,EAAkB,CAAC,EAEvB,QAAgB;AACd,MAAI,CAAC,GAAgB,WAAW,CAAC,EAAI,QACnC;EAGF,IAAM,IAAc,EAAU,QAAS,eAAe,GAChD,IAAc,EAAe,QAAQ,uBAAuB,EAC5D,IAAgB,EAAI,QAAS,uBAAuB;AAE1D,IAAI,QAAQ,SAAS;GACnB,MAAM,EAAY,OAAO,EAAc,OAAO;GAC9C,UAAU;GACX,CAAC;IACD,CAAC,EAAe,CAAC;CAEpB,IAAM,IAAe,EAAsB,KAAK,EAE1C,IAAa,QAAkB;AACnC,EAAI,EAAa,YAAY,SAC3B,qBAAqB,EAAa,QAAQ,EAC1C,EAAa,UAAU;IAExB,EAAE,CAAC,EAEA,IAAc,GAAa,MAAsB;AACrD,MAAI,EAAa,YAAY,KAAM;EACnC,IAAM,UAAa;AAEjB,GADA,EAAI,SAAS,SAAS,EAAE,MAAM,IAAY,GAAG,CAAC,EAC9C,EAAa,UAAU,sBAAsB,EAAK;;AAEpD,IAAa,UAAU,sBAAsB,EAAK;IACjD,EAAE,CAAC,EAEA,IAAoB,GACvB,MAAwC;AACvC,GAAI,EAAE,QAAQ,OAAO,EAAE,QAAQ,YAAS,GAAY;IAEtD,CAAC,EAAW,CACb,EAEK,IAA0B,GAC7B,MAAwC;AACvC,GAAI,EAAE,QAAQ,OAAO,EAAE,QAAQ,aAC7B,EAAE,gBAAgB,EAClB,EAAY,GAAG;IAGnB,CAAC,EAAY,CACd,EAEK,IAA2B,GAC9B,MAAwC;AACvC,GAAI,EAAE,QAAQ,OAAO,EAAE,QAAQ,aAC7B,EAAE,gBAAgB,EAClB,EAAY,EAAE;IAGlB,CAAC,EAAY,CACd;AAED,SAAgB,GAAY,CAAC,EAAW,CAAC;CAEzC,IAAM,IAAQ,EAAE,gBAAgB,GAAY,EACtC,IAAe,KAAiB;AAEtC,QACE,kBAAC,OAAD;EAAK,WAAU;EAAW,aAAU;YAApC;GACG,KACC,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,GAAD;KACE,MAAK;KACL,MAAK;KACL,WAAW,EACT,2GACA,IAAgB,gBAAgB,gCACjC;KACD,mBAAmB,EAAY,GAAG;KAClC,WAAW;KACX,cAAc;KACd,WAAW;KACX,SAAS;KACT,OAAO,CAAC;KACR,UAAU,IAAgB,IAAI;eAC/B;KAEa,CAAA;IACV,CAAA;GAER,kBAAC,OAAD;IACE,WAAW,EACT,2EACA,EACD;IACI;cAEL,kBAAC,OAAD;KAAK,MAAK;KAAU,WAAU;KAAuB;eAArD;MACE,kBAAC,OAAD;OACE,KAAK;OACL,WAAW,EAAG,YAAY,EACxB,0FACE,CAAC,GACJ,CAAA;OACD,CAAA;MACD;MACD,kBAAC,OAAD,EACE,WAAW,EAAG,YAAY,EACxB,0FACE,CAAC,GACJ,CAAC,EACF,CAAA;;;IAEA,CAAA;GACL,KACC,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,GAAD;KACE,MAAK;KACL,MAAK;KACL,WAAW,EACT,2GACA,IAAiB,gBAAgB,gCAClC;KACD,mBAAmB,EAAY,EAAE;KACjC,WAAW;KACX,cAAc;KACd,WAAW;KACX,SAAS;KACT,OAAO,CAAC;KACR,UAAU,IAAiB,IAAI;eAChC;KAEa,CAAA;IACV,CAAA;;;GAYD,KAAgD,EAC3D,UACA,cACA,cAAc,IAAY,mBACtB;CACJ,IAAM,IAAY,GAAc,EAC1B,IAAW,GAAgB;AAQjC,QACE,kBAAC,GAAD;EACE,QAJgB,MAAc,KAAK,KAAA,IAAY,IAI3B,UAAU;EAC9B,WATkB,GAAe,MAAkB;AACrD,KAAS;IAAE,MAAM;IAAU,SAAS,OAAO,EAAA;IAAQ,CAAC;;EASlD,MAAM;EACN,WAAW,EAAG,EAAU;YAEvB,EAAM,KAAK,MACV,kBAAC,UAAD;GAAyB,OAAO,EAAK;aAClC,EAAK;GACC,EAFI,EAAK,MAET,CAAA;EAEJ,CAAA;GA6BA,KAAuD,EAClE,IAAI,IAAU,MACd,UACA,aACA,UACA,aACA,cACA,iBACA,GAAG,QACC;CACJ,IAAM,IAAM,EAAuB,KAAK,EAClC,IAAY,GAAc,EAC1B,IAAM,GAAY,EAClB,IAAW,EAAsB;EAAE;EAAY;EAAkC,CAAC,EAClF,IAAoB,EAAO,EAAU,EAErC,IAAW,EAAO,MAAc,EAAM;AAC5C,GAAS,UAAU,MAAc;CAEjC,IAAM,IAAY,EAAE,eAAe,GAAO;AAE1C,SAAgB;AAKd,EAJI,EAAkB,YAAY,KAAa,MAAU,MACvD,EAAI,SAAS,OAAO,EACpB,IAAW;GAAE;GAAO;GAAO,CAAC,GAE1B,EAAkB,YAAY,MAChC,EAAkB,UAAU;IAE7B;EAAC;EAAO;EAAO;EAAU;EAAU,CAAC;CA8BvC,IAAM,IAAkB,EAAoB;EAC1C,OA7BY,QAAkB;AAC9B,KAAS,EAAE,MAAM,SAAS,CAAC;KAC1B,CAAC,EAAS,CAAC;EA4BZ,KA1BU,QAAkB;AAC5B,KAAS,EAAE,MAAM,OAAO,CAAC;KACxB,CAAC,EAAS,CAAC;EAyBZ,IAvBS,QAAkB;AAC3B,KAAS,EAAE,MAAM,YAAY,CAAC;KAC7B,CAAC,EAAS,CAAC;EAsBZ,MApBW,QAAkB;AAC7B,KAAS,EAAE,MAAM,QAAQ,CAAC;KACzB,CAAC,EAAS,CAAC;EAmBZ,MAjBW,QAAkB;AAG7B,KAAS,EAAE,MAFG,SAAS,gBAAgB,QAAQ,QAEtB,SAAS,YAAY,CAAC;KAC9C,CAAC,EAAS,CAAC;EAcZ,OAZY,QAAkB;AAG9B,KAAS,EAAE,MAFG,SAAS,gBAAgB,QAAQ,QAEtB,aAAa,QAAQ,CAAC;KAC9C,CAAC,EAAS,CAAA;EASZ,CAAC,EAEI,IAAgB,GACnB,MAAqC;EACpC,IAAM,IAAU,EAAE,QAAQ,OAAO,EAAE,QAAQ,cAAc,EAAE,SAAS,SAC9D,IAAU,EAAE,QAAQ,WAAW,EAAE,SAAS;AAEhD,MAAI,EAAS,YAAY,KAAW,IAAU;AAC5C,KAAE,gBAAgB;AAClB;;AAGF,IAAgB,EAAE;IAEpB,CAAC,EAAgB,CAClB,EAEK,UAAoB;AACpB,IAAS,WAIb,EAAS;GAAE,MAAM;GAAU,SAAS;GAAO,CAAC;;AAG9C,QACE,kBAAC,OAAD;EACE,GAAI;EACJ,IAAI,EAAK,MAAM,OAAO,EAAM,GAAG;EAC/B,aAAU;EACL;EACL,MAAK;EACL,iBAAe,EAAS;EACxB,iBAAe,YAAY,EAAM,GAAG;EACpC,UAAU,EAAS,UAAU,IAAI;EACjC,WAAW,EACT,+IACA;GACE,cAAc,EAAS;GACvB,cAAc,CAAC,EAAS;GACxB,4CAA4C,EAAS;GACtD,CACF;EACD,WAAW;EACX,SAAS;YAET,kBAAC,GAAD;GACE,WAAW,EACT,qCACA,4PACA,EACD;GACD,GAAM,IAAsC,EAAE,GAA7B,EAAE,MAAM,gBAAgB;aAN3C,CAQE,kBAAC,QAAD;IACE,WAAW,EACT,mDACA,mDACA,WACD;IACD,OAAO;IACP,CAAA,EACF,kBAAC,QAAD;IAAM,WAAU;cAAhB,CACG,KAAY,GACZ,KACC,kBAAC,OAAD;KACE,WAAW,EACT,sHACA,EACE,+HACE,CAAC,EAAS,SACb,CACF;eAEA;KACG,CAAA,CAAA;;;EAIR,CAAA"}
|
|
1
|
+
{"version":3,"file":"Tabs.js","names":[],"sources":["../../../lib/ui/tabs/Tabs.tsx"],"sourcesContent":["'use client';\n\nimport {\n type ComponentProps,\n type ComponentPropsWithoutRef,\n type CSSProperties,\n type FunctionComponent,\n type PropsWithChildren,\n type RefObject,\n type KeyboardEvent,\n type ReactNode,\n useCallback,\n useEffect,\n useRef,\n useState,\n useMemo,\n} from 'react';\n\nimport { TabsProvider } from '../contexts/TabControl';\nimport {\n useActiveTab,\n useActiveTabControl,\n useRegisterTabControl,\n useTabDispatch,\n useTabsUid,\n} from '../hooks/tabControl';\nimport { useKeyboardControls } from '../hooks/useKeyboardControls';\nimport { Select } from '../forms/Select';\nimport { cn } from '../helpers/cn';\nimport { ArrowButton } from '../buttons/ArrowButton';\n\ntype ProviderProps = ComponentProps<typeof TabsProvider>;\n\ninterface Props extends ProviderProps {\n className?: string;\n /**\n * Shrink the spacing between tabs and panels\n */\n compacted?: boolean;\n}\n\nexport const Tabs: FunctionComponent<PropsWithChildren<Props>> = ({\n className,\n compacted = false,\n selected,\n children,\n}) => {\n return (\n <div\n className={cn(\n 'flex flex-col',\n {\n 'sm:gap-y-20': !compacted,\n },\n className,\n )}\n data-name=\"Tabs\"\n >\n <TabsProvider selected={selected}>{children}</TabsProvider>\n </div>\n );\n};\n\ninterface TabsBodyProps {\n className?: string;\n}\n\nexport const TabsBody: FunctionComponent<PropsWithChildren<TabsBodyProps>> = ({\n className,\n children,\n}) => {\n return (\n <div data-name=\"TabsBody\" className={cn('grid grid-rows-1 overflow-hidden', className)}>\n {children}\n </div>\n );\n};\n\ninterface TabPanelProps {\n className?: string;\n /**\n * Tab panel index<br/>\n * _Can be **0** or **1** indexed_\n */\n value: number;\n /**\n * on panel select handler\n */\n onSelect?: (context: { value: TabPanelProps['value'] }) => void;\n}\n\nexport const TabPanel: FunctionComponent<PropsWithChildren<TabPanelProps>> = ({\n value,\n className,\n onSelect,\n children,\n ...attrs\n}) => {\n const uid = useTabsUid();\n const mounted = useRef(false);\n const tabSelected = useActiveTab();\n const isActive = tabSelected === value;\n\n useEffect(() => {\n if (!mounted.current) {\n mounted.current = true;\n return;\n }\n\n if (isActive) {\n onSelect?.({ value });\n }\n }, [isActive, value, onSelect]);\n\n return (\n <div\n {...attrs}\n aria-hidden={!isActive}\n className={cn(\n 'relative col-start-1 row-start-1 transition-opacity duration-500',\n {\n 'pointer-events-none z-0 h-0 opacity-0': !isActive,\n 'pointer-events-auto z-1 h-auto opacity-100': isActive,\n },\n className,\n )}\n inert={isActive ? undefined : true}\n tabIndex={isActive ? 0 : -1}\n id={`TabPanel_${value}_${uid}`}\n data-name={`TabPanel_${value}`}\n role=\"tabpanel\"\n aria-labelledby={`Tab_${value}_${uid}`}\n >\n {children}\n </div>\n );\n};\n\ninterface TabListProps {\n className?: string;\n /**\n * Remove filler placeholders\n */\n constrained?: boolean;\n}\n\nexport const TabList: FunctionComponent<PropsWithChildren<TabListProps>> = ({\n className,\n constrained = false,\n children,\n}) => {\n const ref = useRef<HTMLDivElement>(null);\n const spacerRef = useRef<HTMLDivElement>(null);\n const [, currentControl] = useActiveTabControl();\n const uid = useTabsUid();\n const [canScrollLeft, setCanScrollLeft] = useState(false);\n const [canScrollRight, setCanScrollRight] = useState(false);\n\n const anchorName = `--tab-pill-${uid}` as CSSProperties['anchorName'];\n\n const pillStyle = useMemo<CSSProperties>(\n () => ({\n positionAnchor: anchorName,\n top: 'anchor(top)',\n bottom: 'anchor(bottom)',\n left: 'anchor(left)',\n right: 'anchor(right)',\n position: 'absolute',\n }),\n [anchorName],\n );\n\n const updateScrollState = useCallback(() => {\n const el = ref.current;\n if (!el) return;\n setCanScrollLeft(el.scrollLeft > 0);\n setCanScrollRight(Math.ceil(el.scrollLeft) < el.scrollWidth - el.clientWidth);\n }, []);\n\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n\n updateScrollState();\n\n const observer = new ResizeObserver(updateScrollState);\n observer.observe(el);\n el.addEventListener('scroll', updateScrollState, { passive: true });\n\n return () => {\n observer.disconnect();\n el.removeEventListener('scroll', updateScrollState);\n };\n }, [updateScrollState]);\n\n useEffect(() => {\n if (!currentControl?.current || !ref.current) {\n return;\n }\n\n const spacerWidth = spacerRef.current!.offsetWidth ?? 0;\n const currentRect = currentControl.current.getBoundingClientRect();\n const containerRect = ref.current!.getBoundingClientRect();\n\n ref.current.scrollBy({\n left: currentRect.left - containerRect.left - spacerWidth,\n behavior: 'smooth',\n });\n }, [currentControl]);\n\n const scrollRafRef = useRef<number | null>(null);\n\n const stopScroll = useCallback(() => {\n if (scrollRafRef.current !== null) {\n cancelAnimationFrame(scrollRafRef.current);\n scrollRafRef.current = null;\n }\n }, []);\n\n const startScroll = useCallback((direction: -1 | 1) => {\n if (scrollRafRef.current !== null) return;\n const step = () => {\n ref.current?.scrollBy({ left: direction * 6 });\n scrollRafRef.current = requestAnimationFrame(step);\n };\n scrollRafRef.current = requestAnimationFrame(step);\n }, []);\n\n const handleScrollKeyUp = useCallback(\n (e: KeyboardEvent<HTMLButtonElement>) => {\n if (e.key === ' ' || e.key === 'Enter') stopScroll();\n },\n [stopScroll],\n );\n\n const handleScrollLeftKeyDown = useCallback(\n (e: KeyboardEvent<HTMLButtonElement>) => {\n if (e.key === ' ' || e.key === 'Enter') {\n e.preventDefault();\n startScroll(-1);\n }\n },\n [startScroll],\n );\n\n const handleScrollRightKeyDown = useCallback(\n (e: KeyboardEvent<HTMLButtonElement>) => {\n if (e.key === ' ' || e.key === 'Enter') {\n e.preventDefault();\n startScroll(1);\n }\n },\n [startScroll],\n );\n\n useEffect(() => stopScroll, [stopScroll]);\n\n const isScrollable = canScrollLeft || canScrollRight;\n\n return (\n <div className=\"relative\" data-name=\"TabsHeader\">\n {isScrollable && (\n <div className=\"pointer-events-none absolute inset-y-0 left-0 z-10 flex items-center\">\n <ArrowButton\n icon=\"ArrowDefaultLeft\"\n size=\"small\"\n className={cn(\n 'pointer-events-auto transition-opacity duration-200 focus-visible:ring-4 focus-visible:ring-black focus-visible:ring-offset-2',\n canScrollLeft ? 'opacity-100' : 'pointer-events-none opacity-0',\n )}\n onMouseDown={() => startScroll(-1)}\n onMouseUp={stopScroll}\n onMouseLeave={stopScroll}\n onKeyDown={handleScrollLeftKeyDown}\n onKeyUp={handleScrollKeyUp}\n inert={!canScrollLeft}\n tabIndex={canScrollLeft ? 0 : -1}\n >\n Scroll tabs left\n </ArrowButton>\n </div>\n )}\n <div\n className={cn(\n 'scrollbar-hidden relative isolate flex max-w-full overflow-x-auto py-20',\n className,\n )}\n ref={ref}\n >\n <div role=\"tablist\" className=\"relative flex flex-row\">\n <span\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute rounded-pill bg-black transition-all duration-300\"\n style={pillStyle}\n />\n <div\n ref={spacerRef}\n className={cn('shrink-0', {\n 'w-16 lg:w-[max(calc((100vw-1212px)/2),116px)] xl:w-[max(calc((100vw-1212px)/2),156px)]':\n !constrained,\n })}\n />\n {children}\n <div\n className={cn('shrink-0', {\n 'w-16 lg:w-[max(calc((100vw-1212px)/2),116px)] xl:w-[max(calc((100vw-1212px)/2),156px)]':\n !constrained,\n })}\n />\n </div>\n </div>\n {isScrollable && (\n <div className=\"pointer-events-none absolute inset-y-0 right-0 z-10 flex items-center\">\n <ArrowButton\n icon=\"ArrowDefaultRight\"\n size=\"small\"\n className={cn(\n 'pointer-events-auto transition-opacity duration-200 focus-visible:ring-4 focus-visible:ring-black focus-visible:ring-offset-2',\n canScrollRight ? 'opacity-100' : 'pointer-events-none opacity-0',\n )}\n onMouseDown={() => startScroll(1)}\n onMouseUp={stopScroll}\n onMouseLeave={stopScroll}\n onKeyDown={handleScrollRightKeyDown}\n onKeyUp={handleScrollKeyUp}\n inert={!canScrollRight}\n tabIndex={canScrollRight ? 0 : -1}\n >\n Scroll tabs right\n </ArrowButton>\n </div>\n )}\n </div>\n );\n};\n\nexport interface TabSelectProps {\n items: { label: string; value: number }[];\n className?: string;\n 'aria-label'?: string;\n}\n\nexport const TabSelect: FunctionComponent<TabSelectProps> = ({\n items,\n className,\n 'aria-label': ariaLabel = 'Select tab',\n}) => {\n const activeTab = useActiveTab();\n const dispatch = useTabDispatch();\n\n const handleChange = (_event: Event, value: string) => {\n dispatch({ type: 'update', payload: Number(value) });\n };\n\n const selectValue = activeTab === -1 ? undefined : activeTab;\n\n return (\n <Select\n value={selectValue?.toString()}\n onChange={handleChange}\n name={ariaLabel}\n className={cn(className)}\n >\n {items.map((item) => (\n <option key={item.value} value={item.value}>\n {item.label}\n </option>\n ))}\n </Select>\n );\n};\n\ninterface TabProps extends Omit<ComponentPropsWithoutRef<'div'>, 'onSelect'> {\n /**\n * Notification content\n */\n notification?: ReactNode;\n /**\n * Tab Heading text\n */\n label?: string;\n /**\n * Tab heading index<br/>\n * _Can be **0** or **1** indexed_\n */\n value: number;\n /**\n * on tab select handler\n */\n onSelect?: (context: { value: TabProps['value']; label: TabProps['label'] }) => void;\n /**\n * Heading type\n * _default: **h2**_\n */\n as?: 'div' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5';\n}\n\nexport const Tab: FunctionComponent<PropsWithChildren<TabProps>> = ({\n as: TagName = 'h2',\n label,\n children,\n value,\n onSelect,\n className,\n notification,\n ...attr\n}) => {\n const ref = useRef<HTMLDivElement>(null);\n const activeTab = useActiveTab();\n const uid = useTabsUid();\n const dispatch = useRegisterTabControl({ value, ref: ref as RefObject<HTMLDivElement> });\n const previousActiveTab = useRef(activeTab);\n\n const isActive = useRef(activeTab === value);\n isActive.current = activeTab === value;\n\n const anchorName = `--tab-pill-${uid}` as CSSProperties['anchorName'];\n\n useEffect(() => {\n if (previousActiveTab.current !== activeTab && value === activeTab) {\n ref.current?.focus();\n onSelect?.({ value, label });\n }\n if (previousActiveTab.current !== activeTab) {\n previousActiveTab.current = activeTab;\n }\n }, [label, value, onSelect, activeTab]);\n\n const start = useCallback(() => {\n dispatch({ type: 'start' });\n }, [dispatch]);\n\n const end = useCallback(() => {\n dispatch({ type: 'end' });\n }, [dispatch]);\n\n const up = useCallback(() => {\n dispatch({ type: 'previous' });\n }, [dispatch]);\n\n const down = useCallback(() => {\n dispatch({ type: 'next' });\n }, [dispatch]);\n\n const left = useCallback(() => {\n const isRTL = document.documentElement.dir === 'rtl';\n\n dispatch({ type: isRTL ? 'next' : 'previous' });\n }, [dispatch]);\n\n const right = useCallback(() => {\n const isRTL = document.documentElement.dir === 'rtl';\n\n dispatch({ type: isRTL ? 'previous' : 'next' });\n }, [dispatch]);\n\n const keyboardHandler = useKeyboardControls({\n start,\n end,\n up,\n down,\n left,\n right,\n });\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLDivElement>) => {\n const isSpace = e.key === ' ' || e.key === 'Spacebar' || e.code === 'Space';\n const isEnter = e.key === 'Enter' || e.code === 'Enter';\n\n if (isActive.current && (isSpace || isEnter)) {\n e.preventDefault();\n return;\n }\n\n keyboardHandler(e);\n },\n [keyboardHandler],\n );\n\n const handleClick = () => {\n if (isActive.current) {\n return;\n }\n\n dispatch({ type: 'update', payload: value });\n };\n\n return (\n <div\n {...attr}\n id={attr.id || `Tab_${value}_${uid}`}\n data-name=\"Tab\"\n ref={ref}\n role=\"tab\"\n aria-selected={isActive.current}\n aria-controls={`TabPanel_${value}_${uid}`}\n tabIndex={isActive.current ? 0 : -1}\n className={cn(\n 'group/tab text-b3 inline-block cursor-pointer overflow-hidden bg-transparent align-middle font-semibold whitespace-nowrap outline-none focus-visible:ring-4 focus-visible:ring-black focus-visible:ring-offset-2 rounded-pill',\n {\n 'text-white': isActive.current,\n 'text-black': !isActive.current,\n 'transition-transform active:scale-[1.03]': isActive.current,\n '[@supports(not(anchor-name:--x))]:bg-black': isActive.current,\n },\n )}\n onKeyDown={handleKeyDown}\n onClick={handleClick}\n >\n <TagName\n className={cn(\n 'relative inline-block px-20 py-12',\n !isActive.current &&\n 'before:rounded-pill before:transition-colors/opacity before:absolute before:inset-0 before:-z-1 before:duration-300 group-focus-within/tab:before:bg-(--color-pearl) group-hover/tab:before:bg-(--color-pearl) group/tab-focus:before:bg-(--color-pearl)',\n className,\n )}\n style={isActive.current ? { anchorName } : undefined}\n {...(!isActive.current ? { role: 'presentation' } : {})}\n >\n <span className=\"flex items-center gap-8\">\n {children ?? label}\n {notification && (\n <div\n className={cn(\n 'size-18 flex items-center justify-center text-b5 rounded-full bg-saffron text-black transition-colors duration-300',\n {\n 'group-focus-within/tab:bg-darkGrey group-hover/tab:bg-darkGrey group-focus-within/tab:text-pearl group-hover/tab:text-pearl':\n !isActive.current,\n },\n )}\n >\n {notification}\n </div>\n )}\n </span>\n </TagName>\n </div>\n );\n};\n"],"mappings":"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"}
|