@mystravil/hardpoint 0.2.0 → 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.
Files changed (54) hide show
  1. package/CHANGELOG.md +51 -38
  2. package/LICENSE +25 -25
  3. package/README.md +67 -64
  4. package/dist/base.css +625 -625
  5. package/dist/components/AppShell.svelte +698 -698
  6. package/dist/components/Button.svelte +221 -174
  7. package/dist/components/Button.svelte.d.ts +18 -2
  8. package/dist/components/Checkbox.svelte +235 -235
  9. package/dist/components/CheckboxGroup.svelte +207 -207
  10. package/dist/components/Combobox.svelte +901 -901
  11. package/dist/components/Dialog.svelte +359 -359
  12. package/dist/components/Disclosure.svelte +201 -201
  13. package/dist/components/EmptyState.svelte +88 -88
  14. package/dist/components/ErrorState.svelte +135 -135
  15. package/dist/components/ImageViewer.svelte +764 -764
  16. package/dist/components/KeyValueList.svelte +114 -114
  17. package/dist/components/ListDetail.svelte +218 -218
  18. package/dist/components/LoadRegion.svelte +219 -219
  19. package/dist/components/MediaFrame.svelte +110 -110
  20. package/dist/components/MediaImage.svelte +256 -256
  21. package/dist/components/Menu.svelte +275 -258
  22. package/dist/components/MenuCheckboxItem.svelte +119 -119
  23. package/dist/components/MenuGroup.svelte +50 -50
  24. package/dist/components/MenuItem.svelte +94 -94
  25. package/dist/components/MenuRadioGroup.svelte +62 -62
  26. package/dist/components/MenuRadioItem.svelte +110 -110
  27. package/dist/components/MenuSeparator.svelte +28 -28
  28. package/dist/components/Meter.svelte +283 -283
  29. package/dist/components/NativeSelect.svelte +135 -135
  30. package/dist/components/Notice.svelte +262 -262
  31. package/dist/components/Popover.svelte +222 -222
  32. package/dist/components/Progress.svelte +157 -157
  33. package/dist/components/RadioGroup.svelte +440 -440
  34. package/dist/components/Select.svelte +471 -471
  35. package/dist/components/Skeleton.svelte +149 -149
  36. package/dist/components/Spinner.svelte +118 -118
  37. package/dist/components/Stat.svelte +253 -253
  38. package/dist/components/Steps.svelte +189 -189
  39. package/dist/components/Switch.svelte +222 -222
  40. package/dist/components/Table.svelte +504 -504
  41. package/dist/components/Tabs.svelte +246 -246
  42. package/dist/components/Tag.svelte +40 -40
  43. package/dist/components/TextArea.svelte +272 -272
  44. package/dist/components/TextField.svelte +396 -256
  45. package/dist/components/TextField.svelte.d.ts +16 -1
  46. package/dist/components/Timeline.svelte +156 -156
  47. package/dist/components/Toaster.svelte +411 -411
  48. package/dist/components/Tooltip.svelte +200 -200
  49. package/dist/components/TooltipGroup.svelte +46 -46
  50. package/dist/components/internal/Scrim.svelte +52 -52
  51. package/dist/components/internal/Sheet.svelte +263 -263
  52. package/dist/fonts.css +71 -71
  53. package/dist/tokens.css +283 -283
  54. package/package.json +81 -76
@@ -1,189 +1,189 @@
1
- <script lang="ts" module>
2
- import type { HTMLOlAttributes } from 'svelte/elements';
3
-
4
- export type StepsItem = {
5
- /** The step's caps label. A short fixed string the app defines. */
6
- label: string;
7
- /** A supporting line in `--muted`, as written. */
8
- detail?: string;
9
- };
10
-
11
- /** Where a step stands, from `current`. Each step's `<li>` carries it in `data-state`. */
12
- export type StepsState = 'done' | 'current' | 'upcoming';
13
-
14
- /** From which width the steps sit in a row: 600px, 900px or 1200px. */
15
- export type StepsBreakpoint = 'medium' | 'expanded' | 'large';
16
-
17
- export type StepsProps = Omit<HTMLOlAttributes, 'children'> & {
18
- /** In order, first to last. */
19
- steps: StepsItem[];
20
- /**
21
- * The index of the current step, from 0. Steps before it are done,
22
- * steps after it upcoming. `steps.length` marks every step done.
23
- */
24
- current: number;
25
- /**
26
- * From which width the steps sit in a row of equal columns; narrower,
27
- * they stack. Default `medium` (600px). Pick a later one when long
28
- * labels or many steps would not fit their columns.
29
- */
30
- rowFrom?: StepsBreakpoint;
31
- /** Screen-reader text after a done step's label. Default `done`. */
32
- doneLabel?: string;
33
- };
34
- </script>
35
-
36
- <script lang="ts">
37
- let {
38
- steps,
39
- current,
40
- rowFrom = 'medium',
41
- doneLabel = 'done',
42
- class: className,
43
- ...rest
44
- }: StepsProps = $props();
45
-
46
- function stateOf(index: number): StepsState {
47
- return index < current ? 'done' : index === current ? 'current' : 'upcoming';
48
- }
49
- </script>
50
-
51
- <!--
52
- Ordered steps as discrete segments (BRIEF, visual rule 7): each step has a
53
- 3px edge, titanium once reached and --border while upcoming, so the edges
54
- read as a segmented bar. The current step adds the selection tint and
55
- aria-current="step"; a done step shows a check for its number. A row from
56
- `rowFrom` (600px by default), stacked below. When the current step
57
- changes, the edges and the tint fade their colour over --dur-segment.
58
- Extra attributes (an `aria-label` naming the process)
59
- and `class` go to the <ol>.
60
- -->
61
- <ol role="list" {...rest} class={['hp-steps', className]} data-row-from={rowFrom}>
62
- {#each steps as step, index}
63
- {@const state = stateOf(index)}
64
- <li class="hp-steps-step" data-state={state} aria-current={state === 'current' ? 'step' : undefined}>
65
- <span class="hp-steps-mark" aria-hidden="true">
66
- {#if state === 'done'}
67
- <svg viewBox="0 0 16 16" width="16" height="16" focusable="false">
68
- <path d="m3 8.5 3.5 3.5 6.5-7.5" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="square" />
69
- </svg>
70
- {:else}
71
- {index + 1}
72
- {/if}
73
- </span>
74
- <span class="hp-steps-label hp-label">{step.label}</span>
75
- {#if state === 'done'}<span class="hp-visually-hidden">, {doneLabel}</span>{/if}
76
- {#if step.detail}<span class="hp-steps-detail">{step.detail}</span>{/if}
77
- </li>
78
- {/each}
79
- </ol>
80
-
81
- <style>
82
- /* Stacked below 600px. The edges and the current tint reach --bleed into
83
- the gutter, so the labels keep the page edge, as table rows do. */
84
- .hp-steps {
85
- display: grid;
86
- gap: var(--space-1);
87
- margin: 0 calc(-1 * var(--bleed));
88
- padding: 0;
89
- list-style: none;
90
- }
91
-
92
- /* The edge colour is a registered colour property, so it can transition
93
- on its own while the edge's shape switches at once between the stacked
94
- and the row form. */
95
- @property --steps-edge {
96
- syntax: '<color>';
97
- inherits: false;
98
- initial-value: transparent;
99
- }
100
-
101
- /* When the current step changes, the edge and the tint fade their colour
102
- over --dur-segment (BRIEF, short motion). A CSS transition never runs
103
- on an element's first style, so steps show their state at once when
104
- they render. 0ms is a snap. Colour only, so reduced motion keeps it.
105
- The text colour and the number or check change at once. */
106
- .hp-steps-step {
107
- --steps-edge: var(--accent);
108
- position: relative;
109
- display: grid;
110
- grid-template-columns: var(--space-4) minmax(0, 1fr);
111
- column-gap: var(--space-2);
112
- row-gap: var(--space-1);
113
- align-content: start;
114
- padding: var(--space-3) var(--space-3) var(--space-3) var(--bleed);
115
- /* the brief's 3px selection edge */
116
- box-shadow: inset 3px 0 0 var(--steps-edge);
117
- overflow-wrap: anywhere;
118
- transition:
119
- --steps-edge var(--dur-segment) var(--settle),
120
- background-color var(--dur-segment) var(--settle);
121
- }
122
- .hp-steps-step[data-state='current'] {
123
- background: var(--surface-selected);
124
- }
125
- .hp-steps-step[data-state='upcoming'] {
126
- --steps-edge: var(--border);
127
- color: var(--muted);
128
- }
129
-
130
- /* The number or the check, in a 16px box beside the label's first line. */
131
- .hp-steps-mark {
132
- display: grid;
133
- place-items: center;
134
- height: var(--space-4);
135
- font-size: var(--type-label);
136
- font-weight: 500;
137
- line-height: 16px;
138
- font-variant-numeric: tabular-nums;
139
- }
140
-
141
- .hp-steps-detail {
142
- grid-column: 2;
143
- color: var(--muted);
144
- font-size: var(--type-body);
145
- line-height: 24px;
146
- }
147
- @media (pointer: fine) {
148
- .hp-steps-detail {
149
- font-size: var(--type-dense);
150
- line-height: 20px;
151
- }
152
- }
153
-
154
- /* A row of equal columns from the rowFrom width, the edge on top. A label
155
- longer than its column still breaks rather than widen the page. */
156
- @media (min-width: 600px) {
157
- .hp-steps[data-row-from='medium'] {
158
- grid-auto-columns: minmax(0, 1fr);
159
- grid-auto-flow: column;
160
- }
161
- [data-row-from='medium'] > .hp-steps-step {
162
- padding: var(--space-4) var(--space-2) var(--space-3) var(--bleed);
163
- /* the brief's 3px selection edge */
164
- box-shadow: inset 0 3px 0 var(--steps-edge);
165
- }
166
- }
167
- @media (min-width: 900px) {
168
- .hp-steps[data-row-from='expanded'] {
169
- grid-auto-columns: minmax(0, 1fr);
170
- grid-auto-flow: column;
171
- }
172
- [data-row-from='expanded'] > .hp-steps-step {
173
- padding: var(--space-4) var(--space-2) var(--space-3) var(--bleed);
174
- /* the brief's 3px selection edge */
175
- box-shadow: inset 0 3px 0 var(--steps-edge);
176
- }
177
- }
178
- @media (min-width: 1200px) {
179
- .hp-steps[data-row-from='large'] {
180
- grid-auto-columns: minmax(0, 1fr);
181
- grid-auto-flow: column;
182
- }
183
- [data-row-from='large'] > .hp-steps-step {
184
- padding: var(--space-4) var(--space-2) var(--space-3) var(--bleed);
185
- /* the brief's 3px selection edge */
186
- box-shadow: inset 0 3px 0 var(--steps-edge);
187
- }
188
- }
189
- </style>
1
+ <script lang="ts" module>
2
+ import type { HTMLOlAttributes } from 'svelte/elements';
3
+
4
+ export type StepsItem = {
5
+ /** The step's caps label. A short fixed string the app defines. */
6
+ label: string;
7
+ /** A supporting line in `--muted`, as written. */
8
+ detail?: string;
9
+ };
10
+
11
+ /** Where a step stands, from `current`. Each step's `<li>` carries it in `data-state`. */
12
+ export type StepsState = 'done' | 'current' | 'upcoming';
13
+
14
+ /** From which width the steps sit in a row: 600px, 900px or 1200px. */
15
+ export type StepsBreakpoint = 'medium' | 'expanded' | 'large';
16
+
17
+ export type StepsProps = Omit<HTMLOlAttributes, 'children'> & {
18
+ /** In order, first to last. */
19
+ steps: StepsItem[];
20
+ /**
21
+ * The index of the current step, from 0. Steps before it are done,
22
+ * steps after it upcoming. `steps.length` marks every step done.
23
+ */
24
+ current: number;
25
+ /**
26
+ * From which width the steps sit in a row of equal columns; narrower,
27
+ * they stack. Default `medium` (600px). Pick a later one when long
28
+ * labels or many steps would not fit their columns.
29
+ */
30
+ rowFrom?: StepsBreakpoint;
31
+ /** Screen-reader text after a done step's label. Default `done`. */
32
+ doneLabel?: string;
33
+ };
34
+ </script>
35
+
36
+ <script lang="ts">
37
+ let {
38
+ steps,
39
+ current,
40
+ rowFrom = 'medium',
41
+ doneLabel = 'done',
42
+ class: className,
43
+ ...rest
44
+ }: StepsProps = $props();
45
+
46
+ function stateOf(index: number): StepsState {
47
+ return index < current ? 'done' : index === current ? 'current' : 'upcoming';
48
+ }
49
+ </script>
50
+
51
+ <!--
52
+ Ordered steps as discrete segments (BRIEF, visual rule 7): each step has a
53
+ 3px edge, titanium once reached and --border while upcoming, so the edges
54
+ read as a segmented bar. The current step adds the selection tint and
55
+ aria-current="step"; a done step shows a check for its number. A row from
56
+ `rowFrom` (600px by default), stacked below. When the current step
57
+ changes, the edges and the tint fade their colour over --dur-segment.
58
+ Extra attributes (an `aria-label` naming the process)
59
+ and `class` go to the <ol>.
60
+ -->
61
+ <ol role="list" {...rest} class={['hp-steps', className]} data-row-from={rowFrom}>
62
+ {#each steps as step, index}
63
+ {@const state = stateOf(index)}
64
+ <li class="hp-steps-step" data-state={state} aria-current={state === 'current' ? 'step' : undefined}>
65
+ <span class="hp-steps-mark" aria-hidden="true">
66
+ {#if state === 'done'}
67
+ <svg viewBox="0 0 16 16" width="16" height="16" focusable="false">
68
+ <path d="m3 8.5 3.5 3.5 6.5-7.5" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="square" />
69
+ </svg>
70
+ {:else}
71
+ {index + 1}
72
+ {/if}
73
+ </span>
74
+ <span class="hp-steps-label hp-label">{step.label}</span>
75
+ {#if state === 'done'}<span class="hp-visually-hidden">, {doneLabel}</span>{/if}
76
+ {#if step.detail}<span class="hp-steps-detail">{step.detail}</span>{/if}
77
+ </li>
78
+ {/each}
79
+ </ol>
80
+
81
+ <style>
82
+ /* Stacked below 600px. The edges and the current tint reach --bleed into
83
+ the gutter, so the labels keep the page edge, as table rows do. */
84
+ .hp-steps {
85
+ display: grid;
86
+ gap: var(--space-1);
87
+ margin: 0 calc(-1 * var(--bleed));
88
+ padding: 0;
89
+ list-style: none;
90
+ }
91
+
92
+ /* The edge colour is a registered colour property, so it can transition
93
+ on its own while the edge's shape switches at once between the stacked
94
+ and the row form. */
95
+ @property --steps-edge {
96
+ syntax: '<color>';
97
+ inherits: false;
98
+ initial-value: transparent;
99
+ }
100
+
101
+ /* When the current step changes, the edge and the tint fade their colour
102
+ over --dur-segment (BRIEF, short motion). A CSS transition never runs
103
+ on an element's first style, so steps show their state at once when
104
+ they render. 0ms is a snap. Colour only, so reduced motion keeps it.
105
+ The text colour and the number or check change at once. */
106
+ .hp-steps-step {
107
+ --steps-edge: var(--accent);
108
+ position: relative;
109
+ display: grid;
110
+ grid-template-columns: var(--space-4) minmax(0, 1fr);
111
+ column-gap: var(--space-2);
112
+ row-gap: var(--space-1);
113
+ align-content: start;
114
+ padding: var(--space-3) var(--space-3) var(--space-3) var(--bleed);
115
+ /* the brief's 3px selection edge */
116
+ box-shadow: inset 3px 0 0 var(--steps-edge);
117
+ overflow-wrap: anywhere;
118
+ transition:
119
+ --steps-edge var(--dur-segment) var(--settle),
120
+ background-color var(--dur-segment) var(--settle);
121
+ }
122
+ .hp-steps-step[data-state='current'] {
123
+ background: var(--surface-selected);
124
+ }
125
+ .hp-steps-step[data-state='upcoming'] {
126
+ --steps-edge: var(--border);
127
+ color: var(--muted);
128
+ }
129
+
130
+ /* The number or the check, in a 16px box beside the label's first line. */
131
+ .hp-steps-mark {
132
+ display: grid;
133
+ place-items: center;
134
+ height: var(--space-4);
135
+ font-size: var(--type-label);
136
+ font-weight: 500;
137
+ line-height: 16px;
138
+ font-variant-numeric: tabular-nums;
139
+ }
140
+
141
+ .hp-steps-detail {
142
+ grid-column: 2;
143
+ color: var(--muted);
144
+ font-size: var(--type-body);
145
+ line-height: 24px;
146
+ }
147
+ @media (pointer: fine) {
148
+ .hp-steps-detail {
149
+ font-size: var(--type-dense);
150
+ line-height: 20px;
151
+ }
152
+ }
153
+
154
+ /* A row of equal columns from the rowFrom width, the edge on top. A label
155
+ longer than its column still breaks rather than widen the page. */
156
+ @media (min-width: 600px) {
157
+ .hp-steps[data-row-from='medium'] {
158
+ grid-auto-columns: minmax(0, 1fr);
159
+ grid-auto-flow: column;
160
+ }
161
+ [data-row-from='medium'] > .hp-steps-step {
162
+ padding: var(--space-4) var(--space-2) var(--space-3) var(--bleed);
163
+ /* the brief's 3px selection edge */
164
+ box-shadow: inset 0 3px 0 var(--steps-edge);
165
+ }
166
+ }
167
+ @media (min-width: 900px) {
168
+ .hp-steps[data-row-from='expanded'] {
169
+ grid-auto-columns: minmax(0, 1fr);
170
+ grid-auto-flow: column;
171
+ }
172
+ [data-row-from='expanded'] > .hp-steps-step {
173
+ padding: var(--space-4) var(--space-2) var(--space-3) var(--bleed);
174
+ /* the brief's 3px selection edge */
175
+ box-shadow: inset 0 3px 0 var(--steps-edge);
176
+ }
177
+ }
178
+ @media (min-width: 1200px) {
179
+ .hp-steps[data-row-from='large'] {
180
+ grid-auto-columns: minmax(0, 1fr);
181
+ grid-auto-flow: column;
182
+ }
183
+ [data-row-from='large'] > .hp-steps-step {
184
+ padding: var(--space-4) var(--space-2) var(--space-3) var(--bleed);
185
+ /* the brief's 3px selection edge */
186
+ box-shadow: inset 0 3px 0 var(--steps-edge);
187
+ }
188
+ }
189
+ </style>