@navikt/ds-react 6.4.1 → 6.5.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/cjs/date/datepicker/parts/DayButton.js +1 -1
- package/cjs/date/datepicker/parts/DayButton.js.map +1 -1
- package/cjs/date/hooks/useDatepicker.js +4 -1
- package/cjs/date/hooks/useDatepicker.js.map +1 -1
- package/cjs/date/hooks/useMonthPicker.js +4 -1
- package/cjs/date/hooks/useMonthPicker.js.map +1 -1
- package/cjs/date/monthpicker/MonthButton.js +1 -1
- package/cjs/date/monthpicker/MonthButton.js.map +1 -1
- package/cjs/tabs/Tabs.context.d.ts +30 -0
- package/cjs/tabs/Tabs.context.js +14 -0
- package/cjs/tabs/Tabs.context.js.map +1 -0
- package/cjs/tabs/Tabs.d.ts +8 -43
- package/cjs/tabs/Tabs.js +19 -12
- package/cjs/tabs/Tabs.js.map +1 -1
- package/cjs/tabs/Tabs.types.d.ts +41 -0
- package/cjs/tabs/Tabs.types.js +3 -0
- package/cjs/tabs/Tabs.types.js.map +1 -0
- package/cjs/tabs/index.d.ts +5 -4
- package/cjs/tabs/index.js +6 -6
- package/cjs/tabs/index.js.map +1 -1
- package/cjs/tabs/parts/tab/Tab.d.ts +25 -0
- package/cjs/tabs/{Tab.js → parts/tab/Tab.js} +15 -14
- package/cjs/tabs/parts/tab/Tab.js.map +1 -0
- package/cjs/tabs/parts/tab/useTab.d.ts +20 -0
- package/cjs/tabs/parts/tab/useTab.js +29 -0
- package/cjs/tabs/parts/tab/useTab.js.map +1 -0
- package/cjs/tabs/parts/tablist/ScrollButtons.d.ts +8 -0
- package/cjs/tabs/parts/tablist/ScrollButtons.js +15 -0
- package/cjs/tabs/parts/tablist/ScrollButtons.js.map +1 -0
- package/{esm/tabs → cjs/tabs/parts/tablist}/TabList.d.ts +1 -1
- package/cjs/tabs/parts/tablist/TabList.js +61 -0
- package/cjs/tabs/parts/tablist/TabList.js.map +1 -0
- package/cjs/tabs/parts/tablist/useScrollButtons.d.ts +12 -0
- package/cjs/tabs/parts/tablist/useScrollButtons.js +61 -0
- package/cjs/tabs/parts/tablist/useScrollButtons.js.map +1 -0
- package/cjs/tabs/parts/tablist/useTabList.d.ts +7 -0
- package/cjs/tabs/parts/tablist/useTabList.js +66 -0
- package/cjs/tabs/parts/tablist/useTabList.js.map +1 -0
- package/cjs/tabs/parts/tabpanel/TabPanel.d.ts +25 -0
- package/cjs/tabs/{TabPanel.js → parts/tabpanel/TabPanel.js} +5 -3
- package/cjs/tabs/parts/tabpanel/TabPanel.js.map +1 -0
- package/cjs/tabs/parts/tabpanel/useTabPanel.d.ts +12 -0
- package/cjs/tabs/parts/tabpanel/useTabPanel.js +17 -0
- package/cjs/tabs/parts/tabpanel/useTabPanel.js.map +1 -0
- package/cjs/tabs/useTabs.d.ts +14 -0
- package/cjs/tabs/useTabs.js +43 -0
- package/cjs/tabs/useTabs.js.map +1 -0
- package/cjs/toggle-group/ToggleGroup.context.d.ts +31 -0
- package/cjs/toggle-group/ToggleGroup.context.js +16 -0
- package/cjs/toggle-group/ToggleGroup.context.js.map +1 -0
- package/cjs/toggle-group/ToggleGroup.d.ts +5 -36
- package/cjs/toggle-group/ToggleGroup.js +24 -24
- package/cjs/toggle-group/ToggleGroup.js.map +1 -1
- package/cjs/toggle-group/ToggleGroup.types.d.ts +38 -0
- package/cjs/toggle-group/ToggleGroup.types.js +3 -0
- package/cjs/toggle-group/ToggleGroup.types.js.map +1 -0
- package/cjs/toggle-group/index.d.ts +3 -2
- package/cjs/toggle-group/index.js +1 -1
- package/cjs/toggle-group/index.js.map +1 -1
- package/cjs/toggle-group/{ToggleItem.d.ts → parts/ToggleItem.d.ts} +2 -2
- package/cjs/toggle-group/{ToggleItem.js → parts/ToggleItem.js} +9 -8
- package/cjs/toggle-group/parts/ToggleItem.js.map +1 -0
- package/cjs/toggle-group/parts/useToggleItem.d.ts +20 -0
- package/cjs/toggle-group/parts/useToggleItem.js +76 -0
- package/cjs/toggle-group/parts/useToggleItem.js.map +1 -0
- package/cjs/toggle-group/useToggleGroup.d.ts +8 -0
- package/cjs/toggle-group/useToggleGroup.js +29 -0
- package/cjs/toggle-group/useToggleGroup.js.map +1 -0
- package/esm/date/datepicker/parts/DayButton.js +1 -1
- package/esm/date/datepicker/parts/DayButton.js.map +1 -1
- package/esm/date/hooks/useDatepicker.js +4 -1
- package/esm/date/hooks/useDatepicker.js.map +1 -1
- package/esm/date/hooks/useMonthPicker.js +4 -1
- package/esm/date/hooks/useMonthPicker.js.map +1 -1
- package/esm/date/monthpicker/MonthButton.js +1 -1
- package/esm/date/monthpicker/MonthButton.js.map +1 -1
- package/esm/tabs/Tabs.context.d.ts +30 -0
- package/esm/tabs/Tabs.context.js +10 -0
- package/esm/tabs/Tabs.context.js.map +1 -0
- package/esm/tabs/Tabs.d.ts +8 -43
- package/esm/tabs/Tabs.js +19 -12
- package/esm/tabs/Tabs.js.map +1 -1
- package/esm/tabs/Tabs.types.d.ts +41 -0
- package/esm/tabs/Tabs.types.js +2 -0
- package/esm/tabs/Tabs.types.js.map +1 -0
- package/esm/tabs/index.d.ts +5 -4
- package/esm/tabs/index.js +3 -3
- package/esm/tabs/index.js.map +1 -1
- package/esm/tabs/parts/tab/Tab.d.ts +25 -0
- package/esm/tabs/parts/tab/Tab.js +35 -0
- package/esm/tabs/parts/tab/Tab.js.map +1 -0
- package/esm/tabs/parts/tab/useTab.d.ts +20 -0
- package/esm/tabs/parts/tab/useTab.js +25 -0
- package/esm/tabs/parts/tab/useTab.js.map +1 -0
- package/esm/tabs/parts/tablist/ScrollButtons.d.ts +8 -0
- package/esm/tabs/parts/tablist/ScrollButtons.js +10 -0
- package/esm/tabs/parts/tablist/ScrollButtons.js.map +1 -0
- package/{cjs/tabs → esm/tabs/parts/tablist}/TabList.d.ts +1 -1
- package/esm/tabs/parts/tablist/TabList.js +32 -0
- package/esm/tabs/parts/tablist/TabList.js.map +1 -0
- package/esm/tabs/parts/tablist/useScrollButtons.d.ts +12 -0
- package/esm/tabs/parts/tablist/useScrollButtons.js +57 -0
- package/esm/tabs/parts/tablist/useScrollButtons.js.map +1 -0
- package/esm/tabs/parts/tablist/useTabList.d.ts +7 -0
- package/esm/tabs/parts/tablist/useTabList.js +62 -0
- package/esm/tabs/parts/tablist/useTabList.js.map +1 -0
- package/esm/tabs/parts/tabpanel/TabPanel.d.ts +25 -0
- package/esm/tabs/parts/tabpanel/TabPanel.js +22 -0
- package/esm/tabs/parts/tabpanel/TabPanel.js.map +1 -0
- package/esm/tabs/parts/tabpanel/useTabPanel.d.ts +12 -0
- package/esm/tabs/parts/tabpanel/useTabPanel.js +13 -0
- package/esm/tabs/parts/tabpanel/useTabPanel.js.map +1 -0
- package/esm/tabs/useTabs.d.ts +14 -0
- package/esm/tabs/useTabs.js +39 -0
- package/esm/tabs/useTabs.js.map +1 -0
- package/esm/toggle-group/ToggleGroup.context.d.ts +31 -0
- package/esm/toggle-group/ToggleGroup.context.js +12 -0
- package/esm/toggle-group/ToggleGroup.context.js.map +1 -0
- package/esm/toggle-group/ToggleGroup.d.ts +5 -36
- package/esm/toggle-group/ToggleGroup.js +24 -24
- package/esm/toggle-group/ToggleGroup.js.map +1 -1
- package/esm/toggle-group/ToggleGroup.types.d.ts +38 -0
- package/esm/toggle-group/ToggleGroup.types.js +2 -0
- package/esm/toggle-group/ToggleGroup.types.js.map +1 -0
- package/esm/toggle-group/index.d.ts +3 -2
- package/esm/toggle-group/index.js +1 -1
- package/esm/toggle-group/index.js.map +1 -1
- package/esm/toggle-group/{ToggleItem.d.ts → parts/ToggleItem.d.ts} +2 -2
- package/esm/toggle-group/parts/ToggleItem.js +25 -0
- package/esm/toggle-group/parts/ToggleItem.js.map +1 -0
- package/esm/toggle-group/parts/useToggleItem.d.ts +20 -0
- package/esm/toggle-group/parts/useToggleItem.js +72 -0
- package/esm/toggle-group/parts/useToggleItem.js.map +1 -0
- package/esm/toggle-group/useToggleGroup.d.ts +8 -0
- package/esm/toggle-group/useToggleGroup.js +25 -0
- package/esm/toggle-group/useToggleGroup.js.map +1 -0
- package/package.json +3 -5
- package/src/date/datepicker/datepicker.stories.tsx +39 -0
- package/src/date/datepicker/parts/DayButton.tsx +2 -0
- package/src/date/hooks/useDatepicker.tsx +5 -1
- package/src/date/hooks/useMonthPicker.tsx +5 -1
- package/src/date/monthpicker/MonthButton.tsx +1 -0
- package/src/date/monthpicker/monthpicker.stories.tsx +36 -19
- package/src/modal/modal.stories.tsx +2 -6
- package/src/tabs/Tabs.context.ts +24 -0
- package/src/tabs/Tabs.stories.tsx +233 -113
- package/src/tabs/Tabs.test.tsx +99 -37
- package/src/tabs/Tabs.tsx +48 -70
- package/src/tabs/Tabs.types.ts +43 -0
- package/src/tabs/index.ts +11 -4
- package/src/tabs/parts/tab/Tab.tsx +93 -0
- package/src/tabs/parts/tab/useTab.ts +52 -0
- package/src/tabs/parts/tablist/ScrollButtons.tsx +29 -0
- package/src/tabs/parts/tablist/TabList.tsx +56 -0
- package/src/tabs/parts/tablist/useScrollButtons.ts +69 -0
- package/src/tabs/parts/tablist/useTabList.ts +68 -0
- package/src/tabs/parts/tabpanel/TabPanel.tsx +50 -0
- package/src/tabs/parts/tabpanel/useTabPanel.ts +18 -0
- package/src/tabs/useTabs.ts +51 -0
- package/src/toggle-group/ToggleGroup.context.ts +31 -0
- package/src/toggle-group/ToggleGroup.stories.tsx +67 -6
- package/src/toggle-group/ToggleGroup.test.tsx +57 -16
- package/src/toggle-group/ToggleGroup.tsx +63 -90
- package/src/toggle-group/ToggleGroup.types.ts +40 -0
- package/src/toggle-group/index.ts +3 -2
- package/src/toggle-group/parts/ToggleItem.tsx +55 -0
- package/src/toggle-group/parts/useToggleItem.ts +104 -0
- package/src/toggle-group/useToggleGroup.ts +33 -0
- package/cjs/tabs/Tab.d.ts +0 -18
- package/cjs/tabs/Tab.js.map +0 -1
- package/cjs/tabs/TabList.js +0 -111
- package/cjs/tabs/TabList.js.map +0 -1
- package/cjs/tabs/TabPanel.d.ts +0 -13
- package/cjs/tabs/TabPanel.js.map +0 -1
- package/cjs/tabs/context.d.ts +0 -8
- package/cjs/tabs/context.js +0 -6
- package/cjs/tabs/context.js.map +0 -1
- package/cjs/toggle-group/ToggleItem.js.map +0 -1
- package/cjs/toggle-group/context.d.ts +0 -6
- package/cjs/toggle-group/context.js +0 -6
- package/cjs/toggle-group/context.js.map +0 -1
- package/esm/tabs/Tab.d.ts +0 -18
- package/esm/tabs/Tab.js +0 -34
- package/esm/tabs/Tab.js.map +0 -1
- package/esm/tabs/TabList.js +0 -82
- package/esm/tabs/TabList.js.map +0 -1
- package/esm/tabs/TabPanel.d.ts +0 -13
- package/esm/tabs/TabPanel.js +0 -20
- package/esm/tabs/TabPanel.js.map +0 -1
- package/esm/tabs/context.d.ts +0 -8
- package/esm/tabs/context.js +0 -3
- package/esm/tabs/context.js.map +0 -1
- package/esm/toggle-group/ToggleItem.js +0 -24
- package/esm/toggle-group/ToggleItem.js.map +0 -1
- package/esm/toggle-group/context.d.ts +0 -6
- package/esm/toggle-group/context.js +0 -3
- package/esm/toggle-group/context.js.map +0 -1
- package/src/tabs/Tab.tsx +0 -66
- package/src/tabs/TabList.tsx +0 -128
- package/src/tabs/TabPanel.tsx +0 -26
- package/src/tabs/context.ts +0 -9
- package/src/toggle-group/ToggleItem.tsx +0 -41
- package/src/toggle-group/context.ts +0 -9
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { Meta } from "@storybook/react";
|
|
1
|
+
import { Meta, StoryObj } from "@storybook/react";
|
|
2
2
|
import React, { useState } from "react";
|
|
3
3
|
import { DishwasherIcon, FreezerIcon, MugIcon } from "@navikt/aksel-icons";
|
|
4
4
|
import { Tabs } from ".";
|
|
5
|
+
import { VStack } from "../layout/stack";
|
|
5
6
|
|
|
6
7
|
export default {
|
|
7
8
|
title: "ds-react/Tabs",
|
|
@@ -20,41 +21,44 @@ export default {
|
|
|
20
21
|
},
|
|
21
22
|
},
|
|
22
23
|
},
|
|
24
|
+
parameters: {
|
|
25
|
+
chromatic: { disable: true },
|
|
26
|
+
},
|
|
23
27
|
} satisfies Meta<typeof Tabs>;
|
|
24
28
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
29
|
+
type Story = StoryObj<typeof Tabs>;
|
|
30
|
+
|
|
31
|
+
const Panel = () => (
|
|
32
|
+
<>
|
|
33
|
+
<Tabs.Panel
|
|
34
|
+
value="test1"
|
|
35
|
+
className="panel"
|
|
36
|
+
style={{ background: "var(--a-gray-50)", height: 100 }}
|
|
37
|
+
>
|
|
38
|
+
Innholdspanel for Skap-tab
|
|
39
|
+
</Tabs.Panel>
|
|
40
|
+
<Tabs.Panel
|
|
41
|
+
value="test2"
|
|
42
|
+
className="panel"
|
|
43
|
+
style={{
|
|
44
|
+
background: "var(--a-green-50)",
|
|
45
|
+
height: 100,
|
|
46
|
+
}}
|
|
47
|
+
>
|
|
48
|
+
Innholdspanel for Oppvaskmaskin-tab
|
|
49
|
+
</Tabs.Panel>
|
|
50
|
+
<Tabs.Panel
|
|
51
|
+
value="test3"
|
|
52
|
+
className="panel"
|
|
53
|
+
style={{ background: "var(--a-red-50)", height: 100 }}
|
|
54
|
+
>
|
|
55
|
+
Innholdspanel for Fryser-tab
|
|
56
|
+
</Tabs.Panel>
|
|
57
|
+
<style>{`.panel[data-state="active"] { display:grid; place-content: center;}`}</style>
|
|
58
|
+
</>
|
|
59
|
+
);
|
|
56
60
|
|
|
57
|
-
export const Default = {
|
|
61
|
+
export const Default: Story = {
|
|
58
62
|
render: (props) => {
|
|
59
63
|
return (
|
|
60
64
|
<Tabs
|
|
@@ -65,13 +69,17 @@ export const Default = {
|
|
|
65
69
|
iconPosition={props?.iconPosition}
|
|
66
70
|
>
|
|
67
71
|
<Tabs.List>
|
|
68
|
-
<Tabs.Tab value="test1" icon={<MugIcon />} label="Skap" />
|
|
72
|
+
<Tabs.Tab value="test1" icon={<MugIcon aria-hidden />} label="Skap" />
|
|
69
73
|
<Tabs.Tab
|
|
70
74
|
value="test2"
|
|
71
75
|
label="Oppvaskmaskin"
|
|
72
|
-
icon={<DishwasherIcon />}
|
|
76
|
+
icon={<DishwasherIcon aria-hidden />}
|
|
77
|
+
/>
|
|
78
|
+
<Tabs.Tab
|
|
79
|
+
value="test3"
|
|
80
|
+
icon={<FreezerIcon aria-hidden />}
|
|
81
|
+
label="Fryser"
|
|
73
82
|
/>
|
|
74
|
-
<Tabs.Tab value="test3" icon={<FreezerIcon />} label="Fryser" />
|
|
75
83
|
</Tabs.List>
|
|
76
84
|
<Panel />
|
|
77
85
|
</Tabs>
|
|
@@ -84,108 +92,220 @@ export const Default = {
|
|
|
84
92
|
},
|
|
85
93
|
};
|
|
86
94
|
|
|
87
|
-
export const Small = () =>
|
|
95
|
+
export const Small = () => (
|
|
96
|
+
<Tabs defaultValue="test2" size="small">
|
|
97
|
+
<Tabs.List>
|
|
98
|
+
<Tabs.Tab value="test1" icon={<MugIcon aria-hidden />} label="Skap" />
|
|
99
|
+
<Tabs.Tab
|
|
100
|
+
value="test2"
|
|
101
|
+
label="Oppvaskmaskin"
|
|
102
|
+
icon={<DishwasherIcon aria-hidden />}
|
|
103
|
+
/>
|
|
104
|
+
<Tabs.Tab
|
|
105
|
+
value="test3"
|
|
106
|
+
icon={<FreezerIcon aria-hidden />}
|
|
107
|
+
label="Fryser"
|
|
108
|
+
/>
|
|
109
|
+
</Tabs.List>
|
|
110
|
+
<Panel />
|
|
111
|
+
</Tabs>
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
export const Controlled = () => {
|
|
115
|
+
const [activeValue, setActiveValue] = useState("test1");
|
|
88
116
|
return (
|
|
89
|
-
<Tabs
|
|
117
|
+
<Tabs value={activeValue} onChange={setActiveValue}>
|
|
90
118
|
<Tabs.List>
|
|
91
|
-
<Tabs.Tab value="test1" icon={<MugIcon />} label="Skap" />
|
|
119
|
+
<Tabs.Tab value="test1" icon={<MugIcon aria-hidden />} label="Skap" />
|
|
92
120
|
<Tabs.Tab
|
|
93
121
|
value="test2"
|
|
94
122
|
label="Oppvaskmaskin"
|
|
95
|
-
icon={<DishwasherIcon />}
|
|
123
|
+
icon={<DishwasherIcon aria-hidden />}
|
|
124
|
+
/>
|
|
125
|
+
<Tabs.Tab
|
|
126
|
+
value="test3"
|
|
127
|
+
icon={<FreezerIcon aria-hidden />}
|
|
128
|
+
label="Fryser"
|
|
96
129
|
/>
|
|
97
|
-
<Tabs.Tab value="test3" icon={<FreezerIcon />} label="Fryser" />
|
|
98
130
|
</Tabs.List>
|
|
99
131
|
<Panel />
|
|
100
132
|
</Tabs>
|
|
101
133
|
);
|
|
102
134
|
};
|
|
103
135
|
|
|
104
|
-
export const
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
<Tabs value={activeValue} onChange={setActiveValue}>
|
|
136
|
+
export const IconPosition = () => (
|
|
137
|
+
<VStack gap="4">
|
|
138
|
+
<Tabs defaultValue="test2" size="small">
|
|
108
139
|
<Tabs.List>
|
|
109
|
-
<Tabs.Tab value="test1" icon={<MugIcon />} label="Skap" />
|
|
140
|
+
<Tabs.Tab value="test1" icon={<MugIcon aria-hidden />} label="Skap" />
|
|
110
141
|
<Tabs.Tab
|
|
111
142
|
value="test2"
|
|
112
143
|
label="Oppvaskmaskin"
|
|
113
|
-
icon={<DishwasherIcon />}
|
|
144
|
+
icon={<DishwasherIcon aria-hidden />}
|
|
145
|
+
/>
|
|
146
|
+
<Tabs.Tab
|
|
147
|
+
value="test3"
|
|
148
|
+
icon={<FreezerIcon aria-hidden />}
|
|
149
|
+
label="Fryser"
|
|
114
150
|
/>
|
|
115
|
-
<Tabs.Tab value="test3" icon={<FreezerIcon />} label="Fryser" />
|
|
116
151
|
</Tabs.List>
|
|
117
152
|
<Panel />
|
|
118
153
|
</Tabs>
|
|
119
|
-
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
export const IconPosition = () => {
|
|
123
|
-
return (
|
|
124
|
-
<div className="colgap">
|
|
125
|
-
<Tabs defaultValue="test2" size="small">
|
|
126
|
-
<Tabs.List>
|
|
127
|
-
<Tabs.Tab value="test1" icon={<MugIcon />} label="Skap" />
|
|
128
|
-
<Tabs.Tab
|
|
129
|
-
value="test2"
|
|
130
|
-
label="Oppvaskmaskin"
|
|
131
|
-
icon={<DishwasherIcon />}
|
|
132
|
-
/>
|
|
133
|
-
<Tabs.Tab value="test3" icon={<FreezerIcon />} label="Fryser" />
|
|
134
|
-
</Tabs.List>
|
|
135
|
-
<Panel />
|
|
136
|
-
</Tabs>
|
|
137
|
-
<Tabs defaultValue="test2" size="small" iconPosition="top">
|
|
138
|
-
<Tabs.List style={{ margin: "0 auto" }}>
|
|
139
|
-
<Tabs.Tab value="test1" icon={<MugIcon />} label="Skap" />
|
|
140
|
-
<Tabs.Tab
|
|
141
|
-
value="test2"
|
|
142
|
-
label="Oppvaskmaskin"
|
|
143
|
-
icon={<DishwasherIcon />}
|
|
144
|
-
/>
|
|
145
|
-
<Tabs.Tab value="test3" icon={<FreezerIcon />} label="Fryser" />
|
|
146
|
-
</Tabs.List>
|
|
147
|
-
<Panel />
|
|
148
|
-
</Tabs>
|
|
149
|
-
</div>
|
|
150
|
-
);
|
|
151
|
-
};
|
|
152
|
-
|
|
153
|
-
export const Icon = () => {
|
|
154
|
-
return (
|
|
155
|
-
<div className="colgap">
|
|
156
|
-
<Tabs defaultValue="test2">
|
|
157
|
-
<Tabs.List style={{ margin: "0 auto" }}>
|
|
158
|
-
<Tabs.Tab value="test1" icon={<MugIcon />} />
|
|
159
|
-
<Tabs.Tab value="test2" icon={<DishwasherIcon />} />
|
|
160
|
-
<Tabs.Tab value="test3" icon={<FreezerIcon />} />
|
|
161
|
-
</Tabs.List>
|
|
162
|
-
<Panel />
|
|
163
|
-
</Tabs>
|
|
164
|
-
<Tabs defaultValue="test2" size="small" iconPosition="top">
|
|
165
|
-
<Tabs.List style={{ margin: "0 auto" }}>
|
|
166
|
-
<Tabs.Tab value="test1" icon={<MugIcon />} />
|
|
167
|
-
<Tabs.Tab value="test2" icon={<DishwasherIcon />} />
|
|
168
|
-
<Tabs.Tab value="test3" icon={<FreezerIcon />} />
|
|
169
|
-
</Tabs.List>
|
|
170
|
-
<Panel />
|
|
171
|
-
</Tabs>
|
|
172
|
-
</div>
|
|
173
|
-
);
|
|
174
|
-
};
|
|
175
|
-
|
|
176
|
-
export const Overflow = () => {
|
|
177
|
-
return (
|
|
178
|
-
<Tabs defaultValue="test2" style={{ maxWidth: 300 }}>
|
|
179
|
-
<Tabs.List>
|
|
180
|
-
<Tabs.Tab value="test1" icon={<MugIcon />} label="Skap" />
|
|
154
|
+
<Tabs defaultValue="test2" size="small" iconPosition="top">
|
|
155
|
+
<Tabs.List style={{ margin: "0 auto" }}>
|
|
156
|
+
<Tabs.Tab value="test1" icon={<MugIcon aria-hidden />} label="Skap" />
|
|
181
157
|
<Tabs.Tab
|
|
182
158
|
value="test2"
|
|
183
159
|
label="Oppvaskmaskin"
|
|
184
|
-
icon={<DishwasherIcon />}
|
|
160
|
+
icon={<DishwasherIcon aria-hidden />}
|
|
161
|
+
/>
|
|
162
|
+
<Tabs.Tab
|
|
163
|
+
value="test3"
|
|
164
|
+
icon={<FreezerIcon aria-hidden />}
|
|
165
|
+
label="Fryser"
|
|
185
166
|
/>
|
|
186
|
-
<Tabs.Tab value="test3" icon={<FreezerIcon />} label="Fryser" />
|
|
187
167
|
</Tabs.List>
|
|
188
168
|
<Panel />
|
|
189
169
|
</Tabs>
|
|
190
|
-
|
|
170
|
+
</VStack>
|
|
171
|
+
);
|
|
172
|
+
|
|
173
|
+
export const Icon = () => (
|
|
174
|
+
<VStack gap="4">
|
|
175
|
+
<Tabs defaultValue="test2">
|
|
176
|
+
<Tabs.List style={{ margin: "0 auto" }}>
|
|
177
|
+
<Tabs.Tab value="test1" icon={<MugIcon title="Skap" />} />
|
|
178
|
+
<Tabs.Tab
|
|
179
|
+
value="test2"
|
|
180
|
+
icon={<DishwasherIcon title="Oppvaskmaskin" />}
|
|
181
|
+
/>
|
|
182
|
+
<Tabs.Tab value="test3" icon={<FreezerIcon title="Fryser" />} />
|
|
183
|
+
</Tabs.List>
|
|
184
|
+
<Panel />
|
|
185
|
+
</Tabs>
|
|
186
|
+
<Tabs defaultValue="test2" size="small" iconPosition="top">
|
|
187
|
+
<Tabs.List style={{ margin: "0 auto" }}>
|
|
188
|
+
<Tabs.Tab value="test1" icon={<MugIcon title="Skap" />} />
|
|
189
|
+
<Tabs.Tab
|
|
190
|
+
value="test2"
|
|
191
|
+
icon={<DishwasherIcon title="Oppvaskmaskin" />}
|
|
192
|
+
/>
|
|
193
|
+
<Tabs.Tab value="test3" icon={<FreezerIcon title="Fryser" />} />
|
|
194
|
+
</Tabs.List>
|
|
195
|
+
<Panel />
|
|
196
|
+
</Tabs>
|
|
197
|
+
</VStack>
|
|
198
|
+
);
|
|
199
|
+
|
|
200
|
+
export const Overflow = () => (
|
|
201
|
+
<Tabs defaultValue="test2" style={{ maxWidth: 300 }}>
|
|
202
|
+
<Tabs.List>
|
|
203
|
+
<Tabs.Tab value="test1" icon={<MugIcon aria-hidden />} label="Skap" />
|
|
204
|
+
<Tabs.Tab
|
|
205
|
+
value="test2"
|
|
206
|
+
label="Oppvaskmaskin"
|
|
207
|
+
icon={<DishwasherIcon aria-hidden />}
|
|
208
|
+
/>
|
|
209
|
+
<Tabs.Tab
|
|
210
|
+
value="test3"
|
|
211
|
+
icon={<FreezerIcon aria-hidden />}
|
|
212
|
+
label="Fryser"
|
|
213
|
+
/>
|
|
214
|
+
</Tabs.List>
|
|
215
|
+
<Panel />
|
|
216
|
+
</Tabs>
|
|
217
|
+
);
|
|
218
|
+
|
|
219
|
+
export const Fill = () => (
|
|
220
|
+
<Tabs defaultValue="test2" fill>
|
|
221
|
+
<Tabs.List>
|
|
222
|
+
<Tabs.Tab value="test1" icon={<MugIcon aria-hidden />} label="Skap" />
|
|
223
|
+
<Tabs.Tab
|
|
224
|
+
value="test2"
|
|
225
|
+
icon={<DishwasherIcon aria-hidden />}
|
|
226
|
+
label="Oppvaskmaskin"
|
|
227
|
+
/>
|
|
228
|
+
<Tabs.Tab
|
|
229
|
+
value="test3"
|
|
230
|
+
icon={<FreezerIcon aria-hidden />}
|
|
231
|
+
label="Fryser"
|
|
232
|
+
/>
|
|
233
|
+
</Tabs.List>
|
|
234
|
+
<Panel />
|
|
235
|
+
</Tabs>
|
|
236
|
+
);
|
|
237
|
+
|
|
238
|
+
Fill.parameters = {
|
|
239
|
+
layout: "fullscreen",
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
export const CustomIds = () => (
|
|
243
|
+
<Tabs defaultValue="test2">
|
|
244
|
+
<Tabs.List>
|
|
245
|
+
<Tabs.Tab
|
|
246
|
+
value="test1"
|
|
247
|
+
label="Skap"
|
|
248
|
+
id="custom-tabid-1"
|
|
249
|
+
aria-controls="custom-tabpanelid-1"
|
|
250
|
+
/>
|
|
251
|
+
<Tabs.Tab
|
|
252
|
+
value="test2"
|
|
253
|
+
label="Oppvaskmaskin"
|
|
254
|
+
id="custom-tabid-2"
|
|
255
|
+
aria-controls="custom-tabpanelid-2"
|
|
256
|
+
/>
|
|
257
|
+
</Tabs.List>
|
|
258
|
+
<Tabs.Panel
|
|
259
|
+
value="test1"
|
|
260
|
+
className="panel"
|
|
261
|
+
id="custom-tabpanelid-1"
|
|
262
|
+
aria-labelledby="custom-tabid-1"
|
|
263
|
+
>
|
|
264
|
+
Innholdspanel for Skap-tab
|
|
265
|
+
</Tabs.Panel>
|
|
266
|
+
<Tabs.Panel
|
|
267
|
+
value="test2"
|
|
268
|
+
className="panel"
|
|
269
|
+
id="custom-tabpanelid-2"
|
|
270
|
+
aria-labelledby="custom-tabid-2"
|
|
271
|
+
>
|
|
272
|
+
Innholdspanel for Oppvaskmaskin-tab
|
|
273
|
+
</Tabs.Panel>
|
|
274
|
+
</Tabs>
|
|
275
|
+
);
|
|
276
|
+
|
|
277
|
+
export const Chromatic = {
|
|
278
|
+
render: () => (
|
|
279
|
+
<VStack gap="6" align="center">
|
|
280
|
+
<div>
|
|
281
|
+
<h2>Small</h2>
|
|
282
|
+
<Small />
|
|
283
|
+
</div>
|
|
284
|
+
<div>
|
|
285
|
+
<h2>Controlled</h2>
|
|
286
|
+
<Controlled />
|
|
287
|
+
</div>
|
|
288
|
+
<div>
|
|
289
|
+
<h2>IconPosition</h2>
|
|
290
|
+
<IconPosition />
|
|
291
|
+
</div>
|
|
292
|
+
<div>
|
|
293
|
+
<h2>Icon</h2>
|
|
294
|
+
<Icon />
|
|
295
|
+
</div>
|
|
296
|
+
<div>
|
|
297
|
+
<h2>Overflow</h2>
|
|
298
|
+
<Overflow />
|
|
299
|
+
</div>
|
|
300
|
+
<div>
|
|
301
|
+
<h2>Fill</h2>
|
|
302
|
+
<div style={{ minWidth: 600 }}>
|
|
303
|
+
<Fill />
|
|
304
|
+
</div>
|
|
305
|
+
</div>
|
|
306
|
+
</VStack>
|
|
307
|
+
),
|
|
308
|
+
parameters: {
|
|
309
|
+
chromatic: { disable: false, delay: 300 },
|
|
310
|
+
},
|
|
191
311
|
};
|
package/src/tabs/Tabs.test.tsx
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { fireEvent, render, screen } from "@testing-library/react";
|
|
1
|
+
import { act, fireEvent, render, screen } from "@testing-library/react";
|
|
2
|
+
import userEvent from "@testing-library/user-event";
|
|
2
3
|
import React from "react";
|
|
3
4
|
import { describe, expect, test } from "vitest";
|
|
4
5
|
import { Tabs } from "./Tabs";
|
|
@@ -39,72 +40,133 @@ const TestTabs = ({
|
|
|
39
40
|
describe("Tabs", () => {
|
|
40
41
|
test("sets default value correctly", () => {
|
|
41
42
|
render(<TestTabs defaultValue="tab2" />);
|
|
42
|
-
const
|
|
43
|
-
const
|
|
43
|
+
const tab2 = screen.getByTestId("tab2");
|
|
44
|
+
const panel2 = screen.getByTestId("tabpanel2");
|
|
44
45
|
|
|
45
|
-
expect(
|
|
46
|
-
expect(
|
|
46
|
+
expect(tab2).toHaveAttribute("aria-selected", "true");
|
|
47
|
+
expect(panel2).toHaveTextContent("Tabpanel 2");
|
|
47
48
|
});
|
|
48
49
|
|
|
49
50
|
test("label-connection between tab and tabpanel is correct", async () => {
|
|
50
51
|
render(<TestTabs defaultValue="tab2" />);
|
|
51
|
-
const
|
|
52
|
-
const
|
|
52
|
+
const tab2 = screen.getByTestId("tab2");
|
|
53
|
+
const panel2 = screen.getByTestId("tabpanel2");
|
|
53
54
|
|
|
54
|
-
const controlsId =
|
|
55
|
-
const panelLabelledBy =
|
|
55
|
+
const controlsId = tab2.getAttribute("aria-controls");
|
|
56
|
+
const panelLabelledBy = panel2.getAttribute("aria-labelledby");
|
|
56
57
|
|
|
57
|
-
expect(controlsId).toEqual(
|
|
58
|
-
expect(
|
|
58
|
+
expect(controlsId).toEqual(panel2.id);
|
|
59
|
+
expect(tab2.id).toEqual(panelLabelledBy);
|
|
59
60
|
});
|
|
60
61
|
|
|
61
62
|
test("sets correct attributes on active tab", () => {
|
|
62
63
|
render(<TestTabs defaultValue="tab2" />);
|
|
63
|
-
const
|
|
64
|
+
const tab2 = screen.getByTestId("tab2");
|
|
64
65
|
|
|
65
|
-
expect(
|
|
66
|
-
expect(
|
|
67
|
-
expect(
|
|
68
|
-
expect(
|
|
66
|
+
expect(tab2).toHaveAttribute("aria-selected", "true");
|
|
67
|
+
expect(tab2).toHaveAttribute("role", "tab");
|
|
68
|
+
expect(tab2).toHaveAttribute("aria-controls");
|
|
69
|
+
expect(tab2).toHaveAttribute("tabindex", "0");
|
|
69
70
|
});
|
|
70
71
|
|
|
71
72
|
test("sets correct attributes on idle tab", () => {
|
|
72
73
|
render(<TestTabs defaultValue="tab2" />);
|
|
73
|
-
const
|
|
74
|
+
const tab1 = screen.getByTestId("tab1");
|
|
74
75
|
|
|
75
|
-
expect(
|
|
76
|
-
expect(
|
|
77
|
-
expect(
|
|
78
|
-
expect(
|
|
76
|
+
expect(tab1).toHaveAttribute("aria-selected", "false");
|
|
77
|
+
expect(tab1).toHaveAttribute("role", "tab");
|
|
78
|
+
expect(tab1).toHaveAttribute("aria-controls");
|
|
79
|
+
expect(tab1).toHaveAttribute("tabindex", "-1");
|
|
79
80
|
});
|
|
80
81
|
|
|
81
82
|
test("sets correct attributes on active tabpanel", () => {
|
|
82
83
|
render(<TestTabs defaultValue="tab2" />);
|
|
83
|
-
const
|
|
84
|
+
const panel2 = screen.getByTestId("tabpanel2");
|
|
84
85
|
|
|
85
|
-
expect(
|
|
86
|
-
expect(
|
|
87
|
-
expect(
|
|
88
|
-
expect(
|
|
89
|
-
expect(
|
|
86
|
+
expect(panel2).toHaveAttribute("aria-labelledby");
|
|
87
|
+
expect(panel2).toHaveAttribute("role", "tabpanel");
|
|
88
|
+
expect(panel2).toHaveAttribute("tabindex", "0");
|
|
89
|
+
expect(panel2).toHaveTextContent("Tabpanel 2");
|
|
90
|
+
expect(panel2).toHaveStyle({ display: "block" });
|
|
90
91
|
});
|
|
91
92
|
|
|
92
93
|
test("sets correct attributes on idle tabpanel", () => {
|
|
93
94
|
render(<TestTabs defaultValue="tab1" />);
|
|
94
|
-
const
|
|
95
|
+
const panel2 = screen.getByTestId("tabpanel2");
|
|
95
96
|
|
|
96
|
-
expect(
|
|
97
|
-
expect(
|
|
98
|
-
expect(
|
|
99
|
-
expect(
|
|
100
|
-
expect(
|
|
97
|
+
expect(panel2).toHaveAttribute("aria-labelledby");
|
|
98
|
+
expect(panel2).toHaveAttribute("role", "tabpanel");
|
|
99
|
+
expect(panel2).toHaveAttribute("tabindex", "0");
|
|
100
|
+
expect(panel2).toBeEmptyDOMElement();
|
|
101
|
+
expect(panel2).toHaveStyle({ display: "none" });
|
|
101
102
|
});
|
|
102
103
|
|
|
103
104
|
test("sets tabindex to 0 when focused", () => {
|
|
104
|
-
render(<TestTabs defaultValue="
|
|
105
|
-
const
|
|
105
|
+
render(<TestTabs defaultValue="tab1" />);
|
|
106
|
+
const tab2 = screen.getByTestId("tab2");
|
|
107
|
+
|
|
108
|
+
fireEvent.focus(tab2);
|
|
109
|
+
expect(tab2).toHaveAttribute("tabindex", "0");
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
test("rowing tabindex keydown moves focus", () => {
|
|
113
|
+
render(<TestTabs defaultValue="tab1" />);
|
|
114
|
+
const tab1 = screen.getByTestId("tab1");
|
|
115
|
+
|
|
116
|
+
expect(tab1).toHaveAttribute("tabindex", "0");
|
|
117
|
+
fireEvent.keyDown(tab1, { key: "ArrowRight" });
|
|
118
|
+
|
|
119
|
+
expect(tab1).toHaveAttribute("tabindex", "-1");
|
|
120
|
+
expect(screen.getByTestId("tab2")).toHaveAttribute("tabindex", "0");
|
|
121
|
+
expect(screen.getByTestId("tab2")).toHaveAttribute(
|
|
122
|
+
"aria-selected",
|
|
123
|
+
"false",
|
|
124
|
+
);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
test("selectionFollowsFocus moves active tabs", () => {
|
|
128
|
+
render(<TestTabs defaultValue="tab1" selectionFollowsFocus />);
|
|
129
|
+
const tab1 = screen.getByTestId("tab1");
|
|
106
130
|
|
|
107
|
-
|
|
108
|
-
|
|
131
|
+
expect(tab1).toHaveAttribute("tabindex", "0");
|
|
132
|
+
fireEvent.keyDown(tab1, { key: "ArrowRight" });
|
|
133
|
+
|
|
134
|
+
expect(screen.getByTestId("tab2")).toHaveAttribute("aria-selected", "true");
|
|
135
|
+
expect(screen.getByTestId("tab2")).toHaveAttribute("tabindex", "0");
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
test("tabbing from tabs moves focus to tabPanel", async () => {
|
|
139
|
+
render(<TestTabs defaultValue="tab1" />);
|
|
140
|
+
const tab1 = screen.getByTestId("tab1");
|
|
141
|
+
|
|
142
|
+
tab1.focus();
|
|
143
|
+
await userEvent.tab();
|
|
144
|
+
|
|
145
|
+
expect(screen.getByTestId("tabpanel1")).toHaveFocus();
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
test("shift+tab back to tablist should focus selected tab", async () => {
|
|
149
|
+
render(<TestTabs defaultValue="tab1" />);
|
|
150
|
+
const tab1 = screen.getByTestId("tab1");
|
|
151
|
+
|
|
152
|
+
/* Move focus to tab2 */
|
|
153
|
+
fireEvent.keyDown(tab1, { key: "ArrowRight" });
|
|
154
|
+
expect(screen.getByTestId("tab2")).toHaveFocus();
|
|
155
|
+
|
|
156
|
+
/* Move focus to tabPanel */
|
|
157
|
+
// eslint-disable-next-line testing-library/no-unnecessary-act
|
|
158
|
+
await act(async () => {
|
|
159
|
+
/* Tablist handles tabbing with setTimeout, so we need to use act */
|
|
160
|
+
await userEvent.tab();
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
expect(screen.getByTestId("tabpanel1")).toHaveFocus();
|
|
164
|
+
/* Move focus back to tablist, now tab1 should have focus */
|
|
165
|
+
|
|
166
|
+
// eslint-disable-next-line testing-library/no-unnecessary-act
|
|
167
|
+
await act(async () => {
|
|
168
|
+
await userEvent.tab({ shift: true });
|
|
169
|
+
});
|
|
170
|
+
expect(screen.getByTestId("tab1")).toHaveFocus();
|
|
109
171
|
});
|
|
110
172
|
});
|