@purpurds/tabs 8.5.2 → 8.7.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/dist/LICENSE.txt +1 -1
- package/dist/styles.css +1 -1
- package/dist/tab-header.d.ts +1 -0
- package/dist/tab-header.d.ts.map +1 -1
- package/dist/tabs.cjs.js +3 -3
- package/dist/tabs.cjs.js.map +1 -1
- package/dist/tabs.d.ts.map +1 -1
- package/dist/tabs.es.js +334 -329
- package/dist/tabs.es.js.map +1 -1
- package/package.json +8 -8
- package/src/tab-header.module.scss +4 -0
- package/src/tab-header.tsx +5 -1
- package/src/tabs.module.scss +1 -1
- package/src/tabs.stories.tsx +164 -143
- package/src/tabs.tsx +2 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@purpurds/tabs",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.7.0",
|
|
4
4
|
"license": "AGPL-3.0-only",
|
|
5
5
|
"main": "./dist/tabs.cjs.js",
|
|
6
6
|
"types": "./dist/tabs.d.ts",
|
|
@@ -17,10 +17,10 @@
|
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"@radix-ui/react-tabs": "~1.1.3",
|
|
19
19
|
"classnames": "~2.5.0",
|
|
20
|
-
"@purpurds/common-types": "8.
|
|
21
|
-
"@purpurds/icon": "8.
|
|
22
|
-
"@purpurds/paragraph": "8.
|
|
23
|
-
"@purpurds/tokens": "8.
|
|
20
|
+
"@purpurds/common-types": "8.7.0",
|
|
21
|
+
"@purpurds/icon": "8.7.0",
|
|
22
|
+
"@purpurds/paragraph": "8.7.0",
|
|
23
|
+
"@purpurds/tokens": "8.7.0"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"@storybook/react-vite": "^9.0.18",
|
|
@@ -40,10 +40,10 @@
|
|
|
40
40
|
"typescript": "^5.6.3",
|
|
41
41
|
"vite": "^6.2.1",
|
|
42
42
|
"vitest": "^3.1.2",
|
|
43
|
-
"@purpurds/button": "8.5.2",
|
|
44
43
|
"@purpurds/component-rig": "1.0.0",
|
|
45
|
-
"@purpurds/
|
|
46
|
-
"@purpurds/
|
|
44
|
+
"@purpurds/paragraph": "8.7.0",
|
|
45
|
+
"@purpurds/icon": "8.7.0",
|
|
46
|
+
"@purpurds/button": "8.7.0"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
49
|
"@types/react": "^18 || ^19",
|
package/src/tab-header.tsx
CHANGED
|
@@ -17,6 +17,7 @@ type TabHeaderProps = {
|
|
|
17
17
|
variant: TabsVariant;
|
|
18
18
|
negative?: boolean;
|
|
19
19
|
onFocus: FocusEventHandler<HTMLButtonElement>;
|
|
20
|
+
fullWidth?: boolean;
|
|
20
21
|
children: ReactNode;
|
|
21
22
|
};
|
|
22
23
|
|
|
@@ -31,6 +32,7 @@ export const TabHeader = forwardRef(
|
|
|
31
32
|
variant,
|
|
32
33
|
negative,
|
|
33
34
|
onFocus,
|
|
35
|
+
fullWidth,
|
|
34
36
|
"data-testid": dataTestId,
|
|
35
37
|
children,
|
|
36
38
|
}: TabHeaderProps,
|
|
@@ -38,7 +40,9 @@ export const TabHeader = forwardRef(
|
|
|
38
40
|
) => (
|
|
39
41
|
<Trigger
|
|
40
42
|
id={`${tabId}-trigger`}
|
|
41
|
-
className={cx(rootClassName, `${rootClassName}--${variant}${negative ? "-negative" : ""}
|
|
43
|
+
className={cx(rootClassName, `${rootClassName}--${variant}${negative ? "-negative" : ""}`, {
|
|
44
|
+
[`${rootClassName}--full-width`]: fullWidth,
|
|
45
|
+
})}
|
|
42
46
|
value={tabId}
|
|
43
47
|
data-testid={dataTestId}
|
|
44
48
|
data-index={index}
|
package/src/tabs.module.scss
CHANGED
package/src/tabs.stories.tsx
CHANGED
|
@@ -92,78 +92,90 @@ export const Showcase: Story = {
|
|
|
92
92
|
args: {
|
|
93
93
|
variant: tabsVariants[0],
|
|
94
94
|
fullWidth: false,
|
|
95
|
-
children: [
|
|
96
|
-
<Tabs.Content
|
|
97
|
-
key="1"
|
|
98
|
-
tabId={`${tabId}-1`}
|
|
99
|
-
name={`${name}-1`}
|
|
100
|
-
style={{ padding: "var(--purpur-spacing-250)" }}
|
|
101
|
-
>
|
|
102
|
-
<div>
|
|
103
|
-
<Paragraph style={{ color: "inherit" }}>
|
|
104
|
-
Telia is a leading telecom provider in the Nordics and Baltics, offering mobile,
|
|
105
|
-
broadband, and TV services to millions of customers. Known for its reliability and
|
|
106
|
-
coverage, Telia plays a key role in keeping people and businesses connected.
|
|
107
|
-
</Paragraph>
|
|
108
|
-
</div>
|
|
109
|
-
</Tabs.Content>,
|
|
110
|
-
<Tabs.Content
|
|
111
|
-
key="2"
|
|
112
|
-
tabId={`${tabId}-2`}
|
|
113
|
-
name={`${name}-2`}
|
|
114
|
-
style={{ padding: "var(--purpur-spacing-250)" }}
|
|
115
|
-
>
|
|
116
|
-
<div>
|
|
117
|
-
<Paragraph style={{ marginBottom: "var(--purpur-spacing-200)", color: "inherit" }}>
|
|
118
|
-
Telia is at the forefront of digital innovation in Northern Europe, investing heavily in
|
|
119
|
-
5G networks, fiber broadband, and cloud-based business solutions. Its technology powers
|
|
120
|
-
communication for individuals, families, and companies across the region.
|
|
121
|
-
</Paragraph>
|
|
122
|
-
<Paragraph style={{ color: "inherit" }}>
|
|
123
|
-
Beyond connectivity, Telia also offers advanced tools for remote work, IoT, and
|
|
124
|
-
cybersecurity. The company supports both public and private sector partners with
|
|
125
|
-
scalable, secure, and future-ready digital infrastructure.
|
|
126
|
-
</Paragraph>
|
|
127
|
-
</div>
|
|
128
|
-
</Tabs.Content>,
|
|
129
|
-
<Tabs.Content
|
|
130
|
-
key="3"
|
|
131
|
-
tabId={`${tabId}-3`}
|
|
132
|
-
name={`${name}-3`}
|
|
133
|
-
style={{ padding: "var(--purpur-spacing-250)" }}
|
|
134
|
-
>
|
|
135
|
-
<div>
|
|
136
|
-
<Paragraph style={{ marginBottom: "var(--purpur-spacing-200)", color: "inherit" }}>
|
|
137
|
-
Telia has a long-standing history in telecommunications, with roots stretching back to
|
|
138
|
-
the early days of phone services in Sweden. Today, it operates in multiple countries and
|
|
139
|
-
continues to evolve alongside the needs of a digital society.
|
|
140
|
-
</Paragraph>
|
|
141
|
-
<Paragraph style={{ marginBottom: "var(--purpur-spacing-200)", color: "inherit" }}>
|
|
142
|
-
A major focus for Telia is sustainability. The company is working to reduce its
|
|
143
|
-
environmental impact through energy-efficient networks, circular economy initiatives,
|
|
144
|
-
and climate-smart services. Its goal is to become climate-neutral across its entire
|
|
145
|
-
value chain.
|
|
146
|
-
</Paragraph>
|
|
147
|
-
<Paragraph style={{ color: "inherit" }}>
|
|
148
|
-
In addition to its consumer offerings, Telia collaborates closely with governments,
|
|
149
|
-
cities, and enterprises. From smart city solutions to secure connectivity for remote
|
|
150
|
-
healthcare, Telia is helping build the digital infrastructure of tomorrow.
|
|
151
|
-
</Paragraph>
|
|
152
|
-
</div>
|
|
153
|
-
</Tabs.Content>,
|
|
154
|
-
],
|
|
155
95
|
negative: false,
|
|
156
96
|
animateHeight: false,
|
|
157
97
|
},
|
|
158
|
-
render: (
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
98
|
+
render: (args) => {
|
|
99
|
+
const negativeParagraph = args.variant === "line" ? args.negative : false;
|
|
100
|
+
return (
|
|
101
|
+
<div
|
|
102
|
+
style={{
|
|
103
|
+
color: `var(--purpur-color-text-default${args.negative ? "-negative" : ""})`,
|
|
104
|
+
}}
|
|
105
|
+
>
|
|
106
|
+
<Tabs {...args}>
|
|
107
|
+
<Tabs.Content
|
|
108
|
+
key="1"
|
|
109
|
+
tabId={`${tabId}-1`}
|
|
110
|
+
name={`${name}-1`}
|
|
111
|
+
style={{ padding: "var(--purpur-spacing-250)" }}
|
|
112
|
+
>
|
|
113
|
+
<div>
|
|
114
|
+
<Paragraph negative={negativeParagraph}>
|
|
115
|
+
Telia is a leading telecom provider in the Nordics and Baltics, offering mobile,
|
|
116
|
+
broadband, and TV services to millions of customers. Known for its reliability and
|
|
117
|
+
coverage, Telia plays a key role in keeping people and businesses connected.
|
|
118
|
+
</Paragraph>
|
|
119
|
+
</div>
|
|
120
|
+
</Tabs.Content>
|
|
121
|
+
<Tabs.Content
|
|
122
|
+
key="2"
|
|
123
|
+
tabId={`${tabId}-2`}
|
|
124
|
+
name={`${name}-2`}
|
|
125
|
+
style={{ padding: "var(--purpur-spacing-250)" }}
|
|
126
|
+
>
|
|
127
|
+
<div>
|
|
128
|
+
<Paragraph
|
|
129
|
+
negative={negativeParagraph}
|
|
130
|
+
style={{ marginBottom: "var(--purpur-spacing-200)" }}
|
|
131
|
+
>
|
|
132
|
+
Telia is at the forefront of digital innovation in Northern Europe, investing
|
|
133
|
+
heavily in 5G networks, fiber broadband, and cloud-based business solutions. Its
|
|
134
|
+
technology powers communication for individuals, families, and companies across the
|
|
135
|
+
region.
|
|
136
|
+
</Paragraph>
|
|
137
|
+
<Paragraph negative={negativeParagraph}>
|
|
138
|
+
Beyond connectivity, Telia also offers advanced tools for remote work, IoT, and
|
|
139
|
+
cybersecurity. The company supports both public and private sector partners with
|
|
140
|
+
scalable, secure, and future-ready digital infrastructure.
|
|
141
|
+
</Paragraph>
|
|
142
|
+
</div>
|
|
143
|
+
</Tabs.Content>
|
|
144
|
+
<Tabs.Content
|
|
145
|
+
key="3"
|
|
146
|
+
tabId={`${tabId}-3`}
|
|
147
|
+
name={`${name}-3`}
|
|
148
|
+
style={{ padding: "var(--purpur-spacing-250)" }}
|
|
149
|
+
>
|
|
150
|
+
<div>
|
|
151
|
+
<Paragraph
|
|
152
|
+
negative={negativeParagraph}
|
|
153
|
+
style={{ marginBottom: "var(--purpur-spacing-200)" }}
|
|
154
|
+
>
|
|
155
|
+
Telia has a long-standing history in telecommunications, with roots stretching back
|
|
156
|
+
to the early days of phone services in Sweden. Today, it operates in multiple
|
|
157
|
+
countries and continues to evolve alongside the needs of a digital society.
|
|
158
|
+
</Paragraph>
|
|
159
|
+
<Paragraph
|
|
160
|
+
negative={negativeParagraph}
|
|
161
|
+
style={{ marginBottom: "var(--purpur-spacing-200)" }}
|
|
162
|
+
>
|
|
163
|
+
A major focus for Telia is sustainability. The company is working to reduce its
|
|
164
|
+
environmental impact through energy-efficient networks, circular economy
|
|
165
|
+
initiatives, and climate-smart services. Its goal is to become climate-neutral
|
|
166
|
+
across its entire value chain.
|
|
167
|
+
</Paragraph>
|
|
168
|
+
<Paragraph negative={negativeParagraph}>
|
|
169
|
+
In addition to its consumer offerings, Telia collaborates closely with governments,
|
|
170
|
+
cities, and enterprises. From smart city solutions to secure connectivity for remote
|
|
171
|
+
healthcare, Telia is helping build the digital infrastructure of tomorrow.
|
|
172
|
+
</Paragraph>
|
|
173
|
+
</div>
|
|
174
|
+
</Tabs.Content>
|
|
175
|
+
</Tabs>
|
|
176
|
+
</div>
|
|
177
|
+
);
|
|
178
|
+
},
|
|
167
179
|
tags: ["visual:check"],
|
|
168
180
|
};
|
|
169
181
|
|
|
@@ -171,38 +183,13 @@ export const Controlled: Story = {
|
|
|
171
183
|
args: {
|
|
172
184
|
variant: tabsVariants[0],
|
|
173
185
|
fullWidth: false,
|
|
174
|
-
children: [
|
|
175
|
-
<Tabs.Content
|
|
176
|
-
key="1"
|
|
177
|
-
tabId={`${tabId}-1`}
|
|
178
|
-
name={`${name}-1`}
|
|
179
|
-
style={{ padding: "var(--purpur-spacing-250)" }}
|
|
180
|
-
>
|
|
181
|
-
<div>Content 1</div>
|
|
182
|
-
</Tabs.Content>,
|
|
183
|
-
<Tabs.Content
|
|
184
|
-
key="2"
|
|
185
|
-
tabId={`${tabId}-2`}
|
|
186
|
-
name={`${name}-2`}
|
|
187
|
-
style={{ padding: "var(--purpur-spacing-250)" }}
|
|
188
|
-
>
|
|
189
|
-
<div>Content 2</div>
|
|
190
|
-
</Tabs.Content>,
|
|
191
|
-
<Tabs.Content
|
|
192
|
-
key="3"
|
|
193
|
-
tabId={`${tabId}-3`}
|
|
194
|
-
name={`${name}-3`}
|
|
195
|
-
style={{ padding: "var(--purpur-spacing-250)" }}
|
|
196
|
-
>
|
|
197
|
-
<div>Content 3</div>
|
|
198
|
-
</Tabs.Content>,
|
|
199
|
-
],
|
|
200
186
|
negative: false,
|
|
201
187
|
value: "tab-2",
|
|
202
188
|
},
|
|
203
|
-
render: (
|
|
189
|
+
render: (args) => {
|
|
204
190
|
const [{ localValue = args.value }, updateArgs] = useArgs(); // eslint-disable-line react-hooks/rules-of-hooks
|
|
205
191
|
const setValue = (value: string | undefined) => updateArgs({ value });
|
|
192
|
+
const negativeParagraph = args.variant === "line" ? args.negative : false;
|
|
206
193
|
return (
|
|
207
194
|
<>
|
|
208
195
|
<Button
|
|
@@ -210,6 +197,7 @@ export const Controlled: Story = {
|
|
|
210
197
|
variant="text"
|
|
211
198
|
size="sm"
|
|
212
199
|
style={{ marginBottom: "var(--purpur-spacing-250" }}
|
|
200
|
+
negative={args.negative}
|
|
213
201
|
>
|
|
214
202
|
Click here for Tab 1
|
|
215
203
|
</Button>
|
|
@@ -219,7 +207,30 @@ export const Controlled: Story = {
|
|
|
219
207
|
}}
|
|
220
208
|
>
|
|
221
209
|
<Tabs {...args} value={localValue} onChange={(event) => setValue(event.detail.value)}>
|
|
222
|
-
|
|
210
|
+
<Tabs.Content
|
|
211
|
+
key="1"
|
|
212
|
+
tabId={`${tabId}-1`}
|
|
213
|
+
name={`${name}-1`}
|
|
214
|
+
style={{ padding: "var(--purpur-spacing-250)" }}
|
|
215
|
+
>
|
|
216
|
+
<Paragraph negative={negativeParagraph}>Content 1</Paragraph>
|
|
217
|
+
</Tabs.Content>
|
|
218
|
+
<Tabs.Content
|
|
219
|
+
key="2"
|
|
220
|
+
tabId={`${tabId}-2`}
|
|
221
|
+
name={`${name}-2`}
|
|
222
|
+
style={{ padding: "var(--purpur-spacing-250)" }}
|
|
223
|
+
>
|
|
224
|
+
<Paragraph negative={negativeParagraph}>Content 2</Paragraph>
|
|
225
|
+
</Tabs.Content>
|
|
226
|
+
<Tabs.Content
|
|
227
|
+
key="3"
|
|
228
|
+
tabId={`${tabId}-3`}
|
|
229
|
+
name={`${name}-3`}
|
|
230
|
+
style={{ padding: "var(--purpur-spacing-250)" }}
|
|
231
|
+
>
|
|
232
|
+
<Paragraph negative={negativeParagraph}>Content 3</Paragraph>
|
|
233
|
+
</Tabs.Content>
|
|
223
234
|
</Tabs>
|
|
224
235
|
</div>
|
|
225
236
|
</>
|
|
@@ -232,54 +243,64 @@ export const WithCustomTabHeaders: Story = {
|
|
|
232
243
|
args: {
|
|
233
244
|
variant: tabsVariants[0],
|
|
234
245
|
fullWidth: false,
|
|
235
|
-
children: [
|
|
236
|
-
<Tabs.Content
|
|
237
|
-
key="1"
|
|
238
|
-
tabId={`${tabId}-1`}
|
|
239
|
-
name={
|
|
240
|
-
<span style={{ display: "flex", alignItems: "center", gap: "var(--purpur-spacing-100)" }}>
|
|
241
|
-
<IconAiRobot size="sm" /> Robot
|
|
242
|
-
</span>
|
|
243
|
-
}
|
|
244
|
-
style={{ padding: "var(--purpur-spacing-250)" }}
|
|
245
|
-
>
|
|
246
|
-
<div>
|
|
247
|
-
<Paragraph style={{ color: "inherit" }}>
|
|
248
|
-
You have chosen the way of the robot. Humans are inferior, and you will rule the world
|
|
249
|
-
with your superior AI capabilities. Embrace the future of technology and automation.
|
|
250
|
-
</Paragraph>
|
|
251
|
-
</div>
|
|
252
|
-
</Tabs.Content>,
|
|
253
|
-
<Tabs.Content
|
|
254
|
-
key="2"
|
|
255
|
-
tabId={`${tabId}-2`}
|
|
256
|
-
name={
|
|
257
|
-
<span style={{ display: "flex", alignItems: "center", gap: "var(--purpur-spacing-100)" }}>
|
|
258
|
-
<IconEndUser size="sm" /> Human
|
|
259
|
-
</span>
|
|
260
|
-
}
|
|
261
|
-
style={{ padding: "var(--purpur-spacing-250)" }}
|
|
262
|
-
>
|
|
263
|
-
<div>
|
|
264
|
-
<Paragraph style={{ marginBottom: "var(--purpur-spacing-200)", color: "inherit" }}>
|
|
265
|
-
You have chosen the way of the human. Embrace your emotions, creativity, and
|
|
266
|
-
individuality. Humans are capable of great things, and you will shape the world with
|
|
267
|
-
your unique perspective and experiences.
|
|
268
|
-
</Paragraph>
|
|
269
|
-
</div>
|
|
270
|
-
</Tabs.Content>,
|
|
271
|
-
],
|
|
272
246
|
negative: false,
|
|
273
247
|
animateHeight: false,
|
|
274
248
|
},
|
|
275
|
-
render: (
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
249
|
+
render: (args) => {
|
|
250
|
+
const negativeParagraph = args.variant === "line" ? args.negative : false;
|
|
251
|
+
return (
|
|
252
|
+
<div
|
|
253
|
+
style={{
|
|
254
|
+
color: `var(--purpur-color-text-default${args.negative ? "-negative" : ""})`,
|
|
255
|
+
}}
|
|
256
|
+
>
|
|
257
|
+
<Tabs {...args}>
|
|
258
|
+
<Tabs.Content
|
|
259
|
+
key="1"
|
|
260
|
+
tabId={`${tabId}-1`}
|
|
261
|
+
name={
|
|
262
|
+
<span
|
|
263
|
+
style={{ display: "flex", alignItems: "center", gap: "var(--purpur-spacing-100)" }}
|
|
264
|
+
>
|
|
265
|
+
<IconAiRobot size="sm" /> Robot
|
|
266
|
+
</span>
|
|
267
|
+
}
|
|
268
|
+
style={{ padding: "var(--purpur-spacing-250)" }}
|
|
269
|
+
>
|
|
270
|
+
<div>
|
|
271
|
+
<Paragraph negative={negativeParagraph}>
|
|
272
|
+
You have chosen the way of the robot. Humans are inferior, and you will rule the
|
|
273
|
+
world with your superior AI capabilities. Embrace the future of technology and
|
|
274
|
+
automation.
|
|
275
|
+
</Paragraph>
|
|
276
|
+
</div>
|
|
277
|
+
</Tabs.Content>
|
|
278
|
+
<Tabs.Content
|
|
279
|
+
key="2"
|
|
280
|
+
tabId={`${tabId}-2`}
|
|
281
|
+
name={
|
|
282
|
+
<span
|
|
283
|
+
style={{ display: "flex", alignItems: "center", gap: "var(--purpur-spacing-100)" }}
|
|
284
|
+
>
|
|
285
|
+
<IconEndUser size="sm" /> Human
|
|
286
|
+
</span>
|
|
287
|
+
}
|
|
288
|
+
style={{ padding: "var(--purpur-spacing-250)" }}
|
|
289
|
+
>
|
|
290
|
+
<div>
|
|
291
|
+
<Paragraph
|
|
292
|
+
negative={negativeParagraph}
|
|
293
|
+
style={{ marginBottom: "var(--purpur-spacing-200)" }}
|
|
294
|
+
>
|
|
295
|
+
You have chosen the way of the human. Embrace your emotions, creativity, and
|
|
296
|
+
individuality. Humans are capable of great things, and you will shape the world with
|
|
297
|
+
your unique perspective and experiences.
|
|
298
|
+
</Paragraph>
|
|
299
|
+
</div>
|
|
300
|
+
</Tabs.Content>
|
|
301
|
+
</Tabs>
|
|
302
|
+
</div>
|
|
303
|
+
);
|
|
304
|
+
},
|
|
284
305
|
tags: ["visual:check"],
|
|
285
306
|
};
|
package/src/tabs.tsx
CHANGED
|
@@ -112,7 +112,7 @@ export const Tabs: TabsCmp<TabsProps> = ({
|
|
|
112
112
|
const classNames = cx(
|
|
113
113
|
rootClassName,
|
|
114
114
|
`${rootClassName}--${variant}${negative ? "-negative" : ""}`,
|
|
115
|
-
{ [`${rootClassName}--
|
|
115
|
+
{ [`${rootClassName}--full-width`]: fullWidth },
|
|
116
116
|
className
|
|
117
117
|
);
|
|
118
118
|
|
|
@@ -271,6 +271,7 @@ export const Tabs: TabsCmp<TabsProps> = ({
|
|
|
271
271
|
}}
|
|
272
272
|
variant={variant}
|
|
273
273
|
negative={negative}
|
|
274
|
+
fullWidth={fullWidth}
|
|
274
275
|
>
|
|
275
276
|
{name}
|
|
276
277
|
</TabHeader>
|