@hyvnt/hyvui 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 (86) hide show
  1. package/README.md +264 -253
  2. package/dist/components/ambient/CornerBrackets.svelte +83 -87
  3. package/dist/components/ambient/DataStream.svelte +111 -94
  4. package/dist/components/ambient/GlyphMark.svelte +69 -69
  5. package/dist/components/ambient/GridOverlay.svelte +26 -28
  6. package/dist/components/ambient/ParallaxLayer.svelte +37 -41
  7. package/dist/components/ambient/ScanBand.svelte +95 -91
  8. package/dist/components/ambient/SignalRing.svelte +100 -100
  9. package/dist/components/ambient/ThreadLine.svelte +71 -78
  10. package/dist/components/ambient/Vignette.svelte +24 -26
  11. package/dist/components/depth/DepthLayer.svelte +22 -27
  12. package/dist/components/depth/DepthStage.svelte +63 -62
  13. package/dist/components/depth/FloatCard.svelte +113 -104
  14. package/dist/components/depth/HorizonGrid.svelte +216 -160
  15. package/dist/components/depth/Plinth.svelte +52 -57
  16. package/dist/components/display/Avatar.svelte +64 -69
  17. package/dist/components/display/Badge.svelte +59 -63
  18. package/dist/components/display/Blockquote.svelte +31 -34
  19. package/dist/components/display/CodeBlock.svelte +71 -76
  20. package/dist/components/display/MetricCard.svelte +77 -83
  21. package/dist/components/display/Table.svelte +99 -104
  22. package/dist/components/feedback/Alert.svelte +71 -76
  23. package/dist/components/feedback/EmptyState.svelte +68 -68
  24. package/dist/components/feedback/ErrorState.svelte +73 -73
  25. package/dist/components/feedback/Skeleton.svelte +52 -52
  26. package/dist/components/feedback/StatusDot.svelte +49 -54
  27. package/dist/components/feedback/StatusLine.svelte +122 -122
  28. package/dist/components/feedback/Toast.svelte +130 -136
  29. package/dist/components/inputs/Button.svelte +240 -237
  30. package/dist/components/inputs/Checkbox.svelte +104 -105
  31. package/dist/components/inputs/FileUpload.svelte +165 -163
  32. package/dist/components/inputs/Input.svelte +145 -147
  33. package/dist/components/inputs/Select.svelte +156 -150
  34. package/dist/components/inputs/Textarea.svelte +153 -154
  35. package/dist/components/inputs/Toggle.svelte +120 -120
  36. package/dist/components/layout/Card.svelte +70 -76
  37. package/dist/components/layout/Drawer.svelte +133 -109
  38. package/dist/components/layout/Grid.svelte +118 -43
  39. package/dist/components/layout/Grid.svelte.d.ts +8 -2
  40. package/dist/components/layout/Modal.svelte +176 -159
  41. package/dist/components/layout/Panel.svelte +49 -54
  42. package/dist/components/layout/Popover.svelte +178 -67
  43. package/dist/components/layout/Popover.svelte.d.ts +10 -1
  44. package/dist/components/layout/Stack.svelte +53 -53
  45. package/dist/components/navigation/Breadcrumb.svelte +70 -73
  46. package/dist/components/navigation/DropdownMenu.svelte +167 -124
  47. package/dist/components/navigation/DropdownMenu.svelte.d.ts +12 -2
  48. package/dist/components/navigation/SidebarNav.svelte +86 -90
  49. package/dist/components/navigation/Tabs.svelte +81 -86
  50. package/dist/components/navigation/Topbar.svelte +85 -85
  51. package/dist/components/patterns/ActionBar.svelte +71 -76
  52. package/dist/components/patterns/ConfirmDialog.svelte +63 -64
  53. package/dist/components/patterns/PageHeader.svelte +109 -114
  54. package/dist/components/patterns/SearchBar.svelte +54 -59
  55. package/dist/components/patterns/TerminalBoot.svelte +104 -104
  56. package/dist/components/primitives/Divider.svelte +26 -29
  57. package/dist/components/primitives/Icon.svelte +44 -49
  58. package/dist/components/primitives/Label.svelte +39 -44
  59. package/dist/components/primitives/Surface.svelte +89 -87
  60. package/dist/components/primitives/Text.svelte +98 -98
  61. package/dist/components/scenes/ArchiveScene.svelte +92 -95
  62. package/dist/components/scenes/ArchiveScene.svelte.d.ts +7 -1
  63. package/dist/components/scenes/LogScene.svelte +72 -77
  64. package/dist/components/scenes/NarrativeScene.svelte +91 -92
  65. package/dist/components/scenes/ReadoutScene.svelte +120 -107
  66. package/dist/components/scenes/ReadoutScene.svelte.d.ts +3 -1
  67. package/dist/components/scenes/StageScene.svelte +97 -104
  68. package/dist/examples/FieldReport.svelte +226 -223
  69. package/dist/examples/ObservationDeck.svelte +333 -317
  70. package/dist/examples/SignalLost.svelte +191 -191
  71. package/dist/styles.css +113 -0
  72. package/dist/system/actions/echo.js +9 -9
  73. package/dist/system/actions/resolve.js +9 -9
  74. package/dist/system/actions/reveal.js +1 -1
  75. package/dist/system/actions/surface.js +13 -1
  76. package/dist/system/depth/depth.css +49 -49
  77. package/dist/system/depth/depth.js +1 -1
  78. package/dist/system/expressions.css +80 -80
  79. package/dist/system/override-template.css +72 -72
  80. package/dist/system/register.css +74 -74
  81. package/dist/system/scroll-lock.d.ts +6 -0
  82. package/dist/system/scroll-lock.js +23 -0
  83. package/dist/tokens/tokens.css +100 -86
  84. package/dist/tokens/tokens.js +4 -4
  85. package/dist/utils/motion.js +1 -1
  86. package/package.json +67 -60
@@ -1,237 +1,240 @@
1
- <script lang="ts">
2
- import { cn } from '../../utils/cn.js';
3
- import type { Snippet } from 'svelte';
4
- import { echo as echoAction } from '../../system/actions/echo.js';
5
-
6
- interface Props {
7
- /** Button visual style. */
8
- variant?: 'primary' | 'secondary' | 'ghost' | 'destructive';
9
- /** Button size. */
10
- size?: 'sm' | 'md';
11
- /** Disables the button. */
12
- disabled?: boolean;
13
- /** Shows a pending status indicator instead of the label. */
14
- loading?: boolean;
15
- /** Enables the click echo ripple. */
16
- echo?: boolean;
17
- /** Additional CSS classes. */
18
- class?: string;
19
- /** Button type attribute. */
20
- type?: 'button' | 'submit' | 'reset';
21
- /** Optional href to render an anchor instead of a button. */
22
- href?: string;
23
- /** Anchor target. */
24
- target?: string;
25
- /** Anchor rel. */
26
- rel?: string;
27
- /** Click handler. */
28
- onclick?: (e: MouseEvent) => void;
29
- /** Button label content. */
30
- children?: Snippet;
31
- }
32
-
33
- let {
34
- variant = 'secondary',
35
- size = 'md',
36
- disabled = false,
37
- loading = false,
38
- echo = false,
39
- class: className = '',
40
- type = 'button',
41
- href,
42
- target,
43
- rel,
44
- onclick,
45
- children,
46
- }: Props = $props();
47
-
48
- function activeEcho(node: HTMLElement) {
49
- if (!echo) return {};
50
- return echoAction(node);
51
- }
52
-
53
- function handleAnchorClick(e: MouseEvent) {
54
- if (disabled || loading) {
55
- e.preventDefault();
56
- return;
57
- }
58
-
59
- onclick?.(e);
60
- }
61
- </script>
62
-
63
- {#if href}
64
- <a
65
- {href}
66
- {target}
67
- {rel}
68
- use:activeEcho
69
- class={cn(
70
- 'hyvui-btn',
71
- `hyvui-btn-${variant}`,
72
- `hyvui-btn-${size}`,
73
- loading && 'hyvui-btn-loading',
74
- disabled && 'hyvui-btn-disabled',
75
- className
76
- )}
77
- aria-disabled={disabled || loading}
78
- tabindex={disabled || loading ? -1 : undefined}
79
- onclick={handleAnchorClick}
80
- >
81
- {#if loading}
82
- <span class="hyvui-btn-dot" aria-label="loading"></span>
83
- {:else if children}
84
- {@render children()}
85
- {/if}
86
- </a>
87
- {:else}
88
- <button
89
- {type}
90
- use:activeEcho
91
- class={cn(
92
- 'hyvui-btn',
93
- `hyvui-btn-${variant}`,
94
- `hyvui-btn-${size}`,
95
- loading && 'hyvui-btn-loading',
96
- className
97
- )}
98
- disabled={disabled || loading}
99
- {onclick}
100
- >
101
- {#if loading}
102
- <span class="hyvui-btn-dot" aria-label="loading"></span>
103
- {:else if children}
104
- {@render children()}
105
- {/if}
106
- </button>
107
- {/if}
108
-
109
- <style>
110
- .hyvui-btn {
111
- position: relative;
112
- overflow: clip;
113
- font-family: var(--font-mono);
114
- font-size: 0.72rem;
115
- font-weight: 400;
116
- letter-spacing: 0.16em;
117
- text-transform: uppercase;
118
- border: 1px solid var(--line);
119
- border-radius: var(--radius-md);
120
- cursor: pointer;
121
- display: inline-flex;
122
- align-items: center;
123
- justify-content: center;
124
- gap: var(--control-gap);
125
- transition:
126
- color var(--transition-smooth),
127
- border-color var(--transition-smooth),
128
- background var(--transition-smooth),
129
- transform var(--transition-smooth),
130
- box-shadow var(--transition-smooth);
131
- white-space: nowrap;
132
- text-decoration: none;
133
- line-height: 1;
134
- max-width: 100%;
135
- box-shadow: var(--surface-stroke);
136
- }
137
-
138
- .hyvui-btn:disabled,
139
- .hyvui-btn-disabled {
140
- opacity: 0.46;
141
- cursor: not-allowed;
142
- transform: none !important;
143
- box-shadow: none;
144
- }
145
-
146
- .hyvui-btn-md {
147
- min-height: var(--control-height-md);
148
- padding: 0.75rem 1.15rem;
149
- }
150
-
151
- .hyvui-btn-sm {
152
- min-height: var(--control-height-sm);
153
- padding: 0.5rem 0.8rem;
154
- font-size: 0.68rem;
155
- }
156
-
157
- /* primary */
158
- .hyvui-btn-primary {
159
- background:
160
- linear-gradient(180deg, color-mix(in srgb, var(--accent-strong) 22%, transparent), transparent 70%),
161
- linear-gradient(135deg, var(--accent), var(--accent-strong));
162
- color: var(--bg);
163
- border-color: color-mix(in srgb, var(--accent-strong) 45%, var(--accent));
164
- box-shadow:
165
- inset 0 1px 0 rgba(255, 255, 255, 0.16),
166
- 0 14px 26px rgba(199, 156, 87, 0.16);
167
- }
168
-
169
- .hyvui-btn-primary:hover:not(:disabled):not(.hyvui-btn-disabled) {
170
- transform: translateY(-2px);
171
- filter: brightness(1.03);
172
- }
173
-
174
- /* secondary */
175
- .hyvui-btn-secondary {
176
- background:
177
- linear-gradient(180deg, rgba(121, 166, 163, 0.06), transparent 62%),
178
- rgba(10, 12, 14, 0.74);
179
- color: var(--text-soft);
180
- border-color: var(--line-strong);
181
- }
182
-
183
- .hyvui-btn-secondary:hover:not(:disabled):not(.hyvui-btn-disabled) {
184
- transform: translateY(-2px);
185
- border-color: color-mix(in srgb, var(--accent) 46%, var(--line-strong));
186
- color: var(--text);
187
- }
188
-
189
- /* ghost */
190
- .hyvui-btn-ghost {
191
- background: transparent;
192
- color: var(--muted);
193
- border-color: transparent;
194
- box-shadow: none;
195
- }
196
-
197
- .hyvui-btn-ghost:hover:not(:disabled):not(.hyvui-btn-disabled) {
198
- background: linear-gradient(90deg, rgba(199, 156, 87, 0.12), transparent 78%);
199
- color: var(--text);
200
- transform: translateX(2px);
201
- }
202
-
203
- /* destructive */
204
- .hyvui-btn-destructive {
205
- background: rgba(10, 12, 14, 0.74);
206
- color: var(--text-soft);
207
- border-color: rgba(182, 106, 72, 0.34);
208
- }
209
-
210
- .hyvui-btn-destructive:hover:not(:disabled):not(.hyvui-btn-disabled) {
211
- background-color: rgba(182, 106, 72, 0.1);
212
- transform: translateY(-2px);
213
- }
214
-
215
- /* loading dot */
216
- .hyvui-btn-dot {
217
- width: 6px;
218
- height: 6px;
219
- border-radius: 50%;
220
- background-color: var(--status-pend);
221
- animation: pulse-dot 2s ease-in-out infinite;
222
- }
223
-
224
- @media (prefers-reduced-motion: reduce) {
225
- .hyvui-btn {
226
- transition: none;
227
- }
228
-
229
- .hyvui-btn:hover:not(:disabled):not(.hyvui-btn-disabled) {
230
- transform: none;
231
- }
232
-
233
- .hyvui-btn-dot {
234
- animation: none;
235
- }
236
- }
237
- </style>
1
+ <script lang="ts">
2
+ import { cn } from '../../utils/cn.js';
3
+ import type { Snippet } from 'svelte';
4
+ import { echo as echoAction } from '../../system/actions/echo.js';
5
+
6
+ interface Props {
7
+ /** Button visual style. */
8
+ variant?: 'primary' | 'secondary' | 'ghost' | 'destructive';
9
+ /** Button size. */
10
+ size?: 'sm' | 'md';
11
+ /** Disables the button. */
12
+ disabled?: boolean;
13
+ /** Shows a pending status indicator instead of the label. */
14
+ loading?: boolean;
15
+ /** Enables the click echo ripple. */
16
+ echo?: boolean;
17
+ /** Additional CSS classes. */
18
+ class?: string;
19
+ /** Button type attribute. */
20
+ type?: 'button' | 'submit' | 'reset';
21
+ /** Optional href to render an anchor instead of a button. */
22
+ href?: string;
23
+ /** Anchor target. */
24
+ target?: string;
25
+ /** Anchor rel. */
26
+ rel?: string;
27
+ /** Click handler. */
28
+ onclick?: (e: MouseEvent) => void;
29
+ /** Button label content. */
30
+ children?: Snippet;
31
+ }
32
+
33
+ let {
34
+ variant = 'secondary',
35
+ size = 'md',
36
+ disabled = false,
37
+ loading = false,
38
+ echo = false,
39
+ class: className = '',
40
+ type = 'button',
41
+ href,
42
+ target,
43
+ rel,
44
+ onclick,
45
+ children
46
+ }: Props = $props();
47
+
48
+ function activeEcho(node: HTMLElement) {
49
+ if (!echo) return {};
50
+ return echoAction(node);
51
+ }
52
+
53
+ function handleAnchorClick(e: MouseEvent) {
54
+ if (disabled || loading) {
55
+ e.preventDefault();
56
+ return;
57
+ }
58
+
59
+ onclick?.(e);
60
+ }
61
+ </script>
62
+
63
+ {#if href}
64
+ <a
65
+ {href}
66
+ {target}
67
+ {rel}
68
+ use:activeEcho
69
+ class={cn(
70
+ 'hyvui-btn',
71
+ `hyvui-btn-${variant}`,
72
+ `hyvui-btn-${size}`,
73
+ loading && 'hyvui-btn-loading',
74
+ disabled && 'hyvui-btn-disabled',
75
+ className
76
+ )}
77
+ aria-disabled={disabled || loading}
78
+ tabindex={disabled || loading ? -1 : undefined}
79
+ onclick={handleAnchorClick}
80
+ >
81
+ {#if loading}
82
+ <span class="hyvui-btn-dot" aria-label="loading"></span>
83
+ {:else if children}
84
+ {@render children()}
85
+ {/if}
86
+ </a>
87
+ {:else}
88
+ <button
89
+ {type}
90
+ use:activeEcho
91
+ class={cn(
92
+ 'hyvui-btn',
93
+ `hyvui-btn-${variant}`,
94
+ `hyvui-btn-${size}`,
95
+ loading && 'hyvui-btn-loading',
96
+ className
97
+ )}
98
+ disabled={disabled || loading}
99
+ {onclick}
100
+ >
101
+ {#if loading}
102
+ <span class="hyvui-btn-dot" aria-label="loading"></span>
103
+ {:else if children}
104
+ {@render children()}
105
+ {/if}
106
+ </button>
107
+ {/if}
108
+
109
+ <style>
110
+ .hyvui-btn {
111
+ position: relative;
112
+ overflow: clip;
113
+ font-family: var(--font-mono);
114
+ font-size: 0.72rem;
115
+ font-weight: 400;
116
+ letter-spacing: 0.16em;
117
+ text-transform: uppercase;
118
+ border: 1px solid var(--line);
119
+ border-radius: var(--radius-md);
120
+ cursor: pointer;
121
+ display: inline-flex;
122
+ align-items: center;
123
+ justify-content: center;
124
+ gap: var(--control-gap);
125
+ transition:
126
+ color var(--transition-smooth),
127
+ border-color var(--transition-smooth),
128
+ background var(--transition-smooth),
129
+ transform var(--transition-smooth),
130
+ box-shadow var(--transition-smooth);
131
+ white-space: nowrap;
132
+ text-decoration: none;
133
+ line-height: 1;
134
+ max-width: 100%;
135
+ box-shadow: var(--surface-stroke);
136
+ }
137
+
138
+ .hyvui-btn:disabled,
139
+ .hyvui-btn-disabled {
140
+ opacity: 0.46;
141
+ cursor: not-allowed;
142
+ transform: none !important;
143
+ box-shadow: none;
144
+ }
145
+
146
+ .hyvui-btn-md {
147
+ min-height: var(--control-height-md);
148
+ padding: 0.75rem 1.15rem;
149
+ }
150
+
151
+ .hyvui-btn-sm {
152
+ min-height: var(--control-height-sm);
153
+ padding: 0.5rem 0.8rem;
154
+ font-size: 0.68rem;
155
+ }
156
+
157
+ /* primary */
158
+ .hyvui-btn-primary {
159
+ background:
160
+ linear-gradient(
161
+ 180deg,
162
+ color-mix(in srgb, var(--accent-strong) 22%, transparent),
163
+ transparent 70%
164
+ ),
165
+ linear-gradient(135deg, var(--accent), var(--accent-strong));
166
+ color: var(--bg);
167
+ border-color: color-mix(in srgb, var(--accent-strong) 45%, var(--accent));
168
+ box-shadow:
169
+ inset 0 1px 0 rgba(255, 255, 255, 0.16),
170
+ 0 14px 26px rgba(199, 156, 87, 0.16);
171
+ }
172
+
173
+ .hyvui-btn-primary:hover:not(:disabled):not(.hyvui-btn-disabled) {
174
+ transform: translateY(-2px);
175
+ filter: brightness(1.03);
176
+ }
177
+
178
+ /* secondary */
179
+ .hyvui-btn-secondary {
180
+ background:
181
+ linear-gradient(180deg, rgba(121, 166, 163, 0.06), transparent 62%), rgba(10, 12, 14, 0.74);
182
+ color: var(--text-soft);
183
+ border-color: var(--line-strong);
184
+ }
185
+
186
+ .hyvui-btn-secondary:hover:not(:disabled):not(.hyvui-btn-disabled) {
187
+ transform: translateY(-2px);
188
+ border-color: color-mix(in srgb, var(--accent) 46%, var(--line-strong));
189
+ color: var(--text);
190
+ }
191
+
192
+ /* ghost */
193
+ .hyvui-btn-ghost {
194
+ background: transparent;
195
+ color: var(--muted);
196
+ border-color: transparent;
197
+ box-shadow: none;
198
+ }
199
+
200
+ .hyvui-btn-ghost:hover:not(:disabled):not(.hyvui-btn-disabled) {
201
+ background: linear-gradient(90deg, rgba(199, 156, 87, 0.12), transparent 78%);
202
+ color: var(--text);
203
+ transform: translateX(2px);
204
+ }
205
+
206
+ /* destructive */
207
+ .hyvui-btn-destructive {
208
+ background: rgba(10, 12, 14, 0.74);
209
+ color: var(--text-soft);
210
+ border-color: rgba(182, 106, 72, 0.34);
211
+ }
212
+
213
+ .hyvui-btn-destructive:hover:not(:disabled):not(.hyvui-btn-disabled) {
214
+ background-color: rgba(182, 106, 72, 0.1);
215
+ transform: translateY(-2px);
216
+ }
217
+
218
+ /* loading dot */
219
+ .hyvui-btn-dot {
220
+ width: 6px;
221
+ height: 6px;
222
+ border-radius: 50%;
223
+ background-color: var(--status-pend);
224
+ animation: pulse-dot 2s ease-in-out infinite;
225
+ }
226
+
227
+ @media (prefers-reduced-motion: reduce) {
228
+ .hyvui-btn {
229
+ transition: none;
230
+ }
231
+
232
+ .hyvui-btn:hover:not(:disabled):not(.hyvui-btn-disabled) {
233
+ transform: none;
234
+ }
235
+
236
+ .hyvui-btn-dot {
237
+ animation: none;
238
+ }
239
+ }
240
+ </style>