@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,156 +1,156 @@
1
- <script lang="ts" module>
2
- import type { HTMLOlAttributes } from 'svelte/elements';
3
-
4
- /** A status hue for an event's node: `ok` done, `warn` waiting or needs you, `danger` failed. */
5
- export type TimelineTone = 'ok' | 'warn' | 'danger';
6
-
7
- export type TimelineEvent = {
8
- /** What happened, as the app or a user wrote it. */
9
- title: string;
10
- /** A supporting line in `--muted`. */
11
- detail?: string;
12
- /** The date as shown. */
13
- date: string;
14
- /** The time as shown, after the date. */
15
- time?: string;
16
- /**
17
- * The machine-readable moment for `<time datetime>`. Defaults to
18
- * `date`, or `dateTtime` with a time, so ISO dates need nothing else.
19
- */
20
- datetime?: string;
21
- /**
22
- * Colours the node in a status hue. The title must say the same, because
23
- * colour is never the only signal.
24
- */
25
- tone?: TimelineTone;
26
- };
27
-
28
- export type TimelineProps = Omit<HTMLOlAttributes, 'children'> & {
29
- /** Oldest first or newest first, in the order given. */
30
- events: TimelineEvent[];
31
- };
32
- </script>
33
-
34
- <script lang="ts">
35
- import { onMount, untrack } from 'svelte';
36
- import { useMotion } from '../motion/index.js';
37
-
38
- let { events, class: className, ...rest }: TimelineProps = $props();
39
-
40
- // Expressive stagger (motion rule 7), as in Table: only the events of the
41
- // first render enter, by their index. Each <li> carries its node and its
42
- // rail segment, so they enter with it. Any change to `events` (a new array
43
- // or a changed length) ends the entrance, and so does its last animation.
44
- const motion = useMotion();
45
- const firstEvents = untrack(() => events);
46
- const firstCount = untrack(() => events.length);
47
- let entering = $state.raw(motion.expressive);
48
- let root: HTMLOListElement;
49
-
50
- $effect.pre(() => {
51
- if (events !== firstEvents || events.length !== firstCount) entering = false;
52
- });
53
-
54
- onMount(() => {
55
- if (!entering) return;
56
- const running = root
57
- .getAnimations({ subtree: true })
58
- .filter((a) => a instanceof CSSAnimation && a.animationName === 'hp-enter');
59
- Promise.allSettled(running.map((a) => a.finished)).then(() => {
60
- entering = false;
61
- });
62
- });
63
- </script>
64
-
65
- <!--
66
- Square nodes on a 2px titanium rail (BRIEF, visual rule 7; da3-60), in
67
- Geist Mono. Extra attributes and `class` go to the <ol>.
68
- -->
69
- <ol {...rest} bind:this={root} class={['hp-timeline', className]}>
70
- {#each events as event, i}
71
- <li data-tone={event.tone} class={[entering && 'hp-enter']} style:--i={entering ? i : undefined}>
72
- <span>{event.title}</span>
73
- {#if event.detail}
74
- <span class="detail">{event.detail}</span>
75
- {/if}
76
- <span class="when"
77
- ><time datetime={event.datetime ?? (event.time ? `${event.date}T${event.time}` : event.date)}
78
- >{event.date}</time
79
- >{#if event.time}<span>{event.time}</span>{/if}</span
80
- >
81
- </li>
82
- {/each}
83
- </ol>
84
-
85
- <style>
86
- /* 16px on touch, the dense 14px on fine pointers. A long identifier or
87
- path breaks anywhere rather than widen the page. */
88
- .hp-timeline {
89
- margin: 0;
90
- padding: 0 0 0 var(--space-8);
91
- font-family: var(--mono);
92
- font-size: var(--type-body);
93
- line-height: 24px;
94
- list-style: none;
95
- overflow-wrap: anywhere;
96
- }
97
- @media (pointer: fine) {
98
- .hp-timeline {
99
- font-size: var(--type-dense);
100
- line-height: 20px;
101
- }
102
- }
103
-
104
- li {
105
- position: relative;
106
- display: grid;
107
- padding-bottom: var(--space-6);
108
- }
109
- li:last-child {
110
- padding-bottom: 0;
111
- }
112
-
113
- /* The node: a 12px square, titanium or the event's status hue, centred on
114
- the first line (4px from the top at 20px lines, 6px at 24px). */
115
- li::before {
116
- content: '';
117
- position: absolute;
118
- top: calc((1lh - 12px) / 2);
119
- left: calc(-1 * var(--space-8));
120
- width: 12px;
121
- height: 12px;
122
- background: var(--accent);
123
- }
124
- li[data-tone='ok']::before {
125
- background: var(--ok);
126
- }
127
- li[data-tone='warn']::before {
128
- background: var(--warn);
129
- }
130
- li[data-tone='danger']::before {
131
- background: var(--danger);
132
- }
133
-
134
- /* The rail: 2px, centred under the node, from its bottom edge down to the
135
- next node's top edge. */
136
- li:not(:last-child)::after {
137
- content: '';
138
- position: absolute;
139
- top: calc((1lh + 12px) / 2);
140
- bottom: calc((12px - 1lh) / 2);
141
- /* matches the approved specimen */
142
- left: calc(-1 * var(--space-8) + 5px);
143
- /* matches the approved specimen */
144
- width: 2px;
145
- background: var(--accent);
146
- }
147
-
148
- .detail {
149
- color: var(--muted);
150
- }
151
- .when {
152
- display: flex;
153
- /* matches the approved specimen */
154
- gap: 4ch;
155
- }
156
- </style>
1
+ <script lang="ts" module>
2
+ import type { HTMLOlAttributes } from 'svelte/elements';
3
+
4
+ /** A status hue for an event's node: `ok` done, `warn` waiting or needs you, `danger` failed. */
5
+ export type TimelineTone = 'ok' | 'warn' | 'danger';
6
+
7
+ export type TimelineEvent = {
8
+ /** What happened, as the app or a user wrote it. */
9
+ title: string;
10
+ /** A supporting line in `--muted`. */
11
+ detail?: string;
12
+ /** The date as shown. */
13
+ date: string;
14
+ /** The time as shown, after the date. */
15
+ time?: string;
16
+ /**
17
+ * The machine-readable moment for `<time datetime>`. Defaults to
18
+ * `date`, or `dateTtime` with a time, so ISO dates need nothing else.
19
+ */
20
+ datetime?: string;
21
+ /**
22
+ * Colours the node in a status hue. The title must say the same, because
23
+ * colour is never the only signal.
24
+ */
25
+ tone?: TimelineTone;
26
+ };
27
+
28
+ export type TimelineProps = Omit<HTMLOlAttributes, 'children'> & {
29
+ /** Oldest first or newest first, in the order given. */
30
+ events: TimelineEvent[];
31
+ };
32
+ </script>
33
+
34
+ <script lang="ts">
35
+ import { onMount, untrack } from 'svelte';
36
+ import { useMotion } from '../motion/index.js';
37
+
38
+ let { events, class: className, ...rest }: TimelineProps = $props();
39
+
40
+ // Expressive stagger (motion rule 7), as in Table: only the events of the
41
+ // first render enter, by their index. Each <li> carries its node and its
42
+ // rail segment, so they enter with it. Any change to `events` (a new array
43
+ // or a changed length) ends the entrance, and so does its last animation.
44
+ const motion = useMotion();
45
+ const firstEvents = untrack(() => events);
46
+ const firstCount = untrack(() => events.length);
47
+ let entering = $state.raw(motion.expressive);
48
+ let root: HTMLOListElement;
49
+
50
+ $effect.pre(() => {
51
+ if (events !== firstEvents || events.length !== firstCount) entering = false;
52
+ });
53
+
54
+ onMount(() => {
55
+ if (!entering) return;
56
+ const running = root
57
+ .getAnimations({ subtree: true })
58
+ .filter((a) => a instanceof CSSAnimation && a.animationName === 'hp-enter');
59
+ Promise.allSettled(running.map((a) => a.finished)).then(() => {
60
+ entering = false;
61
+ });
62
+ });
63
+ </script>
64
+
65
+ <!--
66
+ Square nodes on a 2px titanium rail (BRIEF, visual rule 7; da3-60), in
67
+ Geist Mono. Extra attributes and `class` go to the <ol>.
68
+ -->
69
+ <ol {...rest} bind:this={root} class={['hp-timeline', className]}>
70
+ {#each events as event, i}
71
+ <li data-tone={event.tone} class={[entering && 'hp-enter']} style:--i={entering ? i : undefined}>
72
+ <span>{event.title}</span>
73
+ {#if event.detail}
74
+ <span class="detail">{event.detail}</span>
75
+ {/if}
76
+ <span class="when"
77
+ ><time datetime={event.datetime ?? (event.time ? `${event.date}T${event.time}` : event.date)}
78
+ >{event.date}</time
79
+ >{#if event.time}<span>{event.time}</span>{/if}</span
80
+ >
81
+ </li>
82
+ {/each}
83
+ </ol>
84
+
85
+ <style>
86
+ /* 16px on touch, the dense 14px on fine pointers. A long identifier or
87
+ path breaks anywhere rather than widen the page. */
88
+ .hp-timeline {
89
+ margin: 0;
90
+ padding: 0 0 0 var(--space-8);
91
+ font-family: var(--mono);
92
+ font-size: var(--type-body);
93
+ line-height: 24px;
94
+ list-style: none;
95
+ overflow-wrap: anywhere;
96
+ }
97
+ @media (pointer: fine) {
98
+ .hp-timeline {
99
+ font-size: var(--type-dense);
100
+ line-height: 20px;
101
+ }
102
+ }
103
+
104
+ li {
105
+ position: relative;
106
+ display: grid;
107
+ padding-bottom: var(--space-6);
108
+ }
109
+ li:last-child {
110
+ padding-bottom: 0;
111
+ }
112
+
113
+ /* The node: a 12px square, titanium or the event's status hue, centred on
114
+ the first line (4px from the top at 20px lines, 6px at 24px). */
115
+ li::before {
116
+ content: '';
117
+ position: absolute;
118
+ top: calc((1lh - 12px) / 2);
119
+ left: calc(-1 * var(--space-8));
120
+ width: 12px;
121
+ height: 12px;
122
+ background: var(--accent);
123
+ }
124
+ li[data-tone='ok']::before {
125
+ background: var(--ok);
126
+ }
127
+ li[data-tone='warn']::before {
128
+ background: var(--warn);
129
+ }
130
+ li[data-tone='danger']::before {
131
+ background: var(--danger);
132
+ }
133
+
134
+ /* The rail: 2px, centred under the node, from its bottom edge down to the
135
+ next node's top edge. */
136
+ li:not(:last-child)::after {
137
+ content: '';
138
+ position: absolute;
139
+ top: calc((1lh + 12px) / 2);
140
+ bottom: calc((12px - 1lh) / 2);
141
+ /* matches the approved specimen */
142
+ left: calc(-1 * var(--space-8) + 5px);
143
+ /* matches the approved specimen */
144
+ width: 2px;
145
+ background: var(--accent);
146
+ }
147
+
148
+ .detail {
149
+ color: var(--muted);
150
+ }
151
+ .when {
152
+ display: flex;
153
+ /* matches the approved specimen */
154
+ gap: 4ch;
155
+ }
156
+ </style>