@mystravil/hardpoint 0.2.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 -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 +174 -174
- 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 +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 -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 +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/fonts.css +71 -71
- package/dist/tokens.css +283 -283
- package/package.json +81 -76
|
@@ -1,174 +1,174 @@
|
|
|
1
|
-
<script lang="ts" module>
|
|
2
|
-
import { Button as BitsButton } from 'bits-ui';
|
|
3
|
-
|
|
4
|
-
export type ButtonVariant = 'primary' | 'secondary' | 'tertiary';
|
|
5
|
-
|
|
6
|
-
export type ButtonProps = BitsButton.RootProps & {
|
|
7
|
-
/**
|
|
8
|
-
* `primary`: solid titanium block, for the view's one group of solid
|
|
9
|
-
* blocks. `secondary` (default): outlined. `tertiary`: caps label only.
|
|
10
|
-
*/
|
|
11
|
-
variant?: ButtonVariant;
|
|
12
|
-
/** Ends the label in a small ▸: the button opens another view. */
|
|
13
|
-
opens?: boolean;
|
|
14
|
-
/**
|
|
15
|
-
* A square, icon-only button (height and width are `--control-height`).
|
|
16
|
-
* It has no visible label, so it needs an accessible name: pass
|
|
17
|
-
* `aria-label`.
|
|
18
|
-
*/
|
|
19
|
-
icon?: boolean;
|
|
20
|
-
};
|
|
21
|
-
</script>
|
|
22
|
-
|
|
23
|
-
<script lang="ts">
|
|
24
|
-
let {
|
|
25
|
-
variant = 'secondary',
|
|
26
|
-
opens = false,
|
|
27
|
-
icon = false,
|
|
28
|
-
class: className,
|
|
29
|
-
ref = $bindable(null),
|
|
30
|
-
children,
|
|
31
|
-
...rest
|
|
32
|
-
}: ButtonProps = $props();
|
|
33
|
-
</script>
|
|
34
|
-
|
|
35
|
-
<!--
|
|
36
|
-
An <a> when `href` is set, a <button> otherwise (Bits UI Button.Root). A
|
|
37
|
-
disabled link renders without href, with aria-disabled="true" and
|
|
38
|
-
tabindex -1; a disabled <button> is not focusable.
|
|
39
|
-
-->
|
|
40
|
-
<BitsButton.Root
|
|
41
|
-
bind:ref
|
|
42
|
-
class={['hp-button', 'hp-label', className]}
|
|
43
|
-
data-variant={variant}
|
|
44
|
-
data-opens={opens || undefined}
|
|
45
|
-
data-icon={icon || undefined}
|
|
46
|
-
{...rest}
|
|
47
|
-
>
|
|
48
|
-
{@render children?.()}
|
|
49
|
-
</BitsButton.Root>
|
|
50
|
-
|
|
51
|
-
<style>
|
|
52
|
-
/* Bits UI renders the element, so the root class reaches it from the
|
|
53
|
-
outside: the rules are :global, keyed on .hp-button and its data-*. */
|
|
54
|
-
:global(.hp-button) {
|
|
55
|
-
display: inline-flex;
|
|
56
|
-
align-items: center;
|
|
57
|
-
justify-content: space-between;
|
|
58
|
-
gap: var(--space-4);
|
|
59
|
-
box-sizing: border-box;
|
|
60
|
-
height: var(--control-height);
|
|
61
|
-
/* The visible box is the hit area: 36px fine, 44px coarse, and never
|
|
62
|
-
narrower than --hit-target for a short label. */
|
|
63
|
-
min-width: var(--hit-target);
|
|
64
|
-
padding: 0 var(--space-3);
|
|
65
|
-
border: 0;
|
|
66
|
-
background: transparent;
|
|
67
|
-
color: var(--text);
|
|
68
|
-
font-family: var(--sans);
|
|
69
|
-
text-decoration: none;
|
|
70
|
-
white-space: nowrap;
|
|
71
|
-
cursor: pointer;
|
|
72
|
-
-webkit-tap-highlight-color: transparent;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/* ---- Variants ---------------------------------------------------- */
|
|
76
|
-
|
|
77
|
-
/* Solid titanium block with a black label. */
|
|
78
|
-
:global(.hp-button[data-variant='primary']) {
|
|
79
|
-
background: var(--accent);
|
|
80
|
-
color: var(--canvas);
|
|
81
|
-
}
|
|
82
|
-
/* Outlined: a 3:1 boundary, titanium label, black fill. */
|
|
83
|
-
:global(.hp-button[data-variant='secondary']) {
|
|
84
|
-
border: 1px solid var(--border-control);
|
|
85
|
-
background: var(--canvas);
|
|
86
|
-
}
|
|
87
|
-
/* The label alone. */
|
|
88
|
-
:global(.hp-button[data-variant='tertiary']) {
|
|
89
|
-
background: transparent;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/* ---- Opens another view: a small ▸ drawn in CSS ------------------ */
|
|
93
|
-
|
|
94
|
-
:global(.hp-button[data-opens]::after) {
|
|
95
|
-
content: '';
|
|
96
|
-
flex: none;
|
|
97
|
-
width: 6px;
|
|
98
|
-
height: 8px;
|
|
99
|
-
background: currentColor;
|
|
100
|
-
clip-path: polygon(0 0, 100% 50%, 0 100%);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/* ---- Icon only: a square ----------------------------------------- */
|
|
104
|
-
|
|
105
|
-
:global(.hp-button[data-icon]) {
|
|
106
|
-
justify-content: center;
|
|
107
|
-
width: var(--control-height);
|
|
108
|
-
padding: 0;
|
|
109
|
-
}
|
|
110
|
-
/* The icon is the consumer's inline <svg>; it draws in currentColor. */
|
|
111
|
-
:global(.hp-button svg) {
|
|
112
|
-
flex: none;
|
|
113
|
-
}
|
|
114
|
-
:global(.hp-button[data-icon] svg) {
|
|
115
|
-
width: var(--space-4);
|
|
116
|
-
height: var(--space-4);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/* ---- Hover: fine pointers only ----------------------------------- */
|
|
120
|
-
|
|
121
|
-
@media (hover: hover) and (pointer: fine) {
|
|
122
|
-
:global(.hp-button) {
|
|
123
|
-
transition:
|
|
124
|
-
background-color var(--dur-hover) var(--settle),
|
|
125
|
-
color var(--dur-hover) var(--settle);
|
|
126
|
-
}
|
|
127
|
-
:global(.hp-button:active:not(:disabled):not([aria-disabled='true'])) {
|
|
128
|
-
transition-duration: var(--dur-press);
|
|
129
|
-
}
|
|
130
|
-
:global(.hp-button[data-variant='primary']:hover:not(:disabled):not([aria-disabled='true'])) {
|
|
131
|
-
background: var(--muted);
|
|
132
|
-
}
|
|
133
|
-
:global(.hp-button[data-variant='secondary']:hover:not(:disabled):not([aria-disabled='true'])),
|
|
134
|
-
:global(.hp-button[data-variant='tertiary']:hover:not(:disabled):not([aria-disabled='true'])) {
|
|
135
|
-
background: var(--surface-hover);
|
|
136
|
-
}
|
|
137
|
-
/* The tint alone barely shows (1.03:1), so the label also underlines. */
|
|
138
|
-
:global(.hp-button[data-variant='tertiary']:hover:not(:disabled):not([aria-disabled='true'])) {
|
|
139
|
-
text-decoration: underline;
|
|
140
|
-
text-decoration-thickness: 1px;
|
|
141
|
-
text-underline-offset: 0.3em;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/* ---- Press: after hover, so it wins while the pointer is down ----- */
|
|
146
|
-
|
|
147
|
-
:global(.hp-button[data-variant='primary']:active:not(:disabled):not([aria-disabled='true'])) {
|
|
148
|
-
background: var(--muted);
|
|
149
|
-
}
|
|
150
|
-
/* One step past the hover tint, so a press reads on a phone too. */
|
|
151
|
-
:global(.hp-button[data-variant='secondary']:active:not(:disabled):not([aria-disabled='true'])),
|
|
152
|
-
:global(.hp-button[data-variant='tertiary']:active:not(:disabled):not([aria-disabled='true'])) {
|
|
153
|
-
background: var(--surface-raised);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/* ---- Disabled: muted ink. A <button> is not focusable; a link has
|
|
157
|
-
no href. -------------------------------------------------------- */
|
|
158
|
-
|
|
159
|
-
:global(.hp-button:disabled),
|
|
160
|
-
:global(.hp-button[aria-disabled='true']) {
|
|
161
|
-
color: var(--muted);
|
|
162
|
-
cursor: not-allowed;
|
|
163
|
-
}
|
|
164
|
-
:global(.hp-button[data-variant='primary']:disabled),
|
|
165
|
-
:global(.hp-button[data-variant='primary'][aria-disabled='true']) {
|
|
166
|
-
/* --muted is 4.9:1 on the band. */
|
|
167
|
-
background: var(--surface-band);
|
|
168
|
-
}
|
|
169
|
-
:global(.hp-button[data-variant='secondary']:disabled),
|
|
170
|
-
:global(.hp-button[data-variant='secondary'][aria-disabled='true']) {
|
|
171
|
-
/* An off control needs no 3:1 boundary. */
|
|
172
|
-
border-color: var(--border);
|
|
173
|
-
}
|
|
174
|
-
</style>
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
import { Button as BitsButton } from 'bits-ui';
|
|
3
|
+
|
|
4
|
+
export type ButtonVariant = 'primary' | 'secondary' | 'tertiary';
|
|
5
|
+
|
|
6
|
+
export type ButtonProps = BitsButton.RootProps & {
|
|
7
|
+
/**
|
|
8
|
+
* `primary`: solid titanium block, for the view's one group of solid
|
|
9
|
+
* blocks. `secondary` (default): outlined. `tertiary`: caps label only.
|
|
10
|
+
*/
|
|
11
|
+
variant?: ButtonVariant;
|
|
12
|
+
/** Ends the label in a small ▸: the button opens another view. */
|
|
13
|
+
opens?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* A square, icon-only button (height and width are `--control-height`).
|
|
16
|
+
* It has no visible label, so it needs an accessible name: pass
|
|
17
|
+
* `aria-label`.
|
|
18
|
+
*/
|
|
19
|
+
icon?: boolean;
|
|
20
|
+
};
|
|
21
|
+
</script>
|
|
22
|
+
|
|
23
|
+
<script lang="ts">
|
|
24
|
+
let {
|
|
25
|
+
variant = 'secondary',
|
|
26
|
+
opens = false,
|
|
27
|
+
icon = false,
|
|
28
|
+
class: className,
|
|
29
|
+
ref = $bindable(null),
|
|
30
|
+
children,
|
|
31
|
+
...rest
|
|
32
|
+
}: ButtonProps = $props();
|
|
33
|
+
</script>
|
|
34
|
+
|
|
35
|
+
<!--
|
|
36
|
+
An <a> when `href` is set, a <button> otherwise (Bits UI Button.Root). A
|
|
37
|
+
disabled link renders without href, with aria-disabled="true" and
|
|
38
|
+
tabindex -1; a disabled <button> is not focusable.
|
|
39
|
+
-->
|
|
40
|
+
<BitsButton.Root
|
|
41
|
+
bind:ref
|
|
42
|
+
class={['hp-button', 'hp-label', className]}
|
|
43
|
+
data-variant={variant}
|
|
44
|
+
data-opens={opens || undefined}
|
|
45
|
+
data-icon={icon || undefined}
|
|
46
|
+
{...rest}
|
|
47
|
+
>
|
|
48
|
+
{@render children?.()}
|
|
49
|
+
</BitsButton.Root>
|
|
50
|
+
|
|
51
|
+
<style>
|
|
52
|
+
/* Bits UI renders the element, so the root class reaches it from the
|
|
53
|
+
outside: the rules are :global, keyed on .hp-button and its data-*. */
|
|
54
|
+
:global(.hp-button) {
|
|
55
|
+
display: inline-flex;
|
|
56
|
+
align-items: center;
|
|
57
|
+
justify-content: space-between;
|
|
58
|
+
gap: var(--space-4);
|
|
59
|
+
box-sizing: border-box;
|
|
60
|
+
height: var(--control-height);
|
|
61
|
+
/* The visible box is the hit area: 36px fine, 44px coarse, and never
|
|
62
|
+
narrower than --hit-target for a short label. */
|
|
63
|
+
min-width: var(--hit-target);
|
|
64
|
+
padding: 0 var(--space-3);
|
|
65
|
+
border: 0;
|
|
66
|
+
background: transparent;
|
|
67
|
+
color: var(--text);
|
|
68
|
+
font-family: var(--sans);
|
|
69
|
+
text-decoration: none;
|
|
70
|
+
white-space: nowrap;
|
|
71
|
+
cursor: pointer;
|
|
72
|
+
-webkit-tap-highlight-color: transparent;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/* ---- Variants ---------------------------------------------------- */
|
|
76
|
+
|
|
77
|
+
/* Solid titanium block with a black label. */
|
|
78
|
+
:global(.hp-button[data-variant='primary']) {
|
|
79
|
+
background: var(--accent);
|
|
80
|
+
color: var(--canvas);
|
|
81
|
+
}
|
|
82
|
+
/* Outlined: a 3:1 boundary, titanium label, black fill. */
|
|
83
|
+
:global(.hp-button[data-variant='secondary']) {
|
|
84
|
+
border: 1px solid var(--border-control);
|
|
85
|
+
background: var(--canvas);
|
|
86
|
+
}
|
|
87
|
+
/* The label alone. */
|
|
88
|
+
:global(.hp-button[data-variant='tertiary']) {
|
|
89
|
+
background: transparent;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/* ---- Opens another view: a small ▸ drawn in CSS ------------------ */
|
|
93
|
+
|
|
94
|
+
:global(.hp-button[data-opens]::after) {
|
|
95
|
+
content: '';
|
|
96
|
+
flex: none;
|
|
97
|
+
width: 6px;
|
|
98
|
+
height: 8px;
|
|
99
|
+
background: currentColor;
|
|
100
|
+
clip-path: polygon(0 0, 100% 50%, 0 100%);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/* ---- Icon only: a square ----------------------------------------- */
|
|
104
|
+
|
|
105
|
+
:global(.hp-button[data-icon]) {
|
|
106
|
+
justify-content: center;
|
|
107
|
+
width: var(--control-height);
|
|
108
|
+
padding: 0;
|
|
109
|
+
}
|
|
110
|
+
/* The icon is the consumer's inline <svg>; it draws in currentColor. */
|
|
111
|
+
:global(.hp-button svg) {
|
|
112
|
+
flex: none;
|
|
113
|
+
}
|
|
114
|
+
:global(.hp-button[data-icon] svg) {
|
|
115
|
+
width: var(--space-4);
|
|
116
|
+
height: var(--space-4);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/* ---- Hover: fine pointers only ----------------------------------- */
|
|
120
|
+
|
|
121
|
+
@media (hover: hover) and (pointer: fine) {
|
|
122
|
+
:global(.hp-button) {
|
|
123
|
+
transition:
|
|
124
|
+
background-color var(--dur-hover) var(--settle),
|
|
125
|
+
color var(--dur-hover) var(--settle);
|
|
126
|
+
}
|
|
127
|
+
:global(.hp-button:active:not(:disabled):not([aria-disabled='true'])) {
|
|
128
|
+
transition-duration: var(--dur-press);
|
|
129
|
+
}
|
|
130
|
+
:global(.hp-button[data-variant='primary']:hover:not(:disabled):not([aria-disabled='true'])) {
|
|
131
|
+
background: var(--muted);
|
|
132
|
+
}
|
|
133
|
+
:global(.hp-button[data-variant='secondary']:hover:not(:disabled):not([aria-disabled='true'])),
|
|
134
|
+
:global(.hp-button[data-variant='tertiary']:hover:not(:disabled):not([aria-disabled='true'])) {
|
|
135
|
+
background: var(--surface-hover);
|
|
136
|
+
}
|
|
137
|
+
/* The tint alone barely shows (1.03:1), so the label also underlines. */
|
|
138
|
+
:global(.hp-button[data-variant='tertiary']:hover:not(:disabled):not([aria-disabled='true'])) {
|
|
139
|
+
text-decoration: underline;
|
|
140
|
+
text-decoration-thickness: 1px;
|
|
141
|
+
text-underline-offset: 0.3em;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/* ---- Press: after hover, so it wins while the pointer is down ----- */
|
|
146
|
+
|
|
147
|
+
:global(.hp-button[data-variant='primary']:active:not(:disabled):not([aria-disabled='true'])) {
|
|
148
|
+
background: var(--muted);
|
|
149
|
+
}
|
|
150
|
+
/* One step past the hover tint, so a press reads on a phone too. */
|
|
151
|
+
:global(.hp-button[data-variant='secondary']:active:not(:disabled):not([aria-disabled='true'])),
|
|
152
|
+
:global(.hp-button[data-variant='tertiary']:active:not(:disabled):not([aria-disabled='true'])) {
|
|
153
|
+
background: var(--surface-raised);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/* ---- Disabled: muted ink. A <button> is not focusable; a link has
|
|
157
|
+
no href. -------------------------------------------------------- */
|
|
158
|
+
|
|
159
|
+
:global(.hp-button:disabled),
|
|
160
|
+
:global(.hp-button[aria-disabled='true']) {
|
|
161
|
+
color: var(--muted);
|
|
162
|
+
cursor: not-allowed;
|
|
163
|
+
}
|
|
164
|
+
:global(.hp-button[data-variant='primary']:disabled),
|
|
165
|
+
:global(.hp-button[data-variant='primary'][aria-disabled='true']) {
|
|
166
|
+
/* --muted is 4.9:1 on the band. */
|
|
167
|
+
background: var(--surface-band);
|
|
168
|
+
}
|
|
169
|
+
:global(.hp-button[data-variant='secondary']:disabled),
|
|
170
|
+
:global(.hp-button[data-variant='secondary'][aria-disabled='true']) {
|
|
171
|
+
/* An off control needs no 3:1 boundary. */
|
|
172
|
+
border-color: var(--border);
|
|
173
|
+
}
|
|
174
|
+
</style>
|