@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,222 +1,222 @@
1
- <script lang="ts" module>
2
- import type { Snippet } from 'svelte';
3
- import { Popover as BitsPopover } from 'bits-ui';
4
-
5
- export type PopoverTriggerSnippetProps = {
6
- /** Spread onto the button that opens the popover. */
7
- props: Record<string, unknown>;
8
- };
9
-
10
- export type PopoverActionsSnippetProps = {
11
- /** Closes the popover; focus returns to the trigger. */
12
- close: () => void;
13
- };
14
-
15
- /**
16
- * Attributes and handlers not listed here go to the panel (Bits UI
17
- * `Popover.Content`), among them `side` (default `bottom`), `align`
18
- * (default `start`), `sideOffset`, `onOpenAutoFocus`, `onCloseAutoFocus`,
19
- * `onEscapeKeydown` and `onInteractOutside`. The placement props apply
20
- * from 600px only; below it the panel is a bottom sheet.
21
- */
22
- export type PopoverProps = Omit<
23
- BitsPopover.ContentProps,
24
- 'child' | 'children' | 'forceMount' | 'ref' | 'title'
25
- > & {
26
- open?: boolean;
27
- /** The caps title, and the panel's accessible name. */
28
- title: string;
29
- /** The button the panel is anchored to: spread `props` onto it. */
30
- trigger: Snippet<[PopoverTriggerSnippetProps]>;
31
- /** The body, under the title. */
32
- children: Snippet;
33
- /** The action row at the bottom, primary action last. */
34
- actions?: Snippet<[PopoverActionsSnippetProps]>;
35
- /** The sheet's close button's accessible name (below 600px). */
36
- closeLabel?: string;
37
- /** The panel element. */
38
- ref?: HTMLElement | null;
39
- };
40
- </script>
41
-
42
- <script lang="ts">
43
- import { MediaQuery } from 'svelte/reactivity';
44
- import { pop } from '../motion/index.js';
45
- import Sheet from './internal/Sheet.svelte';
46
-
47
- const uid = $props.id();
48
-
49
- let {
50
- open = $bindable(false),
51
- title,
52
- trigger,
53
- children,
54
- actions,
55
- closeLabel = 'Close',
56
- ref = $bindable(null),
57
- class: className,
58
- ...rest
59
- }: PopoverProps = $props();
60
-
61
- const titleId = `${uid}-title`;
62
-
63
- // The form follows the width (BRIEF, Apps and phones: Overlays): a panel
64
- // anchored to the trigger from 600px, the shared bottom sheet below it.
65
- const wide = new MediaQuery('min-width: 600px', true);
66
- const form = $derived(wide.current ? 'popover' : 'sheet');
67
-
68
- function close() {
69
- open = false;
70
- }
71
- </script>
72
-
73
- <!--
74
- Bits UI gives the trigger aria-haspopup="dialog", aria-expanded and
75
- aria-controls; the panel takes role="dialog" and its title as its name.
76
- Focus moves into the panel on open (to the sheet's close button on
77
- compact) and returns to the trigger on close. Escape, a press outside,
78
- the trigger and, on compact, the close button and a swipe down close it.
79
- -->
80
- <BitsPopover.Root bind:open>
81
- <BitsPopover.Trigger>
82
- {#snippet child({ props })}
83
- {@render trigger({ props })}
84
- {/snippet}
85
- </BitsPopover.Trigger>
86
-
87
- <BitsPopover.Portal>
88
- {#if wide.current}
89
- <BitsPopover.Content
90
- forceMount
91
- bind:ref
92
- role="dialog"
93
- aria-labelledby={titleId}
94
- side="bottom"
95
- align="start"
96
- sideOffset={8}
97
- collisionPadding={8}
98
- {...rest}
99
- >
100
- {#snippet child({ wrapperProps, props, open: shown })}
101
- {#if shown}
102
- <div {...wrapperProps}>
103
- <div {...props} class={['hp-popover', className]} data-form="popover" transition:pop>
104
- <p id={titleId} class="hp-popover-title hp-label">{title}</p>
105
- {@render body()}
106
- {#if actions}
107
- {@render actionRow()}
108
- {/if}
109
- </div>
110
- </div>
111
- {/if}
112
- {/snippet}
113
- </BitsPopover.Content>
114
- {:else}
115
- <BitsPopover.ContentStatic forceMount preventScroll bind:ref role="dialog" aria-labelledby={titleId} {...rest}>
116
- {#snippet child({ props, open: shown })}
117
- <Sheet
118
- {...props}
119
- class={['hp-popover', className]}
120
- data-form="sheet"
121
- open={shown}
122
- layer="popover"
123
- {title}
124
- {titleId}
125
- {closeLabel}
126
- onclose={close}
127
- footer={actions ? actionRow : undefined}
128
- >
129
- {@render body()}
130
- </Sheet>
131
- {/snippet}
132
- </BitsPopover.ContentStatic>
133
- {/if}
134
- </BitsPopover.Portal>
135
- </BitsPopover.Root>
136
-
137
- {#snippet body()}
138
- <div class="hp-popover-body" data-form={form} data-end={actions ? undefined : ''}>
139
- {@render children()}
140
- </div>
141
- {/snippet}
142
-
143
- {#snippet actionRow()}
144
- <div class="hp-popover-actions" data-form={form}>
145
- {@render actions?.({ close })}
146
- </div>
147
- {/snippet}
148
-
149
- <style>
150
- /* ---- Popover (600px and up): a black panel under its trigger --------- */
151
-
152
- /* On the popover layer (tokens.css), over the shell and over an open
153
- dialog. Bits UI copies the z-index to the positioned wrapper. As wide
154
- as its content up to --popover-width, 360px unless set (an app sets it
155
- with a class on the Popover and a rule in its stylesheet; the default
156
- is the var() fallback, so any rule wins whatever its specificity; the
157
- sheet ignores it), and as tall as the space beside the trigger; the
158
- body scrolls inside. */
159
- .hp-popover {
160
- position: relative;
161
- z-index: var(--layer-popover);
162
- display: flex;
163
- flex-direction: column;
164
- box-sizing: border-box;
165
- width: max-content;
166
- max-width: min(var(--popover-width, 360px), var(--bits-popover-content-available-width));
167
- max-height: var(--bits-popover-content-available-height);
168
- border: 1px solid var(--border-control);
169
- background: var(--canvas);
170
- color: var(--text);
171
- overscroll-behavior: contain;
172
- }
173
-
174
- /* A caps label names the panel, in the main ink, so the muted caps
175
- labels of fields inside it read as one level down. */
176
- .hp-popover-title {
177
- flex: none;
178
- margin: 0;
179
- padding: var(--space-3) var(--space-4) 0;
180
- }
181
-
182
- /* ---- Body and actions, in both forms -------------------------------- */
183
-
184
- /* The top padding keeps a first control's focus contour (4px out, 2px
185
- wide) inside the scrolling box. */
186
- .hp-popover-body {
187
- display: grid;
188
- align-content: start;
189
- gap: var(--space-4);
190
- min-width: 0;
191
- font-size: var(--type-body);
192
- line-height: 24px;
193
- }
194
- .hp-popover-body[data-form='popover'] {
195
- flex: 1 1 auto;
196
- min-height: 0;
197
- padding: var(--space-3) var(--space-4);
198
- overflow-y: auto;
199
- overscroll-behavior: contain;
200
- }
201
- /* The sheet's body scrolls itself. */
202
- .hp-popover-body[data-form='sheet'] {
203
- padding: var(--space-2) var(--gutter);
204
- }
205
- /* Without an action row the body ends the panel. */
206
- .hp-popover-body[data-end] {
207
- padding-bottom: var(--space-4);
208
- }
209
-
210
- /* Actions sit at the end, primary last, 8px apart. */
211
- .hp-popover-actions {
212
- flex: none;
213
- display: flex;
214
- flex-wrap: wrap;
215
- justify-content: flex-end;
216
- gap: var(--space-2);
217
- padding: var(--space-4) var(--gutter);
218
- }
219
- .hp-popover-actions[data-form='popover'] {
220
- padding: var(--space-1) var(--space-4) var(--space-4);
221
- }
222
- </style>
1
+ <script lang="ts" module>
2
+ import type { Snippet } from 'svelte';
3
+ import { Popover as BitsPopover } from 'bits-ui';
4
+
5
+ export type PopoverTriggerSnippetProps = {
6
+ /** Spread onto the button that opens the popover. */
7
+ props: Record<string, unknown>;
8
+ };
9
+
10
+ export type PopoverActionsSnippetProps = {
11
+ /** Closes the popover; focus returns to the trigger. */
12
+ close: () => void;
13
+ };
14
+
15
+ /**
16
+ * Attributes and handlers not listed here go to the panel (Bits UI
17
+ * `Popover.Content`), among them `side` (default `bottom`), `align`
18
+ * (default `start`), `sideOffset`, `onOpenAutoFocus`, `onCloseAutoFocus`,
19
+ * `onEscapeKeydown` and `onInteractOutside`. The placement props apply
20
+ * from 600px only; below it the panel is a bottom sheet.
21
+ */
22
+ export type PopoverProps = Omit<
23
+ BitsPopover.ContentProps,
24
+ 'child' | 'children' | 'forceMount' | 'ref' | 'title'
25
+ > & {
26
+ open?: boolean;
27
+ /** The caps title, and the panel's accessible name. */
28
+ title: string;
29
+ /** The button the panel is anchored to: spread `props` onto it. */
30
+ trigger: Snippet<[PopoverTriggerSnippetProps]>;
31
+ /** The body, under the title. */
32
+ children: Snippet;
33
+ /** The action row at the bottom, primary action last. */
34
+ actions?: Snippet<[PopoverActionsSnippetProps]>;
35
+ /** The sheet's close button's accessible name (below 600px). */
36
+ closeLabel?: string;
37
+ /** The panel element. */
38
+ ref?: HTMLElement | null;
39
+ };
40
+ </script>
41
+
42
+ <script lang="ts">
43
+ import { MediaQuery } from 'svelte/reactivity';
44
+ import { pop } from '../motion/index.js';
45
+ import Sheet from './internal/Sheet.svelte';
46
+
47
+ const uid = $props.id();
48
+
49
+ let {
50
+ open = $bindable(false),
51
+ title,
52
+ trigger,
53
+ children,
54
+ actions,
55
+ closeLabel = 'Close',
56
+ ref = $bindable(null),
57
+ class: className,
58
+ ...rest
59
+ }: PopoverProps = $props();
60
+
61
+ const titleId = `${uid}-title`;
62
+
63
+ // The form follows the width (BRIEF, Apps and phones: Overlays): a panel
64
+ // anchored to the trigger from 600px, the shared bottom sheet below it.
65
+ const wide = new MediaQuery('min-width: 600px', true);
66
+ const form = $derived(wide.current ? 'popover' : 'sheet');
67
+
68
+ function close() {
69
+ open = false;
70
+ }
71
+ </script>
72
+
73
+ <!--
74
+ Bits UI gives the trigger aria-haspopup="dialog", aria-expanded and
75
+ aria-controls; the panel takes role="dialog" and its title as its name.
76
+ Focus moves into the panel on open (to the sheet's close button on
77
+ compact) and returns to the trigger on close. Escape, a press outside,
78
+ the trigger and, on compact, the close button and a swipe down close it.
79
+ -->
80
+ <BitsPopover.Root bind:open>
81
+ <BitsPopover.Trigger>
82
+ {#snippet child({ props })}
83
+ {@render trigger({ props })}
84
+ {/snippet}
85
+ </BitsPopover.Trigger>
86
+
87
+ <BitsPopover.Portal>
88
+ {#if wide.current}
89
+ <BitsPopover.Content
90
+ forceMount
91
+ bind:ref
92
+ role="dialog"
93
+ aria-labelledby={titleId}
94
+ side="bottom"
95
+ align="start"
96
+ sideOffset={8}
97
+ collisionPadding={8}
98
+ {...rest}
99
+ >
100
+ {#snippet child({ wrapperProps, props, open: shown })}
101
+ {#if shown}
102
+ <div {...wrapperProps}>
103
+ <div {...props} class={['hp-popover', className]} data-form="popover" transition:pop>
104
+ <p id={titleId} class="hp-popover-title hp-label">{title}</p>
105
+ {@render body()}
106
+ {#if actions}
107
+ {@render actionRow()}
108
+ {/if}
109
+ </div>
110
+ </div>
111
+ {/if}
112
+ {/snippet}
113
+ </BitsPopover.Content>
114
+ {:else}
115
+ <BitsPopover.ContentStatic forceMount preventScroll bind:ref role="dialog" aria-labelledby={titleId} {...rest}>
116
+ {#snippet child({ props, open: shown })}
117
+ <Sheet
118
+ {...props}
119
+ class={['hp-popover', className]}
120
+ data-form="sheet"
121
+ open={shown}
122
+ layer="popover"
123
+ {title}
124
+ {titleId}
125
+ {closeLabel}
126
+ onclose={close}
127
+ footer={actions ? actionRow : undefined}
128
+ >
129
+ {@render body()}
130
+ </Sheet>
131
+ {/snippet}
132
+ </BitsPopover.ContentStatic>
133
+ {/if}
134
+ </BitsPopover.Portal>
135
+ </BitsPopover.Root>
136
+
137
+ {#snippet body()}
138
+ <div class="hp-popover-body" data-form={form} data-end={actions ? undefined : ''}>
139
+ {@render children()}
140
+ </div>
141
+ {/snippet}
142
+
143
+ {#snippet actionRow()}
144
+ <div class="hp-popover-actions" data-form={form}>
145
+ {@render actions?.({ close })}
146
+ </div>
147
+ {/snippet}
148
+
149
+ <style>
150
+ /* ---- Popover (600px and up): a black panel under its trigger --------- */
151
+
152
+ /* On the popover layer (tokens.css), over the shell and over an open
153
+ dialog. Bits UI copies the z-index to the positioned wrapper. As wide
154
+ as its content up to --popover-width, 360px unless set (an app sets it
155
+ with a class on the Popover and a rule in its stylesheet; the default
156
+ is the var() fallback, so any rule wins whatever its specificity; the
157
+ sheet ignores it), and as tall as the space beside the trigger; the
158
+ body scrolls inside. */
159
+ .hp-popover {
160
+ position: relative;
161
+ z-index: var(--layer-popover);
162
+ display: flex;
163
+ flex-direction: column;
164
+ box-sizing: border-box;
165
+ width: max-content;
166
+ max-width: min(var(--popover-width, 360px), var(--bits-popover-content-available-width));
167
+ max-height: var(--bits-popover-content-available-height);
168
+ border: 1px solid var(--border-control);
169
+ background: var(--canvas);
170
+ color: var(--text);
171
+ overscroll-behavior: contain;
172
+ }
173
+
174
+ /* A caps label names the panel, in the main ink, so the muted caps
175
+ labels of fields inside it read as one level down. */
176
+ .hp-popover-title {
177
+ flex: none;
178
+ margin: 0;
179
+ padding: var(--space-3) var(--space-4) 0;
180
+ }
181
+
182
+ /* ---- Body and actions, in both forms -------------------------------- */
183
+
184
+ /* The top padding keeps a first control's focus contour (4px out, 2px
185
+ wide) inside the scrolling box. */
186
+ .hp-popover-body {
187
+ display: grid;
188
+ align-content: start;
189
+ gap: var(--space-4);
190
+ min-width: 0;
191
+ font-size: var(--type-body);
192
+ line-height: 24px;
193
+ }
194
+ .hp-popover-body[data-form='popover'] {
195
+ flex: 1 1 auto;
196
+ min-height: 0;
197
+ padding: var(--space-3) var(--space-4);
198
+ overflow-y: auto;
199
+ overscroll-behavior: contain;
200
+ }
201
+ /* The sheet's body scrolls itself. */
202
+ .hp-popover-body[data-form='sheet'] {
203
+ padding: var(--space-2) var(--gutter);
204
+ }
205
+ /* Without an action row the body ends the panel. */
206
+ .hp-popover-body[data-end] {
207
+ padding-bottom: var(--space-4);
208
+ }
209
+
210
+ /* Actions sit at the end, primary last, 8px apart. */
211
+ .hp-popover-actions {
212
+ flex: none;
213
+ display: flex;
214
+ flex-wrap: wrap;
215
+ justify-content: flex-end;
216
+ gap: var(--space-2);
217
+ padding: var(--space-4) var(--gutter);
218
+ }
219
+ .hp-popover-actions[data-form='popover'] {
220
+ padding: var(--space-1) var(--space-4) var(--space-4);
221
+ }
222
+ </style>