@dillingerstaffing/strand-ui 0.10.0 → 0.12.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 +11 -7
- package/dist/components/DataReadout/DataReadout.d.ts +2 -2
- package/dist/components/DataReadout/DataReadout.d.ts.map +1 -1
- package/dist/css/strand-ui.css +102 -0
- package/package.json +2 -2
- package/src/components/DataReadout/DataReadout.css +4 -0
- package/src/components/DataReadout/DataReadout.test.tsx +8 -0
- package/src/components/DataReadout/DataReadout.tsx +2 -2
- package/src/components/Link/Link.css +26 -0
- package/src/components/ScrollReveal/ScrollReveal.css +24 -0
- package/src/components/Section/Section.css +5 -0
- package/src/static.css +43 -0
package/HTML_REFERENCE.md
CHANGED
|
@@ -407,7 +407,7 @@ All container components (Grid, Stack, Card, Container) enforce boundary integri
|
|
|
407
407
|
</div>
|
|
408
408
|
```
|
|
409
409
|
|
|
410
|
-
**Sizes:** `--sm` (text-xl, 25px) | default (text-3xl, 39px) | `--lg` (text-4xl, 49px). Label stays xs across all sizes.
|
|
410
|
+
**Sizes:** `--sm` (text-xl, 25px) | default (text-3xl, 39px) | `--lg` (text-4xl, 49px) | `--xl` (fluid 72-112px, primary instrument readout). Label stays xs across all sizes.
|
|
411
411
|
|
|
412
412
|
> **The DataReadout pattern** is uniquely Strand: monospace overline + large light-weight value + tabular numerals. See [DESIGN_LANGUAGE.md 11.2: Data Display (L918-L955)](./DESIGN_LANGUAGE.md#L918).
|
|
413
413
|
|
|
@@ -900,15 +900,19 @@ Named CSS classes for common compositions. Each implements one or more productio
|
|
|
900
900
|
Production: `section-boundary`.
|
|
901
901
|
|
|
902
902
|
```html
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
903
|
+
<!-- Single label -->
|
|
904
|
+
<div class="strand-card-section">
|
|
905
|
+
<span class="strand-overline">Section Label</span>
|
|
906
|
+
</div>
|
|
907
|
+
|
|
908
|
+
<!-- Distributed header (label + secondary) -->
|
|
909
|
+
<div class="strand-card-section">
|
|
910
|
+
<span class="strand-overline">7-Day Forecast</span>
|
|
911
|
+
<span class="strand-overline" style="color: var(--strand-gray-400)">Ethiopian Yirgacheffe</span>
|
|
908
912
|
</div>
|
|
909
913
|
```
|
|
910
914
|
|
|
911
|
-
Multiple sections stack
|
|
915
|
+
Children distribute on the inline axis (space-between). Single child sits at the start. Multiple sections stack; last omits trailing border via `:last-child`.
|
|
912
916
|
|
|
913
917
|
### Key-Value Row
|
|
914
918
|
|
|
@@ -5,8 +5,8 @@ export interface DataReadoutProps extends Omit<JSX.HTMLAttributes<HTMLDivElement
|
|
|
5
5
|
label: string;
|
|
6
6
|
/** The large displayed value */
|
|
7
7
|
value: string | number;
|
|
8
|
-
/** Size variant: sm (compact), md (default), lg (hero) */
|
|
9
|
-
size?: "sm" | "md" | "lg";
|
|
8
|
+
/** Size variant: sm (compact), md (default), lg (hero), xl (primary instrument) */
|
|
9
|
+
size?: "sm" | "md" | "lg" | "xl";
|
|
10
10
|
}
|
|
11
11
|
export declare const DataReadout: import("preact").FunctionalComponent<import("preact/compat").PropsWithoutRef<DataReadoutProps> & {
|
|
12
12
|
ref?: import("preact").Ref<HTMLDivElement> | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DataReadout.d.ts","sourceRoot":"","sources":["../../../src/components/DataReadout/DataReadout.tsx"],"names":[],"mappings":"AAAA,sDAAsD;AAEtD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAGlC,MAAM,WAAW,gBACf,SAAQ,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzD,0BAA0B;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,gCAAgC;IAChC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,
|
|
1
|
+
{"version":3,"file":"DataReadout.d.ts","sourceRoot":"","sources":["../../../src/components/DataReadout/DataReadout.tsx"],"names":[],"mappings":"AAAA,sDAAsD;AAEtD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAGlC,MAAM,WAAW,gBACf,SAAQ,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzD,0BAA0B;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,gCAAgC;IAChC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,mFAAmF;IACnF,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;CAClC;AAED,eAAO,MAAM,WAAW;;EAiBvB,CAAC"}
|
package/dist/css/strand-ui.css
CHANGED
|
@@ -763,6 +763,10 @@
|
|
|
763
763
|
font-size: var(--strand-text-4xl);
|
|
764
764
|
}
|
|
765
765
|
|
|
766
|
+
.strand-data-readout--xl .strand-data-readout__value {
|
|
767
|
+
font-size: clamp(4.5rem, 10vw, 7rem);
|
|
768
|
+
}
|
|
769
|
+
|
|
766
770
|
|
|
767
771
|
/* Dialog */
|
|
768
772
|
/*! Strand UI | MIT License | dillingerstaffing.com */
|
|
@@ -1136,6 +1140,32 @@
|
|
|
1136
1140
|
outline-offset: 2px;
|
|
1137
1141
|
}
|
|
1138
1142
|
|
|
1143
|
+
/* ── CTA link variant ── */
|
|
1144
|
+
.strand-link--cta {
|
|
1145
|
+
display: inline-flex;
|
|
1146
|
+
align-items: center;
|
|
1147
|
+
min-height: var(--strand-touch-target);
|
|
1148
|
+
padding-block: var(--strand-space-2);
|
|
1149
|
+
font-size: var(--strand-text-sm);
|
|
1150
|
+
}
|
|
1151
|
+
|
|
1152
|
+
.strand-link--cta:hover {
|
|
1153
|
+
color: var(--strand-blue-vivid);
|
|
1154
|
+
}
|
|
1155
|
+
|
|
1156
|
+
/* ── Monospace link variant (footer, overline-style) ── */
|
|
1157
|
+
.strand-link--mono {
|
|
1158
|
+
font-family: var(--strand-font-mono);
|
|
1159
|
+
font-size: var(--strand-text-xs);
|
|
1160
|
+
letter-spacing: var(--strand-tracking-wider);
|
|
1161
|
+
color: var(--strand-gray-400);
|
|
1162
|
+
background-image: none;
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
.strand-link--mono:hover {
|
|
1166
|
+
color: var(--strand-blue-primary);
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1139
1169
|
/* ── Reduced motion ── */
|
|
1140
1170
|
@media (prefers-reduced-motion: reduce) {
|
|
1141
1171
|
.strand-link {
|
|
@@ -1547,11 +1577,35 @@
|
|
|
1547
1577
|
.strand-reveal-group > .strand-reveal:nth-child(5) { transition-delay: calc(var(--strand-stagger-delay) * 4); }
|
|
1548
1578
|
.strand-reveal-group > .strand-reveal:nth-child(6) { transition-delay: var(--strand-duration-slow); }
|
|
1549
1579
|
|
|
1580
|
+
/* ── CSS-only scroll-driven animation (no JS required) ── */
|
|
1581
|
+
@supports (animation-timeline: view()) {
|
|
1582
|
+
.strand-reveal {
|
|
1583
|
+
opacity: 0;
|
|
1584
|
+
transform: translateY(24px);
|
|
1585
|
+
transition: none;
|
|
1586
|
+
animation: strand-reveal-up linear both;
|
|
1587
|
+
animation-timeline: view();
|
|
1588
|
+
animation-range: entry 0% entry 100%;
|
|
1589
|
+
}
|
|
1590
|
+
|
|
1591
|
+
.strand-reveal-group > .strand-reveal {
|
|
1592
|
+
animation: strand-reveal-up linear both;
|
|
1593
|
+
animation-timeline: view();
|
|
1594
|
+
animation-range: entry 0% entry 100%;
|
|
1595
|
+
}
|
|
1596
|
+
|
|
1597
|
+
@keyframes strand-reveal-up {
|
|
1598
|
+
from { opacity: 0; transform: translateY(24px); }
|
|
1599
|
+
to { opacity: 1; transform: translateY(0); }
|
|
1600
|
+
}
|
|
1601
|
+
}
|
|
1602
|
+
|
|
1550
1603
|
@media (prefers-reduced-motion: reduce) {
|
|
1551
1604
|
.strand-reveal {
|
|
1552
1605
|
opacity: 1;
|
|
1553
1606
|
transform: none;
|
|
1554
1607
|
transition: none;
|
|
1608
|
+
animation: none;
|
|
1555
1609
|
}
|
|
1556
1610
|
}
|
|
1557
1611
|
|
|
@@ -1586,6 +1640,11 @@
|
|
|
1586
1640
|
background-color: var(--strand-surface-recessed);
|
|
1587
1641
|
}
|
|
1588
1642
|
|
|
1643
|
+
/* ── Border variant ── */
|
|
1644
|
+
.strand-section--border-top {
|
|
1645
|
+
border-top: 1px solid var(--strand-gray-200);
|
|
1646
|
+
}
|
|
1647
|
+
|
|
1589
1648
|
|
|
1590
1649
|
/* Select */
|
|
1591
1650
|
/*! Strand UI | MIT License | dillingerstaffing.com */
|
|
@@ -2687,6 +2746,9 @@
|
|
|
2687
2746
|
Derivation: section-boundary production (DL 11.10).
|
|
2688
2747
|
OVERLINE + border-bottom + margin-bottom + padding-bottom */
|
|
2689
2748
|
.strand-card-section {
|
|
2749
|
+
display: flex;
|
|
2750
|
+
justify-content: space-between;
|
|
2751
|
+
align-items: center;
|
|
2690
2752
|
margin-bottom: var(--strand-space-3);
|
|
2691
2753
|
padding-bottom: var(--strand-space-2);
|
|
2692
2754
|
border-bottom: 1px solid var(--strand-gray-200);
|
|
@@ -2822,4 +2884,44 @@
|
|
|
2822
2884
|
color: var(--strand-gray-400);
|
|
2823
2885
|
}
|
|
2824
2886
|
|
|
2887
|
+
/* ══════════════════════════════════════════════════
|
|
2888
|
+
UTILITIES
|
|
2889
|
+
══════════════════════════════════════════════════ */
|
|
2890
|
+
|
|
2891
|
+
/* ── Screen reader only ── */
|
|
2892
|
+
.strand-sr-only {
|
|
2893
|
+
position: absolute;
|
|
2894
|
+
width: 1px;
|
|
2895
|
+
height: 1px;
|
|
2896
|
+
padding: 0;
|
|
2897
|
+
margin: -1px;
|
|
2898
|
+
overflow: hidden;
|
|
2899
|
+
clip: rect(0, 0, 0, 0);
|
|
2900
|
+
white-space: nowrap;
|
|
2901
|
+
border: 0;
|
|
2902
|
+
}
|
|
2903
|
+
|
|
2904
|
+
/* ── Section header ──
|
|
2905
|
+
Derivation: section-boundary production (DL 11.10).
|
|
2906
|
+
Centered heading group with bottom margin. */
|
|
2907
|
+
.strand-section-header {
|
|
2908
|
+
margin-bottom: clamp(2rem, 4vw, 4rem);
|
|
2909
|
+
}
|
|
2910
|
+
|
|
2911
|
+
/* ── Step indicator ──
|
|
2912
|
+
Numbered position indicator for sequential steps. */
|
|
2913
|
+
.strand-step-indicator {
|
|
2914
|
+
display: inline-flex;
|
|
2915
|
+
align-items: center;
|
|
2916
|
+
justify-content: center;
|
|
2917
|
+
width: var(--strand-space-8);
|
|
2918
|
+
height: var(--strand-space-8);
|
|
2919
|
+
border-radius: var(--strand-radius-full);
|
|
2920
|
+
background: var(--strand-blue-glow);
|
|
2921
|
+
color: var(--strand-blue-primary);
|
|
2922
|
+
font-family: var(--strand-font-mono);
|
|
2923
|
+
font-size: var(--strand-text-sm);
|
|
2924
|
+
font-weight: var(--strand-weight-semibold);
|
|
2925
|
+
}
|
|
2926
|
+
|
|
2825
2927
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dillingerstaffing/strand-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.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.12.0"
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|
|
66
66
|
"@testing-library/preact": "^3.2.0",
|
|
@@ -111,6 +111,14 @@ describe("DataReadout", () => {
|
|
|
111
111
|
expect(readout?.className).toContain("strand-data-readout--lg");
|
|
112
112
|
});
|
|
113
113
|
|
|
114
|
+
it("applies xl size modifier class", () => {
|
|
115
|
+
const { container } = render(
|
|
116
|
+
<DataReadout label="Remaining" value="284g" size="xl" />,
|
|
117
|
+
);
|
|
118
|
+
const readout = container.querySelector(".strand-data-readout");
|
|
119
|
+
expect(readout?.className).toContain("strand-data-readout--xl");
|
|
120
|
+
});
|
|
121
|
+
|
|
114
122
|
it("does not apply size modifier for md (default)", () => {
|
|
115
123
|
const { container } = render(
|
|
116
124
|
<DataReadout label="Metric" value="100" size="md" />,
|
|
@@ -9,8 +9,8 @@ export interface DataReadoutProps
|
|
|
9
9
|
label: string;
|
|
10
10
|
/** The large displayed value */
|
|
11
11
|
value: string | number;
|
|
12
|
-
/** Size variant: sm (compact), md (default), lg (hero) */
|
|
13
|
-
size?: "sm" | "md" | "lg";
|
|
12
|
+
/** Size variant: sm (compact), md (default), lg (hero), xl (primary instrument) */
|
|
13
|
+
size?: "sm" | "md" | "lg" | "xl";
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
export const DataReadout = forwardRef<HTMLDivElement, DataReadoutProps>(
|
|
@@ -22,6 +22,32 @@
|
|
|
22
22
|
outline-offset: 2px;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
/* ── CTA link variant ── */
|
|
26
|
+
.strand-link--cta {
|
|
27
|
+
display: inline-flex;
|
|
28
|
+
align-items: center;
|
|
29
|
+
min-height: var(--strand-touch-target);
|
|
30
|
+
padding-block: var(--strand-space-2);
|
|
31
|
+
font-size: var(--strand-text-sm);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.strand-link--cta:hover {
|
|
35
|
+
color: var(--strand-blue-vivid);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/* ── Monospace link variant (footer, overline-style) ── */
|
|
39
|
+
.strand-link--mono {
|
|
40
|
+
font-family: var(--strand-font-mono);
|
|
41
|
+
font-size: var(--strand-text-xs);
|
|
42
|
+
letter-spacing: var(--strand-tracking-wider);
|
|
43
|
+
color: var(--strand-gray-400);
|
|
44
|
+
background-image: none;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.strand-link--mono:hover {
|
|
48
|
+
color: var(--strand-blue-primary);
|
|
49
|
+
}
|
|
50
|
+
|
|
25
51
|
/* ── Reduced motion ── */
|
|
26
52
|
@media (prefers-reduced-motion: reduce) {
|
|
27
53
|
.strand-link {
|
|
@@ -20,10 +20,34 @@
|
|
|
20
20
|
.strand-reveal-group > .strand-reveal:nth-child(5) { transition-delay: calc(var(--strand-stagger-delay) * 4); }
|
|
21
21
|
.strand-reveal-group > .strand-reveal:nth-child(6) { transition-delay: var(--strand-duration-slow); }
|
|
22
22
|
|
|
23
|
+
/* ── CSS-only scroll-driven animation (no JS required) ── */
|
|
24
|
+
@supports (animation-timeline: view()) {
|
|
25
|
+
.strand-reveal {
|
|
26
|
+
opacity: 0;
|
|
27
|
+
transform: translateY(24px);
|
|
28
|
+
transition: none;
|
|
29
|
+
animation: strand-reveal-up linear both;
|
|
30
|
+
animation-timeline: view();
|
|
31
|
+
animation-range: entry 0% entry 100%;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.strand-reveal-group > .strand-reveal {
|
|
35
|
+
animation: strand-reveal-up linear both;
|
|
36
|
+
animation-timeline: view();
|
|
37
|
+
animation-range: entry 0% entry 100%;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
@keyframes strand-reveal-up {
|
|
41
|
+
from { opacity: 0; transform: translateY(24px); }
|
|
42
|
+
to { opacity: 1; transform: translateY(0); }
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
23
46
|
@media (prefers-reduced-motion: reduce) {
|
|
24
47
|
.strand-reveal {
|
|
25
48
|
opacity: 1;
|
|
26
49
|
transform: none;
|
|
27
50
|
transition: none;
|
|
51
|
+
animation: none;
|
|
28
52
|
}
|
|
29
53
|
}
|
package/src/static.css
CHANGED
|
@@ -118,6 +118,9 @@
|
|
|
118
118
|
Derivation: section-boundary production (DL 11.10).
|
|
119
119
|
OVERLINE + border-bottom + margin-bottom + padding-bottom */
|
|
120
120
|
.strand-card-section {
|
|
121
|
+
display: flex;
|
|
122
|
+
justify-content: space-between;
|
|
123
|
+
align-items: center;
|
|
121
124
|
margin-bottom: var(--strand-space-3);
|
|
122
125
|
padding-bottom: var(--strand-space-2);
|
|
123
126
|
border-bottom: 1px solid var(--strand-gray-200);
|
|
@@ -252,3 +255,43 @@
|
|
|
252
255
|
text-transform: uppercase;
|
|
253
256
|
color: var(--strand-gray-400);
|
|
254
257
|
}
|
|
258
|
+
|
|
259
|
+
/* ══════════════════════════════════════════════════
|
|
260
|
+
UTILITIES
|
|
261
|
+
══════════════════════════════════════════════════ */
|
|
262
|
+
|
|
263
|
+
/* ── Screen reader only ── */
|
|
264
|
+
.strand-sr-only {
|
|
265
|
+
position: absolute;
|
|
266
|
+
width: 1px;
|
|
267
|
+
height: 1px;
|
|
268
|
+
padding: 0;
|
|
269
|
+
margin: -1px;
|
|
270
|
+
overflow: hidden;
|
|
271
|
+
clip: rect(0, 0, 0, 0);
|
|
272
|
+
white-space: nowrap;
|
|
273
|
+
border: 0;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/* ── Section header ──
|
|
277
|
+
Derivation: section-boundary production (DL 11.10).
|
|
278
|
+
Centered heading group with bottom margin. */
|
|
279
|
+
.strand-section-header {
|
|
280
|
+
margin-bottom: clamp(2rem, 4vw, 4rem);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/* ── Step indicator ──
|
|
284
|
+
Numbered position indicator for sequential steps. */
|
|
285
|
+
.strand-step-indicator {
|
|
286
|
+
display: inline-flex;
|
|
287
|
+
align-items: center;
|
|
288
|
+
justify-content: center;
|
|
289
|
+
width: var(--strand-space-8);
|
|
290
|
+
height: var(--strand-space-8);
|
|
291
|
+
border-radius: var(--strand-radius-full);
|
|
292
|
+
background: var(--strand-blue-glow);
|
|
293
|
+
color: var(--strand-blue-primary);
|
|
294
|
+
font-family: var(--strand-font-mono);
|
|
295
|
+
font-size: var(--strand-text-sm);
|
|
296
|
+
font-weight: var(--strand-weight-semibold);
|
|
297
|
+
}
|