@entur/tab 1.0.0-alpha.0 → 1.0.0-next.0
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/README.md +2 -2
- package/dist/Tab.d.ts +5 -5
- package/dist/TabList.d.ts +9 -5
- package/dist/TabPanel.d.ts +7 -7
- package/dist/TabPanels.d.ts +7 -5
- package/dist/Tabs.d.ts +7 -7
- package/dist/TabsContext.d.ts +20 -0
- package/dist/index.d.ts +0 -1
- package/dist/styles.css +374 -143
- package/dist/tab.cjs.js +199 -0
- package/dist/tab.cjs.js.map +1 -0
- package/dist/tab.esm.js +192 -83
- package/dist/tab.esm.js.map +1 -1
- package/package.json +25 -14
- package/dist/index.js +0 -8
- package/dist/tab.cjs.development.js +0 -98
- package/dist/tab.cjs.development.js.map +0 -1
- package/dist/tab.cjs.production.min.js +0 -2
- package/dist/tab.cjs.production.min.js.map +0 -1
package/dist/tab.cjs.js
ADDED
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const utils = require("@entur/utils");
|
|
4
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
5
|
+
const React = require("react");
|
|
6
|
+
const classNames = require("classnames");
|
|
7
|
+
const TabsContext = React.createContext({
|
|
8
|
+
selectedIndex: 0,
|
|
9
|
+
onSelect: () => void 0,
|
|
10
|
+
tabsId: ""
|
|
11
|
+
});
|
|
12
|
+
const TabItemContext = React.createContext(
|
|
13
|
+
null
|
|
14
|
+
);
|
|
15
|
+
const TabPanelItemContext = React.createContext(null);
|
|
16
|
+
const Tab = ({
|
|
17
|
+
className,
|
|
18
|
+
removeActiveLine = false,
|
|
19
|
+
as,
|
|
20
|
+
disabled = false,
|
|
21
|
+
children,
|
|
22
|
+
...rest
|
|
23
|
+
}) => {
|
|
24
|
+
const { selectedIndex, onSelect } = React.useContext(TabsContext);
|
|
25
|
+
const itemContext = React.useContext(TabItemContext);
|
|
26
|
+
const tabIndex = itemContext?.tabIndex ?? 0;
|
|
27
|
+
const isSelected = selectedIndex === tabIndex;
|
|
28
|
+
const Element = as || "button";
|
|
29
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
30
|
+
Element,
|
|
31
|
+
{
|
|
32
|
+
role: "tab",
|
|
33
|
+
type: as ? void 0 : "button",
|
|
34
|
+
id: itemContext?.tabId,
|
|
35
|
+
"aria-selected": isSelected,
|
|
36
|
+
"aria-controls": itemContext?.panelId,
|
|
37
|
+
tabIndex: isSelected ? 0 : -1,
|
|
38
|
+
disabled: disabled || void 0,
|
|
39
|
+
"aria-disabled": disabled || void 0,
|
|
40
|
+
className: classNames(
|
|
41
|
+
"eds-tab",
|
|
42
|
+
{ "eds-tab--remove-active-line": removeActiveLine },
|
|
43
|
+
className
|
|
44
|
+
),
|
|
45
|
+
onClick: () => {
|
|
46
|
+
if (!disabled) onSelect(tabIndex);
|
|
47
|
+
},
|
|
48
|
+
...rest,
|
|
49
|
+
children
|
|
50
|
+
}
|
|
51
|
+
);
|
|
52
|
+
};
|
|
53
|
+
const Tabs = ({
|
|
54
|
+
className,
|
|
55
|
+
index,
|
|
56
|
+
defaultIndex,
|
|
57
|
+
onChange,
|
|
58
|
+
as,
|
|
59
|
+
children,
|
|
60
|
+
...rest
|
|
61
|
+
}) => {
|
|
62
|
+
const [internalIndex, setInternalIndex] = React.useState(defaultIndex ?? 0);
|
|
63
|
+
const isControlled = index !== void 0;
|
|
64
|
+
const selectedIndex = isControlled ? index : internalIndex;
|
|
65
|
+
const tabsId = React.useId();
|
|
66
|
+
const onSelect = React.useCallback(
|
|
67
|
+
(i) => {
|
|
68
|
+
if (!isControlled) {
|
|
69
|
+
setInternalIndex(i);
|
|
70
|
+
}
|
|
71
|
+
onChange?.(i);
|
|
72
|
+
},
|
|
73
|
+
[isControlled, onChange]
|
|
74
|
+
);
|
|
75
|
+
const Element = as || "div";
|
|
76
|
+
return /* @__PURE__ */ jsxRuntime.jsx(TabsContext.Provider, { value: { selectedIndex, onSelect, tabsId }, children: /* @__PURE__ */ jsxRuntime.jsx(Element, { className: classNames("eds-tabs", className), ...rest, children }) });
|
|
77
|
+
};
|
|
78
|
+
const TabPanel = ({
|
|
79
|
+
className,
|
|
80
|
+
as,
|
|
81
|
+
children,
|
|
82
|
+
...rest
|
|
83
|
+
}) => {
|
|
84
|
+
const { selectedIndex } = React.useContext(TabsContext);
|
|
85
|
+
const itemContext = React.useContext(TabPanelItemContext);
|
|
86
|
+
const tabIndex = itemContext?.tabIndex ?? 0;
|
|
87
|
+
const keepMounted = itemContext?.keepMounted ?? false;
|
|
88
|
+
const isSelected = selectedIndex === tabIndex;
|
|
89
|
+
const isHiddenButMounted = keepMounted && !isSelected;
|
|
90
|
+
if (!isSelected && !keepMounted) return null;
|
|
91
|
+
const Element = as || "div";
|
|
92
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
93
|
+
Element,
|
|
94
|
+
{
|
|
95
|
+
role: "tabpanel",
|
|
96
|
+
id: itemContext?.panelId,
|
|
97
|
+
"aria-labelledby": itemContext?.tabId,
|
|
98
|
+
tabIndex: isSelected ? 0 : -1,
|
|
99
|
+
hidden: isHiddenButMounted || void 0,
|
|
100
|
+
className: classNames("eds-tab-panel", className),
|
|
101
|
+
...rest,
|
|
102
|
+
children
|
|
103
|
+
}
|
|
104
|
+
);
|
|
105
|
+
};
|
|
106
|
+
const TabPanels = ({
|
|
107
|
+
className,
|
|
108
|
+
as,
|
|
109
|
+
keepMounted = false,
|
|
110
|
+
children,
|
|
111
|
+
...rest
|
|
112
|
+
}) => {
|
|
113
|
+
const { tabsId } = React.useContext(TabsContext);
|
|
114
|
+
const Element = as || "div";
|
|
115
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Element, { className: classNames("eds-tab-panels", className), ...rest, children: React.Children.map(children, (child, idx) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
116
|
+
TabPanelItemContext.Provider,
|
|
117
|
+
{
|
|
118
|
+
value: {
|
|
119
|
+
tabIndex: idx,
|
|
120
|
+
tabId: `${tabsId}-tab-${idx}`,
|
|
121
|
+
panelId: `${tabsId}-panel-${idx}`,
|
|
122
|
+
keepMounted
|
|
123
|
+
},
|
|
124
|
+
children: child
|
|
125
|
+
}
|
|
126
|
+
)) });
|
|
127
|
+
};
|
|
128
|
+
const TabList = ({
|
|
129
|
+
className,
|
|
130
|
+
width,
|
|
131
|
+
as,
|
|
132
|
+
children,
|
|
133
|
+
...rest
|
|
134
|
+
}) => {
|
|
135
|
+
const { tabsId } = React.useContext(TabsContext);
|
|
136
|
+
const tabListRef = React.useRef(null);
|
|
137
|
+
const handleKeyDown = React.useCallback((e) => {
|
|
138
|
+
const tabs = tabListRef.current?.querySelectorAll(
|
|
139
|
+
'[role="tab"]:not([disabled])'
|
|
140
|
+
);
|
|
141
|
+
if (!tabs || tabs.length === 0) return;
|
|
142
|
+
const currentIndex = Array.from(tabs).findIndex(
|
|
143
|
+
(tab) => tab === document.activeElement
|
|
144
|
+
);
|
|
145
|
+
if (currentIndex === -1) return;
|
|
146
|
+
let nextIndex;
|
|
147
|
+
switch (e.key) {
|
|
148
|
+
case "ArrowRight":
|
|
149
|
+
nextIndex = (currentIndex + 1) % tabs.length;
|
|
150
|
+
break;
|
|
151
|
+
case "ArrowLeft":
|
|
152
|
+
nextIndex = (currentIndex - 1 + tabs.length) % tabs.length;
|
|
153
|
+
break;
|
|
154
|
+
case "Home":
|
|
155
|
+
nextIndex = 0;
|
|
156
|
+
break;
|
|
157
|
+
case "End":
|
|
158
|
+
nextIndex = tabs.length - 1;
|
|
159
|
+
break;
|
|
160
|
+
}
|
|
161
|
+
if (nextIndex !== void 0) {
|
|
162
|
+
e.preventDefault();
|
|
163
|
+
tabs[nextIndex].focus();
|
|
164
|
+
tabs[nextIndex].click();
|
|
165
|
+
}
|
|
166
|
+
}, []);
|
|
167
|
+
const Element = as || "div";
|
|
168
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
169
|
+
Element,
|
|
170
|
+
{
|
|
171
|
+
role: "tablist",
|
|
172
|
+
tabIndex: -1,
|
|
173
|
+
ref: tabListRef,
|
|
174
|
+
className: classNames("eds-tab-list", className, {
|
|
175
|
+
"eds-tab-list--width-fluid": width === "fluid"
|
|
176
|
+
}),
|
|
177
|
+
onKeyDown: handleKeyDown,
|
|
178
|
+
...rest,
|
|
179
|
+
children: React.Children.map(children, (child, idx) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
180
|
+
TabItemContext.Provider,
|
|
181
|
+
{
|
|
182
|
+
value: {
|
|
183
|
+
tabIndex: idx,
|
|
184
|
+
tabId: `${tabsId}-tab-${idx}`,
|
|
185
|
+
panelId: `${tabsId}-panel-${idx}`
|
|
186
|
+
},
|
|
187
|
+
children: child
|
|
188
|
+
}
|
|
189
|
+
))
|
|
190
|
+
}
|
|
191
|
+
);
|
|
192
|
+
};
|
|
193
|
+
utils.warnAboutMissingStyles("tab");
|
|
194
|
+
exports.Tab = Tab;
|
|
195
|
+
exports.TabList = TabList;
|
|
196
|
+
exports.TabPanel = TabPanel;
|
|
197
|
+
exports.TabPanels = TabPanels;
|
|
198
|
+
exports.Tabs = Tabs;
|
|
199
|
+
//# sourceMappingURL=tab.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tab.cjs.js","sources":["../src/TabsContext.tsx","../src/Tab.tsx","../src/Tabs.tsx","../src/TabPanel.tsx","../src/TabPanels.tsx","../src/TabList.tsx","../src/index.tsx"],"sourcesContent":["import React from 'react';\n\nexport type TabsContextValue = {\n selectedIndex: number;\n onSelect: (index: number) => void;\n tabsId: string;\n};\n\nexport const TabsContext = React.createContext<TabsContextValue>({\n selectedIndex: 0,\n onSelect: () => undefined,\n tabsId: '',\n});\n\nexport type TabItemContextValue = {\n tabIndex: number;\n tabId: string;\n panelId: string;\n};\n\nexport const TabItemContext = React.createContext<TabItemContextValue | null>(\n null,\n);\n\nexport type TabPanelItemContextValue = {\n tabIndex: number;\n tabId: string;\n panelId: string;\n keepMounted: boolean;\n};\n\nexport const TabPanelItemContext =\n React.createContext<TabPanelItemContextValue | null>(null);\n","import React, { useContext } from 'react';\nimport classNames from 'classnames';\n\nimport { TabItemContext, TabsContext } from './TabsContext';\n\nexport type TabProps = {\n /** Overskriften til taben */\n children: React.ReactNode;\n /** Om taben er disabled eller ikke */\n disabled?: boolean;\n /** HTML-elementet eller React-komponenten som lager komponenten */\n as?: keyof JSX.IntrinsicElements | React.ElementType;\n removeActiveLine?: boolean;\n className?: string;\n} & Omit<React.ComponentPropsWithoutRef<'button'>, 'children' | 'disabled'>;\n\nexport const Tab = ({\n className,\n removeActiveLine = false,\n as,\n disabled = false,\n children,\n ...rest\n}: TabProps) => {\n const { selectedIndex, onSelect } = useContext(TabsContext);\n const itemContext = useContext(TabItemContext);\n const tabIndex = itemContext?.tabIndex ?? 0;\n const isSelected = selectedIndex === tabIndex;\n const Element: React.ElementType = as || 'button';\n\n return (\n <Element\n role=\"tab\"\n type={as ? undefined : 'button'}\n id={itemContext?.tabId}\n aria-selected={isSelected}\n aria-controls={itemContext?.panelId}\n tabIndex={isSelected ? 0 : -1}\n disabled={disabled || undefined}\n aria-disabled={disabled || undefined}\n className={classNames(\n 'eds-tab',\n { 'eds-tab--remove-active-line': removeActiveLine },\n className,\n )}\n onClick={() => {\n if (!disabled) onSelect(tabIndex);\n }}\n {...rest}\n >\n {children}\n </Element>\n );\n};\n","import React, { useCallback, useId, useState } from 'react';\nimport classNames from 'classnames';\n\nimport { TabsContext } from './TabsContext';\n\nexport type TabsProps = {\n /** Tab-innholdet */\n children: React.ReactNode;\n /** Kalles når taben endres */\n onChange?: (index: number) => void;\n /** Hvilken tab som skal være åpen by default */\n defaultIndex?: number;\n /** Den åpne indexen (kontrollert) */\n index?: number;\n /** HTML-elementet eller React-komponenten som lager komponenten */\n as?: keyof JSX.IntrinsicElements | React.ElementType;\n className?: string;\n} & Omit<React.ComponentPropsWithoutRef<'div'>, 'children' | 'onChange'>;\n\nexport const Tabs = ({\n className,\n index,\n defaultIndex,\n onChange,\n as,\n children,\n ...rest\n}: TabsProps) => {\n const [internalIndex, setInternalIndex] = useState(defaultIndex ?? 0);\n const isControlled = index !== undefined;\n const selectedIndex = isControlled ? index : internalIndex;\n const tabsId = useId();\n\n const onSelect = useCallback(\n (i: number) => {\n if (!isControlled) {\n setInternalIndex(i);\n }\n onChange?.(i);\n },\n [isControlled, onChange],\n );\n\n const Element: React.ElementType = as || 'div';\n\n return (\n <TabsContext.Provider value={{ selectedIndex, onSelect, tabsId }}>\n <Element className={classNames('eds-tabs', className)} {...rest}>\n {children}\n </Element>\n </TabsContext.Provider>\n );\n};\n","import React, { useContext } from 'react';\nimport classNames from 'classnames';\n\nimport { TabPanelItemContext, TabsContext } from './TabsContext';\n\nexport type TabPanelProps = {\n /** Innholdet i tab-panelet */\n children?: React.ReactNode;\n /** HTML-elementet eller React-komponenten som lager komponenten */\n as?: keyof JSX.IntrinsicElements | React.ElementType;\n className?: string;\n} & Omit<React.ComponentPropsWithoutRef<'div'>, 'children'>;\n\nexport const TabPanel = ({\n className,\n as,\n children,\n ...rest\n}: TabPanelProps) => {\n const { selectedIndex } = useContext(TabsContext);\n const itemContext = useContext(TabPanelItemContext);\n const tabIndex = itemContext?.tabIndex ?? 0;\n const keepMounted = itemContext?.keepMounted ?? false;\n\n const isSelected = selectedIndex === tabIndex;\n const isHiddenButMounted = keepMounted && !isSelected;\n\n if (!isSelected && !keepMounted) return null;\n\n const Element: React.ElementType = as || 'div';\n\n return (\n <Element\n role=\"tabpanel\"\n id={itemContext?.panelId}\n aria-labelledby={itemContext?.tabId}\n tabIndex={isSelected ? 0 : -1}\n hidden={isHiddenButMounted || undefined}\n className={classNames('eds-tab-panel', className)}\n {...rest}\n >\n {children}\n </Element>\n );\n};\n","import React, { useContext } from 'react';\nimport classNames from 'classnames';\n\nimport { TabPanelItemContext, TabsContext } from './TabsContext';\n\nexport type TabPanelsProps = {\n /** Tab-panelene */\n children: React.ReactNode;\n /** HTML-elementet eller React-komponenten som lager komponenten */\n as?: keyof JSX.IntrinsicElements | React.ElementType;\n /** Behold alle panel-noder i DOM (skjult med hidden-attributt) i stedet for å avmontere */\n keepMounted?: boolean;\n className?: string;\n} & Omit<React.ComponentPropsWithoutRef<'div'>, 'children'>;\n\nexport const TabPanels = ({\n className,\n as,\n keepMounted = false,\n children,\n ...rest\n}: TabPanelsProps) => {\n const { tabsId } = useContext(TabsContext);\n\n const Element: React.ElementType = as || 'div';\n\n return (\n <Element className={classNames('eds-tab-panels', className)} {...rest}>\n {React.Children.map(children, (child, idx) => (\n <TabPanelItemContext.Provider\n value={{\n tabIndex: idx,\n tabId: `${tabsId}-tab-${idx}`,\n panelId: `${tabsId}-panel-${idx}`,\n keepMounted,\n }}\n >\n {child}\n </TabPanelItemContext.Provider>\n ))}\n </Element>\n );\n};\n","import React, { useCallback, useContext, useRef } from 'react';\nimport classNames from 'classnames';\n\nimport { TabItemContext, TabsContext } from './TabsContext';\n\nexport type TabListProps = {\n /** Tab-komponenter */\n children: React.ReactNode;\n /** HTML-elementet eller React-komponenten som lager komponenten */\n as?: keyof JSX.IntrinsicElements | React.ElementType;\n width?: 'fluid';\n className?: string;\n /** Tilgjengelig navn på tab-listen (dersom det ikke finnes en synlig overskrift) */\n 'aria-label'?: string;\n /** ID til elementet som navngir tab-listen */\n 'aria-labelledby'?: string;\n} & Omit<React.ComponentPropsWithoutRef<'div'>, 'children'>;\n\nexport const TabList = ({\n className,\n width,\n as,\n children,\n ...rest\n}: TabListProps) => {\n const { tabsId } = useContext(TabsContext);\n const tabListRef = useRef<HTMLElement>(null);\n\n const handleKeyDown = useCallback((e: React.KeyboardEvent) => {\n const tabs = tabListRef.current?.querySelectorAll<HTMLElement>(\n '[role=\"tab\"]:not([disabled])',\n );\n if (!tabs || tabs.length === 0) return;\n\n const currentIndex = Array.from(tabs).findIndex(\n tab => tab === document.activeElement,\n );\n if (currentIndex === -1) return;\n\n let nextIndex: number | undefined;\n switch (e.key) {\n case 'ArrowRight':\n nextIndex = (currentIndex + 1) % tabs.length;\n break;\n case 'ArrowLeft':\n nextIndex = (currentIndex - 1 + tabs.length) % tabs.length;\n break;\n case 'Home':\n nextIndex = 0;\n break;\n case 'End':\n nextIndex = tabs.length - 1;\n break;\n }\n\n if (nextIndex !== undefined) {\n e.preventDefault();\n tabs[nextIndex].focus();\n tabs[nextIndex].click();\n }\n }, []);\n\n const Element: React.ElementType = as || 'div';\n\n return (\n <Element\n role=\"tablist\"\n tabIndex={-1}\n ref={tabListRef}\n className={classNames('eds-tab-list', className, {\n 'eds-tab-list--width-fluid': width === 'fluid',\n })}\n onKeyDown={handleKeyDown}\n {...rest}\n >\n {React.Children.map(children, (child, idx) => (\n <TabItemContext.Provider\n value={{\n tabIndex: idx,\n tabId: `${tabsId}-tab-${idx}`,\n panelId: `${tabsId}-panel-${idx}`,\n }}\n >\n {child}\n </TabItemContext.Provider>\n ))}\n </Element>\n );\n};\n","import { warnAboutMissingStyles } from '@entur/utils';\nimport './index.scss';\n\nwarnAboutMissingStyles('tab');\n\nexport * from './Tab';\nexport * from './Tabs';\nexport * from './TabPanel';\nexport * from './TabPanels';\nexport * from './TabList';\n"],"names":["useContext","jsx","useState","useId","useCallback","useRef","warnAboutMissingStyles"],"mappings":"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"}
|
package/dist/tab.esm.js
CHANGED
|
@@ -1,90 +1,199 @@
|
|
|
1
|
-
import { warnAboutMissingStyles } from
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import classNames from
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
1
|
+
import { warnAboutMissingStyles } from "@entur/utils";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import React, { useContext, useState, useId, useCallback, useRef } from "react";
|
|
4
|
+
import classNames from "classnames";
|
|
5
|
+
const TabsContext = React.createContext({
|
|
6
|
+
selectedIndex: 0,
|
|
7
|
+
onSelect: () => void 0,
|
|
8
|
+
tabsId: ""
|
|
9
|
+
});
|
|
10
|
+
const TabItemContext = React.createContext(
|
|
11
|
+
null
|
|
12
|
+
);
|
|
13
|
+
const TabPanelItemContext = React.createContext(null);
|
|
14
|
+
const Tab = ({
|
|
15
|
+
className,
|
|
16
|
+
removeActiveLine = false,
|
|
17
|
+
as,
|
|
18
|
+
disabled = false,
|
|
19
|
+
children,
|
|
20
|
+
...rest
|
|
21
|
+
}) => {
|
|
22
|
+
const { selectedIndex, onSelect } = useContext(TabsContext);
|
|
23
|
+
const itemContext = useContext(TabItemContext);
|
|
24
|
+
const tabIndex = itemContext?.tabIndex ?? 0;
|
|
25
|
+
const isSelected = selectedIndex === tabIndex;
|
|
26
|
+
const Element = as || "button";
|
|
27
|
+
return /* @__PURE__ */ jsx(
|
|
28
|
+
Element,
|
|
29
|
+
{
|
|
30
|
+
role: "tab",
|
|
31
|
+
type: as ? void 0 : "button",
|
|
32
|
+
id: itemContext?.tabId,
|
|
33
|
+
"aria-selected": isSelected,
|
|
34
|
+
"aria-controls": itemContext?.panelId,
|
|
35
|
+
tabIndex: isSelected ? 0 : -1,
|
|
36
|
+
disabled: disabled || void 0,
|
|
37
|
+
"aria-disabled": disabled || void 0,
|
|
38
|
+
className: classNames(
|
|
39
|
+
"eds-tab",
|
|
40
|
+
{ "eds-tab--remove-active-line": removeActiveLine },
|
|
41
|
+
className
|
|
42
|
+
),
|
|
43
|
+
onClick: () => {
|
|
44
|
+
if (!disabled) onSelect(tabIndex);
|
|
45
|
+
},
|
|
46
|
+
...rest,
|
|
47
|
+
children
|
|
15
48
|
}
|
|
16
|
-
|
|
17
|
-
};
|
|
18
|
-
return _extends.apply(this, arguments);
|
|
19
|
-
}
|
|
20
|
-
function _objectWithoutPropertiesLoose(source, excluded) {
|
|
21
|
-
if (source == null) return {};
|
|
22
|
-
var target = {};
|
|
23
|
-
var sourceKeys = Object.keys(source);
|
|
24
|
-
var key, i;
|
|
25
|
-
for (i = 0; i < sourceKeys.length; i++) {
|
|
26
|
-
key = sourceKeys[i];
|
|
27
|
-
if (excluded.indexOf(key) >= 0) continue;
|
|
28
|
-
target[key] = source[key];
|
|
29
|
-
}
|
|
30
|
-
return target;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
var _excluded$4 = ["className", "removeActiveLine"];
|
|
34
|
-
var Tab = function Tab(_ref) {
|
|
35
|
-
var className = _ref.className,
|
|
36
|
-
_ref$removeActiveLine = _ref.removeActiveLine,
|
|
37
|
-
removeActiveLine = _ref$removeActiveLine === void 0 ? false : _ref$removeActiveLine,
|
|
38
|
-
rest = _objectWithoutPropertiesLoose(_ref, _excluded$4);
|
|
39
|
-
return React.createElement(Tab$1, _extends({
|
|
40
|
-
className: classNames('eds-tab', {
|
|
41
|
-
'eds-tab--remove-active-line': removeActiveLine
|
|
42
|
-
}, className)
|
|
43
|
-
}, rest));
|
|
49
|
+
);
|
|
44
50
|
};
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
const Tabs = ({
|
|
52
|
+
className,
|
|
53
|
+
index,
|
|
54
|
+
defaultIndex,
|
|
55
|
+
onChange,
|
|
56
|
+
as,
|
|
57
|
+
children,
|
|
58
|
+
...rest
|
|
59
|
+
}) => {
|
|
60
|
+
const [internalIndex, setInternalIndex] = useState(defaultIndex ?? 0);
|
|
61
|
+
const isControlled = index !== void 0;
|
|
62
|
+
const selectedIndex = isControlled ? index : internalIndex;
|
|
63
|
+
const tabsId = useId();
|
|
64
|
+
const onSelect = useCallback(
|
|
65
|
+
(i) => {
|
|
66
|
+
if (!isControlled) {
|
|
67
|
+
setInternalIndex(i);
|
|
68
|
+
}
|
|
69
|
+
onChange?.(i);
|
|
70
|
+
},
|
|
71
|
+
[isControlled, onChange]
|
|
72
|
+
);
|
|
73
|
+
const Element = as || "div";
|
|
74
|
+
return /* @__PURE__ */ jsx(TabsContext.Provider, { value: { selectedIndex, onSelect, tabsId }, children: /* @__PURE__ */ jsx(Element, { className: classNames("eds-tabs", className), ...rest, children }) });
|
|
75
|
+
};
|
|
76
|
+
const TabPanel = ({
|
|
77
|
+
className,
|
|
78
|
+
as,
|
|
79
|
+
children,
|
|
80
|
+
...rest
|
|
81
|
+
}) => {
|
|
82
|
+
const { selectedIndex } = useContext(TabsContext);
|
|
83
|
+
const itemContext = useContext(TabPanelItemContext);
|
|
84
|
+
const tabIndex = itemContext?.tabIndex ?? 0;
|
|
85
|
+
const keepMounted = itemContext?.keepMounted ?? false;
|
|
86
|
+
const isSelected = selectedIndex === tabIndex;
|
|
87
|
+
const isHiddenButMounted = keepMounted && !isSelected;
|
|
88
|
+
if (!isSelected && !keepMounted) return null;
|
|
89
|
+
const Element = as || "div";
|
|
90
|
+
return /* @__PURE__ */ jsx(
|
|
91
|
+
Element,
|
|
92
|
+
{
|
|
93
|
+
role: "tabpanel",
|
|
94
|
+
id: itemContext?.panelId,
|
|
95
|
+
"aria-labelledby": itemContext?.tabId,
|
|
96
|
+
tabIndex: isSelected ? 0 : -1,
|
|
97
|
+
hidden: isHiddenButMounted || void 0,
|
|
98
|
+
className: classNames("eds-tab-panel", className),
|
|
99
|
+
...rest,
|
|
100
|
+
children
|
|
101
|
+
}
|
|
102
|
+
);
|
|
53
103
|
};
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
|
|
104
|
+
const TabPanels = ({
|
|
105
|
+
className,
|
|
106
|
+
as,
|
|
107
|
+
keepMounted = false,
|
|
108
|
+
children,
|
|
109
|
+
...rest
|
|
110
|
+
}) => {
|
|
111
|
+
const { tabsId } = useContext(TabsContext);
|
|
112
|
+
const Element = as || "div";
|
|
113
|
+
return /* @__PURE__ */ jsx(Element, { className: classNames("eds-tab-panels", className), ...rest, children: React.Children.map(children, (child, idx) => /* @__PURE__ */ jsx(
|
|
114
|
+
TabPanelItemContext.Provider,
|
|
115
|
+
{
|
|
116
|
+
value: {
|
|
117
|
+
tabIndex: idx,
|
|
118
|
+
tabId: `${tabsId}-tab-${idx}`,
|
|
119
|
+
panelId: `${tabsId}-panel-${idx}`,
|
|
120
|
+
keepMounted
|
|
121
|
+
},
|
|
122
|
+
children: child
|
|
123
|
+
}
|
|
124
|
+
)) });
|
|
64
125
|
};
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
126
|
+
const TabList = ({
|
|
127
|
+
className,
|
|
128
|
+
width,
|
|
129
|
+
as,
|
|
130
|
+
children,
|
|
131
|
+
...rest
|
|
132
|
+
}) => {
|
|
133
|
+
const { tabsId } = useContext(TabsContext);
|
|
134
|
+
const tabListRef = useRef(null);
|
|
135
|
+
const handleKeyDown = useCallback((e) => {
|
|
136
|
+
const tabs = tabListRef.current?.querySelectorAll(
|
|
137
|
+
'[role="tab"]:not([disabled])'
|
|
138
|
+
);
|
|
139
|
+
if (!tabs || tabs.length === 0) return;
|
|
140
|
+
const currentIndex = Array.from(tabs).findIndex(
|
|
141
|
+
(tab) => tab === document.activeElement
|
|
142
|
+
);
|
|
143
|
+
if (currentIndex === -1) return;
|
|
144
|
+
let nextIndex;
|
|
145
|
+
switch (e.key) {
|
|
146
|
+
case "ArrowRight":
|
|
147
|
+
nextIndex = (currentIndex + 1) % tabs.length;
|
|
148
|
+
break;
|
|
149
|
+
case "ArrowLeft":
|
|
150
|
+
nextIndex = (currentIndex - 1 + tabs.length) % tabs.length;
|
|
151
|
+
break;
|
|
152
|
+
case "Home":
|
|
153
|
+
nextIndex = 0;
|
|
154
|
+
break;
|
|
155
|
+
case "End":
|
|
156
|
+
nextIndex = tabs.length - 1;
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
if (nextIndex !== void 0) {
|
|
160
|
+
e.preventDefault();
|
|
161
|
+
tabs[nextIndex].focus();
|
|
162
|
+
tabs[nextIndex].click();
|
|
163
|
+
}
|
|
164
|
+
}, []);
|
|
165
|
+
const Element = as || "div";
|
|
166
|
+
return /* @__PURE__ */ jsx(
|
|
167
|
+
Element,
|
|
168
|
+
{
|
|
169
|
+
role: "tablist",
|
|
170
|
+
tabIndex: -1,
|
|
171
|
+
ref: tabListRef,
|
|
172
|
+
className: classNames("eds-tab-list", className, {
|
|
173
|
+
"eds-tab-list--width-fluid": width === "fluid"
|
|
174
|
+
}),
|
|
175
|
+
onKeyDown: handleKeyDown,
|
|
176
|
+
...rest,
|
|
177
|
+
children: React.Children.map(children, (child, idx) => /* @__PURE__ */ jsx(
|
|
178
|
+
TabItemContext.Provider,
|
|
179
|
+
{
|
|
180
|
+
value: {
|
|
181
|
+
tabIndex: idx,
|
|
182
|
+
tabId: `${tabsId}-tab-${idx}`,
|
|
183
|
+
panelId: `${tabsId}-panel-${idx}`
|
|
184
|
+
},
|
|
185
|
+
children: child
|
|
186
|
+
}
|
|
187
|
+
))
|
|
188
|
+
}
|
|
189
|
+
);
|
|
73
190
|
};
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
className: classNames('eds-tab-list', className, {
|
|
82
|
-
'eds-tab-list--width-fluid': width === 'fluid'
|
|
83
|
-
})
|
|
84
|
-
}, rest));
|
|
191
|
+
warnAboutMissingStyles("tab");
|
|
192
|
+
export {
|
|
193
|
+
Tab,
|
|
194
|
+
TabList,
|
|
195
|
+
TabPanel,
|
|
196
|
+
TabPanels,
|
|
197
|
+
Tabs
|
|
85
198
|
};
|
|
86
|
-
|
|
87
|
-
warnAboutMissingStyles('tab');
|
|
88
|
-
|
|
89
|
-
export { Tab, TabList, TabPanel, TabPanels, Tabs };
|
|
90
199
|
//# sourceMappingURL=tab.esm.js.map
|
package/dist/tab.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tab.esm.js","sources":["../src/Tab.tsx","../src/Tabs.tsx","../src/TabPanel.tsx","../src/TabPanels.tsx","../src/TabList.tsx","../src/index.tsx"],"sourcesContent":["import React from 'react';\nimport { Tab as ReachTab } from '@reach/tabs';\nimport classNames from 'classnames';\n\nexport type TabProps = {\n /** Overskriften til taben */\n children: React.ReactNode;\n /** Om taben er disabled eller ikke */\n disabled?: boolean;\n /** HTML-elementet eller React-komponenten som lager komponenten */\n as?: keyof JSX.IntrinsicElements | any;\n removeActiveLine?: boolean;\n [key: string]: any;\n};\n\nexport const Tab: React.FC<TabProps> = ({\n className,\n removeActiveLine = false,\n ...rest\n}) => {\n return (\n <ReachTab\n className={classNames(\n 'eds-tab',\n { 'eds-tab--remove-active-line': removeActiveLine },\n className,\n )}\n {...rest}\n />\n );\n};\n","import React from 'react';\nimport { Tabs as ReachTabs } from '@reach/tabs';\nimport classNames from 'classnames';\n\nexport type TabsProps = {\n /** Overskriften til taben */\n children: React.ReactNode;\n /** Kalles når taben endres */\n onChange?: (index: number) => void;\n /** Hvilken tab som skal være åpen by default */\n defaultIndex?: number;\n /** Den åpne indexen */\n index?: number;\n /** HTML-elementet eller React-komponenten som lager komponenten */\n as?: keyof JSX.IntrinsicElements | any;\n\n [key: string]: any;\n};\n\nexport const Tabs: React.FC<TabsProps> = ({ className, ...rest }) => {\n return <ReachTabs className={classNames('eds-tabs', className)} {...rest} />;\n};\n","import React from 'react';\nimport { TabPanel as ReachTabPanel } from '@reach/tabs';\nimport classNames from 'classnames';\n\nexport type TabPanelProps = {\n /** Overskriften til taben */\n children: React.ReactNode;\n /** HTML-elementet eller React-komponenten som lager komponenten */\n as?: keyof JSX.IntrinsicElements | any;\n [key: string]: any;\n};\n\nexport const TabPanel: React.FC<TabPanelProps> = ({ className, ...rest }) => {\n return (\n <ReachTabPanel\n className={classNames('eds-tab-panel', className)}\n {...rest}\n tabIndex={undefined}\n />\n );\n};\n","import React from 'react';\nimport { TabPanels as ReachTabPanels } from '@reach/tabs';\nimport classNames from 'classnames';\n\nexport type TabPanelsProps = {\n /** Tab-panelene */\n children: React.ReactNode;\n /** HTML-elementet eller React-komponenten som lager komponenten */\n as?: keyof JSX.IntrinsicElements | any;\n [key: string]: any;\n};\n\nexport const TabPanels: React.FC<TabPanelsProps> = ({ className, ...rest }) => {\n return (\n <ReachTabPanels\n className={classNames('eds-tab-panels', className)}\n {...rest}\n />\n );\n};\n","import React from 'react';\nimport { TabList as ReachTabList } from '@reach/tabs';\nimport classNames from 'classnames';\n\nexport type TabListProps = {\n /** Tab-komponenter */\n children: React.ReactNode;\n /** HTML-elementet eller React-komponenten som lager komponenten */\n as?: keyof JSX.IntrinsicElements | any;\n width?: 'fluid';\n [key: string]: any;\n};\n\nexport const TabList: React.FC<TabListProps> = ({\n className,\n width,\n ...rest\n}) => {\n return (\n <ReachTabList\n className={classNames('eds-tab-list', className, {\n 'eds-tab-list--width-fluid': width === 'fluid',\n })}\n {...rest}\n />\n );\n};\n","import { warnAboutMissingStyles } from '@entur/utils';\nimport './index.scss';\n\nwarnAboutMissingStyles('tab');\n\nexport * from './Tab';\nexport * from './Tabs';\nexport * from './TabPanel';\nexport * from './TabPanels';\nexport * from './TabList';\n"],"names":["Tab","className","removeActiveLine","rest","_excluded","React","ReachTab","classNames","Tabs","createElement","ReachTabs","TabPanel","ReachTabPanel","tabIndex","undefined","TabPanels","ReachTabPanels","TabList","width","ReachTabList","warnAboutMissingStyles"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAeaA,IAAAA,GAAG,GAAuB,SAA1BA,GAAG,CAIX,IAAA,EAAA;EAAA,IAHHC,SAAS,QAATA,SAAS;AAAA,IAAA,qBAAA,GAAA,IAAA,CACTC,gBAAgB;AAAhBA,IAAAA,gBAAgB,sCAAG,KAAK,GAAA,qBAAA;IACrBC,IAAI,GAAA,6BAAA,CAAA,IAAA,EAAAC,WAAA,CAAA,CAAA;AAEP,EAAA,OACEC,oBAACC,KAAQ,EAAA,QAAA,CAAA;AACPL,IAAAA,SAAS,EAAEM,UAAU,CACnB,SAAS,EACT;AAAE,MAAA,6BAA6B,EAAEL,gBAAAA;KAAkB,EACnDD,SAAS,CAAA;AACV,GAAA,EACGE,IAAI,CACR,CAAA,CAAA;AAEN;;;ACXaK,IAAAA,IAAI,GAAwB,SAA5BA,IAAI,CAAmD,IAAA,EAAA;EAAA,IAAxBP,SAAS,QAATA,SAAS;IAAKE,IAAI,GAAA,6BAAA,CAAA,IAAA,EAAAC,WAAA,CAAA,CAAA;AAC5D,EAAA,OAAOC,KAAC,CAAAI,aAAA,CAAAC,MAAS,EAAA,QAAA,CAAA;AAACT,IAAAA,SAAS,EAAEM,UAAU,CAAC,UAAU,EAAEN,SAAS,CAAA;AAAC,GAAA,EAAME,IAAI,CAAI,CAAA,CAAA;AAC9E;;;ACTaQ,IAAAA,QAAQ,GAA4B,SAApCA,QAAQ,CAAuD,IAAA,EAAA;EAAA,IAAxBV,SAAS,QAATA,SAAS;IAAKE,IAAI,GAAA,6BAAA,CAAA,IAAA,EAAAC,WAAA,CAAA,CAAA;AACpE,EAAA,OACEC,oBAACO,UAAa,EAAA,QAAA,CAAA;AACZX,IAAAA,SAAS,EAAEM,UAAU,CAAC,eAAe,EAAEN,SAAS,CAAA;AAAC,GAAA,EAC7CE,IAAI,EAAA;AACRU,IAAAA,QAAQ,EAAEC,SAAAA;GACV,CAAA,CAAA,CAAA;AAEN;;;ACRaC,IAAAA,SAAS,GAA6B,SAAtCA,SAAS,CAAwD,IAAA,EAAA;EAAA,IAAxBd,SAAS,QAATA,SAAS;IAAKE,IAAI,GAAA,6BAAA,CAAA,IAAA,EAAAC,WAAA,CAAA,CAAA;AACtE,EAAA,OACEC,KAAC,CAAAI,aAAA,CAAAO,WAAc,EAAA,QAAA,CAAA;AACbf,IAAAA,SAAS,EAAEM,UAAU,CAAC,gBAAgB,EAAEN,SAAS,CAAA;AAAC,GAAA,EAC9CE,IAAI,CACR,CAAA,CAAA;AAEN;;;ACNac,IAAAA,OAAO,GAA2B,SAAlCA,OAAO,CAIf,IAAA,EAAA;EAAA,IAHHhB,SAAS,QAATA,SAAS;AACTiB,IAAAA,KAAK,QAALA,KAAK;IACFf,IAAI,GAAA,6BAAA,CAAA,IAAA,EAAA,SAAA,CAAA,CAAA;AAEP,EAAA,OACEE,KAAC,CAAAI,aAAA,CAAAU,SAAY,EAAA,QAAA,CAAA;AACXlB,IAAAA,SAAS,EAAEM,UAAU,CAAC,cAAc,EAAEN,SAAS,EAAE;MAC/C,2BAA2B,EAAEiB,KAAK,KAAK,OAAA;KACxC,CAAA;AAAC,GAAA,EACEf,IAAI,CACR,CAAA,CAAA;AAEN;;ACvBAiB,sBAAsB,CAAC,KAAK,CAAC;;;;"}
|
|
1
|
+
{"version":3,"file":"tab.esm.js","sources":["../src/TabsContext.tsx","../src/Tab.tsx","../src/Tabs.tsx","../src/TabPanel.tsx","../src/TabPanels.tsx","../src/TabList.tsx","../src/index.tsx"],"sourcesContent":["import React from 'react';\n\nexport type TabsContextValue = {\n selectedIndex: number;\n onSelect: (index: number) => void;\n tabsId: string;\n};\n\nexport const TabsContext = React.createContext<TabsContextValue>({\n selectedIndex: 0,\n onSelect: () => undefined,\n tabsId: '',\n});\n\nexport type TabItemContextValue = {\n tabIndex: number;\n tabId: string;\n panelId: string;\n};\n\nexport const TabItemContext = React.createContext<TabItemContextValue | null>(\n null,\n);\n\nexport type TabPanelItemContextValue = {\n tabIndex: number;\n tabId: string;\n panelId: string;\n keepMounted: boolean;\n};\n\nexport const TabPanelItemContext =\n React.createContext<TabPanelItemContextValue | null>(null);\n","import React, { useContext } from 'react';\nimport classNames from 'classnames';\n\nimport { TabItemContext, TabsContext } from './TabsContext';\n\nexport type TabProps = {\n /** Overskriften til taben */\n children: React.ReactNode;\n /** Om taben er disabled eller ikke */\n disabled?: boolean;\n /** HTML-elementet eller React-komponenten som lager komponenten */\n as?: keyof JSX.IntrinsicElements | React.ElementType;\n removeActiveLine?: boolean;\n className?: string;\n} & Omit<React.ComponentPropsWithoutRef<'button'>, 'children' | 'disabled'>;\n\nexport const Tab = ({\n className,\n removeActiveLine = false,\n as,\n disabled = false,\n children,\n ...rest\n}: TabProps) => {\n const { selectedIndex, onSelect } = useContext(TabsContext);\n const itemContext = useContext(TabItemContext);\n const tabIndex = itemContext?.tabIndex ?? 0;\n const isSelected = selectedIndex === tabIndex;\n const Element: React.ElementType = as || 'button';\n\n return (\n <Element\n role=\"tab\"\n type={as ? undefined : 'button'}\n id={itemContext?.tabId}\n aria-selected={isSelected}\n aria-controls={itemContext?.panelId}\n tabIndex={isSelected ? 0 : -1}\n disabled={disabled || undefined}\n aria-disabled={disabled || undefined}\n className={classNames(\n 'eds-tab',\n { 'eds-tab--remove-active-line': removeActiveLine },\n className,\n )}\n onClick={() => {\n if (!disabled) onSelect(tabIndex);\n }}\n {...rest}\n >\n {children}\n </Element>\n );\n};\n","import React, { useCallback, useId, useState } from 'react';\nimport classNames from 'classnames';\n\nimport { TabsContext } from './TabsContext';\n\nexport type TabsProps = {\n /** Tab-innholdet */\n children: React.ReactNode;\n /** Kalles når taben endres */\n onChange?: (index: number) => void;\n /** Hvilken tab som skal være åpen by default */\n defaultIndex?: number;\n /** Den åpne indexen (kontrollert) */\n index?: number;\n /** HTML-elementet eller React-komponenten som lager komponenten */\n as?: keyof JSX.IntrinsicElements | React.ElementType;\n className?: string;\n} & Omit<React.ComponentPropsWithoutRef<'div'>, 'children' | 'onChange'>;\n\nexport const Tabs = ({\n className,\n index,\n defaultIndex,\n onChange,\n as,\n children,\n ...rest\n}: TabsProps) => {\n const [internalIndex, setInternalIndex] = useState(defaultIndex ?? 0);\n const isControlled = index !== undefined;\n const selectedIndex = isControlled ? index : internalIndex;\n const tabsId = useId();\n\n const onSelect = useCallback(\n (i: number) => {\n if (!isControlled) {\n setInternalIndex(i);\n }\n onChange?.(i);\n },\n [isControlled, onChange],\n );\n\n const Element: React.ElementType = as || 'div';\n\n return (\n <TabsContext.Provider value={{ selectedIndex, onSelect, tabsId }}>\n <Element className={classNames('eds-tabs', className)} {...rest}>\n {children}\n </Element>\n </TabsContext.Provider>\n );\n};\n","import React, { useContext } from 'react';\nimport classNames from 'classnames';\n\nimport { TabPanelItemContext, TabsContext } from './TabsContext';\n\nexport type TabPanelProps = {\n /** Innholdet i tab-panelet */\n children?: React.ReactNode;\n /** HTML-elementet eller React-komponenten som lager komponenten */\n as?: keyof JSX.IntrinsicElements | React.ElementType;\n className?: string;\n} & Omit<React.ComponentPropsWithoutRef<'div'>, 'children'>;\n\nexport const TabPanel = ({\n className,\n as,\n children,\n ...rest\n}: TabPanelProps) => {\n const { selectedIndex } = useContext(TabsContext);\n const itemContext = useContext(TabPanelItemContext);\n const tabIndex = itemContext?.tabIndex ?? 0;\n const keepMounted = itemContext?.keepMounted ?? false;\n\n const isSelected = selectedIndex === tabIndex;\n const isHiddenButMounted = keepMounted && !isSelected;\n\n if (!isSelected && !keepMounted) return null;\n\n const Element: React.ElementType = as || 'div';\n\n return (\n <Element\n role=\"tabpanel\"\n id={itemContext?.panelId}\n aria-labelledby={itemContext?.tabId}\n tabIndex={isSelected ? 0 : -1}\n hidden={isHiddenButMounted || undefined}\n className={classNames('eds-tab-panel', className)}\n {...rest}\n >\n {children}\n </Element>\n );\n};\n","import React, { useContext } from 'react';\nimport classNames from 'classnames';\n\nimport { TabPanelItemContext, TabsContext } from './TabsContext';\n\nexport type TabPanelsProps = {\n /** Tab-panelene */\n children: React.ReactNode;\n /** HTML-elementet eller React-komponenten som lager komponenten */\n as?: keyof JSX.IntrinsicElements | React.ElementType;\n /** Behold alle panel-noder i DOM (skjult med hidden-attributt) i stedet for å avmontere */\n keepMounted?: boolean;\n className?: string;\n} & Omit<React.ComponentPropsWithoutRef<'div'>, 'children'>;\n\nexport const TabPanels = ({\n className,\n as,\n keepMounted = false,\n children,\n ...rest\n}: TabPanelsProps) => {\n const { tabsId } = useContext(TabsContext);\n\n const Element: React.ElementType = as || 'div';\n\n return (\n <Element className={classNames('eds-tab-panels', className)} {...rest}>\n {React.Children.map(children, (child, idx) => (\n <TabPanelItemContext.Provider\n value={{\n tabIndex: idx,\n tabId: `${tabsId}-tab-${idx}`,\n panelId: `${tabsId}-panel-${idx}`,\n keepMounted,\n }}\n >\n {child}\n </TabPanelItemContext.Provider>\n ))}\n </Element>\n );\n};\n","import React, { useCallback, useContext, useRef } from 'react';\nimport classNames from 'classnames';\n\nimport { TabItemContext, TabsContext } from './TabsContext';\n\nexport type TabListProps = {\n /** Tab-komponenter */\n children: React.ReactNode;\n /** HTML-elementet eller React-komponenten som lager komponenten */\n as?: keyof JSX.IntrinsicElements | React.ElementType;\n width?: 'fluid';\n className?: string;\n /** Tilgjengelig navn på tab-listen (dersom det ikke finnes en synlig overskrift) */\n 'aria-label'?: string;\n /** ID til elementet som navngir tab-listen */\n 'aria-labelledby'?: string;\n} & Omit<React.ComponentPropsWithoutRef<'div'>, 'children'>;\n\nexport const TabList = ({\n className,\n width,\n as,\n children,\n ...rest\n}: TabListProps) => {\n const { tabsId } = useContext(TabsContext);\n const tabListRef = useRef<HTMLElement>(null);\n\n const handleKeyDown = useCallback((e: React.KeyboardEvent) => {\n const tabs = tabListRef.current?.querySelectorAll<HTMLElement>(\n '[role=\"tab\"]:not([disabled])',\n );\n if (!tabs || tabs.length === 0) return;\n\n const currentIndex = Array.from(tabs).findIndex(\n tab => tab === document.activeElement,\n );\n if (currentIndex === -1) return;\n\n let nextIndex: number | undefined;\n switch (e.key) {\n case 'ArrowRight':\n nextIndex = (currentIndex + 1) % tabs.length;\n break;\n case 'ArrowLeft':\n nextIndex = (currentIndex - 1 + tabs.length) % tabs.length;\n break;\n case 'Home':\n nextIndex = 0;\n break;\n case 'End':\n nextIndex = tabs.length - 1;\n break;\n }\n\n if (nextIndex !== undefined) {\n e.preventDefault();\n tabs[nextIndex].focus();\n tabs[nextIndex].click();\n }\n }, []);\n\n const Element: React.ElementType = as || 'div';\n\n return (\n <Element\n role=\"tablist\"\n tabIndex={-1}\n ref={tabListRef}\n className={classNames('eds-tab-list', className, {\n 'eds-tab-list--width-fluid': width === 'fluid',\n })}\n onKeyDown={handleKeyDown}\n {...rest}\n >\n {React.Children.map(children, (child, idx) => (\n <TabItemContext.Provider\n value={{\n tabIndex: idx,\n tabId: `${tabsId}-tab-${idx}`,\n panelId: `${tabsId}-panel-${idx}`,\n }}\n >\n {child}\n </TabItemContext.Provider>\n ))}\n </Element>\n );\n};\n","import { warnAboutMissingStyles } from '@entur/utils';\nimport './index.scss';\n\nwarnAboutMissingStyles('tab');\n\nexport * from './Tab';\nexport * from './Tabs';\nexport * from './TabPanel';\nexport * from './TabPanels';\nexport * from './TabList';\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,35 +1,46 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@entur/tab",
|
|
3
|
-
"version": "1.0.0-
|
|
3
|
+
"version": "1.0.0-next.0",
|
|
4
4
|
"license": "EUPL-1.2",
|
|
5
|
-
"main": "dist/
|
|
5
|
+
"main": "dist/tab.cjs.js",
|
|
6
6
|
"module": "dist/tab.esm.js",
|
|
7
|
-
"
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
8
|
"files": [
|
|
9
9
|
"dist"
|
|
10
10
|
],
|
|
11
11
|
"repository": {
|
|
12
12
|
"type": "git",
|
|
13
|
-
"url": "https://
|
|
13
|
+
"url": "https://github.com/entur/design-system.git",
|
|
14
14
|
"directory": "packages/tab"
|
|
15
15
|
},
|
|
16
16
|
"publishConfig": {
|
|
17
17
|
"access": "public"
|
|
18
18
|
},
|
|
19
19
|
"scripts": {
|
|
20
|
-
"start": "
|
|
21
|
-
"build": "
|
|
22
|
-
"
|
|
20
|
+
"start": "vite build --watch",
|
|
21
|
+
"build": "vite build",
|
|
22
|
+
"test": "jest"
|
|
23
23
|
},
|
|
24
24
|
"peerDependencies": {
|
|
25
|
-
"react": ">=
|
|
26
|
-
"react-dom": ">=
|
|
25
|
+
"react": ">=18.0.0",
|
|
26
|
+
"react-dom": ">=18.0.0"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@entur/tokens": "^3.
|
|
30
|
-
"@entur/utils": "^0.
|
|
31
|
-
"
|
|
32
|
-
"classnames": "^2.3.1"
|
|
29
|
+
"@entur/tokens": "^3.24.1-next.0",
|
|
30
|
+
"@entur/utils": "^1.0.0-next.0",
|
|
31
|
+
"classnames": "^2.5.1"
|
|
33
32
|
},
|
|
34
|
-
"
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@testing-library/jest-dom": "^5.17.0",
|
|
35
|
+
"@testing-library/react": "^16.3.0",
|
|
36
|
+
"@testing-library/user-event": "14.6.1",
|
|
37
|
+
"@vitejs/plugin-react": "^5.0.1",
|
|
38
|
+
"jest": "^29.0.0",
|
|
39
|
+
"jest-environment-jsdom": "^29.0.0",
|
|
40
|
+
"ts-jest": "^29.0.0",
|
|
41
|
+
"typescript": "^5.9.2",
|
|
42
|
+
"vite": "^7.3.2",
|
|
43
|
+
"vite-plugin-dts": "^4.5.4"
|
|
44
|
+
},
|
|
45
|
+
"gitHead": "0f435bdeec98cc3cea1db7434b13b1f771a39a18"
|
|
35
46
|
}
|