@dillingerstaffing/strand-ui 0.5.1 → 0.6.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/HTML_REFERENCE.md +15 -2
- package/dist/components/Alert/Alert.d.ts.map +1 -1
- package/dist/components/Toast/Toast.d.ts.map +1 -1
- package/dist/css/strand-ui.css +49 -38
- package/dist/index.js +51 -48
- package/package.json +2 -2
- package/src/components/Alert/Alert.css +24 -13
- package/src/components/Alert/Alert.test.tsx +30 -0
- package/src/components/Alert/Alert.tsx +4 -0
- package/src/components/CodeBlock/CodeBlock.css +1 -1
- package/src/components/FormField/FormField.css +5 -3
- package/src/components/Tabs/Tabs.css +1 -1
- package/src/components/Tag/Tag.css +3 -3
- package/src/components/Toast/Toast.css +15 -17
- package/src/components/Toast/Toast.test.tsx +28 -0
- package/src/components/Toast/Toast.tsx +8 -0
package/HTML_REFERENCE.md
CHANGED
|
@@ -8,9 +8,20 @@
|
|
|
8
8
|
|
|
9
9
|
## Required CSS
|
|
10
10
|
|
|
11
|
+
**CDN (no install):**
|
|
12
|
+
|
|
13
|
+
```html
|
|
14
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@dillingerstaffing/strand@0.5/css/tokens.css">
|
|
15
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@dillingerstaffing/strand@0.5/css/reset.css">
|
|
16
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@dillingerstaffing/strand@0.5/css/base.css">
|
|
17
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@dillingerstaffing/strand-ui@0.5/dist/css/strand-ui.css">
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
**npm:**
|
|
21
|
+
|
|
11
22
|
```html
|
|
12
|
-
<link rel="stylesheet" href="
|
|
13
|
-
<link rel="stylesheet" href="
|
|
23
|
+
<link rel="stylesheet" href="node_modules/@dillingerstaffing/strand/css/tokens.css">
|
|
24
|
+
<link rel="stylesheet" href="node_modules/@dillingerstaffing/strand-ui/dist/css/strand-ui.css">
|
|
14
25
|
```
|
|
15
26
|
|
|
16
27
|
> **Token roles:** Don't guess which token to use. See [DESIGN_LANGUAGE.md 3.8: Color Roles (L290-L311)](./DESIGN_LANGUAGE.md#L290) for which color in which context, and [Appendix B: Token Quick Reference (L1372-L1431)](./DESIGN_LANGUAGE.md#L1372) for the full lookup table.
|
|
@@ -608,6 +619,7 @@ All container components (Grid, Stack, Card, Container) enforce boundary integri
|
|
|
608
619
|
|
|
609
620
|
```html
|
|
610
621
|
<div class="strand-toast strand-toast--info" role="status" aria-live="polite">
|
|
622
|
+
<span class="strand-toast__status">INFO</span>
|
|
611
623
|
<span class="strand-toast__message">Changes saved successfully.</span>
|
|
612
624
|
<button type="button" class="strand-toast__dismiss" aria-label="Dismiss">×</button>
|
|
613
625
|
</div>
|
|
@@ -630,6 +642,7 @@ All container components (Grid, Stack, Card, Container) enforce boundary integri
|
|
|
630
642
|
|
|
631
643
|
```html
|
|
632
644
|
<div class="strand-alert strand-alert--info" role="status">
|
|
645
|
+
<span class="strand-alert__status">INFO</span>
|
|
633
646
|
<div class="strand-alert__content">This is an informational message.</div>
|
|
634
647
|
</div>
|
|
635
648
|
```
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Alert.d.ts","sourceRoot":"","sources":["../../../src/components/Alert/Alert.tsx"],"names":[],"mappings":"AAAA,sDAAsD;AAEtD,OAAO,KAAK,EAAE,iBAAiB,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAGrD,MAAM,WAAW,UACf,SAAQ,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,QAAQ,CAAC;IAC1D,iCAAiC;IACjC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;IAClD,0BAA0B;IAC1B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,oBAAoB;IACpB,QAAQ,CAAC,EAAE,iBAAiB,CAAC;CAC9B;AAED,eAAO,MAAM,KAAK;;
|
|
1
|
+
{"version":3,"file":"Alert.d.ts","sourceRoot":"","sources":["../../../src/components/Alert/Alert.tsx"],"names":[],"mappings":"AAAA,sDAAsD;AAEtD,OAAO,KAAK,EAAE,iBAAiB,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAGrD,MAAM,WAAW,UACf,SAAQ,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,QAAQ,CAAC;IAC1D,iCAAiC;IACjC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;IAClD,0BAA0B;IAC1B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,oBAAoB;IACpB,QAAQ,CAAC,EAAE,iBAAiB,CAAC;CAC9B;AAED,eAAO,MAAM,KAAK;;EA2CjB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Toast.d.ts","sourceRoot":"","sources":["../../../src/components/Toast/Toast.tsx"],"names":[],"mappings":"AAAA,sDAAsD;AAEtD,OAAO,KAAK,EAAE,iBAAiB,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAKrD,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AAEnE,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAOD,UAAU,iBAAiB;IACzB,KAAK,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,CAAC;CACxC;AAID,wBAAgB,QAAQ,IAAI,iBAAiB,CAM5C;AAID,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,aAAa;8BAAkC,kBAAkB;;CAqC7E,CAAC;
|
|
1
|
+
{"version":3,"file":"Toast.d.ts","sourceRoot":"","sources":["../../../src/components/Toast/Toast.tsx"],"names":[],"mappings":"AAAA,sDAAsD;AAEtD,OAAO,KAAK,EAAE,iBAAiB,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAKrD,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AAEnE,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAOD,UAAU,iBAAiB;IACzB,KAAK,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,CAAC;CACxC;AAID,wBAAgB,QAAQ,IAAI,iBAAiB,CAM5C;AAID,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,aAAa;8BAAkC,kBAAkB;;CAqC7E,CAAC;AAwDF,MAAM,WAAW,UACf,SAAQ,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,QAAQ,CAAC;IAC1D,oBAAoB;IACpB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,yBAAyB;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB;AAED,eAAO,MAAM,KAAK;;EAsCjB,CAAC"}
|
package/dist/css/strand-ui.css
CHANGED
|
@@ -11,34 +11,45 @@
|
|
|
11
11
|
justify-content: space-between;
|
|
12
12
|
width: 100%;
|
|
13
13
|
padding: var(--strand-space-6);
|
|
14
|
-
padding-left: var(--strand-space-5);
|
|
15
14
|
border-radius: var(--strand-radius-md);
|
|
16
|
-
border-left: 4px solid transparent;
|
|
17
15
|
font-family: var(--strand-font-sans);
|
|
18
16
|
font-size: var(--strand-text-sm);
|
|
17
|
+
background: var(--strand-surface-recessed);
|
|
19
18
|
}
|
|
20
19
|
|
|
21
|
-
/* ── Status variants ── */
|
|
20
|
+
/* ── Status variants (neutral background, status color on prefix only) ── */
|
|
22
21
|
.strand-alert--info {
|
|
23
|
-
background: var(--strand-
|
|
24
|
-
border-left-color: var(--strand-blue-primary);
|
|
22
|
+
background: var(--strand-surface-recessed);
|
|
25
23
|
}
|
|
26
24
|
|
|
27
25
|
.strand-alert--success {
|
|
28
|
-
background:
|
|
29
|
-
border-left-color: var(--strand-green-positive);
|
|
26
|
+
background: var(--strand-surface-recessed);
|
|
30
27
|
}
|
|
31
28
|
|
|
32
29
|
.strand-alert--warning {
|
|
33
|
-
background:
|
|
34
|
-
border-left-color: var(--strand-amber-caution);
|
|
30
|
+
background: var(--strand-surface-recessed);
|
|
35
31
|
}
|
|
36
32
|
|
|
37
33
|
.strand-alert--error {
|
|
38
|
-
background:
|
|
39
|
-
|
|
34
|
+
background: var(--strand-surface-recessed);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/* ── Status prefix ── */
|
|
38
|
+
.strand-alert__status {
|
|
39
|
+
font-family: var(--strand-font-mono);
|
|
40
|
+
font-size: var(--strand-text-xs);
|
|
41
|
+
font-weight: var(--strand-weight-semibold);
|
|
42
|
+
letter-spacing: var(--strand-tracking-wider);
|
|
43
|
+
text-transform: uppercase;
|
|
44
|
+
margin-right: var(--strand-space-3);
|
|
45
|
+
flex-shrink: 0;
|
|
40
46
|
}
|
|
41
47
|
|
|
48
|
+
.strand-alert--info .strand-alert__status { color: var(--strand-blue-primary); }
|
|
49
|
+
.strand-alert--success .strand-alert__status { color: var(--strand-teal-vital); }
|
|
50
|
+
.strand-alert--warning .strand-alert__status { color: var(--strand-amber-caution); }
|
|
51
|
+
.strand-alert--error .strand-alert__status { color: var(--strand-red-alert); }
|
|
52
|
+
|
|
42
53
|
/* ── Content ── */
|
|
43
54
|
.strand-alert__content {
|
|
44
55
|
flex: 1;
|
|
@@ -51,8 +62,8 @@
|
|
|
51
62
|
display: inline-flex;
|
|
52
63
|
align-items: center;
|
|
53
64
|
justify-content: center;
|
|
54
|
-
width:
|
|
55
|
-
height:
|
|
65
|
+
width: var(--strand-space-6);
|
|
66
|
+
height: var(--strand-space-6);
|
|
56
67
|
margin-left: var(--strand-space-4);
|
|
57
68
|
padding: 0;
|
|
58
69
|
border: none;
|
|
@@ -660,7 +671,7 @@
|
|
|
660
671
|
line-height: var(--strand-leading-relaxed);
|
|
661
672
|
color: var(--strand-blue-midnight);
|
|
662
673
|
background: var(--strand-surface-recessed);
|
|
663
|
-
box-shadow: inset 0 1px 3px rgba(15, 23, 42, 0.06);
|
|
674
|
+
box-shadow: inset 0 1px 3px rgba(15, 23, 42, 0.06); /* strand-blue-abyss at 6% opacity */
|
|
664
675
|
border-radius: var(--strand-radius-lg);
|
|
665
676
|
padding: var(--strand-space-3) var(--strand-space-4);
|
|
666
677
|
overflow-x: auto;
|
|
@@ -893,10 +904,12 @@
|
|
|
893
904
|
|
|
894
905
|
/* ── Label ── */
|
|
895
906
|
.strand-form-field__label {
|
|
896
|
-
font-family: var(--strand-font-
|
|
897
|
-
font-size: var(--strand-text-
|
|
907
|
+
font-family: var(--strand-font-mono);
|
|
908
|
+
font-size: var(--strand-text-xs);
|
|
898
909
|
font-weight: var(--strand-weight-medium);
|
|
899
|
-
|
|
910
|
+
letter-spacing: var(--strand-tracking-widest);
|
|
911
|
+
text-transform: uppercase;
|
|
912
|
+
color: var(--strand-gray-500);
|
|
900
913
|
line-height: var(--strand-leading-snug);
|
|
901
914
|
}
|
|
902
915
|
|
|
@@ -2065,7 +2078,7 @@
|
|
|
2065
2078
|
.strand-tabs [role="tablist"] {
|
|
2066
2079
|
display: flex;
|
|
2067
2080
|
gap: var(--strand-space-1);
|
|
2068
|
-
border-bottom: 1px solid var(--strand-gray-
|
|
2081
|
+
border-bottom: 1px solid var(--strand-gray-200);
|
|
2069
2082
|
}
|
|
2070
2083
|
|
|
2071
2084
|
/* ── Tab button ── */
|
|
@@ -2137,7 +2150,7 @@
|
|
|
2137
2150
|
}
|
|
2138
2151
|
|
|
2139
2152
|
.strand-tag--solid.strand-tag--teal {
|
|
2140
|
-
background:
|
|
2153
|
+
background: var(--strand-surface-recessed);
|
|
2141
2154
|
color: var(--strand-on-teal-tint);
|
|
2142
2155
|
}
|
|
2143
2156
|
|
|
@@ -2147,12 +2160,12 @@
|
|
|
2147
2160
|
}
|
|
2148
2161
|
|
|
2149
2162
|
.strand-tag--solid.strand-tag--amber {
|
|
2150
|
-
background:
|
|
2163
|
+
background: var(--strand-surface-recessed);
|
|
2151
2164
|
color: var(--strand-on-amber-tint);
|
|
2152
2165
|
}
|
|
2153
2166
|
|
|
2154
2167
|
.strand-tag--solid.strand-tag--red {
|
|
2155
|
-
background:
|
|
2168
|
+
background: var(--strand-surface-recessed);
|
|
2156
2169
|
color: var(--strand-on-red-tint);
|
|
2157
2170
|
}
|
|
2158
2171
|
|
|
@@ -2321,7 +2334,6 @@
|
|
|
2321
2334
|
padding: var(--strand-space-4) var(--strand-space-5);
|
|
2322
2335
|
background: var(--strand-surface-elevated);
|
|
2323
2336
|
border-radius: var(--strand-radius-lg);
|
|
2324
|
-
border-left: 4px solid transparent;
|
|
2325
2337
|
box-shadow: var(--strand-elevation-3);
|
|
2326
2338
|
font-family: var(--strand-font-sans);
|
|
2327
2339
|
font-size: var(--strand-text-sm);
|
|
@@ -2329,22 +2341,21 @@
|
|
|
2329
2341
|
animation: strand-toast-in var(--strand-duration-normal) var(--strand-ease-out-expo);
|
|
2330
2342
|
}
|
|
2331
2343
|
|
|
2332
|
-
/* ── Status
|
|
2333
|
-
.strand-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
.strand-toast--warning {
|
|
2342
|
-
border-left-color: var(--strand-amber-caution);
|
|
2344
|
+
/* ── Status prefix ── */
|
|
2345
|
+
.strand-toast__status {
|
|
2346
|
+
font-family: var(--strand-font-mono);
|
|
2347
|
+
font-size: var(--strand-text-xs);
|
|
2348
|
+
font-weight: var(--strand-weight-semibold);
|
|
2349
|
+
letter-spacing: var(--strand-tracking-wider);
|
|
2350
|
+
text-transform: uppercase;
|
|
2351
|
+
margin-right: var(--strand-space-3);
|
|
2352
|
+
flex-shrink: 0;
|
|
2343
2353
|
}
|
|
2344
2354
|
|
|
2345
|
-
.strand-toast--
|
|
2346
|
-
|
|
2347
|
-
}
|
|
2355
|
+
.strand-toast--info .strand-toast__status { color: var(--strand-blue-primary); }
|
|
2356
|
+
.strand-toast--success .strand-toast__status { color: var(--strand-teal-vital); }
|
|
2357
|
+
.strand-toast--warning .strand-toast__status { color: var(--strand-amber-caution); }
|
|
2358
|
+
.strand-toast--error .strand-toast__status { color: var(--strand-red-alert); }
|
|
2348
2359
|
|
|
2349
2360
|
/* ── Message ── */
|
|
2350
2361
|
.strand-toast__message {
|
|
@@ -2359,8 +2370,8 @@
|
|
|
2359
2370
|
display: inline-flex;
|
|
2360
2371
|
align-items: center;
|
|
2361
2372
|
justify-content: center;
|
|
2362
|
-
width:
|
|
2363
|
-
height:
|
|
2373
|
+
width: var(--strand-space-6);
|
|
2374
|
+
height: var(--strand-space-6);
|
|
2364
2375
|
margin-left: var(--strand-space-3);
|
|
2365
2376
|
padding: 0;
|
|
2366
2377
|
border: none;
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { jsxs as _, jsx as s } from "preact/jsx-runtime";
|
|
2
2
|
import { forwardRef as p } from "preact/compat";
|
|
3
|
-
import { useRef as k, useCallback as v, useEffect as
|
|
4
|
-
import { createContext as
|
|
5
|
-
const
|
|
3
|
+
import { useRef as k, useCallback as v, useEffect as C, useState as B, useContext as E } from "preact/hooks";
|
|
4
|
+
import { createContext as R } from "preact";
|
|
5
|
+
const I = p(
|
|
6
6
|
({
|
|
7
7
|
variant: a = "primary",
|
|
8
8
|
size: t = "md",
|
|
@@ -51,8 +51,8 @@ const E = p(
|
|
|
51
51
|
);
|
|
52
52
|
}
|
|
53
53
|
);
|
|
54
|
-
|
|
55
|
-
const
|
|
54
|
+
I.displayName = "Button";
|
|
55
|
+
const L = p(
|
|
56
56
|
({
|
|
57
57
|
type: a = "text",
|
|
58
58
|
error: t = !1,
|
|
@@ -87,8 +87,8 @@ const K = p(
|
|
|
87
87
|
] });
|
|
88
88
|
}
|
|
89
89
|
);
|
|
90
|
-
|
|
91
|
-
const
|
|
90
|
+
L.displayName = "Input";
|
|
91
|
+
const K = p(
|
|
92
92
|
({
|
|
93
93
|
autoResize: a = !1,
|
|
94
94
|
showCount: t = !1,
|
|
@@ -139,8 +139,8 @@ const A = p(
|
|
|
139
139
|
] });
|
|
140
140
|
}
|
|
141
141
|
);
|
|
142
|
-
|
|
143
|
-
const
|
|
142
|
+
K.displayName = "Textarea";
|
|
143
|
+
const M = p(
|
|
144
144
|
({
|
|
145
145
|
options: a,
|
|
146
146
|
value: t,
|
|
@@ -178,8 +178,8 @@ const L = p(
|
|
|
178
178
|
] });
|
|
179
179
|
}
|
|
180
180
|
);
|
|
181
|
-
|
|
182
|
-
const
|
|
181
|
+
M.displayName = "Select";
|
|
182
|
+
const A = p(
|
|
183
183
|
({
|
|
184
184
|
checked: a = !1,
|
|
185
185
|
indeterminate: t = !1,
|
|
@@ -190,7 +190,7 @@ const M = p(
|
|
|
190
190
|
...r
|
|
191
191
|
}, i) => {
|
|
192
192
|
const c = k(null);
|
|
193
|
-
|
|
193
|
+
C(() => {
|
|
194
194
|
const f = typeof i == "function" ? c.current : (i == null ? void 0 : i.current) ?? c.current;
|
|
195
195
|
f && (f.indeterminate = t);
|
|
196
196
|
}, [t, i]);
|
|
@@ -272,7 +272,7 @@ const M = p(
|
|
|
272
272
|
);
|
|
273
273
|
}
|
|
274
274
|
);
|
|
275
|
-
|
|
275
|
+
A.displayName = "Checkbox";
|
|
276
276
|
const P = p(
|
|
277
277
|
({
|
|
278
278
|
checked: a = !1,
|
|
@@ -351,7 +351,7 @@ const F = p(
|
|
|
351
351
|
}
|
|
352
352
|
);
|
|
353
353
|
F.displayName = "Switch";
|
|
354
|
-
const
|
|
354
|
+
const U = p(
|
|
355
355
|
({
|
|
356
356
|
min: a = 0,
|
|
357
357
|
max: t = 100,
|
|
@@ -387,8 +387,8 @@ const q = p(
|
|
|
387
387
|
) });
|
|
388
388
|
}
|
|
389
389
|
);
|
|
390
|
-
|
|
391
|
-
const
|
|
390
|
+
U.displayName = "Slider";
|
|
391
|
+
const q = p(
|
|
392
392
|
({
|
|
393
393
|
label: a,
|
|
394
394
|
htmlFor: t,
|
|
@@ -421,8 +421,8 @@ const G = p(
|
|
|
421
421
|
] });
|
|
422
422
|
}
|
|
423
423
|
);
|
|
424
|
-
|
|
425
|
-
const
|
|
424
|
+
q.displayName = "FormField";
|
|
425
|
+
const O = p(
|
|
426
426
|
({
|
|
427
427
|
variant: a = "elevated",
|
|
428
428
|
padding: t = "md",
|
|
@@ -439,8 +439,8 @@ const H = p(
|
|
|
439
439
|
return /* @__PURE__ */ s("div", { ref: o, className: r, ...l, children: n });
|
|
440
440
|
}
|
|
441
441
|
);
|
|
442
|
-
|
|
443
|
-
const
|
|
442
|
+
O.displayName = "Card";
|
|
443
|
+
const G = p(
|
|
444
444
|
({
|
|
445
445
|
variant: a = "count",
|
|
446
446
|
status: t = "default",
|
|
@@ -470,8 +470,8 @@ const U = p(
|
|
|
470
470
|
] });
|
|
471
471
|
}
|
|
472
472
|
);
|
|
473
|
-
|
|
474
|
-
const
|
|
473
|
+
G.displayName = "Badge";
|
|
474
|
+
const H = p(
|
|
475
475
|
({
|
|
476
476
|
src: a,
|
|
477
477
|
alt: t = "",
|
|
@@ -498,8 +498,8 @@ const V = p(
|
|
|
498
498
|
) : /* @__PURE__ */ s("span", { className: "strand-avatar__initials", "aria-hidden": "true", children: h }) });
|
|
499
499
|
}
|
|
500
500
|
);
|
|
501
|
-
|
|
502
|
-
const
|
|
501
|
+
H.displayName = "Avatar";
|
|
502
|
+
const V = p(
|
|
503
503
|
({
|
|
504
504
|
variant: a = "solid",
|
|
505
505
|
status: t = "default",
|
|
@@ -548,7 +548,7 @@ const O = p(
|
|
|
548
548
|
] });
|
|
549
549
|
}
|
|
550
550
|
);
|
|
551
|
-
|
|
551
|
+
V.displayName = "Tag";
|
|
552
552
|
const z = p(
|
|
553
553
|
({ columns: a, data: t, onSort: e, className: n = "", ...l }, o) => {
|
|
554
554
|
const [r, i] = B(null), [c, u] = B("asc"), d = v(
|
|
@@ -950,9 +950,9 @@ const na = p(
|
|
|
950
950
|
}
|
|
951
951
|
);
|
|
952
952
|
na.displayName = "Nav";
|
|
953
|
-
const S =
|
|
953
|
+
const S = R(null);
|
|
954
954
|
function ga() {
|
|
955
|
-
const a =
|
|
955
|
+
const a = E(S);
|
|
956
956
|
if (!a)
|
|
957
957
|
throw new Error("useToast must be used within a ToastProvider");
|
|
958
958
|
return a;
|
|
@@ -985,10 +985,10 @@ const la = ({ children: a, className: t = "" }) => {
|
|
|
985
985
|
la.displayName = "ToastProvider";
|
|
986
986
|
function ia({ entry: a, onDismiss: t }) {
|
|
987
987
|
const e = k(null);
|
|
988
|
-
|
|
988
|
+
C(() => (a.duration > 0 && (e.current = setTimeout(t, a.duration)), () => {
|
|
989
989
|
e.current !== null && clearTimeout(e.current);
|
|
990
990
|
}), [a.duration, t]);
|
|
991
|
-
const n = a.status === "error" || a.status === "warning", l = ["strand-toast", `strand-toast--${a.status}`].filter(Boolean).join(" ");
|
|
991
|
+
const n = a.status === "error" || a.status === "warning", l = ["strand-toast", `strand-toast--${a.status}`].filter(Boolean).join(" "), o = a.status === "success" ? "COMPLETE" : a.status.toUpperCase();
|
|
992
992
|
return /* @__PURE__ */ _(
|
|
993
993
|
"div",
|
|
994
994
|
{
|
|
@@ -996,6 +996,7 @@ function ia({ entry: a, onDismiss: t }) {
|
|
|
996
996
|
role: "status",
|
|
997
997
|
"aria-live": n ? "assertive" : "polite",
|
|
998
998
|
children: [
|
|
999
|
+
/* @__PURE__ */ s("span", { className: "strand-toast__status", children: o }),
|
|
999
1000
|
/* @__PURE__ */ s("span", { className: "strand-toast__message", children: a.message }),
|
|
1000
1001
|
/* @__PURE__ */ s(
|
|
1001
1002
|
"button",
|
|
@@ -1017,7 +1018,7 @@ const oa = p(
|
|
|
1017
1018
|
"strand-toast",
|
|
1018
1019
|
`strand-toast--${a}`,
|
|
1019
1020
|
n
|
|
1020
|
-
].filter(Boolean).join(" ");
|
|
1021
|
+
].filter(Boolean).join(" "), c = a === "success" ? "COMPLETE" : a.toUpperCase();
|
|
1021
1022
|
return /* @__PURE__ */ _(
|
|
1022
1023
|
"div",
|
|
1023
1024
|
{
|
|
@@ -1027,6 +1028,7 @@ const oa = p(
|
|
|
1027
1028
|
"aria-live": r ? "assertive" : "polite",
|
|
1028
1029
|
...l,
|
|
1029
1030
|
children: [
|
|
1031
|
+
/* @__PURE__ */ s("span", { className: "strand-toast__status", children: c }),
|
|
1030
1032
|
/* @__PURE__ */ s("span", { className: "strand-toast__message", children: t }),
|
|
1031
1033
|
e && /* @__PURE__ */ s(
|
|
1032
1034
|
"button",
|
|
@@ -1057,8 +1059,9 @@ const da = p(
|
|
|
1057
1059
|
"strand-alert",
|
|
1058
1060
|
`strand-alert--${a}`,
|
|
1059
1061
|
n
|
|
1060
|
-
].filter(Boolean).join(" ");
|
|
1062
|
+
].filter(Boolean).join(" "), u = a === "success" ? "COMPLETE" : a.toUpperCase();
|
|
1061
1063
|
return /* @__PURE__ */ _("div", { ref: r, className: c, role: i, ...o, children: [
|
|
1064
|
+
/* @__PURE__ */ s("span", { className: "strand-alert__status", children: u }),
|
|
1062
1065
|
/* @__PURE__ */ s("div", { className: "strand-alert__content", children: l }),
|
|
1063
1066
|
t && /* @__PURE__ */ s(
|
|
1064
1067
|
"button",
|
|
@@ -1088,7 +1091,7 @@ const ua = p(
|
|
|
1088
1091
|
...i
|
|
1089
1092
|
}, c) => {
|
|
1090
1093
|
const u = k(null), d = k(null), m = k(`strand-dialog-title-${++ca}`).current;
|
|
1091
|
-
|
|
1094
|
+
C(() => {
|
|
1092
1095
|
if (!a) return;
|
|
1093
1096
|
d.current = document.activeElement;
|
|
1094
1097
|
const b = requestAnimationFrame(() => {
|
|
@@ -1102,7 +1105,7 @@ const ua = p(
|
|
|
1102
1105
|
const y = d.current;
|
|
1103
1106
|
y && y instanceof HTMLElement && y.focus();
|
|
1104
1107
|
};
|
|
1105
|
-
}, [a]),
|
|
1108
|
+
}, [a]), C(() => {
|
|
1106
1109
|
if (!a) return;
|
|
1107
1110
|
const b = document.body.style.overflow;
|
|
1108
1111
|
return document.body.style.overflow = "hidden", () => {
|
|
@@ -1224,7 +1227,7 @@ const ha = p(
|
|
|
1224
1227
|
}
|
|
1225
1228
|
);
|
|
1226
1229
|
ha.displayName = "Tooltip";
|
|
1227
|
-
const D = { sm: 24, md: 40, lg: 56 },
|
|
1230
|
+
const D = { sm: 24, md: 40, lg: 56 }, x = 3, pa = p(
|
|
1228
1231
|
({
|
|
1229
1232
|
variant: a = "bar",
|
|
1230
1233
|
value: t,
|
|
@@ -1244,7 +1247,7 @@ const D = { sm: 24, md: 40, lg: 56 }, C = 3, pa = p(
|
|
|
1244
1247
|
"aria-valuemax": 100
|
|
1245
1248
|
};
|
|
1246
1249
|
if (r && (c["aria-valuenow"] = t), a === "ring") {
|
|
1247
|
-
const u = D[e] ?? D.md, d = (u -
|
|
1250
|
+
const u = D[e] ?? D.md, d = (u - x) / 2, h = 2 * Math.PI * d, m = r ? h - h * t / 100 : 0;
|
|
1248
1251
|
return /* @__PURE__ */ s("div", { ref: o, className: i, ...c, ...l, children: /* @__PURE__ */ _(
|
|
1249
1252
|
"svg",
|
|
1250
1253
|
{
|
|
@@ -1260,7 +1263,7 @@ const D = { sm: 24, md: 40, lg: 56 }, C = 3, pa = p(
|
|
|
1260
1263
|
cy: u / 2,
|
|
1261
1264
|
r: d,
|
|
1262
1265
|
fill: "none",
|
|
1263
|
-
"stroke-width":
|
|
1266
|
+
"stroke-width": x,
|
|
1264
1267
|
className: "strand-progress__track"
|
|
1265
1268
|
}
|
|
1266
1269
|
),
|
|
@@ -1271,7 +1274,7 @@ const D = { sm: 24, md: 40, lg: 56 }, C = 3, pa = p(
|
|
|
1271
1274
|
cy: u / 2,
|
|
1272
1275
|
r: d,
|
|
1273
1276
|
fill: "none",
|
|
1274
|
-
"stroke-width":
|
|
1277
|
+
"stroke-width": x,
|
|
1275
1278
|
"stroke-dasharray": h,
|
|
1276
1279
|
"stroke-dashoffset": r ? m : void 0,
|
|
1277
1280
|
"stroke-linecap": "round",
|
|
@@ -1343,35 +1346,35 @@ const _a = p(
|
|
|
1343
1346
|
_a.displayName = "Skeleton";
|
|
1344
1347
|
export {
|
|
1345
1348
|
da as Alert,
|
|
1346
|
-
|
|
1347
|
-
|
|
1349
|
+
H as Avatar,
|
|
1350
|
+
G as Badge,
|
|
1348
1351
|
ta as Breadcrumb,
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
+
I as Button,
|
|
1353
|
+
O as Card,
|
|
1354
|
+
A as Checkbox,
|
|
1352
1355
|
Z as CodeBlock,
|
|
1353
1356
|
X as Container,
|
|
1354
1357
|
W as DataReadout,
|
|
1355
1358
|
ua as Dialog,
|
|
1356
1359
|
Y as Divider,
|
|
1357
|
-
|
|
1360
|
+
q as FormField,
|
|
1358
1361
|
Q as Grid,
|
|
1359
|
-
|
|
1362
|
+
L as Input,
|
|
1360
1363
|
ea as Link,
|
|
1361
1364
|
na as Nav,
|
|
1362
1365
|
pa as Progress,
|
|
1363
1366
|
P as Radio,
|
|
1364
1367
|
aa as Section,
|
|
1365
|
-
|
|
1368
|
+
M as Select,
|
|
1366
1369
|
_a as Skeleton,
|
|
1367
|
-
|
|
1370
|
+
U as Slider,
|
|
1368
1371
|
fa as Spinner,
|
|
1369
1372
|
J as Stack,
|
|
1370
1373
|
F as Switch,
|
|
1371
1374
|
z as Table,
|
|
1372
1375
|
sa as Tabs,
|
|
1373
|
-
|
|
1374
|
-
|
|
1376
|
+
V as Tag,
|
|
1377
|
+
K as Textarea,
|
|
1375
1378
|
oa as Toast,
|
|
1376
1379
|
la as ToastProvider,
|
|
1377
1380
|
ha as Tooltip,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dillingerstaffing/strand-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Strand UI - Preact/React component library built on the Strand Design Language",
|
|
5
5
|
"author": "Dillinger Staffing <engineering@dillingerstaffing.com> (https://dillingerstaffing.com)",
|
|
6
6
|
"license": "MIT",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
}
|
|
61
61
|
},
|
|
62
62
|
"dependencies": {
|
|
63
|
-
"@dillingerstaffing/strand": "^0.
|
|
63
|
+
"@dillingerstaffing/strand": "^0.6.0"
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|
|
66
66
|
"@testing-library/preact": "^3.2.0",
|
|
@@ -8,34 +8,45 @@
|
|
|
8
8
|
justify-content: space-between;
|
|
9
9
|
width: 100%;
|
|
10
10
|
padding: var(--strand-space-6);
|
|
11
|
-
padding-left: var(--strand-space-5);
|
|
12
11
|
border-radius: var(--strand-radius-md);
|
|
13
|
-
border-left: 4px solid transparent;
|
|
14
12
|
font-family: var(--strand-font-sans);
|
|
15
13
|
font-size: var(--strand-text-sm);
|
|
14
|
+
background: var(--strand-surface-recessed);
|
|
16
15
|
}
|
|
17
16
|
|
|
18
|
-
/* ── Status variants ── */
|
|
17
|
+
/* ── Status variants (neutral background, status color on prefix only) ── */
|
|
19
18
|
.strand-alert--info {
|
|
20
|
-
background: var(--strand-
|
|
21
|
-
border-left-color: var(--strand-blue-primary);
|
|
19
|
+
background: var(--strand-surface-recessed);
|
|
22
20
|
}
|
|
23
21
|
|
|
24
22
|
.strand-alert--success {
|
|
25
|
-
background:
|
|
26
|
-
border-left-color: var(--strand-green-positive);
|
|
23
|
+
background: var(--strand-surface-recessed);
|
|
27
24
|
}
|
|
28
25
|
|
|
29
26
|
.strand-alert--warning {
|
|
30
|
-
background:
|
|
31
|
-
border-left-color: var(--strand-amber-caution);
|
|
27
|
+
background: var(--strand-surface-recessed);
|
|
32
28
|
}
|
|
33
29
|
|
|
34
30
|
.strand-alert--error {
|
|
35
|
-
background:
|
|
36
|
-
border-left-color: var(--strand-red-alert);
|
|
31
|
+
background: var(--strand-surface-recessed);
|
|
37
32
|
}
|
|
38
33
|
|
|
34
|
+
/* ── Status prefix ── */
|
|
35
|
+
.strand-alert__status {
|
|
36
|
+
font-family: var(--strand-font-mono);
|
|
37
|
+
font-size: var(--strand-text-xs);
|
|
38
|
+
font-weight: var(--strand-weight-semibold);
|
|
39
|
+
letter-spacing: var(--strand-tracking-wider);
|
|
40
|
+
text-transform: uppercase;
|
|
41
|
+
margin-right: var(--strand-space-3);
|
|
42
|
+
flex-shrink: 0;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.strand-alert--info .strand-alert__status { color: var(--strand-blue-primary); }
|
|
46
|
+
.strand-alert--success .strand-alert__status { color: var(--strand-teal-vital); }
|
|
47
|
+
.strand-alert--warning .strand-alert__status { color: var(--strand-amber-caution); }
|
|
48
|
+
.strand-alert--error .strand-alert__status { color: var(--strand-red-alert); }
|
|
49
|
+
|
|
39
50
|
/* ── Content ── */
|
|
40
51
|
.strand-alert__content {
|
|
41
52
|
flex: 1;
|
|
@@ -48,8 +59,8 @@
|
|
|
48
59
|
display: inline-flex;
|
|
49
60
|
align-items: center;
|
|
50
61
|
justify-content: center;
|
|
51
|
-
width:
|
|
52
|
-
height:
|
|
62
|
+
width: var(--strand-space-6);
|
|
63
|
+
height: var(--strand-space-6);
|
|
53
64
|
margin-left: var(--strand-space-4);
|
|
54
65
|
padding: 0;
|
|
55
66
|
border: none;
|
|
@@ -79,6 +79,36 @@ describe("Alert", () => {
|
|
|
79
79
|
expect(queryByLabelText("Dismiss")).toBeNull();
|
|
80
80
|
});
|
|
81
81
|
|
|
82
|
+
// ── Status prefix ──
|
|
83
|
+
|
|
84
|
+
it("renders status prefix for info", () => {
|
|
85
|
+
const { container } = render(<Alert status="info">Info</Alert>);
|
|
86
|
+
const status = container.querySelector(".strand-alert__status");
|
|
87
|
+
expect(status).toBeTruthy();
|
|
88
|
+
expect(status!.textContent).toBe("INFO");
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it("renders status prefix for success as COMPLETE", () => {
|
|
92
|
+
const { container } = render(<Alert status="success">OK</Alert>);
|
|
93
|
+
const status = container.querySelector(".strand-alert__status");
|
|
94
|
+
expect(status).toBeTruthy();
|
|
95
|
+
expect(status!.textContent).toBe("COMPLETE");
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it("renders status prefix for warning", () => {
|
|
99
|
+
const { container } = render(<Alert status="warning">Warn</Alert>);
|
|
100
|
+
const status = container.querySelector(".strand-alert__status");
|
|
101
|
+
expect(status).toBeTruthy();
|
|
102
|
+
expect(status!.textContent).toBe("WARNING");
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it("renders status prefix for error", () => {
|
|
106
|
+
const { container } = render(<Alert status="error">Fail</Alert>);
|
|
107
|
+
const status = container.querySelector(".strand-alert__status");
|
|
108
|
+
expect(status).toBeTruthy();
|
|
109
|
+
expect(status!.textContent).toBe("ERROR");
|
|
110
|
+
});
|
|
111
|
+
|
|
82
112
|
// ── Custom className ──
|
|
83
113
|
|
|
84
114
|
it("merges custom className", () => {
|
|
@@ -38,8 +38,12 @@ export const Alert = forwardRef<HTMLDivElement, AlertProps>(
|
|
|
38
38
|
.filter(Boolean)
|
|
39
39
|
.join(" ");
|
|
40
40
|
|
|
41
|
+
const statusLabel =
|
|
42
|
+
status === "success" ? "COMPLETE" : status.toUpperCase();
|
|
43
|
+
|
|
41
44
|
return (
|
|
42
45
|
<div ref={ref} className={classes} role={role} {...rest}>
|
|
46
|
+
<span className="strand-alert__status">{statusLabel}</span>
|
|
43
47
|
<div className="strand-alert__content">{children}</div>
|
|
44
48
|
{dismissible && (
|
|
45
49
|
<button
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
line-height: var(--strand-leading-relaxed);
|
|
25
25
|
color: var(--strand-blue-midnight);
|
|
26
26
|
background: var(--strand-surface-recessed);
|
|
27
|
-
box-shadow: inset 0 1px 3px rgba(15, 23, 42, 0.06);
|
|
27
|
+
box-shadow: inset 0 1px 3px rgba(15, 23, 42, 0.06); /* strand-blue-abyss at 6% opacity */
|
|
28
28
|
border-radius: var(--strand-radius-lg);
|
|
29
29
|
padding: var(--strand-space-3) var(--strand-space-4);
|
|
30
30
|
overflow-x: auto;
|
|
@@ -9,10 +9,12 @@
|
|
|
9
9
|
|
|
10
10
|
/* ── Label ── */
|
|
11
11
|
.strand-form-field__label {
|
|
12
|
-
font-family: var(--strand-font-
|
|
13
|
-
font-size: var(--strand-text-
|
|
12
|
+
font-family: var(--strand-font-mono);
|
|
13
|
+
font-size: var(--strand-text-xs);
|
|
14
14
|
font-weight: var(--strand-weight-medium);
|
|
15
|
-
|
|
15
|
+
letter-spacing: var(--strand-tracking-widest);
|
|
16
|
+
text-transform: uppercase;
|
|
17
|
+
color: var(--strand-gray-500);
|
|
16
18
|
line-height: var(--strand-leading-snug);
|
|
17
19
|
}
|
|
18
20
|
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
.strand-tag--solid.strand-tag--teal {
|
|
25
|
-
background:
|
|
25
|
+
background: var(--strand-surface-recessed);
|
|
26
26
|
color: var(--strand-on-teal-tint);
|
|
27
27
|
}
|
|
28
28
|
|
|
@@ -32,12 +32,12 @@
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
.strand-tag--solid.strand-tag--amber {
|
|
35
|
-
background:
|
|
35
|
+
background: var(--strand-surface-recessed);
|
|
36
36
|
color: var(--strand-on-amber-tint);
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
.strand-tag--solid.strand-tag--red {
|
|
40
|
-
background:
|
|
40
|
+
background: var(--strand-surface-recessed);
|
|
41
41
|
color: var(--strand-on-red-tint);
|
|
42
42
|
}
|
|
43
43
|
|
|
@@ -22,7 +22,6 @@
|
|
|
22
22
|
padding: var(--strand-space-4) var(--strand-space-5);
|
|
23
23
|
background: var(--strand-surface-elevated);
|
|
24
24
|
border-radius: var(--strand-radius-lg);
|
|
25
|
-
border-left: 4px solid transparent;
|
|
26
25
|
box-shadow: var(--strand-elevation-3);
|
|
27
26
|
font-family: var(--strand-font-sans);
|
|
28
27
|
font-size: var(--strand-text-sm);
|
|
@@ -30,22 +29,21 @@
|
|
|
30
29
|
animation: strand-toast-in var(--strand-duration-normal) var(--strand-ease-out-expo);
|
|
31
30
|
}
|
|
32
31
|
|
|
33
|
-
/* ── Status
|
|
34
|
-
.strand-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
.strand-toast--warning {
|
|
43
|
-
border-left-color: var(--strand-amber-caution);
|
|
32
|
+
/* ── Status prefix ── */
|
|
33
|
+
.strand-toast__status {
|
|
34
|
+
font-family: var(--strand-font-mono);
|
|
35
|
+
font-size: var(--strand-text-xs);
|
|
36
|
+
font-weight: var(--strand-weight-semibold);
|
|
37
|
+
letter-spacing: var(--strand-tracking-wider);
|
|
38
|
+
text-transform: uppercase;
|
|
39
|
+
margin-right: var(--strand-space-3);
|
|
40
|
+
flex-shrink: 0;
|
|
44
41
|
}
|
|
45
42
|
|
|
46
|
-
.strand-toast--
|
|
47
|
-
|
|
48
|
-
}
|
|
43
|
+
.strand-toast--info .strand-toast__status { color: var(--strand-blue-primary); }
|
|
44
|
+
.strand-toast--success .strand-toast__status { color: var(--strand-teal-vital); }
|
|
45
|
+
.strand-toast--warning .strand-toast__status { color: var(--strand-amber-caution); }
|
|
46
|
+
.strand-toast--error .strand-toast__status { color: var(--strand-red-alert); }
|
|
49
47
|
|
|
50
48
|
/* ── Message ── */
|
|
51
49
|
.strand-toast__message {
|
|
@@ -60,8 +58,8 @@
|
|
|
60
58
|
display: inline-flex;
|
|
61
59
|
align-items: center;
|
|
62
60
|
justify-content: center;
|
|
63
|
-
width:
|
|
64
|
-
height:
|
|
61
|
+
width: var(--strand-space-6);
|
|
62
|
+
height: var(--strand-space-6);
|
|
65
63
|
margin-left: var(--strand-space-3);
|
|
66
64
|
padding: 0;
|
|
67
65
|
border: none;
|
|
@@ -87,6 +87,34 @@ describe("Toast", () => {
|
|
|
87
87
|
container.querySelector(".strand-toast--info"),
|
|
88
88
|
).toBeTruthy();
|
|
89
89
|
});
|
|
90
|
+
|
|
91
|
+
it("renders status prefix for info", () => {
|
|
92
|
+
const { container } = render(<Toast message="Note" status="info" />);
|
|
93
|
+
const status = container.querySelector(".strand-toast__status");
|
|
94
|
+
expect(status).toBeTruthy();
|
|
95
|
+
expect(status!.textContent).toBe("INFO");
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it("renders status prefix for success as COMPLETE", () => {
|
|
99
|
+
const { container } = render(<Toast message="OK" status="success" />);
|
|
100
|
+
const status = container.querySelector(".strand-toast__status");
|
|
101
|
+
expect(status).toBeTruthy();
|
|
102
|
+
expect(status!.textContent).toBe("COMPLETE");
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it("renders status prefix for warning", () => {
|
|
106
|
+
const { container } = render(<Toast message="Warn" status="warning" />);
|
|
107
|
+
const status = container.querySelector(".strand-toast__status");
|
|
108
|
+
expect(status).toBeTruthy();
|
|
109
|
+
expect(status!.textContent).toBe("WARNING");
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it("renders status prefix for error", () => {
|
|
113
|
+
const { container } = render(<Toast message="Fail" status="error" />);
|
|
114
|
+
const status = container.querySelector(".strand-toast__status");
|
|
115
|
+
expect(status).toBeTruthy();
|
|
116
|
+
expect(status!.textContent).toBe("ERROR");
|
|
117
|
+
});
|
|
90
118
|
});
|
|
91
119
|
|
|
92
120
|
describe("ToastProvider + useToast", () => {
|
|
@@ -107,12 +107,16 @@ function ToastItem({ entry, onDismiss }: ToastItemProps) {
|
|
|
107
107
|
.filter(Boolean)
|
|
108
108
|
.join(" ");
|
|
109
109
|
|
|
110
|
+
const statusLabel =
|
|
111
|
+
entry.status === "success" ? "COMPLETE" : entry.status.toUpperCase();
|
|
112
|
+
|
|
110
113
|
return (
|
|
111
114
|
<div
|
|
112
115
|
className={classes}
|
|
113
116
|
role="status"
|
|
114
117
|
aria-live={isUrgent ? "assertive" : "polite"}
|
|
115
118
|
>
|
|
119
|
+
<span className="strand-toast__status">{statusLabel}</span>
|
|
116
120
|
<span className="strand-toast__message">{entry.message}</span>
|
|
117
121
|
<button
|
|
118
122
|
type="button"
|
|
@@ -150,6 +154,9 @@ export const Toast = forwardRef<HTMLDivElement, ToastProps>(
|
|
|
150
154
|
.filter(Boolean)
|
|
151
155
|
.join(" ");
|
|
152
156
|
|
|
157
|
+
const statusLabel =
|
|
158
|
+
status === "success" ? "COMPLETE" : status.toUpperCase();
|
|
159
|
+
|
|
153
160
|
return (
|
|
154
161
|
<div
|
|
155
162
|
ref={ref}
|
|
@@ -158,6 +165,7 @@ export const Toast = forwardRef<HTMLDivElement, ToastProps>(
|
|
|
158
165
|
aria-live={isUrgent ? "assertive" : "polite"}
|
|
159
166
|
{...rest}
|
|
160
167
|
>
|
|
168
|
+
<span className="strand-toast__status">{statusLabel}</span>
|
|
161
169
|
<span className="strand-toast__message">{message}</span>
|
|
162
170
|
{onDismiss && (
|
|
163
171
|
<button
|