@kwtv/components 0.1.3 → 0.3.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 +17 -9
- package/package.json +2 -2
- package/src/astro/AccordionItem.astro +8 -2
- package/src/astro/ActiveFilterTags.astro +12 -3
- package/src/astro/Breadcrumb.astro +5 -1
- package/src/astro/Button.astro +3 -1
- package/src/astro/Card.astro +8 -2
- package/src/astro/CartLine.astro +13 -3
- package/src/astro/ChipRail.astro +6 -1
- package/src/astro/DotGrid.astro +14 -5
- package/src/astro/EmptyState.astro +3 -1
- package/src/astro/FilterGroup.astro +1 -2
- package/src/astro/Filters.astro +7 -1
- package/src/astro/Footer.astro +20 -7
- package/src/astro/Header.astro +13 -4
- package/src/astro/Icon.astro +4 -2
- package/src/astro/IconButton.astro +3 -1
- package/src/astro/Marquee.astro +10 -12
- package/src/astro/NavDropdown.astro +49 -33
- package/src/astro/NavLink.astro +1 -2
- package/src/astro/Newsletter.astro +6 -2
- package/src/astro/Pager.astro +28 -7
- package/src/astro/ProductCard.astro +14 -3
- package/src/astro/Skeleton.astro +17 -3
- package/src/astro/Social.astro +2 -1
- package/src/astro/StepIndicator.astro +15 -3
- package/src/astro/Sticker.astro +24 -3
- package/src/astro/SwipeCarousel.astro +5 -1
- package/src/astro/Table.astro +8 -2
- package/src/astro/TableCard.astro +6 -2
- package/src/astro/TextField.astro +12 -3
- package/src/react/Drawer.tsx +1 -5
- package/src/react/Modal.tsx +4 -6
- package/src/react/NewsCarousel.tsx +7 -1
- package/src/react/Select.tsx +8 -2
- package/src/react/Toast.tsx +38 -4
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
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kwtv/components",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.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.3.0"
|
|
38
38
|
}
|
|
39
39
|
}
|
|
@@ -14,14 +14,20 @@ 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>
|
|
@@ -20,17 +20,26 @@ 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
|
|
|
@@ -20,7 +20,11 @@ const { items, label = "Kruimelpad", class: className, ...rest } = Astro.props;
|
|
|
20
20
|
const lastIndex = items.length - 1;
|
|
21
21
|
---
|
|
22
22
|
|
|
23
|
-
<nav
|
|
23
|
+
<nav
|
|
24
|
+
class={["ui-crumbs", className].filter(Boolean).join(" ")}
|
|
25
|
+
aria-label={label}
|
|
26
|
+
{...rest}
|
|
27
|
+
>
|
|
24
28
|
{items.map((item, i) => (
|
|
25
29
|
<>
|
|
26
30
|
{item.href && i !== lastIndex ? (
|
package/src/astro/Button.astro
CHANGED
|
@@ -59,7 +59,9 @@ const tagProps = href
|
|
|
59
59
|
{...tagProps}
|
|
60
60
|
{...rest}
|
|
61
61
|
>
|
|
62
|
-
<span class="ui-btn__label"
|
|
62
|
+
<span class="ui-btn__label">
|
|
63
|
+
<slot />
|
|
64
|
+
</span>
|
|
63
65
|
{icon && (
|
|
64
66
|
<span class="ui-btn__icon" aria-hidden="true">
|
|
65
67
|
<Icon name={icon as any} size="1em" stroke={1.8} />
|
package/src/astro/Card.astro
CHANGED
|
@@ -25,7 +25,11 @@ const {
|
|
|
25
25
|
|
|
26
26
|
const Title = titleTag;
|
|
27
27
|
|
|
28
|
-
const classes = [
|
|
28
|
+
const classes = [
|
|
29
|
+
"ui-card",
|
|
30
|
+
variant !== "default" && `ui-card--${variant}`,
|
|
31
|
+
className,
|
|
32
|
+
]
|
|
29
33
|
.filter(Boolean)
|
|
30
34
|
.join(" ");
|
|
31
35
|
|
|
@@ -35,7 +39,9 @@ const hasFooter = Astro.slots.has("footer");
|
|
|
35
39
|
<div class={classes} {...rest}>
|
|
36
40
|
{eyebrow && <span class="ui-card__eyebrow">{eyebrow}</span>}
|
|
37
41
|
{title && <Title class="ui-card__title">{title}</Title>}
|
|
38
|
-
<span class="ui-card__body"
|
|
42
|
+
<span class="ui-card__body">
|
|
43
|
+
<slot />
|
|
44
|
+
</span>
|
|
39
45
|
{hasFooter && (
|
|
40
46
|
<div class="ui-card__footer">
|
|
41
47
|
<slot name="footer" />
|
package/src/astro/CartLine.astro
CHANGED
|
@@ -35,13 +35,23 @@ const classes = ["ui-line", className].filter(Boolean).join(" ");
|
|
|
35
35
|
---
|
|
36
36
|
|
|
37
37
|
<div class={classes} {...rest}>
|
|
38
|
-
<img
|
|
38
|
+
<img
|
|
39
|
+
class="ui-line__thumb"
|
|
40
|
+
loading="lazy"
|
|
41
|
+
decoding="async"
|
|
42
|
+
src={img}
|
|
43
|
+
alt={alt}
|
|
44
|
+
/>
|
|
39
45
|
<span class="ui-line__grow">
|
|
40
46
|
<b class="ui-line__title">{title}</b>
|
|
41
47
|
{note && <span class="ui-line__note">{note}</span>}
|
|
42
|
-
<a class="ui-line__remove" href={removeHref}>
|
|
48
|
+
<a class="ui-line__remove" href={removeHref}>
|
|
49
|
+
{removeLabel}
|
|
50
|
+
</a>
|
|
51
|
+
</span>
|
|
52
|
+
<span class="ui-line__qty">
|
|
53
|
+
<slot name="qty" />
|
|
43
54
|
</span>
|
|
44
|
-
<span class="ui-line__qty"><slot name="qty" /></span>
|
|
45
55
|
<b class="ui-line__price">{price}</b>
|
|
46
56
|
</div>
|
|
47
57
|
|
package/src/astro/ChipRail.astro
CHANGED
|
@@ -17,7 +17,12 @@ const classes = ["pl-chips", className].filter(Boolean).join(" ");
|
|
|
17
17
|
|
|
18
18
|
<nav class={classes} aria-label={label} {...rest}>
|
|
19
19
|
{items.map((item) => (
|
|
20
|
-
<a
|
|
20
|
+
<a
|
|
21
|
+
class="pl-chip"
|
|
22
|
+
href={item.href}
|
|
23
|
+
data-on={item.current ? "1" : undefined}
|
|
24
|
+
aria-current={item.current ? "page" : undefined}
|
|
25
|
+
>
|
|
21
26
|
{item.label}
|
|
22
27
|
</a>
|
|
23
28
|
))}
|
package/src/astro/DotGrid.astro
CHANGED
|
@@ -16,7 +16,9 @@ const classes = ["pl-dotgrid", compact && "pl-dotgrid--compact", className]
|
|
|
16
16
|
|
|
17
17
|
<div class={classes} {...rest}>
|
|
18
18
|
<span class="pl-dotgrid__dots" aria-hidden="true"></span>
|
|
19
|
-
<span class="pl-dotgrid__content"
|
|
19
|
+
<span class="pl-dotgrid__content">
|
|
20
|
+
<slot />
|
|
21
|
+
</span>
|
|
20
22
|
</div>
|
|
21
23
|
|
|
22
24
|
<style>
|
|
@@ -32,9 +34,12 @@ const classes = ["pl-dotgrid", compact && "pl-dotgrid--compact", className]
|
|
|
32
34
|
.pl-dotgrid__dots {
|
|
33
35
|
position: absolute;
|
|
34
36
|
inset: 0;
|
|
35
|
-
background-image: radial-gradient(
|
|
37
|
+
background-image: radial-gradient(
|
|
38
|
+
var(--dotgrid-color, var(--sage-light)) 1.4px,
|
|
39
|
+
transparent 1.6px
|
|
40
|
+
);
|
|
36
41
|
background-size: 28px 28px;
|
|
37
|
-
opacity: var(--dotgrid-opacity, var(--dotgrid-theme-opacity, .7));
|
|
42
|
+
opacity: var(--dotgrid-opacity, var(--dotgrid-theme-opacity, 0.7));
|
|
38
43
|
animation: pl-drift 6s linear infinite;
|
|
39
44
|
}
|
|
40
45
|
|
|
@@ -58,9 +63,13 @@ const classes = ["pl-dotgrid", compact && "pl-dotgrid--compact", className]
|
|
|
58
63
|
}
|
|
59
64
|
|
|
60
65
|
/* Explicit themes win over OS preference, as in the token cascade. */
|
|
61
|
-
:global([data-theme="dark"]) .pl-dotgrid {
|
|
66
|
+
:global([data-theme="dark"]) .pl-dotgrid {
|
|
67
|
+
--dotgrid-theme-opacity: 0.2;
|
|
68
|
+
}
|
|
62
69
|
@media (prefers-color-scheme: dark) {
|
|
63
|
-
:global(:root:not([data-theme])) .pl-dotgrid {
|
|
70
|
+
:global(:root:not([data-theme])) .pl-dotgrid {
|
|
71
|
+
--dotgrid-theme-opacity: 0.2;
|
|
72
|
+
}
|
|
64
73
|
}
|
|
65
74
|
|
|
66
75
|
@media (prefers-reduced-motion: reduce) {
|
|
@@ -15,7 +15,9 @@ const hasAction = Astro.slots.has("action");
|
|
|
15
15
|
|
|
16
16
|
<div class={["ui-empty", className].filter(Boolean).join(" ")} {...rest}>
|
|
17
17
|
<b class="ui-empty__title">{title}</b>
|
|
18
|
-
<span class="ui-empty__body"
|
|
18
|
+
<span class="ui-empty__body">
|
|
19
|
+
<slot />
|
|
20
|
+
</span>
|
|
19
21
|
{hasAction && (
|
|
20
22
|
<div class="ui-empty__action">
|
|
21
23
|
<slot name="action" />
|
|
@@ -29,8 +29,7 @@ const classes = ["ui-filtergroup", className].filter(Boolean).join(" ");
|
|
|
29
29
|
margin: 0;
|
|
30
30
|
padding: var(--space-3) 0 0;
|
|
31
31
|
border: 0;
|
|
32
|
-
/* More space above the rule than below it, so the rule belongs to this
|
|
33
|
-
group's top edge. */
|
|
32
|
+
/* More space above the rule than below it, so the rule belongs to this group's top edge. */
|
|
34
33
|
margin-top: var(--space-4);
|
|
35
34
|
border-top: 1px solid var(--border);
|
|
36
35
|
}
|
package/src/astro/Filters.astro
CHANGED
|
@@ -23,7 +23,13 @@ const classes = ["ui-filters", className].filter(Boolean).join(" ");
|
|
|
23
23
|
<aside class={classes} {...rest}>
|
|
24
24
|
<div class="ui-filterbar">
|
|
25
25
|
<span class="ui-eyebrow">Filters</span>
|
|
26
|
-
{clearLabel &&
|
|
26
|
+
{clearLabel && (
|
|
27
|
+
<slot name="clear">
|
|
28
|
+
<button class="ui-filters__clear" type="button">
|
|
29
|
+
{clearLabel}
|
|
30
|
+
</button>
|
|
31
|
+
</slot>
|
|
32
|
+
)}
|
|
27
33
|
</div>
|
|
28
34
|
<slot />
|
|
29
35
|
</aside>
|
package/src/astro/Footer.astro
CHANGED
|
@@ -33,16 +33,27 @@ const classes = ["ui-footer", `ui-footer--${variant}`, className]
|
|
|
33
33
|
|
|
34
34
|
<footer class={classes} {...rest}>
|
|
35
35
|
<div class="ui-footer__brandblock">
|
|
36
|
-
<div class="ui-footer__brand">
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
<div class="ui-footer__brand">
|
|
37
|
+
{brandName}
|
|
38
|
+
<slot name="brand-suffix" />
|
|
39
|
+
</div>
|
|
40
|
+
<div class="ui-footer__addr">
|
|
41
|
+
<slot name="address" />
|
|
42
|
+
</div>
|
|
43
|
+
<div class="ui-footer__social">
|
|
44
|
+
<slot name="social" />
|
|
45
|
+
</div>
|
|
39
46
|
</div>
|
|
40
47
|
|
|
41
48
|
<slot />
|
|
42
49
|
|
|
43
50
|
<div class="ui-footer__bar">
|
|
44
|
-
<span class="ui-footer__legal"
|
|
45
|
-
|
|
51
|
+
<span class="ui-footer__legal">
|
|
52
|
+
<slot name="legal" />
|
|
53
|
+
</span>
|
|
54
|
+
<span class="ui-footer__policies">
|
|
55
|
+
<slot name="policies" />
|
|
56
|
+
</span>
|
|
46
57
|
</div>
|
|
47
58
|
</footer>
|
|
48
59
|
|
|
@@ -166,7 +177,8 @@ const classes = ["ui-footer", `ui-footer--${variant}`, className]
|
|
|
166
177
|
gap: var(--space-2);
|
|
167
178
|
margin-top: calc(var(--space-6) * -1 + var(--space-2));
|
|
168
179
|
}
|
|
169
|
-
.ui-footer--mobile.ui-footer--site
|
|
180
|
+
.ui-footer--mobile.ui-footer--site
|
|
181
|
+
:global(.ui-footer__contact .ui-footer__title),
|
|
170
182
|
.ui-footer--mobile.ui-footer--site :global(.ui-footer__desktop-only) {
|
|
171
183
|
display: none;
|
|
172
184
|
}
|
|
@@ -214,7 +226,8 @@ const classes = ["ui-footer", `ui-footer--${variant}`, className]
|
|
|
214
226
|
.ui-footer--mobile.ui-footer--shop :global(.ui-footer__shop-links) {
|
|
215
227
|
gap: var(--space-4);
|
|
216
228
|
}
|
|
217
|
-
.ui-footer--mobile.ui-footer--shop
|
|
229
|
+
.ui-footer--mobile.ui-footer--shop
|
|
230
|
+
:global(.ui-footer__shop-links .ui-footer__title) {
|
|
218
231
|
display: none;
|
|
219
232
|
}
|
|
220
233
|
.ui-footer--mobile.ui-footer--shop .ui-footer__social:empty {
|
package/src/astro/Header.astro
CHANGED
|
@@ -13,16 +13,25 @@ interface Props {
|
|
|
13
13
|
class?: string;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
const {
|
|
17
|
-
|
|
16
|
+
const {
|
|
17
|
+
brandName = "KWTV",
|
|
18
|
+
brandHref = "/",
|
|
19
|
+
class: className,
|
|
20
|
+
...rest
|
|
21
|
+
} = Astro.props;
|
|
18
22
|
|
|
19
23
|
const classes = ["ui-header", className].filter(Boolean).join(" ");
|
|
20
24
|
---
|
|
21
25
|
|
|
22
26
|
<header class={classes} {...rest}>
|
|
23
27
|
<a class="ui-brand" href={brandHref}>
|
|
24
|
-
<span class="ui-brand__mark"
|
|
25
|
-
|
|
28
|
+
<span class="ui-brand__mark">
|
|
29
|
+
<slot name="logo" />
|
|
30
|
+
</span>
|
|
31
|
+
<span class="ui-brand__name">
|
|
32
|
+
{brandName}
|
|
33
|
+
<slot name="brand-suffix" />
|
|
34
|
+
</span>
|
|
26
35
|
</a>
|
|
27
36
|
|
|
28
37
|
<nav class="ui-nav">
|
package/src/astro/Icon.astro
CHANGED
|
@@ -42,14 +42,16 @@ const paths: Record<Props["name"], string> = {
|
|
|
42
42
|
"chevron-right": '<path d="M9 6l6 6-6 6"/>',
|
|
43
43
|
"chevron-left": '<path d="M15 6l-6 6 6 6"/>',
|
|
44
44
|
info: '<circle cx="12" cy="12" r="9"/><path d="M12 11v5M12 8v.5"/>',
|
|
45
|
-
"alert-circle":
|
|
45
|
+
"alert-circle":
|
|
46
|
+
'<circle cx="12" cy="12" r="9"/><path d="M12 8v4.5M12 16v.5"/>',
|
|
46
47
|
"alert-triangle": '<path d="M12 4l8.5 15h-17L12 4zM12 10v4M12 16.5v.5"/>',
|
|
47
48
|
"arrow-right": '<path d="M5 12h14M13 6l6 6-6 6"/>',
|
|
48
49
|
"arrow-up-right": '<path d="M7 17 17 7M8 7h9v9"/>',
|
|
49
50
|
"arrow-down": '<path d="M12 5v14M6 13l6 6 6-6"/>',
|
|
50
51
|
instagram:
|
|
51
52
|
'<rect x="4" y="4" width="16" height="16" rx="5"/><circle cx="12" cy="12" r="3.6"/><path d="M17 7.2v.01"/>',
|
|
52
|
-
facebook:
|
|
53
|
+
facebook:
|
|
54
|
+
'<path d="M14.5 8.5h2M14.5 8.5c0-2 .8-3 2.5-3M14.5 8.5V19M11 12h6"/>',
|
|
53
55
|
youtube:
|
|
54
56
|
'<rect x="3.5" y="6.5" width="17" height="11" rx="3.2"/><path d="M11 10.2l3.4 1.8-3.4 1.8z"/>',
|
|
55
57
|
};
|
|
@@ -41,7 +41,9 @@ const classes = ["ui-iconbtn", className].filter(Boolean).join(" ");
|
|
|
41
41
|
>
|
|
42
42
|
{icon ? <Icon name={icon as any} size={20} stroke={1.7} /> : <slot />}
|
|
43
43
|
{count !== undefined && (
|
|
44
|
-
<span class="ui-iconbtn__count" aria-hidden="true">
|
|
44
|
+
<span class="ui-iconbtn__count" aria-hidden="true">
|
|
45
|
+
{count}
|
|
46
|
+
</span>
|
|
45
47
|
)}
|
|
46
48
|
</button>
|
|
47
49
|
|
package/src/astro/Marquee.astro
CHANGED
|
@@ -21,18 +21,16 @@ const { items, divider = "✦", class: className } = Astro.props;
|
|
|
21
21
|
|
|
22
22
|
<div class:list={["ui-marquee", className]} aria-hidden="true">
|
|
23
23
|
<div class="ui-marquee__track">
|
|
24
|
-
{
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
))
|
|
35
|
-
}
|
|
24
|
+
{[0, 1].map(() => (
|
|
25
|
+
<div class="ui-marquee__group">
|
|
26
|
+
{items.map((item) => (
|
|
27
|
+
<>
|
|
28
|
+
<span>{item}</span>
|
|
29
|
+
<span class="ui-marquee__div">{divider}</span>
|
|
30
|
+
</>
|
|
31
|
+
))}
|
|
32
|
+
</div>
|
|
33
|
+
))}
|
|
36
34
|
</div>
|
|
37
35
|
</div>
|
|
38
36
|
|
|
@@ -27,9 +27,15 @@ const classes = ["ui-navgroup", open && "is-open", className]
|
|
|
27
27
|
---
|
|
28
28
|
|
|
29
29
|
<div class={classes} data-navdropdown {...rest}>
|
|
30
|
-
<button
|
|
30
|
+
<button
|
|
31
|
+
class="ui-navlink"
|
|
32
|
+
type="button"
|
|
33
|
+
aria-expanded={open ? "true" : "false"}
|
|
34
|
+
>
|
|
31
35
|
{label}
|
|
32
|
-
<span aria-hidden="true"
|
|
36
|
+
<span aria-hidden="true">
|
|
37
|
+
<Icon name="chevron-down" size={11} stroke={2.4} />
|
|
38
|
+
</span>
|
|
33
39
|
</button>
|
|
34
40
|
<div class="ui-navpanel">
|
|
35
41
|
<slot />
|
|
@@ -40,42 +46,52 @@ const classes = ["ui-navgroup", open && "is-open", className]
|
|
|
40
46
|
// Click-to-toggle, on top of the CSS hover/focus-within path: the only way
|
|
41
47
|
// a touchscreen tap, or a Safari click (which does not focus a <button>),
|
|
42
48
|
// can open the panel at all.
|
|
43
|
-
document
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
49
|
+
document
|
|
50
|
+
.querySelectorAll<HTMLElement>("[data-navdropdown]")
|
|
51
|
+
.forEach((group) => {
|
|
52
|
+
const trigger = group.querySelector<HTMLButtonElement>(".ui-navlink");
|
|
53
|
+
if (!trigger) return;
|
|
54
|
+
|
|
55
|
+
const close = () => {
|
|
56
|
+
group.classList.remove("is-open");
|
|
57
|
+
trigger.setAttribute("aria-expanded", "false");
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
trigger.addEventListener("click", (event) => {
|
|
61
|
+
const willOpen = !group.classList.contains("is-open");
|
|
62
|
+
document
|
|
63
|
+
.querySelectorAll<HTMLElement>("[data-navdropdown].is-open")
|
|
64
|
+
.forEach((other) => {
|
|
65
|
+
if (other === group) return;
|
|
66
|
+
other.classList.remove("is-open");
|
|
67
|
+
other
|
|
68
|
+
.querySelector<HTMLButtonElement>(".ui-navlink")
|
|
69
|
+
?.setAttribute("aria-expanded", "false");
|
|
70
|
+
});
|
|
71
|
+
group.classList.toggle("is-open", willOpen);
|
|
72
|
+
trigger.setAttribute("aria-expanded", String(willOpen));
|
|
73
|
+
event.stopPropagation();
|
|
58
74
|
});
|
|
59
|
-
group.classList.toggle("is-open", willOpen);
|
|
60
|
-
trigger.setAttribute("aria-expanded", String(willOpen));
|
|
61
|
-
event.stopPropagation();
|
|
62
|
-
});
|
|
63
75
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
76
|
+
group.addEventListener("keydown", (event) => {
|
|
77
|
+
if (event.key === "Escape") {
|
|
78
|
+
close();
|
|
79
|
+
trigger.focus();
|
|
80
|
+
}
|
|
81
|
+
});
|
|
69
82
|
});
|
|
70
|
-
});
|
|
71
83
|
|
|
72
84
|
document.addEventListener("click", (event) => {
|
|
73
|
-
document
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
group.
|
|
77
|
-
|
|
78
|
-
|
|
85
|
+
document
|
|
86
|
+
.querySelectorAll<HTMLElement>("[data-navdropdown].is-open")
|
|
87
|
+
.forEach((group) => {
|
|
88
|
+
if (!group.contains(event.target as Node)) {
|
|
89
|
+
group.classList.remove("is-open");
|
|
90
|
+
group
|
|
91
|
+
.querySelector<HTMLButtonElement>(".ui-navlink")
|
|
92
|
+
?.setAttribute("aria-expanded", "false");
|
|
93
|
+
}
|
|
94
|
+
});
|
|
79
95
|
});
|
|
80
96
|
</script>
|
|
81
97
|
|
package/src/astro/NavLink.astro
CHANGED
|
@@ -33,8 +33,7 @@ const classes = ["ui-navlink", current && "is-current", className]
|
|
|
33
33
|
display: inline-flex;
|
|
34
34
|
align-items: center;
|
|
35
35
|
gap: var(--space-1-5);
|
|
36
|
-
/* 7 px block / 10 px inline padding with an equal negative margin, so the
|
|
37
|
-
focus ring has room but the header rhythm does not shift. */
|
|
36
|
+
/* 7 px block / 10 px inline padding with an equal negative margin, so the focus ring has room but the header rhythm does not shift. */
|
|
38
37
|
padding: 7px 10px;
|
|
39
38
|
margin: -7px -10px;
|
|
40
39
|
border-radius: var(--radius-sm);
|
|
@@ -40,7 +40,9 @@ const classes = ["ui-news", stacked && "ui-news--stacked", className]
|
|
|
40
40
|
---
|
|
41
41
|
|
|
42
42
|
<form class={classes} action={action} method={method} {...rest}>
|
|
43
|
-
<label class="ui-sr-only" for={id}>
|
|
43
|
+
<label class="ui-sr-only" for={id}>
|
|
44
|
+
{label}
|
|
45
|
+
</label>
|
|
44
46
|
<input
|
|
45
47
|
class="ui-news__input"
|
|
46
48
|
id={id}
|
|
@@ -50,7 +52,9 @@ const classes = ["ui-news", stacked && "ui-news--stacked", className]
|
|
|
50
52
|
placeholder={placeholder}
|
|
51
53
|
autocomplete="email"
|
|
52
54
|
/>
|
|
53
|
-
<button class="ui-news__btn" type="submit">
|
|
55
|
+
<button class="ui-news__btn" type="submit">
|
|
56
|
+
{buttonText}
|
|
57
|
+
</button>
|
|
54
58
|
</form>
|
|
55
59
|
|
|
56
60
|
<style>
|
package/src/astro/Pager.astro
CHANGED
|
@@ -68,17 +68,21 @@ const hasNext = current < total;
|
|
|
68
68
|
<Icon name="chevron-left" size={17} stroke={2.3} />
|
|
69
69
|
</a>
|
|
70
70
|
) : (
|
|
71
|
-
<span class="is-disabled" aria-hidden="true"
|
|
71
|
+
<span class="is-disabled" aria-hidden="true">
|
|
72
|
+
<Icon name="chevron-left" size={17} stroke={2.3} />
|
|
73
|
+
</span>
|
|
72
74
|
)}
|
|
73
75
|
|
|
74
76
|
{list.map((p) =>
|
|
75
77
|
p === "…" ? (
|
|
76
78
|
<span class="ui-pager__gap">…</span>
|
|
77
79
|
) : p === current ? (
|
|
78
|
-
<a class="is-current" href={href(p)} aria-current="page">
|
|
80
|
+
<a class="is-current" href={href(p)} aria-current="page">
|
|
81
|
+
{p}
|
|
82
|
+
</a>
|
|
79
83
|
) : (
|
|
80
84
|
<a href={href(p)}>{p}</a>
|
|
81
|
-
)
|
|
85
|
+
),
|
|
82
86
|
)}
|
|
83
87
|
|
|
84
88
|
{hasNext ? (
|
|
@@ -86,7 +90,9 @@ const hasNext = current < total;
|
|
|
86
90
|
<Icon name="chevron-right" size={17} stroke={2.3} />
|
|
87
91
|
</a>
|
|
88
92
|
) : (
|
|
89
|
-
<span class="is-disabled" aria-hidden="true"
|
|
93
|
+
<span class="is-disabled" aria-hidden="true">
|
|
94
|
+
<Icon name="chevron-right" size={17} stroke={2.3} />
|
|
95
|
+
</span>
|
|
90
96
|
)}
|
|
91
97
|
</nav>
|
|
92
98
|
|
|
@@ -119,13 +125,24 @@ const hasNext = current < total;
|
|
|
119
125
|
const nav = a.closest("[data-ui-pager][data-ui-pager-preserve]");
|
|
120
126
|
if (!nav) return;
|
|
121
127
|
const me = e as MouseEvent;
|
|
122
|
-
if (
|
|
128
|
+
if (
|
|
129
|
+
me.button !== 0 ||
|
|
130
|
+
me.metaKey ||
|
|
131
|
+
me.ctrlKey ||
|
|
132
|
+
me.shiftKey ||
|
|
133
|
+
me.altKey
|
|
134
|
+
)
|
|
135
|
+
return;
|
|
123
136
|
const { page, url } = pageFrom(nav, a);
|
|
124
137
|
if (page == null) return;
|
|
125
138
|
e.preventDefault();
|
|
126
139
|
e.stopImmediatePropagation();
|
|
127
140
|
history.pushState({ uiPager: true, page }, "", url.href);
|
|
128
|
-
window.dispatchEvent(
|
|
141
|
+
window.dispatchEvent(
|
|
142
|
+
new CustomEvent("ui:pagerchange", {
|
|
143
|
+
detail: { page, url: url.href },
|
|
144
|
+
}),
|
|
145
|
+
);
|
|
129
146
|
},
|
|
130
147
|
true,
|
|
131
148
|
);
|
|
@@ -136,7 +153,11 @@ const hasNext = current < total;
|
|
|
136
153
|
const p = parseInt(u.searchParams.get("page") || "1", 10);
|
|
137
154
|
window.dispatchEvent(
|
|
138
155
|
new CustomEvent("ui:pagerchange", {
|
|
139
|
-
detail: {
|
|
156
|
+
detail: {
|
|
157
|
+
page: Number.isFinite(p) ? p : 1,
|
|
158
|
+
url: u.href,
|
|
159
|
+
popped: true,
|
|
160
|
+
},
|
|
140
161
|
}),
|
|
141
162
|
);
|
|
142
163
|
});
|
|
@@ -41,16 +41,27 @@ const ribbonLabel: Record<NonNullable<Props["ribbon"]>, string> = {
|
|
|
41
41
|
fav: "Favoriet",
|
|
42
42
|
};
|
|
43
43
|
|
|
44
|
-
const classes = ["ui-product", soldOut && "is-disabled", className]
|
|
44
|
+
const classes = ["ui-product", soldOut && "is-disabled", className]
|
|
45
|
+
.filter(Boolean)
|
|
46
|
+
.join(" ");
|
|
45
47
|
---
|
|
46
48
|
|
|
47
49
|
<a class={classes} href={href} {...rest}>
|
|
48
50
|
{(ribbon || soldOut) && (
|
|
49
|
-
<span
|
|
51
|
+
<span
|
|
52
|
+
class={`ui-ribbon ui-ribbon--${soldOut ? "sold-out" : ribbon}`}
|
|
53
|
+
aria-hidden="true"
|
|
54
|
+
>
|
|
50
55
|
<i>{soldOut ? "Uitverkocht" : ribbonLabel[ribbon!]}</i>
|
|
51
56
|
</span>
|
|
52
57
|
)}
|
|
53
|
-
<img
|
|
58
|
+
<img
|
|
59
|
+
class="ui-product__img"
|
|
60
|
+
loading="lazy"
|
|
61
|
+
decoding="async"
|
|
62
|
+
src={img}
|
|
63
|
+
alt={alt}
|
|
64
|
+
/>
|
|
54
65
|
<span class="ui-product__body">
|
|
55
66
|
<span class="ui-product__title">{title}</span>
|
|
56
67
|
{meta && <span class="ui-product__meta">{meta}</span>}
|
package/src/astro/Skeleton.astro
CHANGED
|
@@ -12,9 +12,18 @@ interface Props {
|
|
|
12
12
|
class?: string;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
const {
|
|
15
|
+
const {
|
|
16
|
+
variant = "block",
|
|
17
|
+
width,
|
|
18
|
+
height,
|
|
19
|
+
radius,
|
|
20
|
+
class: className,
|
|
21
|
+
...rest
|
|
22
|
+
} = Astro.props;
|
|
16
23
|
|
|
17
|
-
const classes = ["ui-skel", `ui-skel--${variant}`, className]
|
|
24
|
+
const classes = ["ui-skel", `ui-skel--${variant}`, className]
|
|
25
|
+
.filter(Boolean)
|
|
26
|
+
.join(" ");
|
|
18
27
|
|
|
19
28
|
const style = [
|
|
20
29
|
width && `width:${width}`,
|
|
@@ -25,7 +34,12 @@ const style = [
|
|
|
25
34
|
.join(";");
|
|
26
35
|
---
|
|
27
36
|
|
|
28
|
-
<span
|
|
37
|
+
<span
|
|
38
|
+
class={classes}
|
|
39
|
+
style={style || undefined}
|
|
40
|
+
aria-hidden="true"
|
|
41
|
+
{...rest}
|
|
42
|
+
></span>
|
|
29
43
|
|
|
30
44
|
<style>
|
|
31
45
|
.ui-skel {
|
package/src/astro/Social.astro
CHANGED
|
@@ -35,7 +35,8 @@ const classes = ["ui-social", className].filter(Boolean).join(" ");
|
|
|
35
35
|
height: 40px;
|
|
36
36
|
border-radius: var(--radius-md);
|
|
37
37
|
color: var(--ivory-light);
|
|
38
|
-
transition:
|
|
38
|
+
transition:
|
|
39
|
+
color var(--duration-fast) var(--ease-standard),
|
|
39
40
|
background-color var(--duration-fast) var(--ease-standard);
|
|
40
41
|
}
|
|
41
42
|
.ui-social:hover {
|
|
@@ -20,9 +20,18 @@ interface Props {
|
|
|
20
20
|
class?: string;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
const {
|
|
23
|
+
const {
|
|
24
|
+
steps,
|
|
25
|
+
current,
|
|
26
|
+
label,
|
|
27
|
+
mobile = false,
|
|
28
|
+
class: className,
|
|
29
|
+
...rest
|
|
30
|
+
} = Astro.props;
|
|
24
31
|
|
|
25
|
-
const classes = ["ui-steps", mobile && "ui-steps--mobile", className]
|
|
32
|
+
const classes = ["ui-steps", mobile && "ui-steps--mobile", className]
|
|
33
|
+
.filter(Boolean)
|
|
34
|
+
.join(" ");
|
|
26
35
|
---
|
|
27
36
|
|
|
28
37
|
<nav class={classes} aria-label={label} {...rest}>
|
|
@@ -31,7 +40,10 @@ const classes = ["ui-steps", mobile && "ui-steps--mobile", className].filter(Boo
|
|
|
31
40
|
return (
|
|
32
41
|
<>
|
|
33
42
|
{i > 0 && <span class="ui-steps__sep"></span>}
|
|
34
|
-
<span
|
|
43
|
+
<span
|
|
44
|
+
class={["ui-step", state].filter(Boolean).join(" ")}
|
|
45
|
+
aria-current={i === current ? "step" : undefined}
|
|
46
|
+
>
|
|
35
47
|
<span class="ui-step__dot" aria-hidden="true">
|
|
36
48
|
{i < current ? <Icon name="check" size={11} stroke={3} /> : i + 1}
|
|
37
49
|
</span>
|
package/src/astro/Sticker.astro
CHANGED
|
@@ -15,12 +15,33 @@ const classes = ["pl-sticker", `pl-sticker--${size}`, className]
|
|
|
15
15
|
<span class={classes} aria-hidden="true" {...rest}>
|
|
16
16
|
<svg class="pl-sticker__disc" viewBox="0 0 112 112">
|
|
17
17
|
<circle cx="56" cy="56" r="52" fill="var(--surface-inverse)"></circle>
|
|
18
|
-
<circle
|
|
18
|
+
<circle
|
|
19
|
+
class="pl-sticker__ring"
|
|
20
|
+
cx="56"
|
|
21
|
+
cy="56"
|
|
22
|
+
r="47"
|
|
23
|
+
fill="none"
|
|
24
|
+
stroke="var(--sage-light)"
|
|
25
|
+
stroke-width="1.5"
|
|
26
|
+
stroke-dasharray="5 7"
|
|
27
|
+
></circle>
|
|
19
28
|
</svg>
|
|
20
29
|
<span class="pl-sticker__content">
|
|
21
|
-
<span
|
|
30
|
+
<span>
|
|
31
|
+
<slot />
|
|
32
|
+
</span>
|
|
22
33
|
{arrow && (
|
|
23
|
-
<svg
|
|
34
|
+
<svg
|
|
35
|
+
class="pl-sticker__arrow"
|
|
36
|
+
width="18"
|
|
37
|
+
height="18"
|
|
38
|
+
viewBox="0 0 24 24"
|
|
39
|
+
fill="none"
|
|
40
|
+
stroke="currentColor"
|
|
41
|
+
stroke-width="2.4"
|
|
42
|
+
stroke-linecap="round"
|
|
43
|
+
stroke-linejoin="round"
|
|
44
|
+
>
|
|
24
45
|
<path d="M12 5v14M6 13l6 6 6-6"></path>
|
|
25
46
|
</svg>
|
|
26
47
|
)}
|
|
@@ -5,7 +5,11 @@ interface Props {
|
|
|
5
5
|
class?: string;
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
const {
|
|
8
|
+
const {
|
|
9
|
+
label = "Uitgelichte artikelen",
|
|
10
|
+
class: className,
|
|
11
|
+
...rest
|
|
12
|
+
} = Astro.props;
|
|
9
13
|
const classes = ["pl-carousel", className].filter(Boolean).join(" ");
|
|
10
14
|
---
|
|
11
15
|
|
package/src/astro/Table.astro
CHANGED
|
@@ -27,8 +27,14 @@ interface Props {
|
|
|
27
27
|
class?: string;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
const {
|
|
31
|
-
|
|
30
|
+
const {
|
|
31
|
+
columns,
|
|
32
|
+
numeric = false,
|
|
33
|
+
busy = false,
|
|
34
|
+
caption,
|
|
35
|
+
class: className,
|
|
36
|
+
...rest
|
|
37
|
+
} = Astro.props;
|
|
32
38
|
|
|
33
39
|
const classes = ["ui-table", numeric && "ui-table--numeric", className]
|
|
34
40
|
.filter(Boolean)
|
|
@@ -15,8 +15,12 @@ const classes = ["ui-tablecard", className].filter(Boolean).join(" ");
|
|
|
15
15
|
---
|
|
16
16
|
|
|
17
17
|
<div class={classes} aria-hidden={busy ? "true" : undefined} {...rest}>
|
|
18
|
-
<span class="ui-tablecard__main"
|
|
19
|
-
|
|
18
|
+
<span class="ui-tablecard__main">
|
|
19
|
+
<slot name="main" />
|
|
20
|
+
</span>
|
|
21
|
+
<span class="ui-tablecard__end">
|
|
22
|
+
<slot name="end" />
|
|
23
|
+
</span>
|
|
20
24
|
</div>
|
|
21
25
|
|
|
22
26
|
<style>
|
|
@@ -64,14 +64,19 @@ const inputClasses = [
|
|
|
64
64
|
.filter(Boolean)
|
|
65
65
|
.join(" ");
|
|
66
66
|
|
|
67
|
-
const charCount =
|
|
67
|
+
const charCount =
|
|
68
|
+
count && maxlength ? `${String(value).length} / ${maxlength}` : null;
|
|
68
69
|
---
|
|
69
70
|
|
|
70
71
|
<label class={["ui-field", className].filter(Boolean).join(" ")}>
|
|
71
72
|
{label && (
|
|
72
73
|
<span class="ui-field__label">
|
|
73
74
|
{label}
|
|
74
|
-
{required &&
|
|
75
|
+
{required && (
|
|
76
|
+
<span class="ui-field__req" aria-hidden="true">
|
|
77
|
+
*
|
|
78
|
+
</span>
|
|
79
|
+
)}
|
|
75
80
|
</span>
|
|
76
81
|
)}
|
|
77
82
|
|
|
@@ -115,7 +120,11 @@ const charCount = count && maxlength ? `${String(value).length} / ${maxlength}`
|
|
|
115
120
|
{error}
|
|
116
121
|
</span>
|
|
117
122
|
) : (
|
|
118
|
-
hint &&
|
|
123
|
+
hint && (
|
|
124
|
+
<span class="ui-field__hint" id={hintId}>
|
|
125
|
+
{hint}
|
|
126
|
+
</span>
|
|
127
|
+
)
|
|
119
128
|
)}
|
|
120
129
|
|
|
121
130
|
{charCount && <span class="ui-field__count">{charCount}</span>}
|
package/src/react/Drawer.tsx
CHANGED
package/src/react/Modal.tsx
CHANGED
|
@@ -89,7 +89,9 @@ export default function Modal({
|
|
|
89
89
|
if (!panel) return;
|
|
90
90
|
const items = Array.from(
|
|
91
91
|
panel.querySelectorAll<HTMLElement>(FOCUSABLE),
|
|
92
|
-
).filter(
|
|
92
|
+
).filter(
|
|
93
|
+
(el) => el.offsetParent !== null || el === document.activeElement,
|
|
94
|
+
);
|
|
93
95
|
if (items.length === 0) {
|
|
94
96
|
e.preventDefault();
|
|
95
97
|
panel.focus();
|
|
@@ -124,11 +126,7 @@ export default function Modal({
|
|
|
124
126
|
>
|
|
125
127
|
<div
|
|
126
128
|
ref={panelRef}
|
|
127
|
-
className={[
|
|
128
|
-
"ui-modal",
|
|
129
|
-
isSheet && "ui-sheet",
|
|
130
|
-
className,
|
|
131
|
-
]
|
|
129
|
+
className={["ui-modal", isSheet && "ui-sheet", className]
|
|
132
130
|
.filter(Boolean)
|
|
133
131
|
.join(" ")}
|
|
134
132
|
role="dialog"
|
|
@@ -29,7 +29,13 @@ export interface NewsCarouselProps {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
const ChevronIcon = ({ direction }: { direction: "left" | "right" }) => (
|
|
32
|
-
<svg
|
|
32
|
+
<svg
|
|
33
|
+
width={18}
|
|
34
|
+
height={18}
|
|
35
|
+
viewBox="0 0 24 24"
|
|
36
|
+
fill="none"
|
|
37
|
+
aria-hidden="true"
|
|
38
|
+
>
|
|
33
39
|
<path
|
|
34
40
|
d={direction === "left" ? "M15 6l-6 6 6 6" : "M9 6l6 6-6 6"}
|
|
35
41
|
stroke="currentColor"
|
package/src/react/Select.tsx
CHANGED
|
@@ -129,7 +129,9 @@ export default function Select({
|
|
|
129
129
|
const openList = useCallback(() => {
|
|
130
130
|
if (disabled) return;
|
|
131
131
|
setOpen(true);
|
|
132
|
-
const current = selectable.findIndex(
|
|
132
|
+
const current = selectable.findIndex(
|
|
133
|
+
(o) => o.value === value && !o.disabled,
|
|
134
|
+
);
|
|
133
135
|
const firstEnabled = selectable.findIndex((o) => !o.disabled);
|
|
134
136
|
setActiveIndex(current >= 0 ? current : firstEnabled);
|
|
135
137
|
}, [disabled, selectable, value]);
|
|
@@ -236,7 +238,11 @@ export default function Select({
|
|
|
236
238
|
|
|
237
239
|
const describedBy = [errorId, hintId].filter(Boolean).join(" ") || undefined;
|
|
238
240
|
|
|
239
|
-
const fieldClasses = [
|
|
241
|
+
const fieldClasses = [
|
|
242
|
+
"ui-select",
|
|
243
|
+
invalid && "ui-select--invalid",
|
|
244
|
+
open && "is-open",
|
|
245
|
+
]
|
|
240
246
|
.filter(Boolean)
|
|
241
247
|
.join(" ");
|
|
242
248
|
|
package/src/react/Toast.tsx
CHANGED
|
@@ -71,20 +71,54 @@ export function Toast({
|
|
|
71
71
|
>
|
|
72
72
|
<span className="ui-toast__icon" aria-hidden="true">
|
|
73
73
|
{tone === "success" ? (
|
|
74
|
-
<svg
|
|
74
|
+
<svg
|
|
75
|
+
width="18"
|
|
76
|
+
height="18"
|
|
77
|
+
viewBox="0 0 24 24"
|
|
78
|
+
fill="none"
|
|
79
|
+
stroke="currentColor"
|
|
80
|
+
strokeWidth="2.4"
|
|
81
|
+
strokeLinecap="round"
|
|
82
|
+
strokeLinejoin="round"
|
|
83
|
+
>
|
|
75
84
|
<path d="M5 13l4 4L19 7" />
|
|
76
85
|
</svg>
|
|
77
86
|
) : tone === "warning" ? (
|
|
78
|
-
<svg
|
|
87
|
+
<svg
|
|
88
|
+
width="18"
|
|
89
|
+
height="18"
|
|
90
|
+
viewBox="0 0 24 24"
|
|
91
|
+
fill="none"
|
|
92
|
+
stroke="currentColor"
|
|
93
|
+
strokeWidth="2"
|
|
94
|
+
strokeLinecap="round"
|
|
95
|
+
strokeLinejoin="round"
|
|
96
|
+
>
|
|
79
97
|
<path d="M12 4l8.5 15h-17L12 4zM12 10v4M12 16.5v.5" />
|
|
80
98
|
</svg>
|
|
81
99
|
) : tone === "info" ? (
|
|
82
|
-
<svg
|
|
100
|
+
<svg
|
|
101
|
+
width="18"
|
|
102
|
+
height="18"
|
|
103
|
+
viewBox="0 0 24 24"
|
|
104
|
+
fill="none"
|
|
105
|
+
stroke="currentColor"
|
|
106
|
+
strokeWidth="2"
|
|
107
|
+
strokeLinecap="round"
|
|
108
|
+
>
|
|
83
109
|
<circle cx="12" cy="12" r="9" />
|
|
84
110
|
<path d="M12 11v5M12 8v.5" />
|
|
85
111
|
</svg>
|
|
86
112
|
) : (
|
|
87
|
-
<svg
|
|
113
|
+
<svg
|
|
114
|
+
width="18"
|
|
115
|
+
height="18"
|
|
116
|
+
viewBox="0 0 24 24"
|
|
117
|
+
fill="none"
|
|
118
|
+
stroke="currentColor"
|
|
119
|
+
strokeWidth="2"
|
|
120
|
+
strokeLinecap="round"
|
|
121
|
+
>
|
|
88
122
|
<circle cx="12" cy="12" r="9" />
|
|
89
123
|
<path d="M12 8v4.5M12 16v.5" />
|
|
90
124
|
</svg>
|