@dillingerstaffing/strand-ui 0.9.0 → 0.11.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 +113 -2
- 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 +164 -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/static.css +160 -0
package/HTML_REFERENCE.md
CHANGED
|
@@ -8,7 +8,9 @@
|
|
|
8
8
|
|
|
9
9
|
> **Principle 1 (Cognitive Economy):** Every element must earn its place. Test: remove an element. If the task still works, it was decoration. If you're not adding back 10% of what you delete, you're not deleting enough. See [DL L61-69](./DESIGN_LANGUAGE.md#L61).
|
|
10
10
|
|
|
11
|
-
> **Principle 2 (Biosynthetic Restraint):** Max 12 distinct visual elements per screen. See [DL L71-
|
|
11
|
+
> **Principle 2 (Biosynthetic Restraint):** Max 12 distinct visual elements per screen. Every composition must have exactly one visually dominant primary element. If all elements have equal visual weight, the composition has no focal point. An instrument without a focal point is a parts bin, not an instrument. See [DL L71-84](./DESIGN_LANGUAGE.md#L71).
|
|
12
|
+
|
|
13
|
+
> **Principle 9 (Typography Carries the Room):** The largest text and smallest text on the same screen must have at least a 3:1 size ratio. Uniform typography is a spreadsheet. Hierarchical typography is an instrument panel. See [DL L165-178](./DESIGN_LANGUAGE.md#L165).
|
|
12
14
|
|
|
13
15
|
## Required CSS
|
|
14
16
|
|
|
@@ -265,6 +267,8 @@ All container components (Grid, Stack, Card, Container) enforce boundary integri
|
|
|
265
267
|
|
|
266
268
|
> **Elevation:** Cards at rest use Level 1 shadow. On hover, Level 2. See [DESIGN_LANGUAGE.md Principle 5: Earned Elevation (L114-L125)](./DESIGN_LANGUAGE.md#L114) and [7.2: Container Elevation Contexts (L698-L708)](./DESIGN_LANGUAGE.md#L698).
|
|
267
269
|
|
|
270
|
+
> **Cards are instrument panels, not generic containers.** Before placing multiple cards in a layout, apply [Principle 2 hierarchy test (L71-84)](./DESIGN_LANGUAGE.md#L71): which card is the primary instrument? It should be visually dominant. Apply [Principle 10 (L171-196)](./DESIGN_LANGUAGE.md#L171): describe the layout in laboratory vocabulary. If it sounds generic, redesign.
|
|
271
|
+
|
|
268
272
|
---
|
|
269
273
|
|
|
270
274
|
### Badge
|
|
@@ -403,10 +407,12 @@ All container components (Grid, Stack, Card, Container) enforce boundary integri
|
|
|
403
407
|
</div>
|
|
404
408
|
```
|
|
405
409
|
|
|
406
|
-
**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.
|
|
407
411
|
|
|
408
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).
|
|
409
413
|
|
|
414
|
+
> **DataReadout has three sizes for hierarchy, not preference.** Use ONE default or lg readout as the primary focal point, with sm readouts as supporting secondaries. If all readouts on a screen are the same size, apply [Principle 2 hierarchy test (L71-84)](./DESIGN_LANGUAGE.md#L71) and [Principle 9 contrast ratio test (L165-178)](./DESIGN_LANGUAGE.md#L165).
|
|
415
|
+
|
|
410
416
|
---
|
|
411
417
|
|
|
412
418
|
### CodeBlock
|
|
@@ -429,6 +435,10 @@ All container components (Grid, Stack, Card, Container) enforce boundary integri
|
|
|
429
435
|
|
|
430
436
|
> **Spacing rules:** 4px base unit, padding tiers, and the gap > padding hierarchy: [DESIGN_LANGUAGE.md Part V: Spacing (L410-L496)](./DESIGN_LANGUAGE.md#L410). Responsive breakpoints and container system: [Part X: Layout (L829-L877)](./DESIGN_LANGUAGE.md#L829).
|
|
431
437
|
|
|
438
|
+
> **Before composing a layout, apply [Principle 2 (L71-84)](./DESIGN_LANGUAGE.md#L71) and [Principle 10 (L171-196)](./DESIGN_LANGUAGE.md#L171).** Identify the primary element. Describe the layout in laboratory vocabulary. If the description sounds generic ("a grid of data cards"), the composition doesn't embody the DL. An analytical readout panel has one dominant readout and supporting secondaries -- not four equal panels.
|
|
439
|
+
|
|
440
|
+
> **Before sizing text, apply [Principle 9 (L165-178)](./DESIGN_LANGUAGE.md#L165).** Largest to smallest text on the same screen must be at least 3:1. If all text is the same size, the typography is uniform. Uniform typography is a spreadsheet, not an instrument panel.
|
|
441
|
+
|
|
432
442
|
### Stack
|
|
433
443
|
|
|
434
444
|
```html
|
|
@@ -876,3 +886,104 @@ Intro paragraph. Max 50 characters per line. Used after headlines.
|
|
|
876
886
|
Caption/description text. text-sm, gray-500, relaxed leading. The `--xs` modifier reduces to text-xs for metadata and fine print.
|
|
877
887
|
|
|
878
888
|
> **DL foundation:** [DESIGN_LANGUAGE.md Part III.8 Color Roles](./DESIGN_LANGUAGE.md#L290) defines gray-500 as the secondary text role. [Part IV.7 Named Text Patterns](./DESIGN_LANGUAGE.md#L408) specifies the Secondary pattern.
|
|
889
|
+
|
|
890
|
+
---
|
|
891
|
+
|
|
892
|
+
## Composition Molecules
|
|
893
|
+
|
|
894
|
+
Named CSS classes for common compositions. Each implements one or more productions from the [DL Composition Grammar (Part XI-B)](./DESIGN_LANGUAGE.md#L1085).
|
|
895
|
+
|
|
896
|
+
> **Composition rules:** [DL 11.10 Productions](./DESIGN_LANGUAGE.md#L1144) | [DL 11.11 Containment](./DESIGN_LANGUAGE.md#L1199) | [DL 11.12 Derivation](./DESIGN_LANGUAGE.md#L1215) | [DL 11.13 Tests](./DESIGN_LANGUAGE.md#L1246)
|
|
897
|
+
|
|
898
|
+
### Card Section
|
|
899
|
+
|
|
900
|
+
Production: `section-boundary`.
|
|
901
|
+
|
|
902
|
+
```html
|
|
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>
|
|
912
|
+
</div>
|
|
913
|
+
```
|
|
914
|
+
|
|
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`.
|
|
916
|
+
|
|
917
|
+
### Key-Value Row
|
|
918
|
+
|
|
919
|
+
Productions: `inline-pair` + `ranked-sequence`.
|
|
920
|
+
|
|
921
|
+
```html
|
|
922
|
+
<div class="strand-kv">
|
|
923
|
+
<span class="strand-kv__label">Blend</span>
|
|
924
|
+
<span class="strand-kv__value">Ethiopian Yirgacheffe</span>
|
|
925
|
+
</div>
|
|
926
|
+
<div class="strand-kv">
|
|
927
|
+
<span class="strand-kv__label">Status</span>
|
|
928
|
+
<span class="strand-kv__value strand-kv__value--status">Active</span>
|
|
929
|
+
</div>
|
|
930
|
+
```
|
|
931
|
+
|
|
932
|
+
**Modifier:** `strand-kv__value--status` applies semantic color.
|
|
933
|
+
|
|
934
|
+
### Diagnostic Log Entry
|
|
935
|
+
|
|
936
|
+
Productions: `inline-sequence` + `ranked-sequence`.
|
|
937
|
+
|
|
938
|
+
```html
|
|
939
|
+
<div class="strand-log">
|
|
940
|
+
<span class="strand-log__time">9:15</span>
|
|
941
|
+
<span class="strand-log__status strand-log__status--complete">Brewed</span>
|
|
942
|
+
<span class="strand-text-secondary">Pour over. 18g.</span>
|
|
943
|
+
</div>
|
|
944
|
+
<div class="strand-log">
|
|
945
|
+
<span class="strand-log__time">6:30</span>
|
|
946
|
+
<span class="strand-log__status strand-log__status--process">Brewing</span>
|
|
947
|
+
<span class="strand-text-secondary">Espresso. 18g.</span>
|
|
948
|
+
</div>
|
|
949
|
+
```
|
|
950
|
+
|
|
951
|
+
**Status variants:** `--complete` (teal) | `--process` (blue) | `--warning` (amber) | `--error` (red)
|
|
952
|
+
|
|
953
|
+
### Metric Row
|
|
954
|
+
|
|
955
|
+
Production: `centered-group`.
|
|
956
|
+
|
|
957
|
+
```html
|
|
958
|
+
<div class="strand-metric-row">
|
|
959
|
+
<div class="strand-data-readout strand-data-readout--sm">
|
|
960
|
+
<span class="strand-data-readout__label">Daily</span>
|
|
961
|
+
<span class="strand-data-readout__value">36g</span>
|
|
962
|
+
</div>
|
|
963
|
+
<div class="strand-data-readout strand-data-readout--sm">
|
|
964
|
+
<span class="strand-data-readout__label">Days Left</span>
|
|
965
|
+
<span class="strand-data-readout__value">7.9</span>
|
|
966
|
+
</div>
|
|
967
|
+
</div>
|
|
968
|
+
```
|
|
969
|
+
|
|
970
|
+
### Bar Chart
|
|
971
|
+
|
|
972
|
+
Production: `column-array`.
|
|
973
|
+
|
|
974
|
+
```html
|
|
975
|
+
<div class="strand-bar-chart">
|
|
976
|
+
<div class="strand-bar-chart__col">
|
|
977
|
+
<span class="strand-bar-chart__amount">284</span>
|
|
978
|
+
<div class="strand-bar-chart__bar" style="height: 100%"></div>
|
|
979
|
+
<span class="strand-bar-chart__label">Thu</span>
|
|
980
|
+
</div>
|
|
981
|
+
<div class="strand-bar-chart__col">
|
|
982
|
+
<span class="strand-bar-chart__amount">248</span>
|
|
983
|
+
<div class="strand-bar-chart__bar" style="height: 87%"></div>
|
|
984
|
+
<span class="strand-bar-chart__label">Fri</span>
|
|
985
|
+
</div>
|
|
986
|
+
</div>
|
|
987
|
+
```
|
|
988
|
+
|
|
989
|
+
Heights are inline styles (data-driven). Place inside `.strand-instrument-viewport` for dual-surface treatment.
|
|
@@ -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 */
|
|
@@ -2646,6 +2650,16 @@
|
|
|
2646
2650
|
letter-spacing: var(--strand-tracking-tighter);
|
|
2647
2651
|
}
|
|
2648
2652
|
|
|
2653
|
+
/* ── Title (human voice display, DL Part IV.7) ── */
|
|
2654
|
+
.strand-title {
|
|
2655
|
+
font-family: var(--strand-font-sans);
|
|
2656
|
+
font-weight: var(--strand-weight-light);
|
|
2657
|
+
letter-spacing: var(--strand-tracking-tighter);
|
|
2658
|
+
color: var(--strand-blue-midnight);
|
|
2659
|
+
font-size: clamp(1.5rem, 3vw + 0.5rem, 2.5rem);
|
|
2660
|
+
line-height: var(--strand-leading-snug);
|
|
2661
|
+
}
|
|
2662
|
+
|
|
2649
2663
|
/* ── Lead (intro paragraph, DL Part IV.6) ── */
|
|
2650
2664
|
.strand-lead {
|
|
2651
2665
|
font-size: var(--strand-text-lg);
|
|
@@ -2665,4 +2679,154 @@
|
|
|
2665
2679
|
font-size: var(--strand-text-xs);
|
|
2666
2680
|
}
|
|
2667
2681
|
|
|
2682
|
+
/* ══════════════════════════════════════════════════
|
|
2683
|
+
COMPOSITION MOLECULES (DL Part XI-B Grammar)
|
|
2684
|
+
Named derivations of DL composition primitives.
|
|
2685
|
+
Each molecule is a convenience class for a common
|
|
2686
|
+
derivation chain. See DL 11.10 Productions for the
|
|
2687
|
+
grammar rules; DL 11.12 Derivation for verification.
|
|
2688
|
+
══════════════════════════════════════════════════ */
|
|
2689
|
+
|
|
2690
|
+
/* ── Card Section ──
|
|
2691
|
+
Derivation: section-boundary production (DL 11.10).
|
|
2692
|
+
OVERLINE + border-bottom + margin-bottom + padding-bottom */
|
|
2693
|
+
.strand-card-section {
|
|
2694
|
+
display: flex;
|
|
2695
|
+
justify-content: space-between;
|
|
2696
|
+
align-items: center;
|
|
2697
|
+
margin-bottom: var(--strand-space-3);
|
|
2698
|
+
padding-bottom: var(--strand-space-2);
|
|
2699
|
+
border-bottom: 1px solid var(--strand-gray-200);
|
|
2700
|
+
}
|
|
2701
|
+
|
|
2702
|
+
/* ── Key-Value Row ──
|
|
2703
|
+
Derivation: inline-pair + ranked-sequence (DL 11.10).
|
|
2704
|
+
identifier(OVERLINE) + quantifier(MONO_VALUE) + RANK_BORDER */
|
|
2705
|
+
.strand-kv {
|
|
2706
|
+
display: flex;
|
|
2707
|
+
justify-content: space-between;
|
|
2708
|
+
align-items: center;
|
|
2709
|
+
padding-block: var(--strand-space-2);
|
|
2710
|
+
}
|
|
2711
|
+
|
|
2712
|
+
.strand-kv + .strand-kv {
|
|
2713
|
+
border-top: 1px solid var(--strand-border-subtle);
|
|
2714
|
+
}
|
|
2715
|
+
|
|
2716
|
+
.strand-kv__label {
|
|
2717
|
+
font-family: var(--strand-font-mono);
|
|
2718
|
+
font-size: var(--strand-text-xs);
|
|
2719
|
+
font-weight: var(--strand-weight-medium);
|
|
2720
|
+
letter-spacing: var(--strand-tracking-wider);
|
|
2721
|
+
text-transform: uppercase;
|
|
2722
|
+
color: var(--strand-gray-500);
|
|
2723
|
+
}
|
|
2724
|
+
|
|
2725
|
+
.strand-kv__value {
|
|
2726
|
+
font-family: var(--strand-font-mono);
|
|
2727
|
+
font-size: var(--strand-text-xs);
|
|
2728
|
+
color: var(--strand-gray-600);
|
|
2729
|
+
font-variant-numeric: tabular-nums;
|
|
2730
|
+
}
|
|
2731
|
+
|
|
2732
|
+
.strand-kv__value--status {
|
|
2733
|
+
color: var(--strand-teal-vital);
|
|
2734
|
+
}
|
|
2735
|
+
|
|
2736
|
+
/* ── Diagnostic Log Entry ──
|
|
2737
|
+
Derivation: inline-sequence + ranked-sequence (DL 11.10).
|
|
2738
|
+
time(OVERLINE) + status(OVERLINE+COLOR_SEMANTIC) + text(SECONDARY) + RANK_BORDER */
|
|
2739
|
+
.strand-log {
|
|
2740
|
+
display: flex;
|
|
2741
|
+
gap: var(--strand-space-3);
|
|
2742
|
+
padding-block: var(--strand-space-2);
|
|
2743
|
+
}
|
|
2744
|
+
|
|
2745
|
+
.strand-log + .strand-log {
|
|
2746
|
+
border-top: 1px solid var(--strand-border-subtle);
|
|
2747
|
+
}
|
|
2748
|
+
|
|
2749
|
+
.strand-log__time {
|
|
2750
|
+
font-family: var(--strand-font-mono);
|
|
2751
|
+
font-size: var(--strand-text-xs);
|
|
2752
|
+
font-weight: var(--strand-weight-medium);
|
|
2753
|
+
letter-spacing: var(--strand-tracking-wider);
|
|
2754
|
+
text-transform: uppercase;
|
|
2755
|
+
color: var(--strand-gray-400);
|
|
2756
|
+
font-variant-numeric: tabular-nums;
|
|
2757
|
+
white-space: nowrap;
|
|
2758
|
+
}
|
|
2759
|
+
|
|
2760
|
+
.strand-log__status {
|
|
2761
|
+
font-family: var(--strand-font-mono);
|
|
2762
|
+
font-size: var(--strand-text-xs);
|
|
2763
|
+
font-weight: var(--strand-weight-semibold);
|
|
2764
|
+
letter-spacing: var(--strand-tracking-wider);
|
|
2765
|
+
text-transform: uppercase;
|
|
2766
|
+
white-space: nowrap;
|
|
2767
|
+
}
|
|
2768
|
+
|
|
2769
|
+
.strand-log__status--complete { color: var(--strand-teal-vital); }
|
|
2770
|
+
.strand-log__status--process { color: var(--strand-blue-primary); }
|
|
2771
|
+
.strand-log__status--warning { color: var(--strand-amber-caution); }
|
|
2772
|
+
.strand-log__status--error { color: var(--strand-red-alert); }
|
|
2773
|
+
|
|
2774
|
+
/* ── Metric Row ──
|
|
2775
|
+
Derivation: centered-group (DL 11.10).
|
|
2776
|
+
self-contained(atom)* with center distribution + responsive gap */
|
|
2777
|
+
.strand-metric-row {
|
|
2778
|
+
display: flex;
|
|
2779
|
+
justify-content: center;
|
|
2780
|
+
gap: clamp(2rem, 5vw, 4rem);
|
|
2781
|
+
text-align: center;
|
|
2782
|
+
}
|
|
2783
|
+
|
|
2784
|
+
/* ── Bar Chart ──
|
|
2785
|
+
Derivation: column-array (DL 11.10).
|
|
2786
|
+
column(amount? + bar + label)* with equal flex + flex-end alignment.
|
|
2787
|
+
Blue Discipline: one color (--strand-blue-indicator). Part XIII viz rules. */
|
|
2788
|
+
.strand-bar-chart {
|
|
2789
|
+
display: flex;
|
|
2790
|
+
gap: var(--strand-space-2);
|
|
2791
|
+
align-items: flex-end;
|
|
2792
|
+
height: var(--strand-space-24);
|
|
2793
|
+
padding: var(--strand-space-5);
|
|
2794
|
+
}
|
|
2795
|
+
|
|
2796
|
+
.strand-bar-chart__col {
|
|
2797
|
+
flex: 1;
|
|
2798
|
+
display: flex;
|
|
2799
|
+
flex-direction: column;
|
|
2800
|
+
align-items: center;
|
|
2801
|
+
gap: var(--strand-space-1);
|
|
2802
|
+
height: 100%;
|
|
2803
|
+
justify-content: flex-end;
|
|
2804
|
+
}
|
|
2805
|
+
|
|
2806
|
+
.strand-bar-chart__bar {
|
|
2807
|
+
width: 100%;
|
|
2808
|
+
background: var(--strand-blue-indicator);
|
|
2809
|
+
border-radius: var(--strand-radius-sm) var(--strand-radius-sm) 0 0;
|
|
2810
|
+
min-height: var(--strand-space-1);
|
|
2811
|
+
}
|
|
2812
|
+
|
|
2813
|
+
.strand-bar-chart__amount {
|
|
2814
|
+
font-family: var(--strand-font-mono);
|
|
2815
|
+
font-size: var(--strand-text-xs);
|
|
2816
|
+
font-weight: var(--strand-weight-medium);
|
|
2817
|
+
letter-spacing: var(--strand-tracking-wider);
|
|
2818
|
+
text-transform: uppercase;
|
|
2819
|
+
color: var(--strand-gray-300);
|
|
2820
|
+
font-variant-numeric: tabular-nums;
|
|
2821
|
+
}
|
|
2822
|
+
|
|
2823
|
+
.strand-bar-chart__label {
|
|
2824
|
+
font-family: var(--strand-font-mono);
|
|
2825
|
+
font-size: var(--strand-text-xs);
|
|
2826
|
+
font-weight: var(--strand-weight-medium);
|
|
2827
|
+
letter-spacing: var(--strand-tracking-wider);
|
|
2828
|
+
text-transform: uppercase;
|
|
2829
|
+
color: var(--strand-gray-400);
|
|
2830
|
+
}
|
|
2831
|
+
|
|
2668
2832
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dillingerstaffing/strand-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.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.11.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>(
|
package/src/static.css
CHANGED
|
@@ -77,6 +77,16 @@
|
|
|
77
77
|
letter-spacing: var(--strand-tracking-tighter);
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
+
/* ── Title (human voice display, DL Part IV.7) ── */
|
|
81
|
+
.strand-title {
|
|
82
|
+
font-family: var(--strand-font-sans);
|
|
83
|
+
font-weight: var(--strand-weight-light);
|
|
84
|
+
letter-spacing: var(--strand-tracking-tighter);
|
|
85
|
+
color: var(--strand-blue-midnight);
|
|
86
|
+
font-size: clamp(1.5rem, 3vw + 0.5rem, 2.5rem);
|
|
87
|
+
line-height: var(--strand-leading-snug);
|
|
88
|
+
}
|
|
89
|
+
|
|
80
90
|
/* ── Lead (intro paragraph, DL Part IV.6) ── */
|
|
81
91
|
.strand-lead {
|
|
82
92
|
font-size: var(--strand-text-lg);
|
|
@@ -95,3 +105,153 @@
|
|
|
95
105
|
.strand-text-secondary--xs {
|
|
96
106
|
font-size: var(--strand-text-xs);
|
|
97
107
|
}
|
|
108
|
+
|
|
109
|
+
/* ══════════════════════════════════════════════════
|
|
110
|
+
COMPOSITION MOLECULES (DL Part XI-B Grammar)
|
|
111
|
+
Named derivations of DL composition primitives.
|
|
112
|
+
Each molecule is a convenience class for a common
|
|
113
|
+
derivation chain. See DL 11.10 Productions for the
|
|
114
|
+
grammar rules; DL 11.12 Derivation for verification.
|
|
115
|
+
══════════════════════════════════════════════════ */
|
|
116
|
+
|
|
117
|
+
/* ── Card Section ──
|
|
118
|
+
Derivation: section-boundary production (DL 11.10).
|
|
119
|
+
OVERLINE + border-bottom + margin-bottom + padding-bottom */
|
|
120
|
+
.strand-card-section {
|
|
121
|
+
display: flex;
|
|
122
|
+
justify-content: space-between;
|
|
123
|
+
align-items: center;
|
|
124
|
+
margin-bottom: var(--strand-space-3);
|
|
125
|
+
padding-bottom: var(--strand-space-2);
|
|
126
|
+
border-bottom: 1px solid var(--strand-gray-200);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/* ── Key-Value Row ──
|
|
130
|
+
Derivation: inline-pair + ranked-sequence (DL 11.10).
|
|
131
|
+
identifier(OVERLINE) + quantifier(MONO_VALUE) + RANK_BORDER */
|
|
132
|
+
.strand-kv {
|
|
133
|
+
display: flex;
|
|
134
|
+
justify-content: space-between;
|
|
135
|
+
align-items: center;
|
|
136
|
+
padding-block: var(--strand-space-2);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.strand-kv + .strand-kv {
|
|
140
|
+
border-top: 1px solid var(--strand-border-subtle);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.strand-kv__label {
|
|
144
|
+
font-family: var(--strand-font-mono);
|
|
145
|
+
font-size: var(--strand-text-xs);
|
|
146
|
+
font-weight: var(--strand-weight-medium);
|
|
147
|
+
letter-spacing: var(--strand-tracking-wider);
|
|
148
|
+
text-transform: uppercase;
|
|
149
|
+
color: var(--strand-gray-500);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.strand-kv__value {
|
|
153
|
+
font-family: var(--strand-font-mono);
|
|
154
|
+
font-size: var(--strand-text-xs);
|
|
155
|
+
color: var(--strand-gray-600);
|
|
156
|
+
font-variant-numeric: tabular-nums;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.strand-kv__value--status {
|
|
160
|
+
color: var(--strand-teal-vital);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/* ── Diagnostic Log Entry ──
|
|
164
|
+
Derivation: inline-sequence + ranked-sequence (DL 11.10).
|
|
165
|
+
time(OVERLINE) + status(OVERLINE+COLOR_SEMANTIC) + text(SECONDARY) + RANK_BORDER */
|
|
166
|
+
.strand-log {
|
|
167
|
+
display: flex;
|
|
168
|
+
gap: var(--strand-space-3);
|
|
169
|
+
padding-block: var(--strand-space-2);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
.strand-log + .strand-log {
|
|
173
|
+
border-top: 1px solid var(--strand-border-subtle);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.strand-log__time {
|
|
177
|
+
font-family: var(--strand-font-mono);
|
|
178
|
+
font-size: var(--strand-text-xs);
|
|
179
|
+
font-weight: var(--strand-weight-medium);
|
|
180
|
+
letter-spacing: var(--strand-tracking-wider);
|
|
181
|
+
text-transform: uppercase;
|
|
182
|
+
color: var(--strand-gray-400);
|
|
183
|
+
font-variant-numeric: tabular-nums;
|
|
184
|
+
white-space: nowrap;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
.strand-log__status {
|
|
188
|
+
font-family: var(--strand-font-mono);
|
|
189
|
+
font-size: var(--strand-text-xs);
|
|
190
|
+
font-weight: var(--strand-weight-semibold);
|
|
191
|
+
letter-spacing: var(--strand-tracking-wider);
|
|
192
|
+
text-transform: uppercase;
|
|
193
|
+
white-space: nowrap;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.strand-log__status--complete { color: var(--strand-teal-vital); }
|
|
197
|
+
.strand-log__status--process { color: var(--strand-blue-primary); }
|
|
198
|
+
.strand-log__status--warning { color: var(--strand-amber-caution); }
|
|
199
|
+
.strand-log__status--error { color: var(--strand-red-alert); }
|
|
200
|
+
|
|
201
|
+
/* ── Metric Row ──
|
|
202
|
+
Derivation: centered-group (DL 11.10).
|
|
203
|
+
self-contained(atom)* with center distribution + responsive gap */
|
|
204
|
+
.strand-metric-row {
|
|
205
|
+
display: flex;
|
|
206
|
+
justify-content: center;
|
|
207
|
+
gap: clamp(2rem, 5vw, 4rem);
|
|
208
|
+
text-align: center;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/* ── Bar Chart ──
|
|
212
|
+
Derivation: column-array (DL 11.10).
|
|
213
|
+
column(amount? + bar + label)* with equal flex + flex-end alignment.
|
|
214
|
+
Blue Discipline: one color (--strand-blue-indicator). Part XIII viz rules. */
|
|
215
|
+
.strand-bar-chart {
|
|
216
|
+
display: flex;
|
|
217
|
+
gap: var(--strand-space-2);
|
|
218
|
+
align-items: flex-end;
|
|
219
|
+
height: var(--strand-space-24);
|
|
220
|
+
padding: var(--strand-space-5);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
.strand-bar-chart__col {
|
|
224
|
+
flex: 1;
|
|
225
|
+
display: flex;
|
|
226
|
+
flex-direction: column;
|
|
227
|
+
align-items: center;
|
|
228
|
+
gap: var(--strand-space-1);
|
|
229
|
+
height: 100%;
|
|
230
|
+
justify-content: flex-end;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
.strand-bar-chart__bar {
|
|
234
|
+
width: 100%;
|
|
235
|
+
background: var(--strand-blue-indicator);
|
|
236
|
+
border-radius: var(--strand-radius-sm) var(--strand-radius-sm) 0 0;
|
|
237
|
+
min-height: var(--strand-space-1);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
.strand-bar-chart__amount {
|
|
241
|
+
font-family: var(--strand-font-mono);
|
|
242
|
+
font-size: var(--strand-text-xs);
|
|
243
|
+
font-weight: var(--strand-weight-medium);
|
|
244
|
+
letter-spacing: var(--strand-tracking-wider);
|
|
245
|
+
text-transform: uppercase;
|
|
246
|
+
color: var(--strand-gray-300);
|
|
247
|
+
font-variant-numeric: tabular-nums;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
.strand-bar-chart__label {
|
|
251
|
+
font-family: var(--strand-font-mono);
|
|
252
|
+
font-size: var(--strand-text-xs);
|
|
253
|
+
font-weight: var(--strand-weight-medium);
|
|
254
|
+
letter-spacing: var(--strand-tracking-wider);
|
|
255
|
+
text-transform: uppercase;
|
|
256
|
+
color: var(--strand-gray-400);
|
|
257
|
+
}
|