@cerberus-design/react 0.3.1-next-f5a8b6a → 0.3.2
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/build/legacy/_tsup-dts-rollup.d.ts +3 -1
- package/build/legacy/aria-helpers/tabs.aria.js +2 -2
- package/build/{modern/chunk-ODSSU3JD.js → legacy/chunk-5GSXIYD3.js} +8 -2
- package/build/legacy/chunk-5GSXIYD3.js.map +1 -0
- package/build/legacy/{chunk-57HOQM4E.js → chunk-BT2B5C7M.js} +2 -2
- package/build/legacy/{chunk-HQK7SM56.js → chunk-DQOYTLGB.js} +19 -13
- package/build/legacy/chunk-DQOYTLGB.js.map +1 -0
- package/build/legacy/{chunk-36QCFAIS.js → chunk-MYRKQVDI.js} +10 -5
- package/build/legacy/chunk-MYRKQVDI.js.map +1 -0
- package/build/{modern/chunk-RCE2XXL7.js → legacy/chunk-SVZU6LPF.js} +2 -2
- package/build/legacy/components/Tab.js +3 -3
- package/build/legacy/components/TabList.js +3 -1
- package/build/legacy/components/TabPanel.js +2 -2
- package/build/legacy/context/tabs.js +1 -1
- package/build/legacy/index.js +5 -5
- package/build/modern/_tsup-dts-rollup.d.ts +3 -1
- package/build/modern/aria-helpers/tabs.aria.js +2 -2
- package/build/{legacy/chunk-ODSSU3JD.js → modern/chunk-5GSXIYD3.js} +8 -2
- package/build/modern/chunk-5GSXIYD3.js.map +1 -0
- package/build/modern/{chunk-57HOQM4E.js → chunk-BT2B5C7M.js} +2 -2
- package/build/modern/{chunk-HQK7SM56.js → chunk-DQOYTLGB.js} +19 -13
- package/build/modern/chunk-DQOYTLGB.js.map +1 -0
- package/build/modern/{chunk-LAUJGQO2.js → chunk-IQP6HSC4.js} +10 -5
- package/build/modern/chunk-IQP6HSC4.js.map +1 -0
- package/build/{legacy/chunk-RCE2XXL7.js → modern/chunk-SVZU6LPF.js} +2 -2
- package/build/modern/components/Tab.js +3 -3
- package/build/modern/components/TabList.js +3 -1
- package/build/modern/components/TabPanel.js +2 -2
- package/build/modern/context/tabs.js +1 -1
- package/build/modern/index.js +5 -5
- package/package.json +1 -1
- package/src/components/Tab.tsx +9 -2
- package/src/components/TabList.tsx +6 -0
- package/src/context/tabs.tsx +23 -13
- package/build/legacy/chunk-36QCFAIS.js.map +0 -1
- package/build/legacy/chunk-HQK7SM56.js.map +0 -1
- package/build/legacy/chunk-ODSSU3JD.js.map +0 -1
- package/build/modern/chunk-HQK7SM56.js.map +0 -1
- package/build/modern/chunk-LAUJGQO2.js.map +0 -1
- package/build/modern/chunk-ODSSU3JD.js.map +0 -1
- /package/build/legacy/{chunk-57HOQM4E.js.map → chunk-BT2B5C7M.js.map} +0 -0
- /package/build/legacy/{chunk-RCE2XXL7.js.map → chunk-SVZU6LPF.js.map} +0 -0
- /package/build/modern/{chunk-57HOQM4E.js.map → chunk-BT2B5C7M.js.map} +0 -0
- /package/build/modern/{chunk-RCE2XXL7.js.map → chunk-SVZU6LPF.js.map} +0 -0
|
@@ -385,14 +385,16 @@ export { TabsContext as TabsContext_alias_1 }
|
|
|
385
385
|
* @module
|
|
386
386
|
*/
|
|
387
387
|
declare interface TabsContextValue {
|
|
388
|
-
active: string;
|
|
389
388
|
tabs: MutableRefObject<HTMLButtonElement[]>;
|
|
389
|
+
id: string;
|
|
390
|
+
active: string;
|
|
390
391
|
onTabUpdate: (active: string) => void;
|
|
391
392
|
}
|
|
392
393
|
export { TabsContextValue }
|
|
393
394
|
export { TabsContextValue as TabsContextValue_alias_1 }
|
|
394
395
|
|
|
395
396
|
declare interface TabsProps {
|
|
397
|
+
id?: string;
|
|
396
398
|
active?: string;
|
|
397
399
|
cache?: boolean;
|
|
398
400
|
}
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
+
import {
|
|
2
|
+
useTabsContext
|
|
3
|
+
} from "./chunk-DQOYTLGB.js";
|
|
4
|
+
|
|
1
5
|
// src/components/TabList.tsx
|
|
2
6
|
import { cx } from "@cerberus/styled-system/css";
|
|
3
7
|
import { hstack } from "@cerberus/styled-system/patterns";
|
|
4
8
|
import { jsx } from "react/jsx-runtime";
|
|
5
9
|
function TabList(props) {
|
|
6
10
|
const { description, ...nativeProps } = props;
|
|
11
|
+
const { id } = useTabsContext();
|
|
7
12
|
return /* @__PURE__ */ jsx(
|
|
8
13
|
"div",
|
|
9
14
|
{
|
|
@@ -17,7 +22,8 @@ function TabList(props) {
|
|
|
17
22
|
gap: "0",
|
|
18
23
|
w: "full"
|
|
19
24
|
})
|
|
20
|
-
)
|
|
25
|
+
),
|
|
26
|
+
id: id ?? nativeProps.id
|
|
21
27
|
}
|
|
22
28
|
);
|
|
23
29
|
}
|
|
@@ -25,4 +31,4 @@ function TabList(props) {
|
|
|
25
31
|
export {
|
|
26
32
|
TabList
|
|
27
33
|
};
|
|
28
|
-
//# sourceMappingURL=chunk-
|
|
34
|
+
//# sourceMappingURL=chunk-5GSXIYD3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/TabList.tsx"],"sourcesContent":["'use client'\n\nimport { cx } from '@cerberus/styled-system/css'\nimport { hstack } from '@cerberus/styled-system/patterns'\nimport type { HTMLAttributes, PropsWithChildren } from 'react'\nimport { useTabsContext } from '../context/tabs'\n\n/**\n * This module provides a TabList component.\n * @module\n */\n\nexport interface TabListProps extends HTMLAttributes<HTMLDivElement> {\n description: string\n}\n\n/**\n * The TabList component provides a container for tab elements.\n * @param description - a description of what the tab list contains\n * @example\n * ```tsx\n * <TabList description=\"Button details\">\n * <Tab id=\"overview\">Overview</Tab>\n * <Tab id=\"guidelines\">Guidelines</Tab>\n * </TabList>\n * ```\n */\nexport function TabList(props: PropsWithChildren<TabListProps>) {\n const { description, ...nativeProps } = props\n const { id } = useTabsContext()\n\n return (\n <div\n {...nativeProps}\n aria-describedby={description}\n className={cx(\n nativeProps.className,\n hstack({\n borderBottom: '1px solid',\n borderBottomColor: 'action.border.100',\n gap: '0',\n w: 'full',\n }),\n )}\n id={id ?? nativeProps.id}\n />\n )\n}\n"],"mappings":";;;;;AAEA,SAAS,UAAU;AACnB,SAAS,cAAc;AA6BnB;AALG,SAAS,QAAQ,OAAwC;AAC9D,QAAM,EAAE,aAAa,GAAG,YAAY,IAAI;AACxC,QAAM,EAAE,GAAG,IAAI,eAAe;AAE9B,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ,oBAAkB;AAAA,MAClB,WAAW;AAAA,QACT,YAAY;AAAA,QACZ,OAAO;AAAA,UACL,cAAc;AAAA,UACd,mBAAmB;AAAA,UACnB,KAAK;AAAA,UACL,GAAG;AAAA,QACL,CAAC;AAAA,MACH;AAAA,MACA,IAAI,MAAM,YAAY;AAAA;AAAA,EACxB;AAEJ;","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
useTabsContext
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-DQOYTLGB.js";
|
|
4
4
|
|
|
5
5
|
// src/aria-helpers/tabs.aria.ts
|
|
6
6
|
import { useEffect, useState } from "react";
|
|
@@ -62,4 +62,4 @@ function useTabsKeyboardNavigation() {
|
|
|
62
62
|
export {
|
|
63
63
|
useTabsKeyboardNavigation
|
|
64
64
|
};
|
|
65
|
-
//# sourceMappingURL=chunk-
|
|
65
|
+
//# sourceMappingURL=chunk-BT2B5C7M.js.map
|
|
@@ -10,28 +10,34 @@ import {
|
|
|
10
10
|
import { jsx } from "react/jsx-runtime";
|
|
11
11
|
var TabsContext = createContext(null);
|
|
12
12
|
function Tabs(props) {
|
|
13
|
-
const { cache } = props;
|
|
14
|
-
const [
|
|
13
|
+
const { cache, active, id } = props;
|
|
14
|
+
const [activeTab, setActiveTab] = useState(() => cache ? "" : active ?? "");
|
|
15
15
|
const tabs = useRef([]);
|
|
16
|
+
const uuid = useMemo(() => {
|
|
17
|
+
return id ? `cerberus-tabs-${id}` : "cerberus-tabs";
|
|
18
|
+
}, [id]);
|
|
16
19
|
const value = useMemo(
|
|
17
20
|
() => ({
|
|
18
|
-
active,
|
|
19
21
|
tabs,
|
|
20
|
-
|
|
22
|
+
id: uuid,
|
|
23
|
+
active: activeTab,
|
|
24
|
+
onTabUpdate: setActiveTab
|
|
21
25
|
}),
|
|
22
|
-
[
|
|
26
|
+
[activeTab, setActiveTab, uuid, tabs]
|
|
23
27
|
);
|
|
24
28
|
useEffect(() => {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
29
|
+
if (cache) {
|
|
30
|
+
const cachedTab = window.localStorage.getItem(uuid);
|
|
31
|
+
setActiveTab(
|
|
32
|
+
cache ? cachedTab || (props.active ?? "") : props.active ?? ""
|
|
33
|
+
);
|
|
28
34
|
}
|
|
29
|
-
}, [cache]);
|
|
35
|
+
}, [cache, active, uuid]);
|
|
30
36
|
useEffect(() => {
|
|
31
|
-
if (cache) {
|
|
32
|
-
window.localStorage.setItem(
|
|
37
|
+
if (cache && activeTab) {
|
|
38
|
+
window.localStorage.setItem(uuid, activeTab);
|
|
33
39
|
}
|
|
34
|
-
}, [
|
|
40
|
+
}, [activeTab, cache]);
|
|
35
41
|
return /* @__PURE__ */ jsx(TabsContext.Provider, { value, children: props.children });
|
|
36
42
|
}
|
|
37
43
|
function useTabsContext() {
|
|
@@ -47,4 +53,4 @@ export {
|
|
|
47
53
|
Tabs,
|
|
48
54
|
useTabsContext
|
|
49
55
|
};
|
|
50
|
-
//# sourceMappingURL=chunk-
|
|
56
|
+
//# sourceMappingURL=chunk-DQOYTLGB.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/context/tabs.tsx"],"sourcesContent":["'use client'\n\nimport {\n createContext,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type MutableRefObject,\n type PropsWithChildren,\n} from 'react'\n\n/**\n * This module provides a Tabs component and a hook to access its context.\n * @module\n */\n\nexport interface TabsContextValue {\n tabs: MutableRefObject<HTMLButtonElement[]>\n id: string\n active: string\n onTabUpdate: (active: string) => void\n}\n\nexport const TabsContext = createContext<TabsContextValue | null>(null)\n\nexport interface TabsProps {\n id?: string\n active?: string\n cache?: boolean\n}\n\n/**\n * The Tabs component provides a context to manage tab state.\n * @param active - the default active tab id,\n * @param cache - whether to cache the active tab state in local storage\n * @example\n * ```tsx\n * <Tabs cache>\n * <TabList description=\"Button details\">\n * <Tab id=\"overview\">Overview</Tab>\n * <Tab id=\"guidelines\">Guidelines</Tab>\n * </TabList>\n * <TabPanels>\n * <TabPanel id=\"overview\">Overview content</TabPanel>\n * <TabPanel id=\"guidelines\">Guidelines content</TabPanel>\n * </TabPanels>\n * </Tabs>\n * ```\n */\nexport function Tabs(props: PropsWithChildren<TabsProps>): JSX.Element {\n const { cache, active, id } = props\n const [activeTab, setActiveTab] = useState(() => (cache ? '' : active ?? ''))\n const tabs = useRef<HTMLButtonElement[]>([])\n const uuid = useMemo(() => {\n return id ? `cerberus-tabs-${id}` : 'cerberus-tabs'\n }, [id])\n\n const value = useMemo(\n () => ({\n tabs,\n id: uuid,\n active: activeTab,\n onTabUpdate: setActiveTab,\n }),\n [activeTab, setActiveTab, uuid, tabs],\n )\n\n // Get the active tab from local storage\n useEffect(() => {\n if (cache) {\n const cachedTab = window.localStorage.getItem(uuid)\n setActiveTab(\n cache ? cachedTab || (props.active ?? '') : props.active ?? '',\n )\n }\n }, [cache, active, uuid])\n\n // Update the active tab in local storage\n useEffect(() => {\n if (cache && activeTab) {\n window.localStorage.setItem(uuid, activeTab)\n }\n }, [activeTab, cache])\n\n return (\n <TabsContext.Provider value={value}>{props.children}</TabsContext.Provider>\n )\n}\n\nexport function useTabsContext(): TabsContextValue {\n const context = useContext(TabsContext)\n if (!context) {\n throw new Error('useTabsContext must be used within a Tabs Provider.')\n }\n return context\n}\n"],"mappings":";AAEA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AA4EH;AA9DG,IAAM,cAAc,cAAuC,IAAI;AA0B/D,SAAS,KAAK,OAAkD;AACrE,QAAM,EAAE,OAAO,QAAQ,GAAG,IAAI;AAC9B,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,MAAO,QAAQ,KAAK,UAAU,EAAG;AAC5E,QAAM,OAAO,OAA4B,CAAC,CAAC;AAC3C,QAAM,OAAO,QAAQ,MAAM;AACzB,WAAO,KAAK,iBAAiB,EAAE,KAAK;AAAA,EACtC,GAAG,CAAC,EAAE,CAAC;AAEP,QAAM,QAAQ;AAAA,IACZ,OAAO;AAAA,MACL;AAAA,MACA,IAAI;AAAA,MACJ,QAAQ;AAAA,MACR,aAAa;AAAA,IACf;AAAA,IACA,CAAC,WAAW,cAAc,MAAM,IAAI;AAAA,EACtC;AAGA,YAAU,MAAM;AACd,QAAI,OAAO;AACT,YAAM,YAAY,OAAO,aAAa,QAAQ,IAAI;AAClD;AAAA,QACE,QAAQ,cAAc,MAAM,UAAU,MAAM,MAAM,UAAU;AAAA,MAC9D;AAAA,IACF;AAAA,EACF,GAAG,CAAC,OAAO,QAAQ,IAAI,CAAC;AAGxB,YAAU,MAAM;AACd,QAAI,SAAS,WAAW;AACtB,aAAO,aAAa,QAAQ,MAAM,SAAS;AAAA,IAC7C;AAAA,EACF,GAAG,CAAC,WAAW,KAAK,CAAC;AAErB,SACE,oBAAC,YAAY,UAAZ,EAAqB,OAAe,gBAAM,UAAS;AAExD;AAEO,SAAS,iBAAmC;AACjD,QAAM,UAAU,WAAW,WAAW;AACtC,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,qDAAqD;AAAA,EACvE;AACA,SAAO;AACT;","names":[]}
|
|
@@ -1,23 +1,27 @@
|
|
|
1
1
|
import {
|
|
2
2
|
useTabsKeyboardNavigation
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-BT2B5C7M.js";
|
|
4
4
|
import {
|
|
5
5
|
useTabsContext
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-DQOYTLGB.js";
|
|
7
7
|
|
|
8
8
|
// src/components/Tab.tsx
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
useMemo,
|
|
11
|
+
useTransition
|
|
12
|
+
} from "react";
|
|
10
13
|
import { css, cx } from "@cerberus/styled-system/css";
|
|
11
14
|
import { jsx } from "react/jsx-runtime";
|
|
12
15
|
function Tab(props) {
|
|
13
16
|
const { value, ...nativeProps } = props;
|
|
14
17
|
const { active, onTabUpdate } = useTabsContext();
|
|
18
|
+
const [isPending, startTransition] = useTransition();
|
|
15
19
|
const { ref } = useTabsKeyboardNavigation();
|
|
16
20
|
const isActive = useMemo(() => active === value, [active, value]);
|
|
17
21
|
function handleClick(e) {
|
|
18
22
|
var _a;
|
|
19
23
|
(_a = props.onClick) == null ? void 0 : _a.call(props, e);
|
|
20
|
-
onTabUpdate(e.currentTarget.value);
|
|
24
|
+
startTransition(() => onTabUpdate(e.currentTarget.value));
|
|
21
25
|
}
|
|
22
26
|
return /* @__PURE__ */ jsx(
|
|
23
27
|
"button",
|
|
@@ -25,6 +29,7 @@ function Tab(props) {
|
|
|
25
29
|
...nativeProps,
|
|
26
30
|
...!isActive && { tabIndex: -1 },
|
|
27
31
|
"aria-controls": `panel:${value}`,
|
|
32
|
+
"aria-busy": isPending,
|
|
28
33
|
"aria-selected": isActive,
|
|
29
34
|
id: value,
|
|
30
35
|
className: cx(nativeProps.className, btnStyles),
|
|
@@ -118,4 +123,4 @@ var btnStyles = css({
|
|
|
118
123
|
export {
|
|
119
124
|
Tab
|
|
120
125
|
};
|
|
121
|
-
//# sourceMappingURL=chunk-
|
|
126
|
+
//# sourceMappingURL=chunk-MYRKQVDI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/Tab.tsx"],"sourcesContent":["'use client'\n\nimport {\n useMemo,\n useTransition,\n type ButtonHTMLAttributes,\n type MouseEvent,\n} from 'react'\nimport { useTabsContext } from '../context/tabs'\nimport { css, cx } from '@cerberus/styled-system/css'\nimport { useTabsKeyboardNavigation } from '../aria-helpers/tabs.aria'\n\n/**\n * This module provides a Tab component.\n * @module\n */\n\nexport interface TabProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n value: string\n}\n\n/**\n * The Tab component provides a tab element to be used in a TabList.\n * @definition [ARIA Target Size](https://www.w3.org/WAI/WCAG21/Understanding/target-size.html#:~:text=Understanding%20SC%202.5.,%3ATarget%20Size%20(Level%20AAA)&text=The%20size%20of%20the%20target,Equivalent)\n * @definition [Tab docs](https://cerberus.digitalu.design/react/tabs)\n * @param value - the id of the tab that will be tracked as the active tab and used for aria attributes\n * @example\n * ```tsx\n * <Tab value=\"overview\">\n * Overview\n * </Tab>\n * ```\n */\nexport function Tab(props: TabProps) {\n const { value, ...nativeProps } = props\n const { active, onTabUpdate } = useTabsContext()\n const [isPending, startTransition] = useTransition()\n const { ref } = useTabsKeyboardNavigation()\n const isActive = useMemo(() => active === value, [active, value])\n\n function handleClick(e: MouseEvent<HTMLButtonElement>) {\n props.onClick?.(e)\n startTransition(() => onTabUpdate(e.currentTarget.value))\n }\n\n return (\n <button\n {...nativeProps}\n {...(!isActive && { tabIndex: -1 })}\n aria-controls={`panel:${value}`}\n aria-busy={isPending}\n aria-selected={isActive}\n id={value}\n className={cx(nativeProps.className, btnStyles)}\n onClick={handleClick}\n role=\"tab\"\n ref={ref}\n value={value}\n />\n )\n}\n\nconst btnStyles = css({\n alignItems: 'center',\n display: 'inline-flex',\n borderTopLeftRadius: 'md',\n borderTopRightRadius: 'md',\n fontSize: 'sm',\n fontWeight: '600',\n gap: '2',\n h: '2.75rem',\n justifyContent: 'center',\n position: 'relative',\n pxi: '4',\n zIndex: 'base',\n _motionSafe: {\n transition: 'all 200ms ease-in-out',\n _before: {\n transitionProperty: 'height',\n transitionDuration: '200ms',\n transitionTimingFunction: 'ease-in-out',\n },\n _after: {\n transitionProperty: 'height',\n transitionDuration: '200ms',\n transitionTimingFunction: 'ease-in-out',\n },\n },\n _before: {\n bgColor: 'action.border.initial',\n bottom: '0',\n content: '\"\"',\n h: '0',\n position: 'absolute',\n left: '0',\n right: '0',\n w: 'full',\n willChange: 'height',\n zIndex: 'decorator',\n },\n _after: {\n borderTopLeftRadius: 'md',\n borderTopRightRadius: 'md',\n bottom: '0',\n bgColor: 'neutral.surface.100',\n content: '\"\"',\n left: '0',\n position: 'absolute',\n right: '0',\n h: '0',\n w: 'full',\n willChange: 'height',\n zIndex: '-1',\n },\n _hover: {\n _after: {\n h: 'full',\n },\n },\n _focusVisible: {\n boxShadow: 'none',\n outline: '3px solid',\n outlineColor: 'action.border.focus',\n outlineOffset: '2px',\n },\n _disabled: {\n cursor: 'not-allowed',\n opacity: '0.5',\n },\n _selected: {\n color: 'action.text.200',\n _before: {\n h: '3px',\n },\n _hover: {\n _after: {\n h: '0',\n },\n },\n },\n})\n"],"mappings":";;;;;;;;AAEA;AAAA,EACE;AAAA,EACA;AAAA,OAGK;AAEP,SAAS,KAAK,UAAU;AAqCpB;AAbG,SAAS,IAAI,OAAiB;AACnC,QAAM,EAAE,OAAO,GAAG,YAAY,IAAI;AAClC,QAAM,EAAE,QAAQ,YAAY,IAAI,eAAe;AAC/C,QAAM,CAAC,WAAW,eAAe,IAAI,cAAc;AACnD,QAAM,EAAE,IAAI,IAAI,0BAA0B;AAC1C,QAAM,WAAW,QAAQ,MAAM,WAAW,OAAO,CAAC,QAAQ,KAAK,CAAC;AAEhE,WAAS,YAAY,GAAkC;AAxCzD;AAyCI,gBAAM,YAAN,+BAAgB;AAChB,oBAAgB,MAAM,YAAY,EAAE,cAAc,KAAK,CAAC;AAAA,EAC1D;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACH,GAAI,CAAC,YAAY,EAAE,UAAU,GAAG;AAAA,MACjC,iBAAe,SAAS,KAAK;AAAA,MAC7B,aAAW;AAAA,MACX,iBAAe;AAAA,MACf,IAAI;AAAA,MACJ,WAAW,GAAG,YAAY,WAAW,SAAS;AAAA,MAC9C,SAAS;AAAA,MACT,MAAK;AAAA,MACL;AAAA,MACA;AAAA;AAAA,EACF;AAEJ;AAEA,IAAM,YAAY,IAAI;AAAA,EACpB,YAAY;AAAA,EACZ,SAAS;AAAA,EACT,qBAAqB;AAAA,EACrB,sBAAsB;AAAA,EACtB,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,KAAK;AAAA,EACL,GAAG;AAAA,EACH,gBAAgB;AAAA,EAChB,UAAU;AAAA,EACV,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,aAAa;AAAA,IACX,YAAY;AAAA,IACZ,SAAS;AAAA,MACP,oBAAoB;AAAA,MACpB,oBAAoB;AAAA,MACpB,0BAA0B;AAAA,IAC5B;AAAA,IACA,QAAQ;AAAA,MACN,oBAAoB;AAAA,MACpB,oBAAoB;AAAA,MACpB,0BAA0B;AAAA,IAC5B;AAAA,EACF;AAAA,EACA,SAAS;AAAA,IACP,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,GAAG;AAAA,IACH,UAAU;AAAA,IACV,MAAM;AAAA,IACN,OAAO;AAAA,IACP,GAAG;AAAA,IACH,YAAY;AAAA,IACZ,QAAQ;AAAA,EACV;AAAA,EACA,QAAQ;AAAA,IACN,qBAAqB;AAAA,IACrB,sBAAsB;AAAA,IACtB,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,SAAS;AAAA,IACT,MAAM;AAAA,IACN,UAAU;AAAA,IACV,OAAO;AAAA,IACP,GAAG;AAAA,IACH,GAAG;AAAA,IACH,YAAY;AAAA,IACZ,QAAQ;AAAA,EACV;AAAA,EACA,QAAQ;AAAA,IACN,QAAQ;AAAA,MACN,GAAG;AAAA,IACL;AAAA,EACF;AAAA,EACA,eAAe;AAAA,IACb,WAAW;AAAA,IACX,SAAS;AAAA,IACT,cAAc;AAAA,IACd,eAAe;AAAA,EACjB;AAAA,EACA,WAAW;AAAA,IACT,QAAQ;AAAA,IACR,SAAS;AAAA,EACX;AAAA,EACA,WAAW;AAAA,IACT,OAAO;AAAA,IACP,SAAS;AAAA,MACP,GAAG;AAAA,IACL;AAAA,IACA,QAAQ;AAAA,MACN,QAAQ;AAAA,QACN,GAAG;AAAA,MACL;AAAA,IACF;AAAA,EACF;AACF,CAAC;","names":[]}
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-R4H3352X.js";
|
|
4
4
|
import {
|
|
5
5
|
useTabsContext
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-DQOYTLGB.js";
|
|
7
7
|
|
|
8
8
|
// src/components/TabPanel.tsx
|
|
9
9
|
import { css, cx } from "@cerberus/styled-system/css";
|
|
@@ -40,4 +40,4 @@ function TabPanel(props) {
|
|
|
40
40
|
export {
|
|
41
41
|
TabPanel
|
|
42
42
|
};
|
|
43
|
-
//# sourceMappingURL=chunk-
|
|
43
|
+
//# sourceMappingURL=chunk-SVZU6LPF.js.map
|
package/build/legacy/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
TabPanel
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-SVZU6LPF.js";
|
|
4
4
|
import {
|
|
5
5
|
Input
|
|
6
6
|
} from "./chunk-LD5ZV46F.js";
|
|
@@ -26,22 +26,22 @@ import {
|
|
|
26
26
|
} from "./chunk-R4H3352X.js";
|
|
27
27
|
import {
|
|
28
28
|
Tab
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-MYRKQVDI.js";
|
|
30
30
|
import {
|
|
31
31
|
TabList
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-5GSXIYD3.js";
|
|
33
33
|
import "./chunk-55J6XMHW.js";
|
|
34
34
|
import {
|
|
35
35
|
createNavTriggerProps
|
|
36
36
|
} from "./chunk-JF76VIL3.js";
|
|
37
37
|
import {
|
|
38
38
|
useTabsKeyboardNavigation
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-BT2B5C7M.js";
|
|
40
40
|
import {
|
|
41
41
|
Tabs,
|
|
42
42
|
TabsContext,
|
|
43
43
|
useTabsContext
|
|
44
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-DQOYTLGB.js";
|
|
45
45
|
import {
|
|
46
46
|
MODE_KEY,
|
|
47
47
|
THEME_KEY,
|
|
@@ -385,14 +385,16 @@ export { TabsContext as TabsContext_alias_1 }
|
|
|
385
385
|
* @module
|
|
386
386
|
*/
|
|
387
387
|
declare interface TabsContextValue {
|
|
388
|
-
active: string;
|
|
389
388
|
tabs: MutableRefObject<HTMLButtonElement[]>;
|
|
389
|
+
id: string;
|
|
390
|
+
active: string;
|
|
390
391
|
onTabUpdate: (active: string) => void;
|
|
391
392
|
}
|
|
392
393
|
export { TabsContextValue }
|
|
393
394
|
export { TabsContextValue as TabsContextValue_alias_1 }
|
|
394
395
|
|
|
395
396
|
declare interface TabsProps {
|
|
397
|
+
id?: string;
|
|
396
398
|
active?: string;
|
|
397
399
|
cache?: boolean;
|
|
398
400
|
}
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
+
import {
|
|
2
|
+
useTabsContext
|
|
3
|
+
} from "./chunk-DQOYTLGB.js";
|
|
4
|
+
|
|
1
5
|
// src/components/TabList.tsx
|
|
2
6
|
import { cx } from "@cerberus/styled-system/css";
|
|
3
7
|
import { hstack } from "@cerberus/styled-system/patterns";
|
|
4
8
|
import { jsx } from "react/jsx-runtime";
|
|
5
9
|
function TabList(props) {
|
|
6
10
|
const { description, ...nativeProps } = props;
|
|
11
|
+
const { id } = useTabsContext();
|
|
7
12
|
return /* @__PURE__ */ jsx(
|
|
8
13
|
"div",
|
|
9
14
|
{
|
|
@@ -17,7 +22,8 @@ function TabList(props) {
|
|
|
17
22
|
gap: "0",
|
|
18
23
|
w: "full"
|
|
19
24
|
})
|
|
20
|
-
)
|
|
25
|
+
),
|
|
26
|
+
id: id ?? nativeProps.id
|
|
21
27
|
}
|
|
22
28
|
);
|
|
23
29
|
}
|
|
@@ -25,4 +31,4 @@ function TabList(props) {
|
|
|
25
31
|
export {
|
|
26
32
|
TabList
|
|
27
33
|
};
|
|
28
|
-
//# sourceMappingURL=chunk-
|
|
34
|
+
//# sourceMappingURL=chunk-5GSXIYD3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/TabList.tsx"],"sourcesContent":["'use client'\n\nimport { cx } from '@cerberus/styled-system/css'\nimport { hstack } from '@cerberus/styled-system/patterns'\nimport type { HTMLAttributes, PropsWithChildren } from 'react'\nimport { useTabsContext } from '../context/tabs'\n\n/**\n * This module provides a TabList component.\n * @module\n */\n\nexport interface TabListProps extends HTMLAttributes<HTMLDivElement> {\n description: string\n}\n\n/**\n * The TabList component provides a container for tab elements.\n * @param description - a description of what the tab list contains\n * @example\n * ```tsx\n * <TabList description=\"Button details\">\n * <Tab id=\"overview\">Overview</Tab>\n * <Tab id=\"guidelines\">Guidelines</Tab>\n * </TabList>\n * ```\n */\nexport function TabList(props: PropsWithChildren<TabListProps>) {\n const { description, ...nativeProps } = props\n const { id } = useTabsContext()\n\n return (\n <div\n {...nativeProps}\n aria-describedby={description}\n className={cx(\n nativeProps.className,\n hstack({\n borderBottom: '1px solid',\n borderBottomColor: 'action.border.100',\n gap: '0',\n w: 'full',\n }),\n )}\n id={id ?? nativeProps.id}\n />\n )\n}\n"],"mappings":";;;;;AAEA,SAAS,UAAU;AACnB,SAAS,cAAc;AA6BnB;AALG,SAAS,QAAQ,OAAwC;AAC9D,QAAM,EAAE,aAAa,GAAG,YAAY,IAAI;AACxC,QAAM,EAAE,GAAG,IAAI,eAAe;AAE9B,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ,oBAAkB;AAAA,MAClB,WAAW;AAAA,QACT,YAAY;AAAA,QACZ,OAAO;AAAA,UACL,cAAc;AAAA,UACd,mBAAmB;AAAA,UACnB,KAAK;AAAA,UACL,GAAG;AAAA,QACL,CAAC;AAAA,MACH;AAAA,MACA,IAAI,MAAM,YAAY;AAAA;AAAA,EACxB;AAEJ;","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
useTabsContext
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-DQOYTLGB.js";
|
|
4
4
|
|
|
5
5
|
// src/aria-helpers/tabs.aria.ts
|
|
6
6
|
import { useEffect, useState } from "react";
|
|
@@ -62,4 +62,4 @@ function useTabsKeyboardNavigation() {
|
|
|
62
62
|
export {
|
|
63
63
|
useTabsKeyboardNavigation
|
|
64
64
|
};
|
|
65
|
-
//# sourceMappingURL=chunk-
|
|
65
|
+
//# sourceMappingURL=chunk-BT2B5C7M.js.map
|
|
@@ -10,28 +10,34 @@ import {
|
|
|
10
10
|
import { jsx } from "react/jsx-runtime";
|
|
11
11
|
var TabsContext = createContext(null);
|
|
12
12
|
function Tabs(props) {
|
|
13
|
-
const { cache } = props;
|
|
14
|
-
const [
|
|
13
|
+
const { cache, active, id } = props;
|
|
14
|
+
const [activeTab, setActiveTab] = useState(() => cache ? "" : active ?? "");
|
|
15
15
|
const tabs = useRef([]);
|
|
16
|
+
const uuid = useMemo(() => {
|
|
17
|
+
return id ? `cerberus-tabs-${id}` : "cerberus-tabs";
|
|
18
|
+
}, [id]);
|
|
16
19
|
const value = useMemo(
|
|
17
20
|
() => ({
|
|
18
|
-
active,
|
|
19
21
|
tabs,
|
|
20
|
-
|
|
22
|
+
id: uuid,
|
|
23
|
+
active: activeTab,
|
|
24
|
+
onTabUpdate: setActiveTab
|
|
21
25
|
}),
|
|
22
|
-
[
|
|
26
|
+
[activeTab, setActiveTab, uuid, tabs]
|
|
23
27
|
);
|
|
24
28
|
useEffect(() => {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
29
|
+
if (cache) {
|
|
30
|
+
const cachedTab = window.localStorage.getItem(uuid);
|
|
31
|
+
setActiveTab(
|
|
32
|
+
cache ? cachedTab || (props.active ?? "") : props.active ?? ""
|
|
33
|
+
);
|
|
28
34
|
}
|
|
29
|
-
}, [cache]);
|
|
35
|
+
}, [cache, active, uuid]);
|
|
30
36
|
useEffect(() => {
|
|
31
|
-
if (cache) {
|
|
32
|
-
window.localStorage.setItem(
|
|
37
|
+
if (cache && activeTab) {
|
|
38
|
+
window.localStorage.setItem(uuid, activeTab);
|
|
33
39
|
}
|
|
34
|
-
}, [
|
|
40
|
+
}, [activeTab, cache]);
|
|
35
41
|
return /* @__PURE__ */ jsx(TabsContext.Provider, { value, children: props.children });
|
|
36
42
|
}
|
|
37
43
|
function useTabsContext() {
|
|
@@ -47,4 +53,4 @@ export {
|
|
|
47
53
|
Tabs,
|
|
48
54
|
useTabsContext
|
|
49
55
|
};
|
|
50
|
-
//# sourceMappingURL=chunk-
|
|
56
|
+
//# sourceMappingURL=chunk-DQOYTLGB.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/context/tabs.tsx"],"sourcesContent":["'use client'\n\nimport {\n createContext,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type MutableRefObject,\n type PropsWithChildren,\n} from 'react'\n\n/**\n * This module provides a Tabs component and a hook to access its context.\n * @module\n */\n\nexport interface TabsContextValue {\n tabs: MutableRefObject<HTMLButtonElement[]>\n id: string\n active: string\n onTabUpdate: (active: string) => void\n}\n\nexport const TabsContext = createContext<TabsContextValue | null>(null)\n\nexport interface TabsProps {\n id?: string\n active?: string\n cache?: boolean\n}\n\n/**\n * The Tabs component provides a context to manage tab state.\n * @param active - the default active tab id,\n * @param cache - whether to cache the active tab state in local storage\n * @example\n * ```tsx\n * <Tabs cache>\n * <TabList description=\"Button details\">\n * <Tab id=\"overview\">Overview</Tab>\n * <Tab id=\"guidelines\">Guidelines</Tab>\n * </TabList>\n * <TabPanels>\n * <TabPanel id=\"overview\">Overview content</TabPanel>\n * <TabPanel id=\"guidelines\">Guidelines content</TabPanel>\n * </TabPanels>\n * </Tabs>\n * ```\n */\nexport function Tabs(props: PropsWithChildren<TabsProps>): JSX.Element {\n const { cache, active, id } = props\n const [activeTab, setActiveTab] = useState(() => (cache ? '' : active ?? ''))\n const tabs = useRef<HTMLButtonElement[]>([])\n const uuid = useMemo(() => {\n return id ? `cerberus-tabs-${id}` : 'cerberus-tabs'\n }, [id])\n\n const value = useMemo(\n () => ({\n tabs,\n id: uuid,\n active: activeTab,\n onTabUpdate: setActiveTab,\n }),\n [activeTab, setActiveTab, uuid, tabs],\n )\n\n // Get the active tab from local storage\n useEffect(() => {\n if (cache) {\n const cachedTab = window.localStorage.getItem(uuid)\n setActiveTab(\n cache ? cachedTab || (props.active ?? '') : props.active ?? '',\n )\n }\n }, [cache, active, uuid])\n\n // Update the active tab in local storage\n useEffect(() => {\n if (cache && activeTab) {\n window.localStorage.setItem(uuid, activeTab)\n }\n }, [activeTab, cache])\n\n return (\n <TabsContext.Provider value={value}>{props.children}</TabsContext.Provider>\n )\n}\n\nexport function useTabsContext(): TabsContextValue {\n const context = useContext(TabsContext)\n if (!context) {\n throw new Error('useTabsContext must be used within a Tabs Provider.')\n }\n return context\n}\n"],"mappings":";AAEA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AA4EH;AA9DG,IAAM,cAAc,cAAuC,IAAI;AA0B/D,SAAS,KAAK,OAAkD;AACrE,QAAM,EAAE,OAAO,QAAQ,GAAG,IAAI;AAC9B,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,MAAO,QAAQ,KAAK,UAAU,EAAG;AAC5E,QAAM,OAAO,OAA4B,CAAC,CAAC;AAC3C,QAAM,OAAO,QAAQ,MAAM;AACzB,WAAO,KAAK,iBAAiB,EAAE,KAAK;AAAA,EACtC,GAAG,CAAC,EAAE,CAAC;AAEP,QAAM,QAAQ;AAAA,IACZ,OAAO;AAAA,MACL;AAAA,MACA,IAAI;AAAA,MACJ,QAAQ;AAAA,MACR,aAAa;AAAA,IACf;AAAA,IACA,CAAC,WAAW,cAAc,MAAM,IAAI;AAAA,EACtC;AAGA,YAAU,MAAM;AACd,QAAI,OAAO;AACT,YAAM,YAAY,OAAO,aAAa,QAAQ,IAAI;AAClD;AAAA,QACE,QAAQ,cAAc,MAAM,UAAU,MAAM,MAAM,UAAU;AAAA,MAC9D;AAAA,IACF;AAAA,EACF,GAAG,CAAC,OAAO,QAAQ,IAAI,CAAC;AAGxB,YAAU,MAAM;AACd,QAAI,SAAS,WAAW;AACtB,aAAO,aAAa,QAAQ,MAAM,SAAS;AAAA,IAC7C;AAAA,EACF,GAAG,CAAC,WAAW,KAAK,CAAC;AAErB,SACE,oBAAC,YAAY,UAAZ,EAAqB,OAAe,gBAAM,UAAS;AAExD;AAEO,SAAS,iBAAmC;AACjD,QAAM,UAAU,WAAW,WAAW;AACtC,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,qDAAqD;AAAA,EACvE;AACA,SAAO;AACT;","names":[]}
|
|
@@ -1,22 +1,26 @@
|
|
|
1
1
|
import {
|
|
2
2
|
useTabsKeyboardNavigation
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-BT2B5C7M.js";
|
|
4
4
|
import {
|
|
5
5
|
useTabsContext
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-DQOYTLGB.js";
|
|
7
7
|
|
|
8
8
|
// src/components/Tab.tsx
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
useMemo,
|
|
11
|
+
useTransition
|
|
12
|
+
} from "react";
|
|
10
13
|
import { css, cx } from "@cerberus/styled-system/css";
|
|
11
14
|
import { jsx } from "react/jsx-runtime";
|
|
12
15
|
function Tab(props) {
|
|
13
16
|
const { value, ...nativeProps } = props;
|
|
14
17
|
const { active, onTabUpdate } = useTabsContext();
|
|
18
|
+
const [isPending, startTransition] = useTransition();
|
|
15
19
|
const { ref } = useTabsKeyboardNavigation();
|
|
16
20
|
const isActive = useMemo(() => active === value, [active, value]);
|
|
17
21
|
function handleClick(e) {
|
|
18
22
|
props.onClick?.(e);
|
|
19
|
-
onTabUpdate(e.currentTarget.value);
|
|
23
|
+
startTransition(() => onTabUpdate(e.currentTarget.value));
|
|
20
24
|
}
|
|
21
25
|
return /* @__PURE__ */ jsx(
|
|
22
26
|
"button",
|
|
@@ -24,6 +28,7 @@ function Tab(props) {
|
|
|
24
28
|
...nativeProps,
|
|
25
29
|
...!isActive && { tabIndex: -1 },
|
|
26
30
|
"aria-controls": `panel:${value}`,
|
|
31
|
+
"aria-busy": isPending,
|
|
27
32
|
"aria-selected": isActive,
|
|
28
33
|
id: value,
|
|
29
34
|
className: cx(nativeProps.className, btnStyles),
|
|
@@ -117,4 +122,4 @@ var btnStyles = css({
|
|
|
117
122
|
export {
|
|
118
123
|
Tab
|
|
119
124
|
};
|
|
120
|
-
//# sourceMappingURL=chunk-
|
|
125
|
+
//# sourceMappingURL=chunk-IQP6HSC4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/Tab.tsx"],"sourcesContent":["'use client'\n\nimport {\n useMemo,\n useTransition,\n type ButtonHTMLAttributes,\n type MouseEvent,\n} from 'react'\nimport { useTabsContext } from '../context/tabs'\nimport { css, cx } from '@cerberus/styled-system/css'\nimport { useTabsKeyboardNavigation } from '../aria-helpers/tabs.aria'\n\n/**\n * This module provides a Tab component.\n * @module\n */\n\nexport interface TabProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n value: string\n}\n\n/**\n * The Tab component provides a tab element to be used in a TabList.\n * @definition [ARIA Target Size](https://www.w3.org/WAI/WCAG21/Understanding/target-size.html#:~:text=Understanding%20SC%202.5.,%3ATarget%20Size%20(Level%20AAA)&text=The%20size%20of%20the%20target,Equivalent)\n * @definition [Tab docs](https://cerberus.digitalu.design/react/tabs)\n * @param value - the id of the tab that will be tracked as the active tab and used for aria attributes\n * @example\n * ```tsx\n * <Tab value=\"overview\">\n * Overview\n * </Tab>\n * ```\n */\nexport function Tab(props: TabProps) {\n const { value, ...nativeProps } = props\n const { active, onTabUpdate } = useTabsContext()\n const [isPending, startTransition] = useTransition()\n const { ref } = useTabsKeyboardNavigation()\n const isActive = useMemo(() => active === value, [active, value])\n\n function handleClick(e: MouseEvent<HTMLButtonElement>) {\n props.onClick?.(e)\n startTransition(() => onTabUpdate(e.currentTarget.value))\n }\n\n return (\n <button\n {...nativeProps}\n {...(!isActive && { tabIndex: -1 })}\n aria-controls={`panel:${value}`}\n aria-busy={isPending}\n aria-selected={isActive}\n id={value}\n className={cx(nativeProps.className, btnStyles)}\n onClick={handleClick}\n role=\"tab\"\n ref={ref}\n value={value}\n />\n )\n}\n\nconst btnStyles = css({\n alignItems: 'center',\n display: 'inline-flex',\n borderTopLeftRadius: 'md',\n borderTopRightRadius: 'md',\n fontSize: 'sm',\n fontWeight: '600',\n gap: '2',\n h: '2.75rem',\n justifyContent: 'center',\n position: 'relative',\n pxi: '4',\n zIndex: 'base',\n _motionSafe: {\n transition: 'all 200ms ease-in-out',\n _before: {\n transitionProperty: 'height',\n transitionDuration: '200ms',\n transitionTimingFunction: 'ease-in-out',\n },\n _after: {\n transitionProperty: 'height',\n transitionDuration: '200ms',\n transitionTimingFunction: 'ease-in-out',\n },\n },\n _before: {\n bgColor: 'action.border.initial',\n bottom: '0',\n content: '\"\"',\n h: '0',\n position: 'absolute',\n left: '0',\n right: '0',\n w: 'full',\n willChange: 'height',\n zIndex: 'decorator',\n },\n _after: {\n borderTopLeftRadius: 'md',\n borderTopRightRadius: 'md',\n bottom: '0',\n bgColor: 'neutral.surface.100',\n content: '\"\"',\n left: '0',\n position: 'absolute',\n right: '0',\n h: '0',\n w: 'full',\n willChange: 'height',\n zIndex: '-1',\n },\n _hover: {\n _after: {\n h: 'full',\n },\n },\n _focusVisible: {\n boxShadow: 'none',\n outline: '3px solid',\n outlineColor: 'action.border.focus',\n outlineOffset: '2px',\n },\n _disabled: {\n cursor: 'not-allowed',\n opacity: '0.5',\n },\n _selected: {\n color: 'action.text.200',\n _before: {\n h: '3px',\n },\n _hover: {\n _after: {\n h: '0',\n },\n },\n },\n})\n"],"mappings":";;;;;;;;AAEA;AAAA,EACE;AAAA,EACA;AAAA,OAGK;AAEP,SAAS,KAAK,UAAU;AAqCpB;AAbG,SAAS,IAAI,OAAiB;AACnC,QAAM,EAAE,OAAO,GAAG,YAAY,IAAI;AAClC,QAAM,EAAE,QAAQ,YAAY,IAAI,eAAe;AAC/C,QAAM,CAAC,WAAW,eAAe,IAAI,cAAc;AACnD,QAAM,EAAE,IAAI,IAAI,0BAA0B;AAC1C,QAAM,WAAW,QAAQ,MAAM,WAAW,OAAO,CAAC,QAAQ,KAAK,CAAC;AAEhE,WAAS,YAAY,GAAkC;AACrD,UAAM,UAAU,CAAC;AACjB,oBAAgB,MAAM,YAAY,EAAE,cAAc,KAAK,CAAC;AAAA,EAC1D;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACH,GAAI,CAAC,YAAY,EAAE,UAAU,GAAG;AAAA,MACjC,iBAAe,SAAS,KAAK;AAAA,MAC7B,aAAW;AAAA,MACX,iBAAe;AAAA,MACf,IAAI;AAAA,MACJ,WAAW,GAAG,YAAY,WAAW,SAAS;AAAA,MAC9C,SAAS;AAAA,MACT,MAAK;AAAA,MACL;AAAA,MACA;AAAA;AAAA,EACF;AAEJ;AAEA,IAAM,YAAY,IAAI;AAAA,EACpB,YAAY;AAAA,EACZ,SAAS;AAAA,EACT,qBAAqB;AAAA,EACrB,sBAAsB;AAAA,EACtB,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,KAAK;AAAA,EACL,GAAG;AAAA,EACH,gBAAgB;AAAA,EAChB,UAAU;AAAA,EACV,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,aAAa;AAAA,IACX,YAAY;AAAA,IACZ,SAAS;AAAA,MACP,oBAAoB;AAAA,MACpB,oBAAoB;AAAA,MACpB,0BAA0B;AAAA,IAC5B;AAAA,IACA,QAAQ;AAAA,MACN,oBAAoB;AAAA,MACpB,oBAAoB;AAAA,MACpB,0BAA0B;AAAA,IAC5B;AAAA,EACF;AAAA,EACA,SAAS;AAAA,IACP,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,GAAG;AAAA,IACH,UAAU;AAAA,IACV,MAAM;AAAA,IACN,OAAO;AAAA,IACP,GAAG;AAAA,IACH,YAAY;AAAA,IACZ,QAAQ;AAAA,EACV;AAAA,EACA,QAAQ;AAAA,IACN,qBAAqB;AAAA,IACrB,sBAAsB;AAAA,IACtB,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,SAAS;AAAA,IACT,MAAM;AAAA,IACN,UAAU;AAAA,IACV,OAAO;AAAA,IACP,GAAG;AAAA,IACH,GAAG;AAAA,IACH,YAAY;AAAA,IACZ,QAAQ;AAAA,EACV;AAAA,EACA,QAAQ;AAAA,IACN,QAAQ;AAAA,MACN,GAAG;AAAA,IACL;AAAA,EACF;AAAA,EACA,eAAe;AAAA,IACb,WAAW;AAAA,IACX,SAAS;AAAA,IACT,cAAc;AAAA,IACd,eAAe;AAAA,EACjB;AAAA,EACA,WAAW;AAAA,IACT,QAAQ;AAAA,IACR,SAAS;AAAA,EACX;AAAA,EACA,WAAW;AAAA,IACT,OAAO;AAAA,IACP,SAAS;AAAA,MACP,GAAG;AAAA,IACL;AAAA,IACA,QAAQ;AAAA,MACN,QAAQ;AAAA,QACN,GAAG;AAAA,MACL;AAAA,IACF;AAAA,EACF;AACF,CAAC;","names":[]}
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-R4H3352X.js";
|
|
4
4
|
import {
|
|
5
5
|
useTabsContext
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-DQOYTLGB.js";
|
|
7
7
|
|
|
8
8
|
// src/components/TabPanel.tsx
|
|
9
9
|
import { css, cx } from "@cerberus/styled-system/css";
|
|
@@ -40,4 +40,4 @@ function TabPanel(props) {
|
|
|
40
40
|
export {
|
|
41
41
|
TabPanel
|
|
42
42
|
};
|
|
43
|
-
//# sourceMappingURL=chunk-
|
|
43
|
+
//# sourceMappingURL=chunk-SVZU6LPF.js.map
|
package/build/modern/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
TabPanel
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-SVZU6LPF.js";
|
|
4
4
|
import {
|
|
5
5
|
Input
|
|
6
6
|
} from "./chunk-LD5ZV46F.js";
|
|
@@ -26,22 +26,22 @@ import {
|
|
|
26
26
|
} from "./chunk-R4H3352X.js";
|
|
27
27
|
import {
|
|
28
28
|
Tab
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-IQP6HSC4.js";
|
|
30
30
|
import {
|
|
31
31
|
TabList
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-5GSXIYD3.js";
|
|
33
33
|
import "./chunk-55J6XMHW.js";
|
|
34
34
|
import {
|
|
35
35
|
createNavTriggerProps
|
|
36
36
|
} from "./chunk-JF76VIL3.js";
|
|
37
37
|
import {
|
|
38
38
|
useTabsKeyboardNavigation
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-BT2B5C7M.js";
|
|
40
40
|
import {
|
|
41
41
|
Tabs,
|
|
42
42
|
TabsContext,
|
|
43
43
|
useTabsContext
|
|
44
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-DQOYTLGB.js";
|
|
45
45
|
import {
|
|
46
46
|
MODE_KEY,
|
|
47
47
|
THEME_KEY,
|
package/package.json
CHANGED
package/src/components/Tab.tsx
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
useMemo,
|
|
5
|
+
useTransition,
|
|
6
|
+
type ButtonHTMLAttributes,
|
|
7
|
+
type MouseEvent,
|
|
8
|
+
} from 'react'
|
|
4
9
|
import { useTabsContext } from '../context/tabs'
|
|
5
10
|
import { css, cx } from '@cerberus/styled-system/css'
|
|
6
11
|
import { useTabsKeyboardNavigation } from '../aria-helpers/tabs.aria'
|
|
@@ -29,12 +34,13 @@ export interface TabProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
|
|
29
34
|
export function Tab(props: TabProps) {
|
|
30
35
|
const { value, ...nativeProps } = props
|
|
31
36
|
const { active, onTabUpdate } = useTabsContext()
|
|
37
|
+
const [isPending, startTransition] = useTransition()
|
|
32
38
|
const { ref } = useTabsKeyboardNavigation()
|
|
33
39
|
const isActive = useMemo(() => active === value, [active, value])
|
|
34
40
|
|
|
35
41
|
function handleClick(e: MouseEvent<HTMLButtonElement>) {
|
|
36
42
|
props.onClick?.(e)
|
|
37
|
-
onTabUpdate(e.currentTarget.value)
|
|
43
|
+
startTransition(() => onTabUpdate(e.currentTarget.value))
|
|
38
44
|
}
|
|
39
45
|
|
|
40
46
|
return (
|
|
@@ -42,6 +48,7 @@ export function Tab(props: TabProps) {
|
|
|
42
48
|
{...nativeProps}
|
|
43
49
|
{...(!isActive && { tabIndex: -1 })}
|
|
44
50
|
aria-controls={`panel:${value}`}
|
|
51
|
+
aria-busy={isPending}
|
|
45
52
|
aria-selected={isActive}
|
|
46
53
|
id={value}
|
|
47
54
|
className={cx(nativeProps.className, btnStyles)}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
1
3
|
import { cx } from '@cerberus/styled-system/css'
|
|
2
4
|
import { hstack } from '@cerberus/styled-system/patterns'
|
|
3
5
|
import type { HTMLAttributes, PropsWithChildren } from 'react'
|
|
6
|
+
import { useTabsContext } from '../context/tabs'
|
|
4
7
|
|
|
5
8
|
/**
|
|
6
9
|
* This module provides a TabList component.
|
|
@@ -24,6 +27,8 @@ export interface TabListProps extends HTMLAttributes<HTMLDivElement> {
|
|
|
24
27
|
*/
|
|
25
28
|
export function TabList(props: PropsWithChildren<TabListProps>) {
|
|
26
29
|
const { description, ...nativeProps } = props
|
|
30
|
+
const { id } = useTabsContext()
|
|
31
|
+
|
|
27
32
|
return (
|
|
28
33
|
<div
|
|
29
34
|
{...nativeProps}
|
|
@@ -37,6 +42,7 @@ export function TabList(props: PropsWithChildren<TabListProps>) {
|
|
|
37
42
|
w: 'full',
|
|
38
43
|
}),
|
|
39
44
|
)}
|
|
45
|
+
id={id ?? nativeProps.id}
|
|
40
46
|
/>
|
|
41
47
|
)
|
|
42
48
|
}
|
package/src/context/tabs.tsx
CHANGED
|
@@ -17,14 +17,16 @@ import {
|
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
export interface TabsContextValue {
|
|
20
|
-
active: string
|
|
21
20
|
tabs: MutableRefObject<HTMLButtonElement[]>
|
|
21
|
+
id: string
|
|
22
|
+
active: string
|
|
22
23
|
onTabUpdate: (active: string) => void
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
export const TabsContext = createContext<TabsContextValue | null>(null)
|
|
26
27
|
|
|
27
28
|
export interface TabsProps {
|
|
29
|
+
id?: string
|
|
28
30
|
active?: string
|
|
29
31
|
cache?: boolean
|
|
30
32
|
}
|
|
@@ -48,31 +50,39 @@ export interface TabsProps {
|
|
|
48
50
|
* ```
|
|
49
51
|
*/
|
|
50
52
|
export function Tabs(props: PropsWithChildren<TabsProps>): JSX.Element {
|
|
51
|
-
const { cache } = props
|
|
52
|
-
const [
|
|
53
|
+
const { cache, active, id } = props
|
|
54
|
+
const [activeTab, setActiveTab] = useState(() => (cache ? '' : active ?? ''))
|
|
53
55
|
const tabs = useRef<HTMLButtonElement[]>([])
|
|
56
|
+
const uuid = useMemo(() => {
|
|
57
|
+
return id ? `cerberus-tabs-${id}` : 'cerberus-tabs'
|
|
58
|
+
}, [id])
|
|
54
59
|
|
|
55
60
|
const value = useMemo(
|
|
56
61
|
() => ({
|
|
57
|
-
active,
|
|
58
62
|
tabs,
|
|
59
|
-
|
|
63
|
+
id: uuid,
|
|
64
|
+
active: activeTab,
|
|
65
|
+
onTabUpdate: setActiveTab,
|
|
60
66
|
}),
|
|
61
|
-
[
|
|
67
|
+
[activeTab, setActiveTab, uuid, tabs],
|
|
62
68
|
)
|
|
63
69
|
|
|
70
|
+
// Get the active tab from local storage
|
|
64
71
|
useEffect(() => {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
72
|
+
if (cache) {
|
|
73
|
+
const cachedTab = window.localStorage.getItem(uuid)
|
|
74
|
+
setActiveTab(
|
|
75
|
+
cache ? cachedTab || (props.active ?? '') : props.active ?? '',
|
|
76
|
+
)
|
|
68
77
|
}
|
|
69
|
-
}, [cache])
|
|
78
|
+
}, [cache, active, uuid])
|
|
70
79
|
|
|
80
|
+
// Update the active tab in local storage
|
|
71
81
|
useEffect(() => {
|
|
72
|
-
if (cache) {
|
|
73
|
-
window.localStorage.setItem(
|
|
82
|
+
if (cache && activeTab) {
|
|
83
|
+
window.localStorage.setItem(uuid, activeTab)
|
|
74
84
|
}
|
|
75
|
-
}, [
|
|
85
|
+
}, [activeTab, cache])
|
|
76
86
|
|
|
77
87
|
return (
|
|
78
88
|
<TabsContext.Provider value={value}>{props.children}</TabsContext.Provider>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/Tab.tsx"],"sourcesContent":["'use client'\n\nimport { useMemo, type ButtonHTMLAttributes, type MouseEvent } from 'react'\nimport { useTabsContext } from '../context/tabs'\nimport { css, cx } from '@cerberus/styled-system/css'\nimport { useTabsKeyboardNavigation } from '../aria-helpers/tabs.aria'\n\n/**\n * This module provides a Tab component.\n * @module\n */\n\nexport interface TabProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n value: string\n}\n\n/**\n * The Tab component provides a tab element to be used in a TabList.\n * @definition [ARIA Target Size](https://www.w3.org/WAI/WCAG21/Understanding/target-size.html#:~:text=Understanding%20SC%202.5.,%3ATarget%20Size%20(Level%20AAA)&text=The%20size%20of%20the%20target,Equivalent)\n * @definition [Tab docs](https://cerberus.digitalu.design/react/tabs)\n * @param value - the id of the tab that will be tracked as the active tab and used for aria attributes\n * @example\n * ```tsx\n * <Tab value=\"overview\">\n * Overview\n * </Tab>\n * ```\n */\nexport function Tab(props: TabProps) {\n const { value, ...nativeProps } = props\n const { active, onTabUpdate } = useTabsContext()\n const { ref } = useTabsKeyboardNavigation()\n const isActive = useMemo(() => active === value, [active, value])\n\n function handleClick(e: MouseEvent<HTMLButtonElement>) {\n props.onClick?.(e)\n onTabUpdate(e.currentTarget.value)\n }\n\n return (\n <button\n {...nativeProps}\n {...(!isActive && { tabIndex: -1 })}\n aria-controls={`panel:${value}`}\n aria-selected={isActive}\n id={value}\n className={cx(nativeProps.className, btnStyles)}\n onClick={handleClick}\n role=\"tab\"\n ref={ref}\n value={value}\n />\n )\n}\n\nconst btnStyles = css({\n alignItems: 'center',\n display: 'inline-flex',\n borderTopLeftRadius: 'md',\n borderTopRightRadius: 'md',\n fontSize: 'sm',\n fontWeight: '600',\n gap: '2',\n h: '2.75rem',\n justifyContent: 'center',\n position: 'relative',\n pxi: '4',\n zIndex: 'base',\n _motionSafe: {\n transition: 'all 200ms ease-in-out',\n _before: {\n transitionProperty: 'height',\n transitionDuration: '200ms',\n transitionTimingFunction: 'ease-in-out',\n },\n _after: {\n transitionProperty: 'height',\n transitionDuration: '200ms',\n transitionTimingFunction: 'ease-in-out',\n },\n },\n _before: {\n bgColor: 'action.border.initial',\n bottom: '0',\n content: '\"\"',\n h: '0',\n position: 'absolute',\n left: '0',\n right: '0',\n w: 'full',\n willChange: 'height',\n zIndex: 'decorator',\n },\n _after: {\n borderTopLeftRadius: 'md',\n borderTopRightRadius: 'md',\n bottom: '0',\n bgColor: 'neutral.surface.100',\n content: '\"\"',\n left: '0',\n position: 'absolute',\n right: '0',\n h: '0',\n w: 'full',\n willChange: 'height',\n zIndex: '-1',\n },\n _hover: {\n _after: {\n h: 'full',\n },\n },\n _focusVisible: {\n boxShadow: 'none',\n outline: '3px solid',\n outlineColor: 'action.border.focus',\n outlineOffset: '2px',\n },\n _disabled: {\n cursor: 'not-allowed',\n opacity: '0.5',\n },\n _selected: {\n color: 'action.text.200',\n _before: {\n h: '3px',\n },\n _hover: {\n _after: {\n h: '0',\n },\n },\n },\n})\n"],"mappings":";;;;;;;;AAEA,SAAS,eAA2D;AAEpE,SAAS,KAAK,UAAU;AAoCpB;AAZG,SAAS,IAAI,OAAiB;AACnC,QAAM,EAAE,OAAO,GAAG,YAAY,IAAI;AAClC,QAAM,EAAE,QAAQ,YAAY,IAAI,eAAe;AAC/C,QAAM,EAAE,IAAI,IAAI,0BAA0B;AAC1C,QAAM,WAAW,QAAQ,MAAM,WAAW,OAAO,CAAC,QAAQ,KAAK,CAAC;AAEhE,WAAS,YAAY,GAAkC;AAlCzD;AAmCI,gBAAM,YAAN,+BAAgB;AAChB,gBAAY,EAAE,cAAc,KAAK;AAAA,EACnC;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACH,GAAI,CAAC,YAAY,EAAE,UAAU,GAAG;AAAA,MACjC,iBAAe,SAAS,KAAK;AAAA,MAC7B,iBAAe;AAAA,MACf,IAAI;AAAA,MACJ,WAAW,GAAG,YAAY,WAAW,SAAS;AAAA,MAC9C,SAAS;AAAA,MACT,MAAK;AAAA,MACL;AAAA,MACA;AAAA;AAAA,EACF;AAEJ;AAEA,IAAM,YAAY,IAAI;AAAA,EACpB,YAAY;AAAA,EACZ,SAAS;AAAA,EACT,qBAAqB;AAAA,EACrB,sBAAsB;AAAA,EACtB,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,KAAK;AAAA,EACL,GAAG;AAAA,EACH,gBAAgB;AAAA,EAChB,UAAU;AAAA,EACV,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,aAAa;AAAA,IACX,YAAY;AAAA,IACZ,SAAS;AAAA,MACP,oBAAoB;AAAA,MACpB,oBAAoB;AAAA,MACpB,0BAA0B;AAAA,IAC5B;AAAA,IACA,QAAQ;AAAA,MACN,oBAAoB;AAAA,MACpB,oBAAoB;AAAA,MACpB,0BAA0B;AAAA,IAC5B;AAAA,EACF;AAAA,EACA,SAAS;AAAA,IACP,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,GAAG;AAAA,IACH,UAAU;AAAA,IACV,MAAM;AAAA,IACN,OAAO;AAAA,IACP,GAAG;AAAA,IACH,YAAY;AAAA,IACZ,QAAQ;AAAA,EACV;AAAA,EACA,QAAQ;AAAA,IACN,qBAAqB;AAAA,IACrB,sBAAsB;AAAA,IACtB,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,SAAS;AAAA,IACT,MAAM;AAAA,IACN,UAAU;AAAA,IACV,OAAO;AAAA,IACP,GAAG;AAAA,IACH,GAAG;AAAA,IACH,YAAY;AAAA,IACZ,QAAQ;AAAA,EACV;AAAA,EACA,QAAQ;AAAA,IACN,QAAQ;AAAA,MACN,GAAG;AAAA,IACL;AAAA,EACF;AAAA,EACA,eAAe;AAAA,IACb,WAAW;AAAA,IACX,SAAS;AAAA,IACT,cAAc;AAAA,IACd,eAAe;AAAA,EACjB;AAAA,EACA,WAAW;AAAA,IACT,QAAQ;AAAA,IACR,SAAS;AAAA,EACX;AAAA,EACA,WAAW;AAAA,IACT,OAAO;AAAA,IACP,SAAS;AAAA,MACP,GAAG;AAAA,IACL;AAAA,IACA,QAAQ;AAAA,MACN,QAAQ;AAAA,QACN,GAAG;AAAA,MACL;AAAA,IACF;AAAA,EACF;AACF,CAAC;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/context/tabs.tsx"],"sourcesContent":["'use client'\n\nimport {\n createContext,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type MutableRefObject,\n type PropsWithChildren,\n} from 'react'\n\n/**\n * This module provides a Tabs component and a hook to access its context.\n * @module\n */\n\nexport interface TabsContextValue {\n active: string\n tabs: MutableRefObject<HTMLButtonElement[]>\n onTabUpdate: (active: string) => void\n}\n\nexport const TabsContext = createContext<TabsContextValue | null>(null)\n\nexport interface TabsProps {\n active?: string\n cache?: boolean\n}\n\n/**\n * The Tabs component provides a context to manage tab state.\n * @param active - the default active tab id,\n * @param cache - whether to cache the active tab state in local storage\n * @example\n * ```tsx\n * <Tabs cache>\n * <TabList description=\"Button details\">\n * <Tab id=\"overview\">Overview</Tab>\n * <Tab id=\"guidelines\">Guidelines</Tab>\n * </TabList>\n * <TabPanels>\n * <TabPanel id=\"overview\">Overview content</TabPanel>\n * <TabPanel id=\"guidelines\">Guidelines content</TabPanel>\n * </TabPanels>\n * </Tabs>\n * ```\n */\nexport function Tabs(props: PropsWithChildren<TabsProps>): JSX.Element {\n const { cache } = props\n const [active, setActive] = useState(() => (cache ? '' : props.active ?? ''))\n const tabs = useRef<HTMLButtonElement[]>([])\n\n const value = useMemo(\n () => ({\n active,\n tabs,\n onTabUpdate: setActive,\n }),\n [active, setActive],\n )\n\n useEffect(() => {\n const cachedTab = window.localStorage.getItem('cerberus-tabs')\n if (cache && cachedTab) {\n setActive(cachedTab)\n }\n }, [cache])\n\n useEffect(() => {\n if (cache) {\n window.localStorage.setItem('cerberus-tabs', active)\n }\n }, [active, cache])\n\n return (\n <TabsContext.Provider value={value}>{props.children}</TabsContext.Provider>\n )\n}\n\nexport function useTabsContext(): TabsContextValue {\n const context = useContext(TabsContext)\n if (!context) {\n throw new Error('useTabsContext must be used within a Tabs Provider.')\n }\n return context\n}\n"],"mappings":";AAEA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AAkEH;AArDG,IAAM,cAAc,cAAuC,IAAI;AAyB/D,SAAS,KAAK,OAAkD;AACrE,QAAM,EAAE,MAAM,IAAI;AAClB,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,MAAO,QAAQ,KAAK,MAAM,UAAU,EAAG;AAC5E,QAAM,OAAO,OAA4B,CAAC,CAAC;AAE3C,QAAM,QAAQ;AAAA,IACZ,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,aAAa;AAAA,IACf;AAAA,IACA,CAAC,QAAQ,SAAS;AAAA,EACpB;AAEA,YAAU,MAAM;AACd,UAAM,YAAY,OAAO,aAAa,QAAQ,eAAe;AAC7D,QAAI,SAAS,WAAW;AACtB,gBAAU,SAAS;AAAA,IACrB;AAAA,EACF,GAAG,CAAC,KAAK,CAAC;AAEV,YAAU,MAAM;AACd,QAAI,OAAO;AACT,aAAO,aAAa,QAAQ,iBAAiB,MAAM;AAAA,IACrD;AAAA,EACF,GAAG,CAAC,QAAQ,KAAK,CAAC;AAElB,SACE,oBAAC,YAAY,UAAZ,EAAqB,OAAe,gBAAM,UAAS;AAExD;AAEO,SAAS,iBAAmC;AACjD,QAAM,UAAU,WAAW,WAAW;AACtC,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,qDAAqD;AAAA,EACvE;AACA,SAAO;AACT;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/TabList.tsx"],"sourcesContent":["import { cx } from '@cerberus/styled-system/css'\nimport { hstack } from '@cerberus/styled-system/patterns'\nimport type { HTMLAttributes, PropsWithChildren } from 'react'\n\n/**\n * This module provides a TabList component.\n * @module\n */\n\nexport interface TabListProps extends HTMLAttributes<HTMLDivElement> {\n description: string\n}\n\n/**\n * The TabList component provides a container for tab elements.\n * @param description - a description of what the tab list contains\n * @example\n * ```tsx\n * <TabList description=\"Button details\">\n * <Tab id=\"overview\">Overview</Tab>\n * <Tab id=\"guidelines\">Guidelines</Tab>\n * </TabList>\n * ```\n */\nexport function TabList(props: PropsWithChildren<TabListProps>) {\n const { description, ...nativeProps } = props\n return (\n <div\n {...nativeProps}\n aria-describedby={description}\n className={cx(\n nativeProps.className,\n hstack({\n borderBottom: '1px solid',\n borderBottomColor: 'action.border.100',\n gap: '0',\n w: 'full',\n }),\n )}\n />\n )\n}\n"],"mappings":";AAAA,SAAS,UAAU;AACnB,SAAS,cAAc;AA0BnB;AAHG,SAAS,QAAQ,OAAwC;AAC9D,QAAM,EAAE,aAAa,GAAG,YAAY,IAAI;AACxC,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ,oBAAkB;AAAA,MAClB,WAAW;AAAA,QACT,YAAY;AAAA,QACZ,OAAO;AAAA,UACL,cAAc;AAAA,UACd,mBAAmB;AAAA,UACnB,KAAK;AAAA,UACL,GAAG;AAAA,QACL,CAAC;AAAA,MACH;AAAA;AAAA,EACF;AAEJ;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/context/tabs.tsx"],"sourcesContent":["'use client'\n\nimport {\n createContext,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type MutableRefObject,\n type PropsWithChildren,\n} from 'react'\n\n/**\n * This module provides a Tabs component and a hook to access its context.\n * @module\n */\n\nexport interface TabsContextValue {\n active: string\n tabs: MutableRefObject<HTMLButtonElement[]>\n onTabUpdate: (active: string) => void\n}\n\nexport const TabsContext = createContext<TabsContextValue | null>(null)\n\nexport interface TabsProps {\n active?: string\n cache?: boolean\n}\n\n/**\n * The Tabs component provides a context to manage tab state.\n * @param active - the default active tab id,\n * @param cache - whether to cache the active tab state in local storage\n * @example\n * ```tsx\n * <Tabs cache>\n * <TabList description=\"Button details\">\n * <Tab id=\"overview\">Overview</Tab>\n * <Tab id=\"guidelines\">Guidelines</Tab>\n * </TabList>\n * <TabPanels>\n * <TabPanel id=\"overview\">Overview content</TabPanel>\n * <TabPanel id=\"guidelines\">Guidelines content</TabPanel>\n * </TabPanels>\n * </Tabs>\n * ```\n */\nexport function Tabs(props: PropsWithChildren<TabsProps>): JSX.Element {\n const { cache } = props\n const [active, setActive] = useState(() => (cache ? '' : props.active ?? ''))\n const tabs = useRef<HTMLButtonElement[]>([])\n\n const value = useMemo(\n () => ({\n active,\n tabs,\n onTabUpdate: setActive,\n }),\n [active, setActive],\n )\n\n useEffect(() => {\n const cachedTab = window.localStorage.getItem('cerberus-tabs')\n if (cache && cachedTab) {\n setActive(cachedTab)\n }\n }, [cache])\n\n useEffect(() => {\n if (cache) {\n window.localStorage.setItem('cerberus-tabs', active)\n }\n }, [active, cache])\n\n return (\n <TabsContext.Provider value={value}>{props.children}</TabsContext.Provider>\n )\n}\n\nexport function useTabsContext(): TabsContextValue {\n const context = useContext(TabsContext)\n if (!context) {\n throw new Error('useTabsContext must be used within a Tabs Provider.')\n }\n return context\n}\n"],"mappings":";AAEA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AAkEH;AArDG,IAAM,cAAc,cAAuC,IAAI;AAyB/D,SAAS,KAAK,OAAkD;AACrE,QAAM,EAAE,MAAM,IAAI;AAClB,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,MAAO,QAAQ,KAAK,MAAM,UAAU,EAAG;AAC5E,QAAM,OAAO,OAA4B,CAAC,CAAC;AAE3C,QAAM,QAAQ;AAAA,IACZ,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,aAAa;AAAA,IACf;AAAA,IACA,CAAC,QAAQ,SAAS;AAAA,EACpB;AAEA,YAAU,MAAM;AACd,UAAM,YAAY,OAAO,aAAa,QAAQ,eAAe;AAC7D,QAAI,SAAS,WAAW;AACtB,gBAAU,SAAS;AAAA,IACrB;AAAA,EACF,GAAG,CAAC,KAAK,CAAC;AAEV,YAAU,MAAM;AACd,QAAI,OAAO;AACT,aAAO,aAAa,QAAQ,iBAAiB,MAAM;AAAA,IACrD;AAAA,EACF,GAAG,CAAC,QAAQ,KAAK,CAAC;AAElB,SACE,oBAAC,YAAY,UAAZ,EAAqB,OAAe,gBAAM,UAAS;AAExD;AAEO,SAAS,iBAAmC;AACjD,QAAM,UAAU,WAAW,WAAW;AACtC,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,qDAAqD;AAAA,EACvE;AACA,SAAO;AACT;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/Tab.tsx"],"sourcesContent":["'use client'\n\nimport { useMemo, type ButtonHTMLAttributes, type MouseEvent } from 'react'\nimport { useTabsContext } from '../context/tabs'\nimport { css, cx } from '@cerberus/styled-system/css'\nimport { useTabsKeyboardNavigation } from '../aria-helpers/tabs.aria'\n\n/**\n * This module provides a Tab component.\n * @module\n */\n\nexport interface TabProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n value: string\n}\n\n/**\n * The Tab component provides a tab element to be used in a TabList.\n * @definition [ARIA Target Size](https://www.w3.org/WAI/WCAG21/Understanding/target-size.html#:~:text=Understanding%20SC%202.5.,%3ATarget%20Size%20(Level%20AAA)&text=The%20size%20of%20the%20target,Equivalent)\n * @definition [Tab docs](https://cerberus.digitalu.design/react/tabs)\n * @param value - the id of the tab that will be tracked as the active tab and used for aria attributes\n * @example\n * ```tsx\n * <Tab value=\"overview\">\n * Overview\n * </Tab>\n * ```\n */\nexport function Tab(props: TabProps) {\n const { value, ...nativeProps } = props\n const { active, onTabUpdate } = useTabsContext()\n const { ref } = useTabsKeyboardNavigation()\n const isActive = useMemo(() => active === value, [active, value])\n\n function handleClick(e: MouseEvent<HTMLButtonElement>) {\n props.onClick?.(e)\n onTabUpdate(e.currentTarget.value)\n }\n\n return (\n <button\n {...nativeProps}\n {...(!isActive && { tabIndex: -1 })}\n aria-controls={`panel:${value}`}\n aria-selected={isActive}\n id={value}\n className={cx(nativeProps.className, btnStyles)}\n onClick={handleClick}\n role=\"tab\"\n ref={ref}\n value={value}\n />\n )\n}\n\nconst btnStyles = css({\n alignItems: 'center',\n display: 'inline-flex',\n borderTopLeftRadius: 'md',\n borderTopRightRadius: 'md',\n fontSize: 'sm',\n fontWeight: '600',\n gap: '2',\n h: '2.75rem',\n justifyContent: 'center',\n position: 'relative',\n pxi: '4',\n zIndex: 'base',\n _motionSafe: {\n transition: 'all 200ms ease-in-out',\n _before: {\n transitionProperty: 'height',\n transitionDuration: '200ms',\n transitionTimingFunction: 'ease-in-out',\n },\n _after: {\n transitionProperty: 'height',\n transitionDuration: '200ms',\n transitionTimingFunction: 'ease-in-out',\n },\n },\n _before: {\n bgColor: 'action.border.initial',\n bottom: '0',\n content: '\"\"',\n h: '0',\n position: 'absolute',\n left: '0',\n right: '0',\n w: 'full',\n willChange: 'height',\n zIndex: 'decorator',\n },\n _after: {\n borderTopLeftRadius: 'md',\n borderTopRightRadius: 'md',\n bottom: '0',\n bgColor: 'neutral.surface.100',\n content: '\"\"',\n left: '0',\n position: 'absolute',\n right: '0',\n h: '0',\n w: 'full',\n willChange: 'height',\n zIndex: '-1',\n },\n _hover: {\n _after: {\n h: 'full',\n },\n },\n _focusVisible: {\n boxShadow: 'none',\n outline: '3px solid',\n outlineColor: 'action.border.focus',\n outlineOffset: '2px',\n },\n _disabled: {\n cursor: 'not-allowed',\n opacity: '0.5',\n },\n _selected: {\n color: 'action.text.200',\n _before: {\n h: '3px',\n },\n _hover: {\n _after: {\n h: '0',\n },\n },\n },\n})\n"],"mappings":";;;;;;;;AAEA,SAAS,eAA2D;AAEpE,SAAS,KAAK,UAAU;AAoCpB;AAZG,SAAS,IAAI,OAAiB;AACnC,QAAM,EAAE,OAAO,GAAG,YAAY,IAAI;AAClC,QAAM,EAAE,QAAQ,YAAY,IAAI,eAAe;AAC/C,QAAM,EAAE,IAAI,IAAI,0BAA0B;AAC1C,QAAM,WAAW,QAAQ,MAAM,WAAW,OAAO,CAAC,QAAQ,KAAK,CAAC;AAEhE,WAAS,YAAY,GAAkC;AACrD,UAAM,UAAU,CAAC;AACjB,gBAAY,EAAE,cAAc,KAAK;AAAA,EACnC;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACH,GAAI,CAAC,YAAY,EAAE,UAAU,GAAG;AAAA,MACjC,iBAAe,SAAS,KAAK;AAAA,MAC7B,iBAAe;AAAA,MACf,IAAI;AAAA,MACJ,WAAW,GAAG,YAAY,WAAW,SAAS;AAAA,MAC9C,SAAS;AAAA,MACT,MAAK;AAAA,MACL;AAAA,MACA;AAAA;AAAA,EACF;AAEJ;AAEA,IAAM,YAAY,IAAI;AAAA,EACpB,YAAY;AAAA,EACZ,SAAS;AAAA,EACT,qBAAqB;AAAA,EACrB,sBAAsB;AAAA,EACtB,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,KAAK;AAAA,EACL,GAAG;AAAA,EACH,gBAAgB;AAAA,EAChB,UAAU;AAAA,EACV,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,aAAa;AAAA,IACX,YAAY;AAAA,IACZ,SAAS;AAAA,MACP,oBAAoB;AAAA,MACpB,oBAAoB;AAAA,MACpB,0BAA0B;AAAA,IAC5B;AAAA,IACA,QAAQ;AAAA,MACN,oBAAoB;AAAA,MACpB,oBAAoB;AAAA,MACpB,0BAA0B;AAAA,IAC5B;AAAA,EACF;AAAA,EACA,SAAS;AAAA,IACP,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,GAAG;AAAA,IACH,UAAU;AAAA,IACV,MAAM;AAAA,IACN,OAAO;AAAA,IACP,GAAG;AAAA,IACH,YAAY;AAAA,IACZ,QAAQ;AAAA,EACV;AAAA,EACA,QAAQ;AAAA,IACN,qBAAqB;AAAA,IACrB,sBAAsB;AAAA,IACtB,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,SAAS;AAAA,IACT,MAAM;AAAA,IACN,UAAU;AAAA,IACV,OAAO;AAAA,IACP,GAAG;AAAA,IACH,GAAG;AAAA,IACH,YAAY;AAAA,IACZ,QAAQ;AAAA,EACV;AAAA,EACA,QAAQ;AAAA,IACN,QAAQ;AAAA,MACN,GAAG;AAAA,IACL;AAAA,EACF;AAAA,EACA,eAAe;AAAA,IACb,WAAW;AAAA,IACX,SAAS;AAAA,IACT,cAAc;AAAA,IACd,eAAe;AAAA,EACjB;AAAA,EACA,WAAW;AAAA,IACT,QAAQ;AAAA,IACR,SAAS;AAAA,EACX;AAAA,EACA,WAAW;AAAA,IACT,OAAO;AAAA,IACP,SAAS;AAAA,MACP,GAAG;AAAA,IACL;AAAA,IACA,QAAQ;AAAA,MACN,QAAQ;AAAA,QACN,GAAG;AAAA,MACL;AAAA,IACF;AAAA,EACF;AACF,CAAC;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/TabList.tsx"],"sourcesContent":["import { cx } from '@cerberus/styled-system/css'\nimport { hstack } from '@cerberus/styled-system/patterns'\nimport type { HTMLAttributes, PropsWithChildren } from 'react'\n\n/**\n * This module provides a TabList component.\n * @module\n */\n\nexport interface TabListProps extends HTMLAttributes<HTMLDivElement> {\n description: string\n}\n\n/**\n * The TabList component provides a container for tab elements.\n * @param description - a description of what the tab list contains\n * @example\n * ```tsx\n * <TabList description=\"Button details\">\n * <Tab id=\"overview\">Overview</Tab>\n * <Tab id=\"guidelines\">Guidelines</Tab>\n * </TabList>\n * ```\n */\nexport function TabList(props: PropsWithChildren<TabListProps>) {\n const { description, ...nativeProps } = props\n return (\n <div\n {...nativeProps}\n aria-describedby={description}\n className={cx(\n nativeProps.className,\n hstack({\n borderBottom: '1px solid',\n borderBottomColor: 'action.border.100',\n gap: '0',\n w: 'full',\n }),\n )}\n />\n )\n}\n"],"mappings":";AAAA,SAAS,UAAU;AACnB,SAAS,cAAc;AA0BnB;AAHG,SAAS,QAAQ,OAAwC;AAC9D,QAAM,EAAE,aAAa,GAAG,YAAY,IAAI;AACxC,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ,oBAAkB;AAAA,MAClB,WAAW;AAAA,QACT,YAAY;AAAA,QACZ,OAAO;AAAA,UACL,cAAc;AAAA,UACd,mBAAmB;AAAA,UACnB,KAAK;AAAA,UACL,GAAG;AAAA,QACL,CAAC;AAAA,MACH;AAAA;AAAA,EACF;AAEJ;","names":[]}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|