@cerberus-design/react 0.13.2-next-61259ca → 0.14.0-next-01a1b5e

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.
Files changed (71) hide show
  1. package/build/legacy/_tsup-dts-rollup.d.cts +103 -107
  2. package/build/legacy/components/Tabs.client.cjs +104 -0
  3. package/build/legacy/components/Tabs.client.cjs.map +1 -0
  4. package/build/legacy/context/tabs.cjs +53 -24
  5. package/build/legacy/context/tabs.cjs.map +1 -1
  6. package/build/legacy/index.cjs +320 -371
  7. package/build/legacy/index.cjs.map +1 -1
  8. package/build/legacy/utils/index.cjs +21 -2
  9. package/build/legacy/utils/index.cjs.map +1 -1
  10. package/build/legacy/utils/localStorage.cjs +44 -0
  11. package/build/legacy/utils/localStorage.cjs.map +1 -0
  12. package/build/modern/_tsup-dts-rollup.d.ts +103 -107
  13. package/build/modern/{chunk-FRWNAVDM.js → chunk-77B4HFKT.js} +4 -4
  14. package/build/modern/{chunk-G7AGKII3.js → chunk-BHSYQCDV.js} +4 -4
  15. package/build/modern/{chunk-UTGEFJ3L.js → chunk-C5EHJUS5.js} +1 -1
  16. package/build/modern/{chunk-UTGEFJ3L.js.map → chunk-C5EHJUS5.js.map} +1 -1
  17. package/build/modern/chunk-FQLMPEYX.js +18 -0
  18. package/build/modern/chunk-FQLMPEYX.js.map +1 -0
  19. package/build/modern/chunk-N7O6D7BW.js +63 -0
  20. package/build/modern/chunk-N7O6D7BW.js.map +1 -0
  21. package/build/modern/chunk-RZ7NG77U.js +77 -0
  22. package/build/modern/chunk-RZ7NG77U.js.map +1 -0
  23. package/build/modern/{chunk-ECKJGCNH.js → chunk-T6U7AKKP.js} +4 -4
  24. package/build/modern/components/Tabs.client.js +18 -0
  25. package/build/modern/context/confirm-modal.js +2 -2
  26. package/build/modern/context/cta-modal.js +2 -2
  27. package/build/modern/context/prompt-modal.js +2 -2
  28. package/build/modern/context/tabs.js +2 -1
  29. package/build/modern/index.js +42 -40
  30. package/build/modern/index.js.map +1 -1
  31. package/build/modern/utils/index.js +8 -2
  32. package/build/modern/utils/localStorage.js +10 -0
  33. package/package.json +2 -2
  34. package/src/components/Tabs.client.tsx +113 -0
  35. package/src/context/tabs.tsx +66 -65
  36. package/src/index.ts +1 -4
  37. package/src/utils/index.ts +2 -0
  38. package/src/utils/localStorage.ts +28 -0
  39. package/build/legacy/aria-helpers/tabs.aria.cjs +0 -100
  40. package/build/legacy/aria-helpers/tabs.aria.cjs.map +0 -1
  41. package/build/legacy/components/Tab.cjs +0 -135
  42. package/build/legacy/components/Tab.cjs.map +0 -1
  43. package/build/legacy/components/TabList.cjs +0 -69
  44. package/build/legacy/components/TabList.cjs.map +0 -1
  45. package/build/legacy/components/TabPanel.cjs +0 -76
  46. package/build/legacy/components/TabPanel.cjs.map +0 -1
  47. package/build/modern/aria-helpers/tabs.aria.js +0 -9
  48. package/build/modern/chunk-AYIRV5CL.js +0 -32
  49. package/build/modern/chunk-AYIRV5CL.js.map +0 -1
  50. package/build/modern/chunk-ITOIXNJS.js +0 -64
  51. package/build/modern/chunk-ITOIXNJS.js.map +0 -1
  52. package/build/modern/chunk-RIFQSCHT.js +0 -58
  53. package/build/modern/chunk-RIFQSCHT.js.map +0 -1
  54. package/build/modern/chunk-SLF6SIPB.js +0 -46
  55. package/build/modern/chunk-SLF6SIPB.js.map +0 -1
  56. package/build/modern/chunk-UKPF7JOB.js +0 -33
  57. package/build/modern/chunk-UKPF7JOB.js.map +0 -1
  58. package/build/modern/components/Tab.js +0 -10
  59. package/build/modern/components/TabList.js +0 -9
  60. package/build/modern/components/TabList.js.map +0 -1
  61. package/build/modern/components/TabPanel.js +0 -10
  62. package/build/modern/components/TabPanel.js.map +0 -1
  63. package/src/aria-helpers/tabs.aria.ts +0 -70
  64. package/src/components/Tab.tsx +0 -68
  65. package/src/components/TabList.tsx +0 -51
  66. package/src/components/TabPanel.tsx +0 -49
  67. /package/build/modern/{chunk-FRWNAVDM.js.map → chunk-77B4HFKT.js.map} +0 -0
  68. /package/build/modern/{chunk-G7AGKII3.js.map → chunk-BHSYQCDV.js.map} +0 -0
  69. /package/build/modern/{chunk-ECKJGCNH.js.map → chunk-T6U7AKKP.js.map} +0 -0
  70. /package/build/modern/{aria-helpers/tabs.aria.js.map → components/Tabs.client.js.map} +0 -0
  71. /package/build/modern/{components/Tab.js.map → utils/localStorage.js.map} +0 -0
@@ -17,3 +17,5 @@ export function formatNotifyCount(count: number): string {
17
17
  if (count > 99) return '99+'
18
18
  return count.toString()
19
19
  }
20
+
21
+ export * from './localStorage'
@@ -0,0 +1,28 @@
1
+ 'use client'
2
+
3
+ /**
4
+ * A utility function to get a value from local storage.
5
+ * @param key The key to get from local storage.
6
+ * @param defaultValue The fallback value if the key is not found.
7
+ * @returns key or defaultValue
8
+ */
9
+ export function getLocalStorage<T extends string>(
10
+ key: string,
11
+ defaultValue: T,
12
+ ): T {
13
+ const value = window.localStorage.getItem(key)
14
+ if (value) {
15
+ return value as T
16
+ }
17
+ return defaultValue
18
+ }
19
+
20
+ /**
21
+ * A utility function to set a value in local storage.
22
+ * @param key The key to set in local storage.
23
+ * @param value The value to set in local storage.
24
+ */
25
+ export function setLocalStorage<T>(key: string, value: T): void {
26
+ const stringValue = typeof value === 'string' ? value : JSON.stringify(value)
27
+ window.localStorage.setItem(key, stringValue)
28
+ }
@@ -1,100 +0,0 @@
1
- "use strict";
2
- "use client";
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __hasOwnProp = Object.prototype.hasOwnProperty;
7
- var __export = (target, all) => {
8
- for (var name in all)
9
- __defProp(target, name, { get: all[name], enumerable: true });
10
- };
11
- var __copyProps = (to, from, except, desc) => {
12
- if (from && typeof from === "object" || typeof from === "function") {
13
- for (let key of __getOwnPropNames(from))
14
- if (!__hasOwnProp.call(to, key) && key !== except)
15
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
- }
17
- return to;
18
- };
19
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
-
21
- // src/aria-helpers/tabs.aria.ts
22
- var tabs_aria_exports = {};
23
- __export(tabs_aria_exports, {
24
- useTabsKeyboardNavigation: () => useTabsKeyboardNavigation
25
- });
26
- module.exports = __toCommonJS(tabs_aria_exports);
27
- var import_react2 = require("react");
28
-
29
- // src/context/tabs.tsx
30
- var import_recipes = require("@cerberus/styled-system/recipes");
31
- var import_react = require("react");
32
- var import_jsx_runtime = require("react/jsx-runtime");
33
- var TabsContext = (0, import_react.createContext)(null);
34
- function useTabsContext() {
35
- const context = (0, import_react.useContext)(TabsContext);
36
- if (!context) {
37
- throw new Error("useTabsContext must be used within a Tabs Provider.");
38
- }
39
- return context;
40
- }
41
-
42
- // src/aria-helpers/tabs.aria.ts
43
- function getNextIndex(index, length) {
44
- return index === length - 1 ? 0 : index + 1;
45
- }
46
- function getPrevIndex(index, length) {
47
- return index === 0 ? length - 1 : index - 1;
48
- }
49
- function useTabsKeyboardNavigation() {
50
- const { tabs: tabs2 } = useTabsContext();
51
- const [activeTab, setActiveTab] = (0, import_react2.useState)(-1);
52
- (0, import_react2.useEffect)(() => {
53
- const handleKeyDown = (event) => {
54
- const index = activeTab === -1 ? tabs2.current.findIndex((tab) => tab.ariaSelected === "true") : activeTab;
55
- const nextIndex = getNextIndex(index, tabs2.current.length);
56
- const prevIndex = getPrevIndex(index, tabs2.current.length);
57
- if (index === -1) return;
58
- switch (event.key) {
59
- case "ArrowLeft":
60
- event.preventDefault();
61
- setActiveTab(prevIndex);
62
- tabs2.current[prevIndex].focus();
63
- break;
64
- case "ArrowRight":
65
- event.preventDefault();
66
- setActiveTab(nextIndex);
67
- tabs2.current[nextIndex].focus();
68
- break;
69
- case "Home":
70
- event.preventDefault();
71
- setActiveTab(0);
72
- tabs2.current[0].focus();
73
- break;
74
- case "End":
75
- event.preventDefault();
76
- setActiveTab(tabs2.current.length - 1);
77
- tabs2.current[tabs2.current.length - 1].focus();
78
- break;
79
- default:
80
- break;
81
- }
82
- };
83
- document.addEventListener("keydown", handleKeyDown);
84
- return () => {
85
- document.removeEventListener("keydown", handleKeyDown);
86
- };
87
- }, [activeTab, tabs2.current]);
88
- return {
89
- ref: (tab) => {
90
- if (tab && !tabs2.current.includes(tab)) {
91
- tabs2.current.push(tab);
92
- }
93
- }
94
- };
95
- }
96
- // Annotate the CommonJS export names for ESM import in node:
97
- 0 && (module.exports = {
98
- useTabsKeyboardNavigation
99
- });
100
- //# sourceMappingURL=tabs.aria.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../src/aria-helpers/tabs.aria.ts","../../../src/context/tabs.tsx"],"sourcesContent":["'use client'\n\nimport { useEffect, useState } from 'react'\nimport { useTabsContext } from '../context/tabs'\n\nfunction getNextIndex(index: number, length: number) {\n return index === length - 1 ? 0 : index + 1\n}\n\nfunction getPrevIndex(index: number, length: number) {\n return index === 0 ? length - 1 : index - 1\n}\n\nexport function useTabsKeyboardNavigation() {\n const { tabs } = useTabsContext()\n const [activeTab, setActiveTab] = useState(-1)\n\n useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n const index =\n activeTab === -1\n ? tabs.current.findIndex((tab) => tab.ariaSelected === 'true')\n : activeTab\n const nextIndex = getNextIndex(index, tabs.current.length)\n const prevIndex = getPrevIndex(index, tabs.current.length)\n\n // If the active tab is not found, do nothing\n if (index === -1) return\n\n switch (event.key) {\n case 'ArrowLeft':\n event.preventDefault()\n setActiveTab(prevIndex)\n tabs.current[prevIndex].focus()\n break\n case 'ArrowRight':\n event.preventDefault()\n setActiveTab(nextIndex)\n tabs.current[nextIndex].focus()\n break\n case 'Home':\n event.preventDefault()\n setActiveTab(0)\n tabs.current[0].focus()\n break\n case 'End':\n event.preventDefault()\n setActiveTab(tabs.current.length - 1)\n tabs.current[tabs.current.length - 1].focus()\n break\n default:\n break\n }\n }\n\n document.addEventListener('keydown', handleKeyDown)\n\n return () => {\n document.removeEventListener('keydown', handleKeyDown)\n }\n }, [activeTab, tabs.current])\n\n return {\n ref: (tab: HTMLButtonElement) => {\n if (tab && !tabs.current.includes(tab)) {\n tabs.current.push(tab)\n }\n },\n }\n}\n","'use client'\n\nimport { tabs, type TabsVariantProps } from '@cerberus/styled-system/recipes'\nimport type { Pretty } from '@cerberus/styled-system/types'\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 Tabs\n */\n\nexport interface TabsContextValue {\n /**\n * The ref for the tabs.\n */\n tabs: MutableRefObject<HTMLButtonElement[]>\n /**\n * The id of the tabs component.\n */\n id: string\n /**\n * The active tab id.\n */\n active: string\n /**\n * The styles for the tabs.\n */\n styles: Pretty<Record<'tabList' | 'tab' | 'tabPanel', string>>\n /**\n * Called when the active tab is updated.\n */\n onTabUpdate: (active: string) => void\n}\n\nexport const TabsContext = createContext<TabsContextValue | null>(null)\n\nexport interface TabsProps {\n /**\n * A unique identifier for the Tabs component. Typically used when there are\n * multiple Tabs components on the same page.\n */\n id?: string\n /**\n * The default active tab id.\n */\n active?: string\n /**\n * Whether to cache the active tab state in local storage.\n */\n cache?: boolean\n}\n\n/**\n * The Tabs component provides a context to manage tab state.\n * @see https://cerberus.digitalu.design/react/tabs\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(\n props: PropsWithChildren<TabsProps & TabsVariantProps>,\n): JSX.Element {\n const { cache, active, id, palette } = props\n const [activeTab, setActiveTab] = useState(() => (cache ? '' : active ?? ''))\n const tabsList = useRef<HTMLButtonElement[]>([])\n const uuid = useMemo(() => {\n return id ? `cerberus-tabs-${id}` : 'cerberus-tabs'\n }, [id])\n\n const value = useMemo(\n () => ({\n tabs: tabsList,\n id: uuid,\n active: activeTab,\n styles: tabs({ palette }),\n onTabUpdate: setActiveTab,\n }),\n [activeTab, setActiveTab, palette, uuid, tabsList],\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\n/**\n * Used to access the tabs context.\n * @returns The tabs context.\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":";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,IAAAA,gBAAoC;;;ACApC,qBAA4C;AAE5C,mBASO;AAwGH;AA1EG,IAAM,kBAAc,4BAAuC,IAAI;AAkF/D,SAAS,iBAAmC;AACjD,QAAM,cAAU,yBAAW,WAAW;AACtC,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,qDAAqD;AAAA,EACvE;AACA,SAAO;AACT;;;AD9HA,SAAS,aAAa,OAAe,QAAgB;AACnD,SAAO,UAAU,SAAS,IAAI,IAAI,QAAQ;AAC5C;AAEA,SAAS,aAAa,OAAe,QAAgB;AACnD,SAAO,UAAU,IAAI,SAAS,IAAI,QAAQ;AAC5C;AAEO,SAAS,4BAA4B;AAC1C,QAAM,EAAE,MAAAC,MAAK,IAAI,eAAe;AAChC,QAAM,CAAC,WAAW,YAAY,QAAI,wBAAS,EAAE;AAE7C,+BAAU,MAAM;AACd,UAAM,gBAAgB,CAAC,UAAyB;AAC9C,YAAM,QACJ,cAAc,KACVA,MAAK,QAAQ,UAAU,CAAC,QAAQ,IAAI,iBAAiB,MAAM,IAC3D;AACN,YAAM,YAAY,aAAa,OAAOA,MAAK,QAAQ,MAAM;AACzD,YAAM,YAAY,aAAa,OAAOA,MAAK,QAAQ,MAAM;AAGzD,UAAI,UAAU,GAAI;AAElB,cAAQ,MAAM,KAAK;AAAA,QACjB,KAAK;AACH,gBAAM,eAAe;AACrB,uBAAa,SAAS;AACtB,UAAAA,MAAK,QAAQ,SAAS,EAAE,MAAM;AAC9B;AAAA,QACF,KAAK;AACH,gBAAM,eAAe;AACrB,uBAAa,SAAS;AACtB,UAAAA,MAAK,QAAQ,SAAS,EAAE,MAAM;AAC9B;AAAA,QACF,KAAK;AACH,gBAAM,eAAe;AACrB,uBAAa,CAAC;AACd,UAAAA,MAAK,QAAQ,CAAC,EAAE,MAAM;AACtB;AAAA,QACF,KAAK;AACH,gBAAM,eAAe;AACrB,uBAAaA,MAAK,QAAQ,SAAS,CAAC;AACpC,UAAAA,MAAK,QAAQA,MAAK,QAAQ,SAAS,CAAC,EAAE,MAAM;AAC5C;AAAA,QACF;AACE;AAAA,MACJ;AAAA,IACF;AAEA,aAAS,iBAAiB,WAAW,aAAa;AAElD,WAAO,MAAM;AACX,eAAS,oBAAoB,WAAW,aAAa;AAAA,IACvD;AAAA,EACF,GAAG,CAAC,WAAWA,MAAK,OAAO,CAAC;AAE5B,SAAO;AAAA,IACL,KAAK,CAAC,QAA2B;AAC/B,UAAI,OAAO,CAACA,MAAK,QAAQ,SAAS,GAAG,GAAG;AACtC,QAAAA,MAAK,QAAQ,KAAK,GAAG;AAAA,MACvB;AAAA,IACF;AAAA,EACF;AACF;","names":["import_react","tabs"]}
@@ -1,135 +0,0 @@
1
- "use strict";
2
- "use client";
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __hasOwnProp = Object.prototype.hasOwnProperty;
7
- var __export = (target, all) => {
8
- for (var name in all)
9
- __defProp(target, name, { get: all[name], enumerable: true });
10
- };
11
- var __copyProps = (to, from, except, desc) => {
12
- if (from && typeof from === "object" || typeof from === "function") {
13
- for (let key of __getOwnPropNames(from))
14
- if (!__hasOwnProp.call(to, key) && key !== except)
15
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
- }
17
- return to;
18
- };
19
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
-
21
- // src/components/Tab.tsx
22
- var Tab_exports = {};
23
- __export(Tab_exports, {
24
- Tab: () => Tab
25
- });
26
- module.exports = __toCommonJS(Tab_exports);
27
- var import_react3 = require("react");
28
-
29
- // src/context/tabs.tsx
30
- var import_recipes = require("@cerberus/styled-system/recipes");
31
- var import_react = require("react");
32
- var import_jsx_runtime = require("react/jsx-runtime");
33
- var TabsContext = (0, import_react.createContext)(null);
34
- function useTabsContext() {
35
- const context = (0, import_react.useContext)(TabsContext);
36
- if (!context) {
37
- throw new Error("useTabsContext must be used within a Tabs Provider.");
38
- }
39
- return context;
40
- }
41
-
42
- // src/components/Tab.tsx
43
- var import_css = require("@cerberus/styled-system/css");
44
-
45
- // src/aria-helpers/tabs.aria.ts
46
- var import_react2 = require("react");
47
- function getNextIndex(index, length) {
48
- return index === length - 1 ? 0 : index + 1;
49
- }
50
- function getPrevIndex(index, length) {
51
- return index === 0 ? length - 1 : index - 1;
52
- }
53
- function useTabsKeyboardNavigation() {
54
- const { tabs: tabs2 } = useTabsContext();
55
- const [activeTab, setActiveTab] = (0, import_react2.useState)(-1);
56
- (0, import_react2.useEffect)(() => {
57
- const handleKeyDown = (event) => {
58
- const index = activeTab === -1 ? tabs2.current.findIndex((tab) => tab.ariaSelected === "true") : activeTab;
59
- const nextIndex = getNextIndex(index, tabs2.current.length);
60
- const prevIndex = getPrevIndex(index, tabs2.current.length);
61
- if (index === -1) return;
62
- switch (event.key) {
63
- case "ArrowLeft":
64
- event.preventDefault();
65
- setActiveTab(prevIndex);
66
- tabs2.current[prevIndex].focus();
67
- break;
68
- case "ArrowRight":
69
- event.preventDefault();
70
- setActiveTab(nextIndex);
71
- tabs2.current[nextIndex].focus();
72
- break;
73
- case "Home":
74
- event.preventDefault();
75
- setActiveTab(0);
76
- tabs2.current[0].focus();
77
- break;
78
- case "End":
79
- event.preventDefault();
80
- setActiveTab(tabs2.current.length - 1);
81
- tabs2.current[tabs2.current.length - 1].focus();
82
- break;
83
- default:
84
- break;
85
- }
86
- };
87
- document.addEventListener("keydown", handleKeyDown);
88
- return () => {
89
- document.removeEventListener("keydown", handleKeyDown);
90
- };
91
- }, [activeTab, tabs2.current]);
92
- return {
93
- ref: (tab) => {
94
- if (tab && !tabs2.current.includes(tab)) {
95
- tabs2.current.push(tab);
96
- }
97
- }
98
- };
99
- }
100
-
101
- // src/components/Tab.tsx
102
- var import_jsx_runtime2 = require("react/jsx-runtime");
103
- function Tab(props) {
104
- const { value, ...nativeProps } = props;
105
- const { active, onTabUpdate, styles } = useTabsContext();
106
- const [isPending, startTransition] = (0, import_react3.useTransition)();
107
- const { ref } = useTabsKeyboardNavigation();
108
- const isActive = (0, import_react3.useMemo)(() => active === value, [active, value]);
109
- function handleClick(e) {
110
- var _a;
111
- (_a = props.onClick) == null ? void 0 : _a.call(props, e);
112
- startTransition(() => onTabUpdate(e.currentTarget.value));
113
- }
114
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
115
- "button",
116
- {
117
- ...nativeProps,
118
- ...!isActive && { tabIndex: -1 },
119
- "aria-controls": `panel:${value}`,
120
- "aria-busy": isPending,
121
- "aria-selected": isActive,
122
- id: `tab:${value}`,
123
- className: (0, import_css.cx)(nativeProps.className, styles.tab),
124
- onClick: handleClick,
125
- role: "tab",
126
- ref,
127
- value
128
- }
129
- );
130
- }
131
- // Annotate the CommonJS export names for ESM import in node:
132
- 0 && (module.exports = {
133
- Tab
134
- });
135
- //# sourceMappingURL=Tab.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../src/components/Tab.tsx","../../../src/context/tabs.tsx","../../../src/aria-helpers/tabs.aria.ts"],"sourcesContent":["'use client'\n\nimport {\n useMemo,\n useTransition,\n type ButtonHTMLAttributes,\n type MouseEvent,\n} from 'react'\nimport { useTabsContext } from '../context/tabs'\nimport { 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 /**\n * The id of the tab that will be tracked as the active tab and used for aria\n * attributes.\n */\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 * @see https://cerberus.digitalu.design/react/tabs\n * @memberof module:Tabs\n * @example\n * ```tsx\n * <Tabs>\n * <TabList description=\"Profile settings\">\n * <Tab value=\"overview\">Overview</Tab>\n * </TabList>\n * <TabPanel tab=\"overview\">...</TabPanel>\n * </Tabs>\n * ```\n */\nexport function Tab(props: TabProps) {\n const { value, ...nativeProps } = props\n const { active, onTabUpdate, styles } = 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={`tab:${value}`}\n className={cx(nativeProps.className, styles.tab)}\n onClick={handleClick}\n role=\"tab\"\n ref={ref}\n value={value}\n />\n )\n}\n","'use client'\n\nimport { tabs, type TabsVariantProps } from '@cerberus/styled-system/recipes'\nimport type { Pretty } from '@cerberus/styled-system/types'\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 Tabs\n */\n\nexport interface TabsContextValue {\n /**\n * The ref for the tabs.\n */\n tabs: MutableRefObject<HTMLButtonElement[]>\n /**\n * The id of the tabs component.\n */\n id: string\n /**\n * The active tab id.\n */\n active: string\n /**\n * The styles for the tabs.\n */\n styles: Pretty<Record<'tabList' | 'tab' | 'tabPanel', string>>\n /**\n * Called when the active tab is updated.\n */\n onTabUpdate: (active: string) => void\n}\n\nexport const TabsContext = createContext<TabsContextValue | null>(null)\n\nexport interface TabsProps {\n /**\n * A unique identifier for the Tabs component. Typically used when there are\n * multiple Tabs components on the same page.\n */\n id?: string\n /**\n * The default active tab id.\n */\n active?: string\n /**\n * Whether to cache the active tab state in local storage.\n */\n cache?: boolean\n}\n\n/**\n * The Tabs component provides a context to manage tab state.\n * @see https://cerberus.digitalu.design/react/tabs\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(\n props: PropsWithChildren<TabsProps & TabsVariantProps>,\n): JSX.Element {\n const { cache, active, id, palette } = props\n const [activeTab, setActiveTab] = useState(() => (cache ? '' : active ?? ''))\n const tabsList = useRef<HTMLButtonElement[]>([])\n const uuid = useMemo(() => {\n return id ? `cerberus-tabs-${id}` : 'cerberus-tabs'\n }, [id])\n\n const value = useMemo(\n () => ({\n tabs: tabsList,\n id: uuid,\n active: activeTab,\n styles: tabs({ palette }),\n onTabUpdate: setActiveTab,\n }),\n [activeTab, setActiveTab, palette, uuid, tabsList],\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\n/**\n * Used to access the tabs context.\n * @returns The tabs context.\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","'use client'\n\nimport { useEffect, useState } from 'react'\nimport { useTabsContext } from '../context/tabs'\n\nfunction getNextIndex(index: number, length: number) {\n return index === length - 1 ? 0 : index + 1\n}\n\nfunction getPrevIndex(index: number, length: number) {\n return index === 0 ? length - 1 : index - 1\n}\n\nexport function useTabsKeyboardNavigation() {\n const { tabs } = useTabsContext()\n const [activeTab, setActiveTab] = useState(-1)\n\n useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n const index =\n activeTab === -1\n ? tabs.current.findIndex((tab) => tab.ariaSelected === 'true')\n : activeTab\n const nextIndex = getNextIndex(index, tabs.current.length)\n const prevIndex = getPrevIndex(index, tabs.current.length)\n\n // If the active tab is not found, do nothing\n if (index === -1) return\n\n switch (event.key) {\n case 'ArrowLeft':\n event.preventDefault()\n setActiveTab(prevIndex)\n tabs.current[prevIndex].focus()\n break\n case 'ArrowRight':\n event.preventDefault()\n setActiveTab(nextIndex)\n tabs.current[nextIndex].focus()\n break\n case 'Home':\n event.preventDefault()\n setActiveTab(0)\n tabs.current[0].focus()\n break\n case 'End':\n event.preventDefault()\n setActiveTab(tabs.current.length - 1)\n tabs.current[tabs.current.length - 1].focus()\n break\n default:\n break\n }\n }\n\n document.addEventListener('keydown', handleKeyDown)\n\n return () => {\n document.removeEventListener('keydown', handleKeyDown)\n }\n }, [activeTab, tabs.current])\n\n return {\n ref: (tab: HTMLButtonElement) => {\n if (tab && !tabs.current.includes(tab)) {\n tabs.current.push(tab)\n }\n },\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,IAAAA,gBAKO;;;ACLP,qBAA4C;AAE5C,mBASO;AAwGH;AA1EG,IAAM,kBAAc,4BAAuC,IAAI;AAkF/D,SAAS,iBAAmC;AACjD,QAAM,cAAU,yBAAW,WAAW;AACtC,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,qDAAqD;AAAA,EACvE;AACA,SAAO;AACT;;;AD1HA,iBAAmB;;;AEPnB,IAAAC,gBAAoC;AAGpC,SAAS,aAAa,OAAe,QAAgB;AACnD,SAAO,UAAU,SAAS,IAAI,IAAI,QAAQ;AAC5C;AAEA,SAAS,aAAa,OAAe,QAAgB;AACnD,SAAO,UAAU,IAAI,SAAS,IAAI,QAAQ;AAC5C;AAEO,SAAS,4BAA4B;AAC1C,QAAM,EAAE,MAAAC,MAAK,IAAI,eAAe;AAChC,QAAM,CAAC,WAAW,YAAY,QAAI,wBAAS,EAAE;AAE7C,+BAAU,MAAM;AACd,UAAM,gBAAgB,CAAC,UAAyB;AAC9C,YAAM,QACJ,cAAc,KACVA,MAAK,QAAQ,UAAU,CAAC,QAAQ,IAAI,iBAAiB,MAAM,IAC3D;AACN,YAAM,YAAY,aAAa,OAAOA,MAAK,QAAQ,MAAM;AACzD,YAAM,YAAY,aAAa,OAAOA,MAAK,QAAQ,MAAM;AAGzD,UAAI,UAAU,GAAI;AAElB,cAAQ,MAAM,KAAK;AAAA,QACjB,KAAK;AACH,gBAAM,eAAe;AACrB,uBAAa,SAAS;AACtB,UAAAA,MAAK,QAAQ,SAAS,EAAE,MAAM;AAC9B;AAAA,QACF,KAAK;AACH,gBAAM,eAAe;AACrB,uBAAa,SAAS;AACtB,UAAAA,MAAK,QAAQ,SAAS,EAAE,MAAM;AAC9B;AAAA,QACF,KAAK;AACH,gBAAM,eAAe;AACrB,uBAAa,CAAC;AACd,UAAAA,MAAK,QAAQ,CAAC,EAAE,MAAM;AACtB;AAAA,QACF,KAAK;AACH,gBAAM,eAAe;AACrB,uBAAaA,MAAK,QAAQ,SAAS,CAAC;AACpC,UAAAA,MAAK,QAAQA,MAAK,QAAQ,SAAS,CAAC,EAAE,MAAM;AAC5C;AAAA,QACF;AACE;AAAA,MACJ;AAAA,IACF;AAEA,aAAS,iBAAiB,WAAW,aAAa;AAElD,WAAO,MAAM;AACX,eAAS,oBAAoB,WAAW,aAAa;AAAA,IACvD;AAAA,EACF,GAAG,CAAC,WAAWA,MAAK,OAAO,CAAC;AAE5B,SAAO;AAAA,IACL,KAAK,CAAC,QAA2B;AAC/B,UAAI,OAAO,CAACA,MAAK,QAAQ,SAAS,GAAG,GAAG;AACtC,QAAAA,MAAK,QAAQ,KAAK,GAAG;AAAA,MACvB;AAAA,IACF;AAAA,EACF;AACF;;;AFhBI,IAAAC,sBAAA;AAbG,SAAS,IAAI,OAAiB;AACnC,QAAM,EAAE,OAAO,GAAG,YAAY,IAAI;AAClC,QAAM,EAAE,QAAQ,aAAa,OAAO,IAAI,eAAe;AACvD,QAAM,CAAC,WAAW,eAAe,QAAI,6BAAc;AACnD,QAAM,EAAE,IAAI,IAAI,0BAA0B;AAC1C,QAAM,eAAW,uBAAQ,MAAM,WAAW,OAAO,CAAC,QAAQ,KAAK,CAAC;AAEhE,WAAS,YAAY,GAAkC;AA/CzD;AAgDI,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,OAAO,KAAK;AAAA,MAChB,eAAW,eAAG,YAAY,WAAW,OAAO,GAAG;AAAA,MAC/C,SAAS;AAAA,MACT,MAAK;AAAA,MACL;AAAA,MACA;AAAA;AAAA,EACF;AAEJ;","names":["import_react","import_react","tabs","import_jsx_runtime"]}
@@ -1,69 +0,0 @@
1
- "use strict";
2
- "use client";
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __hasOwnProp = Object.prototype.hasOwnProperty;
7
- var __export = (target, all) => {
8
- for (var name in all)
9
- __defProp(target, name, { get: all[name], enumerable: true });
10
- };
11
- var __copyProps = (to, from, except, desc) => {
12
- if (from && typeof from === "object" || typeof from === "function") {
13
- for (let key of __getOwnPropNames(from))
14
- if (!__hasOwnProp.call(to, key) && key !== except)
15
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
- }
17
- return to;
18
- };
19
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
-
21
- // src/components/TabList.tsx
22
- var TabList_exports = {};
23
- __export(TabList_exports, {
24
- TabList: () => TabList
25
- });
26
- module.exports = __toCommonJS(TabList_exports);
27
- var import_css = require("@cerberus/styled-system/css");
28
- var import_patterns = require("@cerberus/styled-system/patterns");
29
-
30
- // src/context/tabs.tsx
31
- var import_recipes = require("@cerberus/styled-system/recipes");
32
- var import_react = require("react");
33
- var import_jsx_runtime = require("react/jsx-runtime");
34
- var TabsContext = (0, import_react.createContext)(null);
35
- function useTabsContext() {
36
- const context = (0, import_react.useContext)(TabsContext);
37
- if (!context) {
38
- throw new Error("useTabsContext must be used within a Tabs Provider.");
39
- }
40
- return context;
41
- }
42
-
43
- // src/components/TabList.tsx
44
- var import_jsx_runtime2 = require("react/jsx-runtime");
45
- function TabList(props) {
46
- const { description, ...nativeProps } = props;
47
- const { id, styles } = useTabsContext();
48
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
49
- "div",
50
- {
51
- ...nativeProps,
52
- "aria-label": description,
53
- className: (0, import_css.cx)(
54
- nativeProps.className,
55
- (0, import_patterns.hstack)({
56
- gap: "0"
57
- }),
58
- styles.tabList
59
- ),
60
- id: id ?? nativeProps.id,
61
- role: "tablist"
62
- }
63
- );
64
- }
65
- // Annotate the CommonJS export names for ESM import in node:
66
- 0 && (module.exports = {
67
- TabList
68
- });
69
- //# sourceMappingURL=TabList.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../src/components/TabList.tsx","../../../src/context/tabs.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 /**\n * A description of what the tab list contains. Required for accessibility.\n */\n description: string\n}\n\n/**\n * The TabList component provides a container for tab elements.\n * @see https://cerberus.digitalu.design/react/tabs\n * @memberof module:Tabs\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, styles } = useTabsContext()\n\n return (\n <div\n {...nativeProps}\n aria-label={description}\n className={cx(\n nativeProps.className,\n hstack({\n gap: '0',\n }),\n styles.tabList,\n )}\n id={id ?? nativeProps.id}\n role=\"tablist\"\n />\n )\n}\n","'use client'\n\nimport { tabs, type TabsVariantProps } from '@cerberus/styled-system/recipes'\nimport type { Pretty } from '@cerberus/styled-system/types'\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 Tabs\n */\n\nexport interface TabsContextValue {\n /**\n * The ref for the tabs.\n */\n tabs: MutableRefObject<HTMLButtonElement[]>\n /**\n * The id of the tabs component.\n */\n id: string\n /**\n * The active tab id.\n */\n active: string\n /**\n * The styles for the tabs.\n */\n styles: Pretty<Record<'tabList' | 'tab' | 'tabPanel', string>>\n /**\n * Called when the active tab is updated.\n */\n onTabUpdate: (active: string) => void\n}\n\nexport const TabsContext = createContext<TabsContextValue | null>(null)\n\nexport interface TabsProps {\n /**\n * A unique identifier for the Tabs component. Typically used when there are\n * multiple Tabs components on the same page.\n */\n id?: string\n /**\n * The default active tab id.\n */\n active?: string\n /**\n * Whether to cache the active tab state in local storage.\n */\n cache?: boolean\n}\n\n/**\n * The Tabs component provides a context to manage tab state.\n * @see https://cerberus.digitalu.design/react/tabs\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(\n props: PropsWithChildren<TabsProps & TabsVariantProps>,\n): JSX.Element {\n const { cache, active, id, palette } = props\n const [activeTab, setActiveTab] = useState(() => (cache ? '' : active ?? ''))\n const tabsList = useRef<HTMLButtonElement[]>([])\n const uuid = useMemo(() => {\n return id ? `cerberus-tabs-${id}` : 'cerberus-tabs'\n }, [id])\n\n const value = useMemo(\n () => ({\n tabs: tabsList,\n id: uuid,\n active: activeTab,\n styles: tabs({ palette }),\n onTabUpdate: setActiveTab,\n }),\n [activeTab, setActiveTab, palette, uuid, tabsList],\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\n/**\n * Used to access the tabs context.\n * @returns The tabs context.\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":";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,iBAAmB;AACnB,sBAAuB;;;ACDvB,qBAA4C;AAE5C,mBASO;AAwGH;AA1EG,IAAM,kBAAc,4BAAuC,IAAI;AAkF/D,SAAS,iBAAmC;AACjD,QAAM,cAAU,yBAAW,WAAW;AACtC,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,qDAAqD;AAAA,EACvE;AACA,SAAO;AACT;;;AD/FI,IAAAA,sBAAA;AALG,SAAS,QAAQ,OAAwC;AAC9D,QAAM,EAAE,aAAa,GAAG,YAAY,IAAI;AACxC,QAAM,EAAE,IAAI,OAAO,IAAI,eAAe;AAEtC,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ,cAAY;AAAA,MACZ,eAAW;AAAA,QACT,YAAY;AAAA,YACZ,wBAAO;AAAA,UACL,KAAK;AAAA,QACP,CAAC;AAAA,QACD,OAAO;AAAA,MACT;AAAA,MACA,IAAI,MAAM,YAAY;AAAA,MACtB,MAAK;AAAA;AAAA,EACP;AAEJ;","names":["import_jsx_runtime"]}
@@ -1,76 +0,0 @@
1
- "use strict";
2
- "use client";
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __hasOwnProp = Object.prototype.hasOwnProperty;
7
- var __export = (target, all) => {
8
- for (var name in all)
9
- __defProp(target, name, { get: all[name], enumerable: true });
10
- };
11
- var __copyProps = (to, from, except, desc) => {
12
- if (from && typeof from === "object" || typeof from === "function") {
13
- for (let key of __getOwnPropNames(from))
14
- if (!__hasOwnProp.call(to, key) && key !== except)
15
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
- }
17
- return to;
18
- };
19
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
-
21
- // src/components/TabPanel.tsx
22
- var TabPanel_exports = {};
23
- __export(TabPanel_exports, {
24
- TabPanel: () => TabPanel
25
- });
26
- module.exports = __toCommonJS(TabPanel_exports);
27
- var import_css = require("@cerberus/styled-system/css");
28
- var import_react3 = require("react");
29
-
30
- // src/context/tabs.tsx
31
- var import_recipes = require("@cerberus/styled-system/recipes");
32
- var import_react = require("react");
33
- var import_jsx_runtime = require("react/jsx-runtime");
34
- var TabsContext = (0, import_react.createContext)(null);
35
- function useTabsContext() {
36
- const context = (0, import_react.useContext)(TabsContext);
37
- if (!context) {
38
- throw new Error("useTabsContext must be used within a Tabs Provider.");
39
- }
40
- return context;
41
- }
42
-
43
- // src/components/Show.tsx
44
- var import_react2 = require("react");
45
- function Show(props) {
46
- const { when, children, fallback } = props;
47
- const condition = (0, import_react2.useMemo)(() => when ?? false, [when]);
48
- return (0, import_react2.useMemo)(() => {
49
- if (condition) return children;
50
- return fallback ?? null;
51
- }, [condition, children, fallback]);
52
- }
53
-
54
- // src/components/TabPanel.tsx
55
- var import_jsx_runtime2 = require("react/jsx-runtime");
56
- function TabPanel(props) {
57
- const { tab, ...nativeProps } = props;
58
- const { active, styles } = useTabsContext();
59
- const isActive = (0, import_react3.useMemo)(() => active === tab, [active, tab]);
60
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Show, { when: isActive, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
61
- "div",
62
- {
63
- ...nativeProps,
64
- ...isActive && { tabIndex: 0 },
65
- "aria-labelledby": `tab:${tab}`,
66
- className: (0, import_css.cx)(nativeProps.className, styles.tabPanel),
67
- id: `panel:${tab}`,
68
- role: "tabpanel"
69
- }
70
- ) });
71
- }
72
- // Annotate the CommonJS export names for ESM import in node:
73
- 0 && (module.exports = {
74
- TabPanel
75
- });
76
- //# sourceMappingURL=TabPanel.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../src/components/TabPanel.tsx","../../../src/context/tabs.tsx","../../../src/components/Show.tsx"],"sourcesContent":["'use client'\n\nimport { cx } from '@cerberus/styled-system/css'\nimport { useMemo, type HTMLAttributes } from 'react'\nimport { useTabsContext } from '../context/tabs'\nimport { Show } from './Show'\n\n/**\n * This module provides a TabPanel component.\n * @module\n */\n\nexport interface TabPanelProps extends HTMLAttributes<HTMLDivElement> {\n /**\n * The unique value of the Tab that is associated with the TabPanel.\n */\n tab: string\n}\n\n/**\n * The TabPanel component provides a panel element to be used in a Tabs\n * provider.\n * @see https://cerberus.digitalu.design/react/tabs\n * @memberof module:Tabs\n * @example\n * ```tsx\n * <TabPanel tab=\"overview\">\n * Overview content\n * </TabPanel>\n * ```\n */\nexport function TabPanel(props: TabPanelProps) {\n const { tab, ...nativeProps } = props\n const { active, styles } = useTabsContext()\n const isActive = useMemo(() => active === tab, [active, tab])\n\n return (\n <Show when={isActive}>\n <div\n {...nativeProps}\n {...(isActive && { tabIndex: 0 })}\n aria-labelledby={`tab:${tab}`}\n className={cx(nativeProps.className, styles.tabPanel)}\n id={`panel:${tab}`}\n role=\"tabpanel\"\n />\n </Show>\n )\n}\n","'use client'\n\nimport { tabs, type TabsVariantProps } from '@cerberus/styled-system/recipes'\nimport type { Pretty } from '@cerberus/styled-system/types'\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 Tabs\n */\n\nexport interface TabsContextValue {\n /**\n * The ref for the tabs.\n */\n tabs: MutableRefObject<HTMLButtonElement[]>\n /**\n * The id of the tabs component.\n */\n id: string\n /**\n * The active tab id.\n */\n active: string\n /**\n * The styles for the tabs.\n */\n styles: Pretty<Record<'tabList' | 'tab' | 'tabPanel', string>>\n /**\n * Called when the active tab is updated.\n */\n onTabUpdate: (active: string) => void\n}\n\nexport const TabsContext = createContext<TabsContextValue | null>(null)\n\nexport interface TabsProps {\n /**\n * A unique identifier for the Tabs component. Typically used when there are\n * multiple Tabs components on the same page.\n */\n id?: string\n /**\n * The default active tab id.\n */\n active?: string\n /**\n * Whether to cache the active tab state in local storage.\n */\n cache?: boolean\n}\n\n/**\n * The Tabs component provides a context to manage tab state.\n * @see https://cerberus.digitalu.design/react/tabs\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(\n props: PropsWithChildren<TabsProps & TabsVariantProps>,\n): JSX.Element {\n const { cache, active, id, palette } = props\n const [activeTab, setActiveTab] = useState(() => (cache ? '' : active ?? ''))\n const tabsList = useRef<HTMLButtonElement[]>([])\n const uuid = useMemo(() => {\n return id ? `cerberus-tabs-${id}` : 'cerberus-tabs'\n }, [id])\n\n const value = useMemo(\n () => ({\n tabs: tabsList,\n id: uuid,\n active: activeTab,\n styles: tabs({ palette }),\n onTabUpdate: setActiveTab,\n }),\n [activeTab, setActiveTab, palette, uuid, tabsList],\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\n/**\n * Used to access the tabs context.\n * @returns The tabs context.\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","'use client'\n\nimport { useMemo, type PropsWithChildren, type ReactNode } from 'react'\n\n/**\n * This module contains the Show component.\n * @module\n */\n\nexport interface ShowProps {\n /**\n * The condition to render memoized children or the fallback content.\n */\n when: boolean | null | undefined\n /**\n * The children to render when the condition is false.\n */\n fallback?: ReactNode\n}\n\n/**\n * Conditionally render a memoized version of the children or optional fallback\n * content.\n * @see https://cerberus.digitalu.design/react/show\n * @example\n * ```tsx\n * <Show when={isLoggedIn} fallback={<Navigate to=\"/login\" />}>\n * <Dashboard />\n * </Show>\n */\nexport function Show(props: PropsWithChildren<ShowProps>): ReactNode {\n const { when, children, fallback } = props\n const condition = useMemo(() => when ?? false, [when])\n\n return useMemo(() => {\n if (condition) return children\n return fallback ?? null\n }, [condition, children, fallback])\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,iBAAmB;AACnB,IAAAA,gBAA6C;;;ACD7C,qBAA4C;AAE5C,mBASO;AAwGH;AA1EG,IAAM,kBAAc,4BAAuC,IAAI;AAkF/D,SAAS,iBAAmC;AACjD,QAAM,cAAU,yBAAW,WAAW;AACtC,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,qDAAqD;AAAA,EACvE;AACA,SAAO;AACT;;;ACjIA,IAAAC,gBAAgE;AA4BzD,SAAS,KAAK,OAAgD;AACnE,QAAM,EAAE,MAAM,UAAU,SAAS,IAAI;AACrC,QAAM,gBAAY,uBAAQ,MAAM,QAAQ,OAAO,CAAC,IAAI,CAAC;AAErD,aAAO,uBAAQ,MAAM;AACnB,QAAI,UAAW,QAAO;AACtB,WAAO,YAAY;AAAA,EACrB,GAAG,CAAC,WAAW,UAAU,QAAQ,CAAC;AACpC;;;AFAM,IAAAC,sBAAA;AAPC,SAAS,SAAS,OAAsB;AAC7C,QAAM,EAAE,KAAK,GAAG,YAAY,IAAI;AAChC,QAAM,EAAE,QAAQ,OAAO,IAAI,eAAe;AAC1C,QAAM,eAAW,uBAAQ,MAAM,WAAW,KAAK,CAAC,QAAQ,GAAG,CAAC;AAE5D,SACE,6CAAC,QAAK,MAAM,UACV;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACH,GAAI,YAAY,EAAE,UAAU,EAAE;AAAA,MAC/B,mBAAiB,OAAO,GAAG;AAAA,MAC3B,eAAW,eAAG,YAAY,WAAW,OAAO,QAAQ;AAAA,MACpD,IAAI,SAAS,GAAG;AAAA,MAChB,MAAK;AAAA;AAAA,EACP,GACF;AAEJ;","names":["import_react","import_react","import_jsx_runtime"]}
@@ -1,9 +0,0 @@
1
- "use client";
2
- import {
3
- useTabsKeyboardNavigation
4
- } from "../chunk-ITOIXNJS.js";
5
- import "../chunk-RIFQSCHT.js";
6
- export {
7
- useTabsKeyboardNavigation
8
- };
9
- //# sourceMappingURL=tabs.aria.js.map
@@ -1,32 +0,0 @@
1
- import {
2
- Show
3
- } from "./chunk-BUVVRQLZ.js";
4
- import {
5
- useTabsContext
6
- } from "./chunk-RIFQSCHT.js";
7
-
8
- // src/components/TabPanel.tsx
9
- import { cx } from "@cerberus/styled-system/css";
10
- import { useMemo } from "react";
11
- import { jsx } from "react/jsx-runtime";
12
- function TabPanel(props) {
13
- const { tab, ...nativeProps } = props;
14
- const { active, styles } = useTabsContext();
15
- const isActive = useMemo(() => active === tab, [active, tab]);
16
- return /* @__PURE__ */ jsx(Show, { when: isActive, children: /* @__PURE__ */ jsx(
17
- "div",
18
- {
19
- ...nativeProps,
20
- ...isActive && { tabIndex: 0 },
21
- "aria-labelledby": `tab:${tab}`,
22
- className: cx(nativeProps.className, styles.tabPanel),
23
- id: `panel:${tab}`,
24
- role: "tabpanel"
25
- }
26
- ) });
27
- }
28
-
29
- export {
30
- TabPanel
31
- };
32
- //# sourceMappingURL=chunk-AYIRV5CL.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/components/TabPanel.tsx"],"sourcesContent":["'use client'\n\nimport { cx } from '@cerberus/styled-system/css'\nimport { useMemo, type HTMLAttributes } from 'react'\nimport { useTabsContext } from '../context/tabs'\nimport { Show } from './Show'\n\n/**\n * This module provides a TabPanel component.\n * @module\n */\n\nexport interface TabPanelProps extends HTMLAttributes<HTMLDivElement> {\n /**\n * The unique value of the Tab that is associated with the TabPanel.\n */\n tab: string\n}\n\n/**\n * The TabPanel component provides a panel element to be used in a Tabs\n * provider.\n * @see https://cerberus.digitalu.design/react/tabs\n * @memberof module:Tabs\n * @example\n * ```tsx\n * <TabPanel tab=\"overview\">\n * Overview content\n * </TabPanel>\n * ```\n */\nexport function TabPanel(props: TabPanelProps) {\n const { tab, ...nativeProps } = props\n const { active, styles } = useTabsContext()\n const isActive = useMemo(() => active === tab, [active, tab])\n\n return (\n <Show when={isActive}>\n <div\n {...nativeProps}\n {...(isActive && { tabIndex: 0 })}\n aria-labelledby={`tab:${tab}`}\n className={cx(nativeProps.className, styles.tabPanel)}\n id={`panel:${tab}`}\n role=\"tabpanel\"\n />\n </Show>\n )\n}\n"],"mappings":";;;;;;;;AAEA,SAAS,UAAU;AACnB,SAAS,eAAoC;AAmCvC;AAPC,SAAS,SAAS,OAAsB;AAC7C,QAAM,EAAE,KAAK,GAAG,YAAY,IAAI;AAChC,QAAM,EAAE,QAAQ,OAAO,IAAI,eAAe;AAC1C,QAAM,WAAW,QAAQ,MAAM,WAAW,KAAK,CAAC,QAAQ,GAAG,CAAC;AAE5D,SACE,oBAAC,QAAK,MAAM,UACV;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACH,GAAI,YAAY,EAAE,UAAU,EAAE;AAAA,MAC/B,mBAAiB,OAAO,GAAG;AAAA,MAC3B,WAAW,GAAG,YAAY,WAAW,OAAO,QAAQ;AAAA,MACpD,IAAI,SAAS,GAAG;AAAA,MAChB,MAAK;AAAA;AAAA,EACP,GACF;AAEJ;","names":[]}
@@ -1,64 +0,0 @@
1
- import {
2
- useTabsContext
3
- } from "./chunk-RIFQSCHT.js";
4
-
5
- // src/aria-helpers/tabs.aria.ts
6
- import { useEffect, useState } from "react";
7
- function getNextIndex(index, length) {
8
- return index === length - 1 ? 0 : index + 1;
9
- }
10
- function getPrevIndex(index, length) {
11
- return index === 0 ? length - 1 : index - 1;
12
- }
13
- function useTabsKeyboardNavigation() {
14
- const { tabs } = useTabsContext();
15
- const [activeTab, setActiveTab] = useState(-1);
16
- useEffect(() => {
17
- const handleKeyDown = (event) => {
18
- const index = activeTab === -1 ? tabs.current.findIndex((tab) => tab.ariaSelected === "true") : activeTab;
19
- const nextIndex = getNextIndex(index, tabs.current.length);
20
- const prevIndex = getPrevIndex(index, tabs.current.length);
21
- if (index === -1) return;
22
- switch (event.key) {
23
- case "ArrowLeft":
24
- event.preventDefault();
25
- setActiveTab(prevIndex);
26
- tabs.current[prevIndex].focus();
27
- break;
28
- case "ArrowRight":
29
- event.preventDefault();
30
- setActiveTab(nextIndex);
31
- tabs.current[nextIndex].focus();
32
- break;
33
- case "Home":
34
- event.preventDefault();
35
- setActiveTab(0);
36
- tabs.current[0].focus();
37
- break;
38
- case "End":
39
- event.preventDefault();
40
- setActiveTab(tabs.current.length - 1);
41
- tabs.current[tabs.current.length - 1].focus();
42
- break;
43
- default:
44
- break;
45
- }
46
- };
47
- document.addEventListener("keydown", handleKeyDown);
48
- return () => {
49
- document.removeEventListener("keydown", handleKeyDown);
50
- };
51
- }, [activeTab, tabs.current]);
52
- return {
53
- ref: (tab) => {
54
- if (tab && !tabs.current.includes(tab)) {
55
- tabs.current.push(tab);
56
- }
57
- }
58
- };
59
- }
60
-
61
- export {
62
- useTabsKeyboardNavigation
63
- };
64
- //# sourceMappingURL=chunk-ITOIXNJS.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/aria-helpers/tabs.aria.ts"],"sourcesContent":["'use client'\n\nimport { useEffect, useState } from 'react'\nimport { useTabsContext } from '../context/tabs'\n\nfunction getNextIndex(index: number, length: number) {\n return index === length - 1 ? 0 : index + 1\n}\n\nfunction getPrevIndex(index: number, length: number) {\n return index === 0 ? length - 1 : index - 1\n}\n\nexport function useTabsKeyboardNavigation() {\n const { tabs } = useTabsContext()\n const [activeTab, setActiveTab] = useState(-1)\n\n useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n const index =\n activeTab === -1\n ? tabs.current.findIndex((tab) => tab.ariaSelected === 'true')\n : activeTab\n const nextIndex = getNextIndex(index, tabs.current.length)\n const prevIndex = getPrevIndex(index, tabs.current.length)\n\n // If the active tab is not found, do nothing\n if (index === -1) return\n\n switch (event.key) {\n case 'ArrowLeft':\n event.preventDefault()\n setActiveTab(prevIndex)\n tabs.current[prevIndex].focus()\n break\n case 'ArrowRight':\n event.preventDefault()\n setActiveTab(nextIndex)\n tabs.current[nextIndex].focus()\n break\n case 'Home':\n event.preventDefault()\n setActiveTab(0)\n tabs.current[0].focus()\n break\n case 'End':\n event.preventDefault()\n setActiveTab(tabs.current.length - 1)\n tabs.current[tabs.current.length - 1].focus()\n break\n default:\n break\n }\n }\n\n document.addEventListener('keydown', handleKeyDown)\n\n return () => {\n document.removeEventListener('keydown', handleKeyDown)\n }\n }, [activeTab, tabs.current])\n\n return {\n ref: (tab: HTMLButtonElement) => {\n if (tab && !tabs.current.includes(tab)) {\n tabs.current.push(tab)\n }\n },\n }\n}\n"],"mappings":";;;;;AAEA,SAAS,WAAW,gBAAgB;AAGpC,SAAS,aAAa,OAAe,QAAgB;AACnD,SAAO,UAAU,SAAS,IAAI,IAAI,QAAQ;AAC5C;AAEA,SAAS,aAAa,OAAe,QAAgB;AACnD,SAAO,UAAU,IAAI,SAAS,IAAI,QAAQ;AAC5C;AAEO,SAAS,4BAA4B;AAC1C,QAAM,EAAE,KAAK,IAAI,eAAe;AAChC,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,EAAE;AAE7C,YAAU,MAAM;AACd,UAAM,gBAAgB,CAAC,UAAyB;AAC9C,YAAM,QACJ,cAAc,KACV,KAAK,QAAQ,UAAU,CAAC,QAAQ,IAAI,iBAAiB,MAAM,IAC3D;AACN,YAAM,YAAY,aAAa,OAAO,KAAK,QAAQ,MAAM;AACzD,YAAM,YAAY,aAAa,OAAO,KAAK,QAAQ,MAAM;AAGzD,UAAI,UAAU,GAAI;AAElB,cAAQ,MAAM,KAAK;AAAA,QACjB,KAAK;AACH,gBAAM,eAAe;AACrB,uBAAa,SAAS;AACtB,eAAK,QAAQ,SAAS,EAAE,MAAM;AAC9B;AAAA,QACF,KAAK;AACH,gBAAM,eAAe;AACrB,uBAAa,SAAS;AACtB,eAAK,QAAQ,SAAS,EAAE,MAAM;AAC9B;AAAA,QACF,KAAK;AACH,gBAAM,eAAe;AACrB,uBAAa,CAAC;AACd,eAAK,QAAQ,CAAC,EAAE,MAAM;AACtB;AAAA,QACF,KAAK;AACH,gBAAM,eAAe;AACrB,uBAAa,KAAK,QAAQ,SAAS,CAAC;AACpC,eAAK,QAAQ,KAAK,QAAQ,SAAS,CAAC,EAAE,MAAM;AAC5C;AAAA,QACF;AACE;AAAA,MACJ;AAAA,IACF;AAEA,aAAS,iBAAiB,WAAW,aAAa;AAElD,WAAO,MAAM;AACX,eAAS,oBAAoB,WAAW,aAAa;AAAA,IACvD;AAAA,EACF,GAAG,CAAC,WAAW,KAAK,OAAO,CAAC;AAE5B,SAAO;AAAA,IACL,KAAK,CAAC,QAA2B;AAC/B,UAAI,OAAO,CAAC,KAAK,QAAQ,SAAS,GAAG,GAAG;AACtC,aAAK,QAAQ,KAAK,GAAG;AAAA,MACvB;AAAA,IACF;AAAA,EACF;AACF;","names":[]}