@kwtv/components 0.2.0 → 0.4.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 +52 -9
- package/package.json +2 -2
- package/src/astro/Accordion.astro +10 -6
- package/src/astro/AccordionItem.astro +55 -45
- package/src/astro/ActiveFilterTags.astro +41 -28
- package/src/astro/Alert.astro +45 -41
- package/src/astro/Badge.astro +80 -76
- package/src/astro/Band.astro +104 -58
- package/src/astro/Breadcrumb.astro +38 -30
- package/src/astro/Button.astro +135 -129
- package/src/astro/Card.astro +72 -62
- package/src/astro/CartLine.astro +72 -58
- package/src/astro/Checkbox.astro +36 -32
- package/src/astro/Chip.astro +68 -64
- package/src/astro/ChipRail.astro +6 -1
- package/src/astro/DotGrid.astro +55 -42
- package/src/astro/EmptyState.astro +29 -23
- package/src/astro/FilterGroup.astro +29 -26
- package/src/astro/Filters.astro +57 -47
- package/src/astro/Footer.astro +195 -178
- package/src/astro/FooterColumn.astro +39 -35
- package/src/astro/Header.astro +80 -67
- package/src/astro/Icon.astro +4 -2
- package/src/astro/IconButton.astro +67 -61
- package/src/astro/Marquee.astro +43 -41
- package/src/astro/NavDropdown.astro +169 -149
- package/src/astro/NavLink.astro +59 -56
- package/src/astro/Newsletter.astro +64 -56
- package/src/astro/Pager.astro +71 -46
- package/src/astro/PickCard.astro +72 -68
- package/src/astro/ProductCard.astro +134 -119
- package/src/astro/Radio.astro +36 -32
- package/src/astro/Skeleton.astro +60 -42
- package/src/astro/Social.astro +26 -21
- package/src/astro/StepIndicator.astro +70 -54
- package/src/astro/Sticker.astro +74 -49
- package/src/astro/Swatch.astro +44 -40
- package/src/astro/SwipeCarousel.astro +5 -1
- package/src/astro/Table.astro +66 -56
- package/src/astro/TableCard.astro +45 -37
- package/src/astro/TextField.astro +104 -91
- package/src/astro/Totals.astro +39 -35
- package/src/react/Drawer.css +60 -56
- package/src/react/Drawer.tsx +1 -5
- package/src/react/Modal.css +97 -93
- package/src/react/Modal.tsx +4 -6
- package/src/react/NewsCarousel.css +108 -104
- package/src/react/NewsCarousel.tsx +7 -1
- package/src/react/QuantityStepper.css +84 -80
- package/src/react/Select.css +159 -155
- package/src/react/Select.tsx +8 -2
- package/src/react/Toast.css +128 -124
- package/src/react/Toast.tsx +38 -4
- package/src/styles/base.css +30 -26
- package/src/styles/controls.css +183 -179
- package/src/styles/motion.css +203 -199
package/README.md
CHANGED
|
@@ -7,13 +7,13 @@ there is no separate library build or consumer alias configuration.
|
|
|
7
7
|
|
|
8
8
|
## What ships
|
|
9
9
|
|
|
10
|
-
| Path
|
|
11
|
-
|
|
|
12
|
-
| `src/astro/*.astro`
|
|
13
|
-
| `src/react/*.tsx`
|
|
14
|
-
| `src/styles/base.css`
|
|
15
|
-
| `src/styles/controls.css` | Button and icon-button styles for React islands that render the `ui-btn` / `ui-iconbtn` classes.
|
|
16
|
-
| `src/styles/motion.css`
|
|
10
|
+
| Path | What it is |
|
|
11
|
+
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
12
|
+
| `src/astro/*.astro` | Static components. Scoped styles, no client JS. |
|
|
13
|
+
| `src/react/*.tsx` | Interactive islands. Select, Modal, Toast, Drawer, QuantityStepper, NewsCarousel. |
|
|
14
|
+
| `src/styles/base.css` | The shared primitives the React islands import: focus ring, touch targets, screen-reader helper. Astro components carry their own scoped styles. |
|
|
15
|
+
| `src/styles/controls.css` | Button and icon-button styles for React islands that render the `ui-btn` / `ui-iconbtn` classes. |
|
|
16
|
+
| `src/styles/motion.css` | The `pl-` motion layer: lift, underline, arrow and row nudges, rise, marquee, chip rail and swipe carousel. |
|
|
17
17
|
|
|
18
18
|
## Install
|
|
19
19
|
|
|
@@ -31,7 +31,10 @@ in your app root, then use the components.
|
|
|
31
31
|
import "@kwtv/tokens/tokens.css";
|
|
32
32
|
import Button from "@kwtv/components/astro/Button.astro";
|
|
33
33
|
---
|
|
34
|
-
|
|
34
|
+
|
|
35
|
+
<Button variant="primary" size="md">
|
|
36
|
+
In de winkelwagen
|
|
37
|
+
</Button>
|
|
35
38
|
```
|
|
36
39
|
|
|
37
40
|
To use React islands, add Astro's React integration if the app does not
|
|
@@ -51,7 +54,12 @@ Then import an island:
|
|
|
51
54
|
---
|
|
52
55
|
import Select from "@kwtv/components/react/Select.tsx";
|
|
53
56
|
---
|
|
54
|
-
|
|
57
|
+
|
|
58
|
+
<Select
|
|
59
|
+
client:load
|
|
60
|
+
label="Groep"
|
|
61
|
+
options={[{ value: "r1", label: "Recreatief 8–10 jaar" }]}
|
|
62
|
+
/>
|
|
55
63
|
```
|
|
56
64
|
|
|
57
65
|
The React islands need their shared stylesheets once in the app. Import
|
|
@@ -63,6 +71,41 @@ import "@kwtv/components/styles/base.css";
|
|
|
63
71
|
import "@kwtv/components/styles/controls.css";
|
|
64
72
|
```
|
|
65
73
|
|
|
74
|
+
## Cascade layers
|
|
75
|
+
|
|
76
|
+
Every stylesheet in this package and in `@kwtv/tokens` sits in a cascade
|
|
77
|
+
layer, in one fixed order:
|
|
78
|
+
|
|
79
|
+
```css
|
|
80
|
+
@layer reset, tokens, base, components, motion, utilities;
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
| Layer | Holds |
|
|
84
|
+
| ------------ | --------------------------------------------------------------- |
|
|
85
|
+
| `reset` | Empty in the packages. The app's element defaults go here. |
|
|
86
|
+
| `tokens` | The token custom properties, in `palette`, `theme` and `scale`. |
|
|
87
|
+
| `base` | `base.css`: focus ring, touch targets, screen-reader helper. |
|
|
88
|
+
| `components` | Astro component styles, React island CSS and `controls.css`. |
|
|
89
|
+
| `motion` | `motion.css`. Above components, because it adjusts their parts. |
|
|
90
|
+
| `utilities` | `@kwtv/tokens/utilities.css`. |
|
|
91
|
+
|
|
92
|
+
Every package stylesheet opens with that order statement. The first one to
|
|
93
|
+
load fixes the order, so it holds whatever order the bundler emits files in.
|
|
94
|
+
|
|
95
|
+
In the app:
|
|
96
|
+
|
|
97
|
+
- Put element defaults (`*`, `html`, `body`, `a`, `button`) in
|
|
98
|
+
`@layer reset { }`. Left unlayered, a bare `a { color }` beats the footer
|
|
99
|
+
and button link colours.
|
|
100
|
+
- Leave everything else unlayered. Unlayered CSS beats every layer, so a
|
|
101
|
+
single class overrides any component rule. Do not raise specificity with
|
|
102
|
+
ids or repeated classes.
|
|
103
|
+
- `!important` flips inside layers: an important declaration in a lower layer
|
|
104
|
+
wins. The package uses it only to stop animation under reduced motion.
|
|
105
|
+
|
|
106
|
+
`npm run layers:check` fails when a package stylesheet is missing the order
|
|
107
|
+
statement or has a rule outside its layer.
|
|
108
|
+
|
|
66
109
|
## Conventions
|
|
67
110
|
|
|
68
111
|
- Use the `.astro`, `.tsx` and `.css` extensions shown in these examples.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kwtv/components",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"license": "UNLICENSED",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "KWTV UI components for Astro, with React islands. Built on the KWTV design tokens.",
|
|
@@ -34,6 +34,6 @@
|
|
|
34
34
|
}
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@kwtv/tokens": "^0.
|
|
37
|
+
"@kwtv/tokens": "^0.4.0"
|
|
38
38
|
}
|
|
39
39
|
}
|
|
@@ -15,11 +15,15 @@ const { class: className, ...rest } = Astro.props;
|
|
|
15
15
|
</div>
|
|
16
16
|
|
|
17
17
|
<style>
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
@layer reset, tokens, base, components, motion, utilities;
|
|
19
|
+
|
|
20
|
+
@layer components {
|
|
21
|
+
.ui-accordion {
|
|
22
|
+
display: flex;
|
|
23
|
+
flex-direction: column;
|
|
24
|
+
border: 1px solid var(--border);
|
|
25
|
+
border-radius: var(--radius-lg);
|
|
26
|
+
overflow: hidden;
|
|
27
|
+
}
|
|
24
28
|
}
|
|
25
29
|
</style>
|
|
@@ -14,64 +14,74 @@ interface Props {
|
|
|
14
14
|
const { summary, open = false, class: className, ...rest } = Astro.props;
|
|
15
15
|
---
|
|
16
16
|
|
|
17
|
-
<details
|
|
17
|
+
<details
|
|
18
|
+
class={["ui-accordion__item", className].filter(Boolean).join(" ")}
|
|
19
|
+
open={open}
|
|
20
|
+
{...rest}
|
|
21
|
+
>
|
|
18
22
|
<summary class="ui-accordion__sum">
|
|
19
23
|
{summary}
|
|
20
24
|
<span class="ui-accordion__chev" aria-hidden="true">
|
|
21
25
|
<Icon name="chevron-down" size={14} stroke={2.2} />
|
|
22
26
|
</span>
|
|
23
27
|
</summary>
|
|
24
|
-
<div class="ui-accordion__body"
|
|
28
|
+
<div class="ui-accordion__body">
|
|
29
|
+
<slot />
|
|
30
|
+
</div>
|
|
25
31
|
</details>
|
|
26
32
|
|
|
27
33
|
<style>
|
|
28
|
-
|
|
29
|
-
border-top: 1px solid var(--border);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
.ui-accordion__sum {
|
|
33
|
-
display: flex;
|
|
34
|
-
align-items: center;
|
|
35
|
-
justify-content: space-between;
|
|
36
|
-
gap: var(--space-3);
|
|
37
|
-
min-height: 44px;
|
|
38
|
-
padding: var(--space-2) var(--space-4);
|
|
39
|
-
font-size: var(--text-sm);
|
|
40
|
-
font-weight: var(--weight-medium);
|
|
41
|
-
color: var(--text);
|
|
42
|
-
cursor: pointer;
|
|
43
|
-
list-style: none;
|
|
44
|
-
}
|
|
45
|
-
.ui-accordion__sum::-webkit-details-marker {
|
|
46
|
-
display: none;
|
|
47
|
-
}
|
|
48
|
-
.ui-accordion__sum:hover {
|
|
49
|
-
background: var(--surface-hover);
|
|
50
|
-
}
|
|
51
|
-
.ui-accordion__sum:focus-visible {
|
|
52
|
-
outline: 2px solid var(--focus);
|
|
53
|
-
outline-offset: -2px;
|
|
54
|
-
}
|
|
34
|
+
@layer reset, tokens, base, components, motion, utilities;
|
|
55
35
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
61
|
-
.ui-accordion__item[open] .ui-accordion__chev {
|
|
62
|
-
transform: rotate(180deg);
|
|
63
|
-
}
|
|
36
|
+
@layer components {
|
|
37
|
+
.ui-accordion__item + .ui-accordion__item {
|
|
38
|
+
border-top: 1px solid var(--border);
|
|
39
|
+
}
|
|
64
40
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
41
|
+
.ui-accordion__sum {
|
|
42
|
+
display: flex;
|
|
43
|
+
align-items: center;
|
|
44
|
+
justify-content: space-between;
|
|
45
|
+
gap: var(--space-3);
|
|
46
|
+
min-height: 44px;
|
|
47
|
+
padding: var(--space-2) var(--space-4);
|
|
48
|
+
font-size: var(--text-sm);
|
|
49
|
+
font-weight: var(--weight-medium);
|
|
50
|
+
color: var(--text);
|
|
51
|
+
cursor: pointer;
|
|
52
|
+
list-style: none;
|
|
53
|
+
}
|
|
54
|
+
.ui-accordion__sum::-webkit-details-marker {
|
|
55
|
+
display: none;
|
|
56
|
+
}
|
|
57
|
+
.ui-accordion__sum:hover {
|
|
58
|
+
background: var(--surface-hover);
|
|
59
|
+
}
|
|
60
|
+
.ui-accordion__sum:focus-visible {
|
|
61
|
+
outline: 2px solid var(--focus);
|
|
62
|
+
outline-offset: -2px;
|
|
63
|
+
}
|
|
71
64
|
|
|
72
|
-
@media (prefers-reduced-motion: reduce) {
|
|
73
65
|
.ui-accordion__chev {
|
|
74
|
-
|
|
66
|
+
display: inline-flex;
|
|
67
|
+
color: var(--text-muted);
|
|
68
|
+
transition: transform var(--duration-fast) var(--ease-standard);
|
|
69
|
+
}
|
|
70
|
+
.ui-accordion__item[open] .ui-accordion__chev {
|
|
71
|
+
transform: rotate(180deg);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.ui-accordion__body {
|
|
75
|
+
padding: 0 var(--space-4) var(--space-4);
|
|
76
|
+
font-size: var(--text-sm);
|
|
77
|
+
line-height: var(--leading-sm);
|
|
78
|
+
color: var(--text-muted);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
@media (prefers-reduced-motion: reduce) {
|
|
82
|
+
.ui-accordion__chev {
|
|
83
|
+
transition: none;
|
|
84
|
+
}
|
|
75
85
|
}
|
|
76
86
|
}
|
|
77
87
|
</style>
|
|
@@ -20,46 +20,59 @@ interface Props {
|
|
|
20
20
|
class?: string;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
const {
|
|
23
|
+
const {
|
|
24
|
+
tags,
|
|
25
|
+
clearAllLabel = "Alles wissen",
|
|
26
|
+
class: className,
|
|
27
|
+
...rest
|
|
28
|
+
} = Astro.props;
|
|
24
29
|
|
|
25
30
|
const classes = ["ui-filtertags", className].filter(Boolean).join(" ");
|
|
26
31
|
---
|
|
27
32
|
|
|
28
33
|
<div class={classes} {...rest}>
|
|
29
34
|
{tags.map((tag) => (
|
|
30
|
-
<Badge tone="outline" removable removeLabel={tag.removeLabel}>
|
|
35
|
+
<Badge tone="outline" removable removeLabel={tag.removeLabel}>
|
|
36
|
+
{tag.label}
|
|
37
|
+
</Badge>
|
|
31
38
|
))}
|
|
32
39
|
{clearAllLabel && tags.length > 0 && (
|
|
33
|
-
<button class="ui-filtertags__clear" type="button">
|
|
40
|
+
<button class="ui-filtertags__clear" type="button">
|
|
41
|
+
{clearAllLabel}
|
|
42
|
+
</button>
|
|
34
43
|
)}
|
|
35
44
|
</div>
|
|
36
45
|
|
|
37
46
|
<style>
|
|
38
|
-
|
|
39
|
-
display: flex;
|
|
40
|
-
flex-wrap: wrap;
|
|
41
|
-
align-items: center;
|
|
42
|
-
gap: var(--space-2);
|
|
43
|
-
}
|
|
47
|
+
@layer reset, tokens, base, components, motion, utilities;
|
|
44
48
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
49
|
+
@layer components {
|
|
50
|
+
.ui-filtertags {
|
|
51
|
+
display: flex;
|
|
52
|
+
flex-wrap: wrap;
|
|
53
|
+
align-items: center;
|
|
54
|
+
gap: var(--space-2);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.ui-filtertags__clear {
|
|
58
|
+
padding: var(--space-1-5) var(--space-2);
|
|
59
|
+
background: transparent;
|
|
60
|
+
border: 0;
|
|
61
|
+
border-radius: var(--radius-sm);
|
|
62
|
+
font-family: var(--font-sans);
|
|
63
|
+
font-size: var(--text-xs);
|
|
64
|
+
font-weight: var(--weight-semibold);
|
|
65
|
+
color: var(--link);
|
|
66
|
+
cursor: pointer;
|
|
67
|
+
}
|
|
68
|
+
.ui-filtertags__clear:hover {
|
|
69
|
+
background: var(--surface-hover);
|
|
70
|
+
color: var(--link-hover);
|
|
71
|
+
}
|
|
72
|
+
.ui-filtertags__clear:focus-visible {
|
|
73
|
+
outline: 2px solid var(--focus);
|
|
74
|
+
outline-offset: 2px;
|
|
75
|
+
box-shadow: 0 0 0 4px var(--focus-outer);
|
|
76
|
+
}
|
|
64
77
|
}
|
|
65
78
|
</style>
|
package/src/astro/Alert.astro
CHANGED
|
@@ -41,53 +41,57 @@ const classes = ["ui-alert", `ui-alert--${tone}`, className]
|
|
|
41
41
|
</div>
|
|
42
42
|
|
|
43
43
|
<style>
|
|
44
|
-
|
|
45
|
-
display: flex;
|
|
46
|
-
align-items: flex-start;
|
|
47
|
-
gap: var(--space-2-5, 0.625rem);
|
|
48
|
-
padding: var(--space-3) var(--space-4);
|
|
49
|
-
border-left: 3px solid currentColor;
|
|
50
|
-
border-radius: var(--radius-md);
|
|
51
|
-
font-family: var(--font-sans);
|
|
52
|
-
font-size: var(--text-sm);
|
|
53
|
-
line-height: var(--leading-sm);
|
|
54
|
-
}
|
|
44
|
+
@layer reset, tokens, base, components, motion, utilities;
|
|
55
45
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
46
|
+
@layer components {
|
|
47
|
+
.ui-alert {
|
|
48
|
+
display: flex;
|
|
49
|
+
align-items: flex-start;
|
|
50
|
+
gap: var(--space-2-5, 0.625rem);
|
|
51
|
+
padding: var(--space-3) var(--space-4);
|
|
52
|
+
border-left: 3px solid currentColor;
|
|
53
|
+
border-radius: var(--radius-md);
|
|
54
|
+
font-family: var(--font-sans);
|
|
55
|
+
font-size: var(--text-sm);
|
|
56
|
+
line-height: var(--leading-sm);
|
|
57
|
+
}
|
|
61
58
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
gap: var(--space-1);
|
|
68
|
-
}
|
|
59
|
+
.ui-alert__icon {
|
|
60
|
+
display: inline-flex;
|
|
61
|
+
flex-shrink: 0;
|
|
62
|
+
margin-top: 1px;
|
|
63
|
+
}
|
|
69
64
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
65
|
+
/* Body keeps full strength; the left rule carries the tone. */
|
|
66
|
+
.ui-alert__body {
|
|
67
|
+
color: var(--text);
|
|
68
|
+
display: flex;
|
|
69
|
+
flex-direction: column;
|
|
70
|
+
gap: var(--space-1);
|
|
71
|
+
}
|
|
73
72
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
73
|
+
.ui-alert__title {
|
|
74
|
+
font-weight: var(--weight-semibold);
|
|
75
|
+
}
|
|
78
76
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
77
|
+
.ui-alert--info {
|
|
78
|
+
background: var(--surface-accent);
|
|
79
|
+
color: var(--surface-accent-fg, var(--primary));
|
|
80
|
+
}
|
|
83
81
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
82
|
+
.ui-alert--success {
|
|
83
|
+
background: var(--success-bg);
|
|
84
|
+
color: var(--success);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.ui-alert--warning {
|
|
88
|
+
background: var(--warning-bg);
|
|
89
|
+
color: var(--warning);
|
|
90
|
+
}
|
|
88
91
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
+
.ui-alert--danger {
|
|
93
|
+
background: var(--danger-bg);
|
|
94
|
+
color: var(--danger);
|
|
95
|
+
}
|
|
92
96
|
}
|
|
93
97
|
</style>
|
package/src/astro/Badge.astro
CHANGED
|
@@ -58,81 +58,85 @@ const classes = [
|
|
|
58
58
|
</span>
|
|
59
59
|
|
|
60
60
|
<style>
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
61
|
+
@layer reset, tokens, base, components, motion, utilities;
|
|
62
|
+
|
|
63
|
+
@layer components {
|
|
64
|
+
.ui-badge {
|
|
65
|
+
display: inline-flex;
|
|
66
|
+
align-items: center;
|
|
67
|
+
gap: var(--space-1-5);
|
|
68
|
+
min-height: 24px;
|
|
69
|
+
padding: 0 var(--space-2);
|
|
70
|
+
border: 1px solid transparent;
|
|
71
|
+
border-radius: var(--radius-full);
|
|
72
|
+
font-family: var(--font-sans);
|
|
73
|
+
font-size: var(--text-xs);
|
|
74
|
+
font-weight: var(--weight-medium);
|
|
75
|
+
line-height: 1;
|
|
76
|
+
white-space: nowrap;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.ui-badge__icon {
|
|
80
|
+
display: inline-flex;
|
|
81
|
+
flex-shrink: 0;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.ui-badge--neutral {
|
|
85
|
+
background: var(--surface-accent);
|
|
86
|
+
color: var(--surface-accent-fg, var(--text));
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.ui-badge--success {
|
|
90
|
+
background: var(--success-bg);
|
|
91
|
+
color: var(--success);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.ui-badge--warning {
|
|
95
|
+
background: var(--warning-bg);
|
|
96
|
+
color: var(--warning);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.ui-badge--danger {
|
|
100
|
+
background: var(--danger-bg);
|
|
101
|
+
color: var(--danger);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/* Outline keeps the strong border and full-strength text, so it reads */
|
|
105
|
+
/* without relying on a fill. */
|
|
106
|
+
.ui-badge--outline {
|
|
107
|
+
background: transparent;
|
|
108
|
+
border: 1px solid var(--border-strong);
|
|
109
|
+
color: var(--text);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.ui-badge--removable {
|
|
113
|
+
padding-right: var(--space-1);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/* Small × target grows with padding plus an equal negative margin, so the */
|
|
117
|
+
/* hit area grows without moving the layout. */
|
|
118
|
+
.ui-badge__x {
|
|
119
|
+
display: inline-flex;
|
|
120
|
+
align-items: center;
|
|
121
|
+
justify-content: center;
|
|
122
|
+
padding: var(--space-2);
|
|
123
|
+
margin: calc(-1 * var(--space-2));
|
|
124
|
+
margin-left: 0;
|
|
125
|
+
background: transparent;
|
|
126
|
+
border: 0;
|
|
127
|
+
border-radius: var(--radius-sm);
|
|
128
|
+
color: inherit;
|
|
129
|
+
cursor: pointer;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.ui-badge__x:hover {
|
|
133
|
+
color: var(--danger);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.ui-badge__x:focus-visible {
|
|
137
|
+
outline: 2px solid var(--focus);
|
|
138
|
+
outline-offset: 2px;
|
|
139
|
+
box-shadow: 0 0 0 4px var(--focus-outer);
|
|
140
|
+
}
|
|
137
141
|
}
|
|
138
142
|
</style>
|