@mystravil/hardpoint 0.1.0 → 0.2.1

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 (67) hide show
  1. package/CHANGELOG.md +42 -18
  2. package/LICENSE +25 -25
  3. package/README.md +67 -64
  4. package/dist/base.css +625 -346
  5. package/dist/components/AppShell.svelte +698 -698
  6. package/dist/components/Button.svelte +174 -174
  7. package/dist/components/Checkbox.svelte +235 -198
  8. package/dist/components/Checkbox.svelte.d.ts +9 -2
  9. package/dist/components/CheckboxGroup.svelte +207 -99
  10. package/dist/components/CheckboxGroup.svelte.d.ts +23 -4
  11. package/dist/components/Combobox.svelte +901 -824
  12. package/dist/components/Combobox.svelte.d.ts +10 -1
  13. package/dist/components/Dialog.svelte +359 -356
  14. package/dist/components/Disclosure.svelte +201 -201
  15. package/dist/components/EmptyState.svelte +88 -88
  16. package/dist/components/ErrorState.svelte +135 -135
  17. package/dist/components/ImageViewer.svelte +764 -0
  18. package/dist/components/ImageViewer.svelte.d.ts +55 -0
  19. package/dist/components/KeyValueList.svelte +114 -114
  20. package/dist/components/ListDetail.svelte +218 -0
  21. package/dist/components/ListDetail.svelte.d.ts +37 -0
  22. package/dist/components/LoadRegion.svelte +219 -219
  23. package/dist/components/MediaFrame.svelte +110 -110
  24. package/dist/components/MediaImage.svelte +256 -256
  25. package/dist/components/Menu.svelte +258 -258
  26. package/dist/components/MenuCheckboxItem.svelte +119 -119
  27. package/dist/components/MenuGroup.svelte +50 -50
  28. package/dist/components/MenuItem.svelte +94 -94
  29. package/dist/components/MenuRadioGroup.svelte +62 -62
  30. package/dist/components/MenuRadioItem.svelte +110 -110
  31. package/dist/components/MenuSeparator.svelte +28 -28
  32. package/dist/components/Meter.svelte +283 -0
  33. package/dist/components/Meter.svelte.d.ts +66 -0
  34. package/dist/components/NativeSelect.svelte +18 -2
  35. package/dist/components/NativeSelect.svelte.d.ts +6 -0
  36. package/dist/components/Notice.svelte +262 -0
  37. package/dist/components/Notice.svelte.d.ts +30 -0
  38. package/dist/components/Popover.svelte +222 -222
  39. package/dist/components/Progress.svelte +157 -157
  40. package/dist/components/RadioGroup.svelte +440 -0
  41. package/dist/components/RadioGroup.svelte.d.ts +50 -0
  42. package/dist/components/Select.svelte +471 -405
  43. package/dist/components/Select.svelte.d.ts +6 -0
  44. package/dist/components/Skeleton.svelte +149 -149
  45. package/dist/components/Spinner.svelte +118 -117
  46. package/dist/components/Stat.svelte +253 -253
  47. package/dist/components/Steps.svelte +189 -189
  48. package/dist/components/Switch.svelte +222 -222
  49. package/dist/components/Table.svelte +504 -504
  50. package/dist/components/Tabs.svelte +246 -246
  51. package/dist/components/Tag.svelte +40 -40
  52. package/dist/components/TextArea.svelte +272 -0
  53. package/dist/components/TextArea.svelte.d.ts +28 -0
  54. package/dist/components/TextField.svelte +256 -256
  55. package/dist/components/Timeline.svelte +156 -156
  56. package/dist/components/Toaster.svelte +411 -411
  57. package/dist/components/Tooltip.svelte +200 -200
  58. package/dist/components/TooltipGroup.svelte +46 -46
  59. package/dist/components/internal/Scrim.svelte +52 -52
  60. package/dist/components/internal/Sheet.svelte +263 -263
  61. package/dist/components/internal/groups.d.ts +14 -0
  62. package/dist/components/internal/groups.js +23 -0
  63. package/dist/fonts.css +71 -71
  64. package/dist/index.d.ts +6 -0
  65. package/dist/index.js +6 -0
  66. package/dist/tokens.css +283 -279
  67. 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>