@navikt/ds-react 5.4.1 → 5.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/_docs.json +650 -454
- package/cjs/index.js +1 -0
- package/cjs/layout/box/Box.js +84 -0
- package/cjs/layout/box/index.js +5 -0
- package/cjs/layout/box/package.json +6 -0
- package/cjs/layout/utilities/css.js +21 -13
- package/cjs/layout/utilities/types.js +2 -0
- package/cjs/skeleton/Skeleton.js +1 -0
- package/esm/index.d.ts +1 -0
- package/esm/index.js +1 -0
- package/esm/index.js.map +1 -1
- package/esm/layout/box/Box.d.ts +78 -0
- package/esm/layout/box/Box.js +56 -0
- package/esm/layout/box/Box.js.map +1 -0
- package/esm/layout/box/index.d.ts +1 -0
- package/esm/layout/box/index.js +2 -0
- package/esm/layout/box/index.js.map +1 -0
- package/esm/layout/utilities/css.d.ts +7 -7
- package/esm/layout/utilities/css.js +18 -10
- package/esm/layout/utilities/css.js.map +1 -1
- package/esm/layout/utilities/types.d.ts +9 -0
- package/esm/layout/utilities/types.js +2 -0
- package/esm/layout/utilities/types.js.map +1 -0
- package/esm/skeleton/Skeleton.js +1 -0
- package/esm/skeleton/Skeleton.js.map +1 -1
- package/package.json +3 -2
- package/src/grid/grid.stories.tsx +1 -1
- package/src/index.ts +1 -0
- package/src/layout/box/Box.stories.tsx +384 -0
- package/src/layout/box/Box.tsx +148 -0
- package/src/layout/box/index.ts +1 -0
- package/src/layout/grid/h-grid.stories.tsx +1 -1
- package/src/layout/responsive/hide.stories.tsx +1 -1
- package/src/layout/responsive/show.stories.tsx +1 -1
- package/src/layout/stack/stack.stories.tsx +1 -1
- package/src/layout/utilities/css.ts +34 -16
- package/src/layout/utilities/types.ts +14 -0
- package/src/skeleton/Skeleton.tsx +1 -0
- package/src/skeleton/skeleton.stories.tsx +4 -3
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
import React, { ReactNode } from "react";
|
|
2
|
+
import type { Meta } from "@storybook/react";
|
|
3
|
+
import { BodyLong, Detail, Heading } from "../../typography";
|
|
4
|
+
import { Box } from "./Box";
|
|
5
|
+
import { HGrid, HStack, VStack } from "../..";
|
|
6
|
+
import { BackgroundToken, BorderRadiiToken } from "../utilities/types";
|
|
7
|
+
import { ChevronRightIcon } from "@navikt/aksel-icons";
|
|
8
|
+
|
|
9
|
+
export default {
|
|
10
|
+
title: "ds-react/Primitives/Box",
|
|
11
|
+
component: Box,
|
|
12
|
+
} satisfies Meta<typeof Box>;
|
|
13
|
+
|
|
14
|
+
export const Default = {
|
|
15
|
+
render: () => (
|
|
16
|
+
<Box>
|
|
17
|
+
<BodyLong>
|
|
18
|
+
This is inside a box. Deserunt veniam eu fugiat ad est occaecat aliqua
|
|
19
|
+
nisi aliquip. Aute amet occaecat ex aliqua irure elit labore pariatur.
|
|
20
|
+
Proident pariatur proident pariatur magna consequat velit id commodo
|
|
21
|
+
quis sunt tempor ullamco aliquip pariatur.
|
|
22
|
+
</BodyLong>
|
|
23
|
+
</Box>
|
|
24
|
+
),
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const Card = ({
|
|
28
|
+
background,
|
|
29
|
+
borderRadius = "xlarge",
|
|
30
|
+
children,
|
|
31
|
+
}: {
|
|
32
|
+
background?: BackgroundToken;
|
|
33
|
+
borderRadius?: BorderRadiiToken;
|
|
34
|
+
children: ReactNode;
|
|
35
|
+
}) => (
|
|
36
|
+
<Box
|
|
37
|
+
padding="4"
|
|
38
|
+
background={background}
|
|
39
|
+
borderColor="border-subtle"
|
|
40
|
+
borderRadius={borderRadius}
|
|
41
|
+
shadow="xsmall"
|
|
42
|
+
>
|
|
43
|
+
<div style={{ width: "20rem" }}>{children}</div>
|
|
44
|
+
</Box>
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
export const AsCard = {
|
|
48
|
+
render: () => {
|
|
49
|
+
return (
|
|
50
|
+
<HStack gap="4" justify="center">
|
|
51
|
+
<Card>
|
|
52
|
+
<h1>Card one</h1>
|
|
53
|
+
<BodyLong>
|
|
54
|
+
This is inside a box. Deserunt veniam eu fugiat ad est occaecat
|
|
55
|
+
aliqua nisi aliquip. Aute amet occaecat ex aliqua irure elit labore
|
|
56
|
+
</BodyLong>
|
|
57
|
+
</Card>
|
|
58
|
+
<Card>
|
|
59
|
+
<h1>Card two</h1>
|
|
60
|
+
<BodyLong>
|
|
61
|
+
This is inside a box. Deserunt veniam eu fugiat ad est occaecat
|
|
62
|
+
aliqua nisi aliquip. Aute amet occaecat ex aliqua irure elit labore
|
|
63
|
+
</BodyLong>
|
|
64
|
+
</Card>
|
|
65
|
+
<Card>
|
|
66
|
+
<h1>Card three</h1>
|
|
67
|
+
<BodyLong>
|
|
68
|
+
This is inside a box. Deserunt veniam eu fugiat ad est occaecat
|
|
69
|
+
aliqua nisi aliquip. Aute amet occaecat ex aliqua irure elit labore
|
|
70
|
+
</BodyLong>
|
|
71
|
+
</Card>
|
|
72
|
+
</HStack>
|
|
73
|
+
);
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export const ThemingDemo = {
|
|
78
|
+
render: () => {
|
|
79
|
+
const LinkCard = () => {
|
|
80
|
+
return (
|
|
81
|
+
<>
|
|
82
|
+
<style>
|
|
83
|
+
{`
|
|
84
|
+
.link-card {
|
|
85
|
+
color: var(--navds-color-text-primary);
|
|
86
|
+
text-decoration: none;
|
|
87
|
+
}
|
|
88
|
+
.link-card:hover {
|
|
89
|
+
border-color: var(--a-border-action);
|
|
90
|
+
box-shadow: var(--a-shadow-small);
|
|
91
|
+
}
|
|
92
|
+
.link-card:hover .navds-heading {
|
|
93
|
+
color: var(--a-text-action);
|
|
94
|
+
text-decoration: underline;
|
|
95
|
+
}
|
|
96
|
+
.link-card:hover .link-card__chevron,
|
|
97
|
+
.link-card:focus-within .link-card__chevron {
|
|
98
|
+
transform: translateX(4px);
|
|
99
|
+
}
|
|
100
|
+
.link-card__chevron {
|
|
101
|
+
flex-shrink: 0;
|
|
102
|
+
font-size: 1.5rem;
|
|
103
|
+
transition: transform 200ms;
|
|
104
|
+
}
|
|
105
|
+
`}
|
|
106
|
+
</style>
|
|
107
|
+
<Box
|
|
108
|
+
as="a"
|
|
109
|
+
href="#"
|
|
110
|
+
className="link-card"
|
|
111
|
+
borderRadius="small"
|
|
112
|
+
borderColor="border-default"
|
|
113
|
+
padding="4"
|
|
114
|
+
onClick={() => alert("Clicked!")}
|
|
115
|
+
>
|
|
116
|
+
<HStack gap="4" align="center">
|
|
117
|
+
<VStack gap="2">
|
|
118
|
+
<Heading size="medium">
|
|
119
|
+
LinkCard som bruker Box, HStack og VStack
|
|
120
|
+
</Heading>
|
|
121
|
+
<BodyLong>This truly is inside a box!</BodyLong>
|
|
122
|
+
</VStack>
|
|
123
|
+
<ChevronRightIcon fontSize={24} className="link-card__chevron" />
|
|
124
|
+
</HStack>
|
|
125
|
+
</Box>
|
|
126
|
+
</>
|
|
127
|
+
);
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
const ChatBubble = () => {
|
|
131
|
+
return (
|
|
132
|
+
<>
|
|
133
|
+
<Box
|
|
134
|
+
background="surface-neutral-subtle"
|
|
135
|
+
shadow="xsmall"
|
|
136
|
+
padding="4"
|
|
137
|
+
borderRadius="xlarge xlarge xlarge 0"
|
|
138
|
+
>
|
|
139
|
+
<VStack gap="2">
|
|
140
|
+
<Detail>BOX • 01.01.21 14:00</Detail>
|
|
141
|
+
<BodyLong>
|
|
142
|
+
Hei! Dette er en chatbobble som bruker Box som base!
|
|
143
|
+
</BodyLong>
|
|
144
|
+
</VStack>
|
|
145
|
+
</Box>
|
|
146
|
+
</>
|
|
147
|
+
);
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
const PricePill = () => {
|
|
151
|
+
return (
|
|
152
|
+
<>
|
|
153
|
+
<style>
|
|
154
|
+
{`
|
|
155
|
+
.old-price {
|
|
156
|
+
text-decoration: line-through;
|
|
157
|
+
}
|
|
158
|
+
`}
|
|
159
|
+
</style>
|
|
160
|
+
<HStack>
|
|
161
|
+
<Box
|
|
162
|
+
background="surface-success-subtle"
|
|
163
|
+
shadow="xsmall"
|
|
164
|
+
padding="4"
|
|
165
|
+
borderRadius="full 0 0 full"
|
|
166
|
+
>
|
|
167
|
+
<VStack align="center">
|
|
168
|
+
<Detail>Episk ny pris</Detail>
|
|
169
|
+
<Heading size="medium">889.99 kr</Heading>
|
|
170
|
+
</VStack>
|
|
171
|
+
</Box>
|
|
172
|
+
<Box
|
|
173
|
+
background="surface-danger-subtle"
|
|
174
|
+
shadow="xsmall"
|
|
175
|
+
padding="4"
|
|
176
|
+
borderRadius="0 full full 0"
|
|
177
|
+
>
|
|
178
|
+
<VStack align="center">
|
|
179
|
+
<Detail>Førpris</Detail>
|
|
180
|
+
<Heading className="old-price" size="medium">
|
|
181
|
+
399.99 kr
|
|
182
|
+
</Heading>
|
|
183
|
+
</VStack>
|
|
184
|
+
</Box>
|
|
185
|
+
</HStack>
|
|
186
|
+
</>
|
|
187
|
+
);
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
return (
|
|
191
|
+
<VStack gap="8">
|
|
192
|
+
<Card>Dette er et Card som bruker Box som base</Card>
|
|
193
|
+
<LinkCard />
|
|
194
|
+
<ChatBubble />
|
|
195
|
+
<PricePill />
|
|
196
|
+
</VStack>
|
|
197
|
+
);
|
|
198
|
+
},
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
export const PaddingBreakpoints = {
|
|
202
|
+
render: () => (
|
|
203
|
+
<div>
|
|
204
|
+
<Box
|
|
205
|
+
padding={{ xs: "2", sm: "3", md: "4", lg: "5", xl: "6" }}
|
|
206
|
+
borderColor="border-default"
|
|
207
|
+
>
|
|
208
|
+
<BodyLong>
|
|
209
|
+
This is inside a box. Deserunt veniam eu fugiat ad est occaecat aliqua
|
|
210
|
+
nisi aliquip. Aute amet occaecat ex aliqua irure elit labore pariatur.
|
|
211
|
+
Proident pariatur proident pariatur magna consequat velit id commodo
|
|
212
|
+
quis sunt tempor ullamco aliquip pariatur.
|
|
213
|
+
</BodyLong>
|
|
214
|
+
</Box>
|
|
215
|
+
</div>
|
|
216
|
+
),
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
export const PaddingBreakpointsInherit1 = {
|
|
220
|
+
render: () => (
|
|
221
|
+
<div>
|
|
222
|
+
<Box
|
|
223
|
+
padding={{ xs: "2" }}
|
|
224
|
+
paddingInline={{ md: "24 0" }}
|
|
225
|
+
borderColor="border-default"
|
|
226
|
+
>
|
|
227
|
+
<BodyLong>
|
|
228
|
+
This is inside a box. Deserunt veniam eu fugiat ad est occaecat aliqua
|
|
229
|
+
nisi aliquip. Aute amet occaecat ex aliqua irure elit labore pariatur.
|
|
230
|
+
Proident pariatur proident pariatur magna consequat velit id commodo
|
|
231
|
+
quis sunt tempor ullamco aliquip pariatur.
|
|
232
|
+
</BodyLong>
|
|
233
|
+
</Box>
|
|
234
|
+
</div>
|
|
235
|
+
),
|
|
236
|
+
};
|
|
237
|
+
export const PaddingBreakpointsInherit2 = {
|
|
238
|
+
render: () => (
|
|
239
|
+
<div>
|
|
240
|
+
<Box
|
|
241
|
+
padding={{ xs: "2", sm: "3" }}
|
|
242
|
+
paddingInline={{ sm: "4 0", md: "24 0" }}
|
|
243
|
+
borderColor="border-default"
|
|
244
|
+
>
|
|
245
|
+
<BodyLong>
|
|
246
|
+
This is inside a box. Deserunt veniam eu fugiat ad est occaecat aliqua
|
|
247
|
+
nisi aliquip. Aute amet occaecat ex aliqua irure elit labore pariatur.
|
|
248
|
+
Proident pariatur proident pariatur magna consequat velit id commodo
|
|
249
|
+
quis sunt tempor ullamco aliquip pariatur.
|
|
250
|
+
</BodyLong>
|
|
251
|
+
</Box>
|
|
252
|
+
</div>
|
|
253
|
+
),
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
export const Padding = {
|
|
257
|
+
render: () => (
|
|
258
|
+
<>
|
|
259
|
+
<style>
|
|
260
|
+
{`
|
|
261
|
+
.navds-box {
|
|
262
|
+
width: fit-content;
|
|
263
|
+
}
|
|
264
|
+
`}
|
|
265
|
+
</style>
|
|
266
|
+
<VStack align="center">
|
|
267
|
+
<Box padding="20" borderColor="border-default">
|
|
268
|
+
<BodyLong>Padding all around</BodyLong>
|
|
269
|
+
</Box>
|
|
270
|
+
<Box padding="1" paddingBlock="20 0" borderColor="border-default">
|
|
271
|
+
<BodyLong>Padding to the North</BodyLong>
|
|
272
|
+
</Box>
|
|
273
|
+
<Box padding="1" paddingInline="0 20" borderColor="border-default">
|
|
274
|
+
<BodyLong>Padding to the East</BodyLong>
|
|
275
|
+
</Box>
|
|
276
|
+
<Box padding="1" paddingBlock="0 20" borderColor="border-default">
|
|
277
|
+
<BodyLong>Padding to the South</BodyLong>
|
|
278
|
+
</Box>
|
|
279
|
+
<Box padding="1" paddingInline="20 0" borderColor="border-default">
|
|
280
|
+
<BodyLong>Padding to the West</BodyLong>
|
|
281
|
+
</Box>
|
|
282
|
+
</VStack>
|
|
283
|
+
</>
|
|
284
|
+
),
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
export const WithHGrid = () => {
|
|
288
|
+
return (
|
|
289
|
+
<Box background="bg-subtle" padding="10">
|
|
290
|
+
<HGrid
|
|
291
|
+
gap="6"
|
|
292
|
+
columns={{ xs: "repeat(auto-fit, minmax(10rem, 1fr))", md: 4 }}
|
|
293
|
+
>
|
|
294
|
+
<Box padding="4" background="bg-default">
|
|
295
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec
|
|
296
|
+
</Box>
|
|
297
|
+
<Box padding="4" background="bg-default">
|
|
298
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec
|
|
299
|
+
</Box>
|
|
300
|
+
<Box padding="4" background="bg-default">
|
|
301
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec
|
|
302
|
+
</Box>
|
|
303
|
+
<Box padding="4" background="bg-default">
|
|
304
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec
|
|
305
|
+
</Box>
|
|
306
|
+
</HGrid>
|
|
307
|
+
</Box>
|
|
308
|
+
);
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
export const BorderWidth = () => {
|
|
312
|
+
return (
|
|
313
|
+
<VStack gap="4">
|
|
314
|
+
<Box
|
|
315
|
+
background="bg-subtle"
|
|
316
|
+
padding="10"
|
|
317
|
+
borderWidth="2"
|
|
318
|
+
borderColor="border-strong"
|
|
319
|
+
>
|
|
320
|
+
Box
|
|
321
|
+
</Box>
|
|
322
|
+
<Box
|
|
323
|
+
background="bg-subtle"
|
|
324
|
+
padding="10"
|
|
325
|
+
borderWidth="1 2 3 4"
|
|
326
|
+
borderColor="border-strong"
|
|
327
|
+
>
|
|
328
|
+
Box
|
|
329
|
+
</Box>
|
|
330
|
+
<Box
|
|
331
|
+
background="bg-subtle"
|
|
332
|
+
padding="10"
|
|
333
|
+
borderWidth="5 2 4 1"
|
|
334
|
+
borderColor="border-strong"
|
|
335
|
+
borderRadius="large"
|
|
336
|
+
>
|
|
337
|
+
Box
|
|
338
|
+
</Box>
|
|
339
|
+
</VStack>
|
|
340
|
+
);
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
export const BorderRadius = () => {
|
|
344
|
+
return (
|
|
345
|
+
<VStack gap="4">
|
|
346
|
+
<Box
|
|
347
|
+
background="bg-subtle"
|
|
348
|
+
padding="10"
|
|
349
|
+
borderWidth="2"
|
|
350
|
+
borderColor="border-strong"
|
|
351
|
+
borderRadius="small medium large xlarge"
|
|
352
|
+
>
|
|
353
|
+
Box
|
|
354
|
+
</Box>
|
|
355
|
+
<Box
|
|
356
|
+
background="bg-subtle"
|
|
357
|
+
padding="10"
|
|
358
|
+
borderWidth="2"
|
|
359
|
+
borderColor="border-strong"
|
|
360
|
+
borderRadius={{
|
|
361
|
+
xs: "small medium large xlarge",
|
|
362
|
+
md: "medium small large full",
|
|
363
|
+
lg: "xlarge large",
|
|
364
|
+
}}
|
|
365
|
+
>
|
|
366
|
+
Box
|
|
367
|
+
</Box>
|
|
368
|
+
</VStack>
|
|
369
|
+
);
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
export const PaddingDemo = () => {
|
|
373
|
+
return (
|
|
374
|
+
<VStack gap="4">
|
|
375
|
+
<Box
|
|
376
|
+
background="bg-subtle"
|
|
377
|
+
padding="0"
|
|
378
|
+
paddingInline={{ xs: "20", lg: "10" }}
|
|
379
|
+
>
|
|
380
|
+
Box
|
|
381
|
+
</Box>
|
|
382
|
+
</VStack>
|
|
383
|
+
);
|
|
384
|
+
};
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import cl from "clsx";
|
|
2
|
+
import React, { forwardRef } from "react";
|
|
3
|
+
import { OverridableComponent } from "../../util/OverridableComponent";
|
|
4
|
+
import { BorderRadiiToken } from "../utilities/types";
|
|
5
|
+
import {
|
|
6
|
+
SpaceDelimitedAttribute,
|
|
7
|
+
ResponsiveProp,
|
|
8
|
+
SpacingScale,
|
|
9
|
+
getResponsiveProps,
|
|
10
|
+
} from "../utilities/css";
|
|
11
|
+
import {
|
|
12
|
+
BackgroundToken,
|
|
13
|
+
BorderColorToken,
|
|
14
|
+
ShadowToken,
|
|
15
|
+
} from "../utilities/types";
|
|
16
|
+
|
|
17
|
+
export interface BoxProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
18
|
+
/** Background color. Accepts a color token. */
|
|
19
|
+
background?: BackgroundToken;
|
|
20
|
+
/** Border color. Accepts a color token. */
|
|
21
|
+
borderColor?: BorderColorToken;
|
|
22
|
+
/** Border radius. Accepts a radius token, or an object of radius tokens for different breakpoints.
|
|
23
|
+
* @example
|
|
24
|
+
* borderRadius='full'
|
|
25
|
+
* borderRadius='0 full large small'
|
|
26
|
+
* borderRadius={{xs: 'small large', sm: '0', md: 'large', lg: 'full'}}
|
|
27
|
+
*/
|
|
28
|
+
borderRadius?: ResponsiveProp<SpaceDelimitedAttribute<BorderRadiiToken>>;
|
|
29
|
+
/**
|
|
30
|
+
* Border-width. If this is not set there will be no border.
|
|
31
|
+
* @example
|
|
32
|
+
* borderWidth='2'
|
|
33
|
+
* borderWidth='1 2 3 4'
|
|
34
|
+
*/
|
|
35
|
+
borderWidth?: SpaceDelimitedAttribute<"0" | "1" | "2" | "3" | "4" | "5">;
|
|
36
|
+
/** Spacing around children. Accepts a spacing token or an object of spacing tokens for different breakpoints.
|
|
37
|
+
* @example
|
|
38
|
+
* padding='4'
|
|
39
|
+
* padding={{xs: '2', sm: '3', md: '4', lg: '5', xl: '6'}}
|
|
40
|
+
*/
|
|
41
|
+
padding?: ResponsiveProp<SpacingScale>;
|
|
42
|
+
/** Horizontal padding around children. Accepts a spacing token or an object of spacing tokens for different breakpoints.
|
|
43
|
+
* @example
|
|
44
|
+
* paddingInline='4'
|
|
45
|
+
* paddingInline='4 5'
|
|
46
|
+
* paddingInline={{xs: '0 32', sm: '3', md: '4 5', lg: '5', xl: '6'}}
|
|
47
|
+
*/
|
|
48
|
+
paddingInline?: ResponsiveProp<
|
|
49
|
+
SpacingScale | `${SpacingScale} ${SpacingScale}`
|
|
50
|
+
>;
|
|
51
|
+
/** Vertical padding around children. Accepts a spacing token or an object of spacing tokens for different breakpoints.
|
|
52
|
+
* @example
|
|
53
|
+
* paddingBlock='4'
|
|
54
|
+
* paddingBlock='4 5'
|
|
55
|
+
* paddingBlock={{xs: '2', sm: '3', md: '4', lg: '5', xl: '6'}}
|
|
56
|
+
*/
|
|
57
|
+
paddingBlock?: ResponsiveProp<
|
|
58
|
+
SpacingScale | `${SpacingScale} ${SpacingScale}`
|
|
59
|
+
>;
|
|
60
|
+
/** Shadow on box. Accepts a shadow token.
|
|
61
|
+
* @example
|
|
62
|
+
* shadow='small'
|
|
63
|
+
*/
|
|
64
|
+
shadow?: ShadowToken;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Foundational Layout-primitive for generic encapsulation & styling.
|
|
69
|
+
*
|
|
70
|
+
* @see [📝 Documentation](https://aksel.nav.no/komponenter/primitives/box)
|
|
71
|
+
* @see 🏷️ {@link BoxProps}
|
|
72
|
+
* @see [🤖 OverridableComponent](https://aksel.nav.no/grunnleggende/kode/overridablecomponent) support
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* <Box padding="4">
|
|
76
|
+
* <BodyShort>Hei</BodyShort>
|
|
77
|
+
* </Box>
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* <Box padding={{xs: '2', sm: '3', md: '4', lg: '5', xl: '6'}}>
|
|
81
|
+
* <BodyShort>Hei</BodyShort>
|
|
82
|
+
* </Box>
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* <VStack gap="8">
|
|
86
|
+
* <Box padding="4">
|
|
87
|
+
* <BodyShort>Hei</BodyShort>
|
|
88
|
+
* </Box>
|
|
89
|
+
* <Box padding="4">
|
|
90
|
+
* <BodyShort>Hei</BodyShort>
|
|
91
|
+
* </Box>
|
|
92
|
+
* </VStack>
|
|
93
|
+
*/
|
|
94
|
+
export const Box: OverridableComponent<BoxProps, HTMLDivElement> = forwardRef(
|
|
95
|
+
(
|
|
96
|
+
{
|
|
97
|
+
as: Component = "div",
|
|
98
|
+
background,
|
|
99
|
+
borderColor,
|
|
100
|
+
borderWidth,
|
|
101
|
+
borderRadius,
|
|
102
|
+
className,
|
|
103
|
+
padding,
|
|
104
|
+
paddingInline,
|
|
105
|
+
paddingBlock,
|
|
106
|
+
shadow,
|
|
107
|
+
style: _style,
|
|
108
|
+
...rest
|
|
109
|
+
},
|
|
110
|
+
ref
|
|
111
|
+
) => {
|
|
112
|
+
const style: React.CSSProperties = {
|
|
113
|
+
..._style,
|
|
114
|
+
"--__ac-box-background": background
|
|
115
|
+
? `var(--a-${background})`
|
|
116
|
+
: undefined,
|
|
117
|
+
"--__ac-box-shadow": shadow ? `var(--a-shadow-${shadow})` : undefined,
|
|
118
|
+
"--__ac-box-border-color": borderColor
|
|
119
|
+
? `var(--a-${borderColor})`
|
|
120
|
+
: undefined,
|
|
121
|
+
"--__ac-box-border-width": borderWidth
|
|
122
|
+
? borderWidth
|
|
123
|
+
.split(" ")
|
|
124
|
+
.map((x) => `${x}px`)
|
|
125
|
+
.join(" ")
|
|
126
|
+
: undefined,
|
|
127
|
+
...getResponsiveProps(
|
|
128
|
+
"box",
|
|
129
|
+
"border-radius",
|
|
130
|
+
"border-radius",
|
|
131
|
+
borderRadius,
|
|
132
|
+
["0"]
|
|
133
|
+
),
|
|
134
|
+
...getResponsiveProps("box", "padding", "spacing", padding),
|
|
135
|
+
...getResponsiveProps("box", "padding-inline", "spacing", paddingInline),
|
|
136
|
+
...getResponsiveProps("box", "padding-block", "spacing", paddingBlock),
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
return (
|
|
140
|
+
<Component
|
|
141
|
+
{...rest}
|
|
142
|
+
className={cl("navds-box", className)}
|
|
143
|
+
ref={ref}
|
|
144
|
+
style={style}
|
|
145
|
+
/>
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Box, type BoxProps } from "./Box";
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export type BreakpointsAlias = "xs" | "sm" | "md" | "lg" | "xl";
|
|
2
|
+
|
|
2
3
|
export type SpacingScale =
|
|
3
4
|
| "0"
|
|
4
5
|
| "05"
|
|
@@ -21,19 +22,22 @@ export type SpacingScale =
|
|
|
21
22
|
| "24"
|
|
22
23
|
| "32";
|
|
23
24
|
|
|
24
|
-
type
|
|
25
|
+
export type SpaceDelimitedAttribute<T extends string> =
|
|
26
|
+
| T
|
|
27
|
+
| `${T} ${T}`
|
|
28
|
+
| `${T} ${T} ${T}`
|
|
29
|
+
| `${T} ${T} ${T} ${T}`;
|
|
30
|
+
|
|
31
|
+
type FixedResponsiveT<T> = {
|
|
25
32
|
// eslint-disable-next-line no-unused-vars
|
|
26
33
|
[Breakpoint in BreakpointsAlias]?: T;
|
|
27
34
|
};
|
|
28
35
|
|
|
29
|
-
export type ResponsiveProp<T> = T |
|
|
36
|
+
export type ResponsiveProp<T> = T | FixedResponsiveT<T>;
|
|
30
37
|
|
|
31
|
-
export
|
|
32
|
-
|
|
33
|
-
export function getResponsiveProps<T = string>(
|
|
38
|
+
export function getResponsiveValue<T = string>(
|
|
34
39
|
componentName: string,
|
|
35
40
|
componentProp: string,
|
|
36
|
-
tokenSubgroup: string,
|
|
37
41
|
responsiveProp?: ResponsiveProp<T>
|
|
38
42
|
) {
|
|
39
43
|
if (!responsiveProp) {
|
|
@@ -42,22 +46,24 @@ export function getResponsiveProps<T = string>(
|
|
|
42
46
|
|
|
43
47
|
if (typeof responsiveProp === "string") {
|
|
44
48
|
return {
|
|
45
|
-
[`--__ac-${componentName}-${componentProp}-xs`]:
|
|
49
|
+
[`--__ac-${componentName}-${componentProp}-xs`]: responsiveProp,
|
|
46
50
|
};
|
|
47
51
|
}
|
|
48
52
|
|
|
49
53
|
return Object.fromEntries(
|
|
50
|
-
Object.entries(responsiveProp).map(([breakpointAlias,
|
|
54
|
+
Object.entries(responsiveProp).map(([breakpointAlias, responsiveValue]) => [
|
|
51
55
|
`--__ac-${componentName}-${componentProp}-${breakpointAlias}`,
|
|
52
|
-
|
|
56
|
+
responsiveValue,
|
|
53
57
|
])
|
|
54
58
|
);
|
|
55
59
|
}
|
|
56
60
|
|
|
57
|
-
export function
|
|
61
|
+
export function getResponsiveProps<T extends string>(
|
|
58
62
|
componentName: string,
|
|
59
63
|
componentProp: string,
|
|
60
|
-
|
|
64
|
+
tokenSubgroup: string,
|
|
65
|
+
responsiveProp?: ResponsiveProp<T>,
|
|
66
|
+
tokenExceptions: string[] = []
|
|
61
67
|
) {
|
|
62
68
|
if (!responsiveProp) {
|
|
63
69
|
return {};
|
|
@@ -65,14 +71,26 @@ export function getResponsiveValue<T = string>(
|
|
|
65
71
|
|
|
66
72
|
if (typeof responsiveProp === "string") {
|
|
67
73
|
return {
|
|
68
|
-
[`--__ac-${componentName}-${componentProp}-xs`]: responsiveProp
|
|
74
|
+
[`--__ac-${componentName}-${componentProp}-xs`]: responsiveProp
|
|
75
|
+
.split(" ")
|
|
76
|
+
.map((x) =>
|
|
77
|
+
tokenExceptions.includes(x) ? x : `var(--a-${tokenSubgroup}-${x})`
|
|
78
|
+
)
|
|
79
|
+
.join(" "),
|
|
69
80
|
};
|
|
70
81
|
}
|
|
71
82
|
|
|
72
83
|
return Object.fromEntries(
|
|
73
|
-
Object.entries(responsiveProp).map(([breakpointAlias,
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
84
|
+
Object.entries(responsiveProp).map(([breakpointAlias, aliasOrScale]) => {
|
|
85
|
+
return [
|
|
86
|
+
`--__ac-${componentName}-${componentProp}-${breakpointAlias}`,
|
|
87
|
+
aliasOrScale
|
|
88
|
+
.split(" ")
|
|
89
|
+
.map((x) =>
|
|
90
|
+
tokenExceptions.includes(x) ? x : `var(--a-${tokenSubgroup}-${x})`
|
|
91
|
+
)
|
|
92
|
+
.join(" "),
|
|
93
|
+
];
|
|
94
|
+
})
|
|
77
95
|
);
|
|
78
96
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import bgColors from "@navikt/ds-tokens/src/colors-bg.json";
|
|
2
|
+
import surfaceColors from "@navikt/ds-tokens/src/colors-surface.json";
|
|
3
|
+
import borderColors from "@navikt/ds-tokens/src/colors-border.json";
|
|
4
|
+
import borderRadii from "@navikt/ds-tokens/src/border.json";
|
|
5
|
+
import shadows from "@navikt/ds-tokens/src/shadow.json";
|
|
6
|
+
|
|
7
|
+
export type BackgroundToken =
|
|
8
|
+
| keyof typeof bgColors.a
|
|
9
|
+
| keyof typeof surfaceColors.a;
|
|
10
|
+
export type BorderColorToken = keyof typeof borderColors.a;
|
|
11
|
+
export type BorderRadiiToken =
|
|
12
|
+
| keyof (typeof borderRadii.a)["border-radius"]
|
|
13
|
+
| "0";
|
|
14
|
+
export type ShadowToken = keyof typeof shadows.a.shadow;
|
|
@@ -57,6 +57,7 @@ export const Skeleton = forwardRef<HTMLDivElement, SkeletonProps>(
|
|
|
57
57
|
"navds-skeleton--has-children": Boolean(children),
|
|
58
58
|
"navds-skeleton--no-height": !height,
|
|
59
59
|
"navds-skeleton--no-width": !width,
|
|
60
|
+
"navds-skeleton--inline": As === "span",
|
|
60
61
|
}
|
|
61
62
|
)}
|
|
62
63
|
style={{ ...style, width, height }}
|