@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.
- package/CHANGELOG.md +42 -18
- package/LICENSE +25 -25
- package/README.md +67 -64
- package/dist/base.css +625 -346
- package/dist/components/AppShell.svelte +698 -698
- package/dist/components/Button.svelte +174 -174
- package/dist/components/Checkbox.svelte +235 -198
- package/dist/components/Checkbox.svelte.d.ts +9 -2
- package/dist/components/CheckboxGroup.svelte +207 -99
- package/dist/components/CheckboxGroup.svelte.d.ts +23 -4
- package/dist/components/Combobox.svelte +901 -824
- package/dist/components/Combobox.svelte.d.ts +10 -1
- package/dist/components/Dialog.svelte +359 -356
- package/dist/components/Disclosure.svelte +201 -201
- package/dist/components/EmptyState.svelte +88 -88
- package/dist/components/ErrorState.svelte +135 -135
- package/dist/components/ImageViewer.svelte +764 -0
- package/dist/components/ImageViewer.svelte.d.ts +55 -0
- package/dist/components/KeyValueList.svelte +114 -114
- package/dist/components/ListDetail.svelte +218 -0
- package/dist/components/ListDetail.svelte.d.ts +37 -0
- package/dist/components/LoadRegion.svelte +219 -219
- package/dist/components/MediaFrame.svelte +110 -110
- package/dist/components/MediaImage.svelte +256 -256
- package/dist/components/Menu.svelte +258 -258
- package/dist/components/MenuCheckboxItem.svelte +119 -119
- package/dist/components/MenuGroup.svelte +50 -50
- package/dist/components/MenuItem.svelte +94 -94
- package/dist/components/MenuRadioGroup.svelte +62 -62
- package/dist/components/MenuRadioItem.svelte +110 -110
- package/dist/components/MenuSeparator.svelte +28 -28
- package/dist/components/Meter.svelte +283 -0
- package/dist/components/Meter.svelte.d.ts +66 -0
- package/dist/components/NativeSelect.svelte +18 -2
- package/dist/components/NativeSelect.svelte.d.ts +6 -0
- package/dist/components/Notice.svelte +262 -0
- package/dist/components/Notice.svelte.d.ts +30 -0
- package/dist/components/Popover.svelte +222 -222
- package/dist/components/Progress.svelte +157 -157
- package/dist/components/RadioGroup.svelte +440 -0
- package/dist/components/RadioGroup.svelte.d.ts +50 -0
- package/dist/components/Select.svelte +471 -405
- package/dist/components/Select.svelte.d.ts +6 -0
- package/dist/components/Skeleton.svelte +149 -149
- package/dist/components/Spinner.svelte +118 -117
- package/dist/components/Stat.svelte +253 -253
- package/dist/components/Steps.svelte +189 -189
- package/dist/components/Switch.svelte +222 -222
- package/dist/components/Table.svelte +504 -504
- package/dist/components/Tabs.svelte +246 -246
- package/dist/components/Tag.svelte +40 -40
- package/dist/components/TextArea.svelte +272 -0
- package/dist/components/TextArea.svelte.d.ts +28 -0
- package/dist/components/TextField.svelte +256 -256
- package/dist/components/Timeline.svelte +156 -156
- package/dist/components/Toaster.svelte +411 -411
- package/dist/components/Tooltip.svelte +200 -200
- package/dist/components/TooltipGroup.svelte +46 -46
- package/dist/components/internal/Scrim.svelte +52 -52
- package/dist/components/internal/Sheet.svelte +263 -263
- package/dist/components/internal/groups.d.ts +14 -0
- package/dist/components/internal/groups.js +23 -0
- package/dist/fonts.css +71 -71
- package/dist/index.d.ts +6 -0
- package/dist/index.js +6 -0
- package/dist/tokens.css +283 -279
- 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>
|