@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.
- package/CHANGELOG.md +51 -38
- package/LICENSE +25 -25
- package/README.md +67 -64
- package/dist/base.css +625 -625
- package/dist/components/AppShell.svelte +698 -698
- package/dist/components/Button.svelte +221 -174
- package/dist/components/Button.svelte.d.ts +18 -2
- package/dist/components/Checkbox.svelte +235 -235
- package/dist/components/CheckboxGroup.svelte +207 -207
- package/dist/components/Combobox.svelte +901 -901
- package/dist/components/Dialog.svelte +359 -359
- 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 -764
- package/dist/components/KeyValueList.svelte +114 -114
- package/dist/components/ListDetail.svelte +218 -218
- 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 +275 -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 -283
- package/dist/components/NativeSelect.svelte +135 -135
- package/dist/components/Notice.svelte +262 -262
- package/dist/components/Popover.svelte +222 -222
- package/dist/components/Progress.svelte +157 -157
- package/dist/components/RadioGroup.svelte +440 -440
- package/dist/components/Select.svelte +471 -471
- package/dist/components/Skeleton.svelte +149 -149
- package/dist/components/Spinner.svelte +118 -118
- 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 -272
- package/dist/components/TextField.svelte +396 -256
- package/dist/components/TextField.svelte.d.ts +16 -1
- 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/fonts.css +71 -71
- package/dist/tokens.css +283 -283
- package/package.json +81 -76
|
@@ -1,157 +1,157 @@
|
|
|
1
|
-
<script lang="ts" module>
|
|
2
|
-
import { Progress as BitsProgress } from 'bits-ui';
|
|
3
|
-
|
|
4
|
-
export type ProgressProps = Omit<BitsProgress.RootProps, 'value' | 'child' | 'children'> & {
|
|
5
|
-
/**
|
|
6
|
-
* How far the work has got, from `min` to `max`. Pass the real figure
|
|
7
|
-
* each time it changes: the bar never moves on its own. Work whose
|
|
8
|
-
* progress is unknown shows a `Spinner` instead.
|
|
9
|
-
*/
|
|
10
|
-
value: number;
|
|
11
|
-
/** The value at which the work is done. Default 100. */
|
|
12
|
-
max?: number;
|
|
13
|
-
/** The value at which the work starts. Default 0. */
|
|
14
|
-
min?: number;
|
|
15
|
-
/**
|
|
16
|
-
* How many segments the bar has (default 20, at least 2). A segment
|
|
17
|
-
* lights once the value has passed its whole share, so the bar never
|
|
18
|
-
* shows more than has been done.
|
|
19
|
-
*/
|
|
20
|
-
segments?: number;
|
|
21
|
-
/**
|
|
22
|
-
* A line above the bar saying what is in progress, as written (never
|
|
23
|
-
* caps: it may hold a file or project name). It names the progress
|
|
24
|
-
* bar; without it, pass `aria-label` or `aria-labelledby`.
|
|
25
|
-
*/
|
|
26
|
-
label?: string;
|
|
27
|
-
/**
|
|
28
|
-
* The value in words, such as `3 of 12 files`. Shown at the end of the
|
|
29
|
-
* label line and read as `aria-valuetext`. Without it both give the
|
|
30
|
-
* percentage done, rounded down.
|
|
31
|
-
*/
|
|
32
|
-
valueText?: string;
|
|
33
|
-
};
|
|
34
|
-
</script>
|
|
35
|
-
|
|
36
|
-
<script lang="ts">
|
|
37
|
-
let {
|
|
38
|
-
value,
|
|
39
|
-
max = 100,
|
|
40
|
-
min = 0,
|
|
41
|
-
segments = 20,
|
|
42
|
-
label,
|
|
43
|
-
valueText,
|
|
44
|
-
id,
|
|
45
|
-
class: className,
|
|
46
|
-
ref = $bindable(null),
|
|
47
|
-
...rest
|
|
48
|
-
}: ProgressProps = $props();
|
|
49
|
-
|
|
50
|
-
const uid = $props.id();
|
|
51
|
-
const labelId = `${uid}-label`;
|
|
52
|
-
|
|
53
|
-
// The value inside its range, so the bar and aria-valuenow agree. An
|
|
54
|
-
// empty range counts as done.
|
|
55
|
-
const current = $derived(Math.min(max, Math.max(min, value)));
|
|
56
|
-
const span = $derived(max - min);
|
|
57
|
-
const count = $derived(Math.max(2, Math.floor(segments)));
|
|
58
|
-
// Round down: a segment lights only when its whole share is done.
|
|
59
|
-
// Multiply before dividing and clear float noise before rounding down,
|
|
60
|
-
// so 58 of 100 and 0.58 of 1 are both 58% and not 57.99…
|
|
61
|
-
const share = (n: number) => Math.floor(Number((((current - min) * n) / span).toPrecision(12)));
|
|
62
|
-
const lit = $derived(current >= max || span <= 0 ? count : share(count));
|
|
63
|
-
const percent = $derived(span > 0 ? share(100) : 100);
|
|
64
|
-
const shown = $derived(valueText ?? `${percent}%`);
|
|
65
|
-
</script>
|
|
66
|
-
|
|
67
|
-
<!--
|
|
68
|
-
Bits UI Progress, rendered through its `child` snippet so the element is
|
|
69
|
-
this component's markup and its styles stay scoped. The root is the
|
|
70
|
-
progressbar (`role`, `aria-valuemin`, `aria-valuemax`, `aria-valuenow`,
|
|
71
|
-
`data-state` loading | loaded); `id`, extra attributes and `class` go to
|
|
72
|
-
it. Its children are presentational to assistive technology, so the label
|
|
73
|
-
line names it through `aria-labelledby`, and the value as shown (the
|
|
74
|
-
`valueText` or the floored percentage) reaches it as `aria-valuetext`.
|
|
75
|
-
A segment that lights or goes out fades its colour over --dur-segment.
|
|
76
|
-
-->
|
|
77
|
-
<BitsProgress.Root
|
|
78
|
-
bind:ref
|
|
79
|
-
value={current}
|
|
80
|
-
{max}
|
|
81
|
-
{min}
|
|
82
|
-
aria-labelledby={label ? labelId : undefined}
|
|
83
|
-
aria-valuetext={shown}
|
|
84
|
-
{...rest}
|
|
85
|
-
>
|
|
86
|
-
{#snippet child({ props })}
|
|
87
|
-
<div {...props} {id} class={['hp-progress', className]} data-lit={lit} data-segments={count}>
|
|
88
|
-
{#if label}
|
|
89
|
-
<div class="hp-progress-line">
|
|
90
|
-
<span id={labelId} class="hp-progress-label">{label}</span>
|
|
91
|
-
<span class="hp-progress-value">{shown}</span>
|
|
92
|
-
</div>
|
|
93
|
-
{/if}
|
|
94
|
-
<div class="hp-progress-bar" style:--segments={count}>
|
|
95
|
-
{#each { length: count }, i}
|
|
96
|
-
<span class="hp-progress-segment" data-lit={i < lit || undefined}></span>
|
|
97
|
-
{/each}
|
|
98
|
-
</div>
|
|
99
|
-
</div>
|
|
100
|
-
{/snippet}
|
|
101
|
-
</BitsProgress.Root>
|
|
102
|
-
|
|
103
|
-
<style>
|
|
104
|
-
/* The bar fills the width it is given; the app sets a narrower one. */
|
|
105
|
-
.hp-progress {
|
|
106
|
-
display: grid;
|
|
107
|
-
gap: var(--space-2);
|
|
108
|
-
min-width: 0;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/* 16px on touch, the dense 14px on fine pointers. The value keeps the
|
|
112
|
-
end of the line; a long label wraps rather than widen the page. */
|
|
113
|
-
.hp-progress-line {
|
|
114
|
-
display: flex;
|
|
115
|
-
align-items: baseline;
|
|
116
|
-
justify-content: space-between;
|
|
117
|
-
gap: var(--space-4);
|
|
118
|
-
font-size: var(--type-body);
|
|
119
|
-
line-height: 24px;
|
|
120
|
-
}
|
|
121
|
-
@media (pointer: fine) {
|
|
122
|
-
.hp-progress-line {
|
|
123
|
-
font-size: var(--type-dense);
|
|
124
|
-
line-height: 20px;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
.hp-progress-label {
|
|
128
|
-
min-width: 0;
|
|
129
|
-
overflow-wrap: anywhere;
|
|
130
|
-
}
|
|
131
|
-
.hp-progress-value {
|
|
132
|
-
flex: none;
|
|
133
|
-
color: var(--muted);
|
|
134
|
-
font-variant-numeric: tabular-nums;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/* Separate segments (BRIEF, visual rule 7; da3-38): titanium once done,
|
|
138
|
-
the 3:1 control boundary while still to do, so the unlit share reads as
|
|
139
|
-
part of the bar. Square, 4px apart, one row. */
|
|
140
|
-
.hp-progress-bar {
|
|
141
|
-
display: grid;
|
|
142
|
-
grid-template-columns: repeat(var(--segments), minmax(0, 1fr));
|
|
143
|
-
gap: var(--space-1);
|
|
144
|
-
height: 12px;
|
|
145
|
-
}
|
|
146
|
-
/* A segment that lights or goes out fades its colour over --dur-segment
|
|
147
|
-
(BRIEF, short motion). A CSS transition never runs on an element's
|
|
148
|
-
first style, so a bar shows its value at once when it renders. 0ms is
|
|
149
|
-
a snap. Colour only, so reduced motion keeps it. */
|
|
150
|
-
.hp-progress-segment {
|
|
151
|
-
background: var(--border-control);
|
|
152
|
-
transition: background-color var(--dur-segment) var(--settle);
|
|
153
|
-
}
|
|
154
|
-
.hp-progress-segment[data-lit] {
|
|
155
|
-
background: var(--accent);
|
|
156
|
-
}
|
|
157
|
-
</style>
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
import { Progress as BitsProgress } from 'bits-ui';
|
|
3
|
+
|
|
4
|
+
export type ProgressProps = Omit<BitsProgress.RootProps, 'value' | 'child' | 'children'> & {
|
|
5
|
+
/**
|
|
6
|
+
* How far the work has got, from `min` to `max`. Pass the real figure
|
|
7
|
+
* each time it changes: the bar never moves on its own. Work whose
|
|
8
|
+
* progress is unknown shows a `Spinner` instead.
|
|
9
|
+
*/
|
|
10
|
+
value: number;
|
|
11
|
+
/** The value at which the work is done. Default 100. */
|
|
12
|
+
max?: number;
|
|
13
|
+
/** The value at which the work starts. Default 0. */
|
|
14
|
+
min?: number;
|
|
15
|
+
/**
|
|
16
|
+
* How many segments the bar has (default 20, at least 2). A segment
|
|
17
|
+
* lights once the value has passed its whole share, so the bar never
|
|
18
|
+
* shows more than has been done.
|
|
19
|
+
*/
|
|
20
|
+
segments?: number;
|
|
21
|
+
/**
|
|
22
|
+
* A line above the bar saying what is in progress, as written (never
|
|
23
|
+
* caps: it may hold a file or project name). It names the progress
|
|
24
|
+
* bar; without it, pass `aria-label` or `aria-labelledby`.
|
|
25
|
+
*/
|
|
26
|
+
label?: string;
|
|
27
|
+
/**
|
|
28
|
+
* The value in words, such as `3 of 12 files`. Shown at the end of the
|
|
29
|
+
* label line and read as `aria-valuetext`. Without it both give the
|
|
30
|
+
* percentage done, rounded down.
|
|
31
|
+
*/
|
|
32
|
+
valueText?: string;
|
|
33
|
+
};
|
|
34
|
+
</script>
|
|
35
|
+
|
|
36
|
+
<script lang="ts">
|
|
37
|
+
let {
|
|
38
|
+
value,
|
|
39
|
+
max = 100,
|
|
40
|
+
min = 0,
|
|
41
|
+
segments = 20,
|
|
42
|
+
label,
|
|
43
|
+
valueText,
|
|
44
|
+
id,
|
|
45
|
+
class: className,
|
|
46
|
+
ref = $bindable(null),
|
|
47
|
+
...rest
|
|
48
|
+
}: ProgressProps = $props();
|
|
49
|
+
|
|
50
|
+
const uid = $props.id();
|
|
51
|
+
const labelId = `${uid}-label`;
|
|
52
|
+
|
|
53
|
+
// The value inside its range, so the bar and aria-valuenow agree. An
|
|
54
|
+
// empty range counts as done.
|
|
55
|
+
const current = $derived(Math.min(max, Math.max(min, value)));
|
|
56
|
+
const span = $derived(max - min);
|
|
57
|
+
const count = $derived(Math.max(2, Math.floor(segments)));
|
|
58
|
+
// Round down: a segment lights only when its whole share is done.
|
|
59
|
+
// Multiply before dividing and clear float noise before rounding down,
|
|
60
|
+
// so 58 of 100 and 0.58 of 1 are both 58% and not 57.99…
|
|
61
|
+
const share = (n: number) => Math.floor(Number((((current - min) * n) / span).toPrecision(12)));
|
|
62
|
+
const lit = $derived(current >= max || span <= 0 ? count : share(count));
|
|
63
|
+
const percent = $derived(span > 0 ? share(100) : 100);
|
|
64
|
+
const shown = $derived(valueText ?? `${percent}%`);
|
|
65
|
+
</script>
|
|
66
|
+
|
|
67
|
+
<!--
|
|
68
|
+
Bits UI Progress, rendered through its `child` snippet so the element is
|
|
69
|
+
this component's markup and its styles stay scoped. The root is the
|
|
70
|
+
progressbar (`role`, `aria-valuemin`, `aria-valuemax`, `aria-valuenow`,
|
|
71
|
+
`data-state` loading | loaded); `id`, extra attributes and `class` go to
|
|
72
|
+
it. Its children are presentational to assistive technology, so the label
|
|
73
|
+
line names it through `aria-labelledby`, and the value as shown (the
|
|
74
|
+
`valueText` or the floored percentage) reaches it as `aria-valuetext`.
|
|
75
|
+
A segment that lights or goes out fades its colour over --dur-segment.
|
|
76
|
+
-->
|
|
77
|
+
<BitsProgress.Root
|
|
78
|
+
bind:ref
|
|
79
|
+
value={current}
|
|
80
|
+
{max}
|
|
81
|
+
{min}
|
|
82
|
+
aria-labelledby={label ? labelId : undefined}
|
|
83
|
+
aria-valuetext={shown}
|
|
84
|
+
{...rest}
|
|
85
|
+
>
|
|
86
|
+
{#snippet child({ props })}
|
|
87
|
+
<div {...props} {id} class={['hp-progress', className]} data-lit={lit} data-segments={count}>
|
|
88
|
+
{#if label}
|
|
89
|
+
<div class="hp-progress-line">
|
|
90
|
+
<span id={labelId} class="hp-progress-label">{label}</span>
|
|
91
|
+
<span class="hp-progress-value">{shown}</span>
|
|
92
|
+
</div>
|
|
93
|
+
{/if}
|
|
94
|
+
<div class="hp-progress-bar" style:--segments={count}>
|
|
95
|
+
{#each { length: count }, i}
|
|
96
|
+
<span class="hp-progress-segment" data-lit={i < lit || undefined}></span>
|
|
97
|
+
{/each}
|
|
98
|
+
</div>
|
|
99
|
+
</div>
|
|
100
|
+
{/snippet}
|
|
101
|
+
</BitsProgress.Root>
|
|
102
|
+
|
|
103
|
+
<style>
|
|
104
|
+
/* The bar fills the width it is given; the app sets a narrower one. */
|
|
105
|
+
.hp-progress {
|
|
106
|
+
display: grid;
|
|
107
|
+
gap: var(--space-2);
|
|
108
|
+
min-width: 0;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/* 16px on touch, the dense 14px on fine pointers. The value keeps the
|
|
112
|
+
end of the line; a long label wraps rather than widen the page. */
|
|
113
|
+
.hp-progress-line {
|
|
114
|
+
display: flex;
|
|
115
|
+
align-items: baseline;
|
|
116
|
+
justify-content: space-between;
|
|
117
|
+
gap: var(--space-4);
|
|
118
|
+
font-size: var(--type-body);
|
|
119
|
+
line-height: 24px;
|
|
120
|
+
}
|
|
121
|
+
@media (pointer: fine) {
|
|
122
|
+
.hp-progress-line {
|
|
123
|
+
font-size: var(--type-dense);
|
|
124
|
+
line-height: 20px;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
.hp-progress-label {
|
|
128
|
+
min-width: 0;
|
|
129
|
+
overflow-wrap: anywhere;
|
|
130
|
+
}
|
|
131
|
+
.hp-progress-value {
|
|
132
|
+
flex: none;
|
|
133
|
+
color: var(--muted);
|
|
134
|
+
font-variant-numeric: tabular-nums;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/* Separate segments (BRIEF, visual rule 7; da3-38): titanium once done,
|
|
138
|
+
the 3:1 control boundary while still to do, so the unlit share reads as
|
|
139
|
+
part of the bar. Square, 4px apart, one row. */
|
|
140
|
+
.hp-progress-bar {
|
|
141
|
+
display: grid;
|
|
142
|
+
grid-template-columns: repeat(var(--segments), minmax(0, 1fr));
|
|
143
|
+
gap: var(--space-1);
|
|
144
|
+
height: 12px;
|
|
145
|
+
}
|
|
146
|
+
/* A segment that lights or goes out fades its colour over --dur-segment
|
|
147
|
+
(BRIEF, short motion). A CSS transition never runs on an element's
|
|
148
|
+
first style, so a bar shows its value at once when it renders. 0ms is
|
|
149
|
+
a snap. Colour only, so reduced motion keeps it. */
|
|
150
|
+
.hp-progress-segment {
|
|
151
|
+
background: var(--border-control);
|
|
152
|
+
transition: background-color var(--dur-segment) var(--settle);
|
|
153
|
+
}
|
|
154
|
+
.hp-progress-segment[data-lit] {
|
|
155
|
+
background: var(--accent);
|
|
156
|
+
}
|
|
157
|
+
</style>
|