@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,114 +1,109 @@
1
- <script lang="ts">
2
- import { cn } from '../../utils/cn.js';
3
- import type { Snippet } from 'svelte';
4
-
5
- interface Props {
6
- /** Page title. */
7
- title?: string;
8
- /** Page subtitle. */
9
- subtitle?: string;
10
- /** Additional CSS classes. */
11
- class?: string;
12
- /** Breadcrumb slot. */
13
- breadcrumb?: Snippet;
14
- /** Actions slot (right-aligned). */
15
- actions?: Snippet;
16
- }
17
-
18
- let {
19
- title = '',
20
- subtitle = '',
21
- class: className = '',
22
- breadcrumb,
23
- actions,
24
- }: Props = $props();
25
- </script>
26
-
27
- <div class={cn('hyvui-page-header', className)}>
28
- {#if breadcrumb}
29
- <div class="hyvui-page-header-breadcrumb">
30
- {@render breadcrumb()}
31
- </div>
32
- {/if}
33
- <div class="hyvui-page-header-row">
34
- <div class="hyvui-page-header-text">
35
- <h1 class="hyvui-page-header-title">{title}</h1>
36
- {#if subtitle}
37
- <p class="hyvui-page-header-subtitle">{subtitle}</p>
38
- {/if}
39
- </div>
40
- {#if actions}
41
- <div class="hyvui-page-header-actions">
42
- {@render actions()}
43
- </div>
44
- {/if}
45
- </div>
46
- </div>
47
-
48
- <style>
49
- .hyvui-page-header {
50
- display: flex;
51
- flex-direction: column;
52
- gap: var(--space-md);
53
- padding-bottom: var(--space-lg);
54
- border-bottom: 1px solid var(--line);
55
- }
56
-
57
- .hyvui-page-header-breadcrumb {
58
- min-width: 0;
59
- }
60
-
61
- .hyvui-page-header-row {
62
- display: flex;
63
- align-items: flex-start;
64
- justify-content: space-between;
65
- gap: var(--space-xl);
66
- }
67
-
68
- .hyvui-page-header-text {
69
- display: flex;
70
- flex-direction: column;
71
- gap: var(--space-sm);
72
- min-width: 0;
73
- }
74
-
75
- .hyvui-page-header-title {
76
- font-family: var(--font-body);
77
- font-size: clamp(2rem, 4vw, 3.25rem);
78
- font-weight: 400;
79
- line-height: 0.95;
80
- letter-spacing: -0.05em;
81
- color: var(--text);
82
- margin: 0;
83
- text-wrap: balance;
84
- }
85
-
86
- .hyvui-page-header-subtitle {
87
- font-family: var(--font-body);
88
- font-size: 1.04rem;
89
- color: var(--muted);
90
- line-height: 1.62;
91
- margin: 0;
92
- max-width: 32rem;
93
- text-wrap: pretty;
94
- }
95
-
96
- .hyvui-page-header-actions {
97
- display: flex;
98
- align-items: center;
99
- flex-wrap: wrap;
100
- justify-content: flex-end;
101
- gap: var(--space-sm);
102
- flex-shrink: 0;
103
- }
104
-
105
- @media (max-width: 720px) {
106
- .hyvui-page-header-row {
107
- flex-direction: column;
108
- }
109
-
110
- .hyvui-page-header-actions {
111
- justify-content: flex-start;
112
- }
113
- }
114
- </style>
1
+ <script lang="ts">
2
+ import { cn } from '../../utils/cn.js';
3
+ import type { Snippet } from 'svelte';
4
+
5
+ interface Props {
6
+ /** Page title. */
7
+ title?: string;
8
+ /** Page subtitle. */
9
+ subtitle?: string;
10
+ /** Additional CSS classes. */
11
+ class?: string;
12
+ /** Breadcrumb slot. */
13
+ breadcrumb?: Snippet;
14
+ /** Actions slot (right-aligned). */
15
+ actions?: Snippet;
16
+ }
17
+
18
+ let { title = '', subtitle = '', class: className = '', breadcrumb, actions }: Props = $props();
19
+ </script>
20
+
21
+ <div class={cn('hyvui-page-header', className)}>
22
+ {#if breadcrumb}
23
+ <div class="hyvui-page-header-breadcrumb">
24
+ {@render breadcrumb()}
25
+ </div>
26
+ {/if}
27
+ <div class="hyvui-page-header-row">
28
+ <div class="hyvui-page-header-text">
29
+ <h1 class="hyvui-page-header-title">{title}</h1>
30
+ {#if subtitle}
31
+ <p class="hyvui-page-header-subtitle">{subtitle}</p>
32
+ {/if}
33
+ </div>
34
+ {#if actions}
35
+ <div class="hyvui-page-header-actions">
36
+ {@render actions()}
37
+ </div>
38
+ {/if}
39
+ </div>
40
+ </div>
41
+
42
+ <style>
43
+ .hyvui-page-header {
44
+ display: flex;
45
+ flex-direction: column;
46
+ gap: var(--space-md);
47
+ padding-bottom: var(--space-lg);
48
+ border-bottom: 1px solid var(--line);
49
+ container-type: inline-size;
50
+ }
51
+
52
+ .hyvui-page-header-breadcrumb {
53
+ min-width: 0;
54
+ }
55
+
56
+ .hyvui-page-header-row {
57
+ display: flex;
58
+ align-items: flex-start;
59
+ justify-content: space-between;
60
+ gap: var(--space-xl);
61
+ }
62
+
63
+ .hyvui-page-header-text {
64
+ display: flex;
65
+ flex-direction: column;
66
+ gap: var(--space-sm);
67
+ min-width: 0;
68
+ }
69
+
70
+ .hyvui-page-header-title {
71
+ font-family: var(--font-body);
72
+ font-size: clamp(2rem, 4vw, 3.25rem);
73
+ font-weight: 400;
74
+ line-height: 0.95;
75
+ letter-spacing: -0.05em;
76
+ color: var(--text);
77
+ margin: 0;
78
+ text-wrap: balance;
79
+ }
80
+
81
+ .hyvui-page-header-subtitle {
82
+ font-family: var(--font-body);
83
+ font-size: 1.04rem;
84
+ color: var(--muted);
85
+ line-height: 1.62;
86
+ margin: 0;
87
+ max-width: 32rem;
88
+ text-wrap: pretty;
89
+ }
90
+
91
+ .hyvui-page-header-actions {
92
+ display: flex;
93
+ align-items: center;
94
+ flex-wrap: wrap;
95
+ justify-content: flex-end;
96
+ gap: var(--space-sm);
97
+ flex-shrink: 0;
98
+ }
99
+
100
+ @container (max-width: var(--cq-sm)) {
101
+ .hyvui-page-header-row {
102
+ flex-direction: column;
103
+ }
104
+
105
+ .hyvui-page-header-actions {
106
+ justify-content: flex-start;
107
+ }
108
+ }
109
+ </style>
@@ -1,59 +1,54 @@
1
- <script lang="ts">
2
- import { cn } from '../../utils/cn.js';
3
- import Input from '../inputs/Input.svelte';
4
- import StatusDot from '../feedback/StatusDot.svelte';
5
-
6
- interface Props {
7
- /** Current search value (bindable). */
8
- value?: string;
9
- /** Placeholder text. */
10
- placeholder?: string;
11
- /** Shows a loading indicator. */
12
- loading?: boolean;
13
- /** Additional CSS classes. */
14
- class?: string;
15
- /** Fires on input with the current value. */
16
- onsearch?: (value: string) => void;
17
- }
18
-
19
- let {
20
- value = $bindable(''),
21
- placeholder = 'search',
22
- loading = false,
23
- class: className = '',
24
- onsearch,
25
- }: Props = $props();
26
-
27
- function handleInput() {
28
- onsearch?.(value);
29
- }
30
- </script>
31
-
32
- <div class={cn('hyvui-search-bar', className)}>
33
- <Input
34
- type="search"
35
- bind:value
36
- {placeholder}
37
- oninput={handleInput}
38
- />
39
- {#if loading}
40
- <div class="hyvui-search-loading">
41
- <StatusDot status="pend" size={6} />
42
- </div>
43
- {/if}
44
- </div>
45
-
46
- <style>
47
- .hyvui-search-bar {
48
- position: relative;
49
- width: 100%;
50
- }
51
-
52
- .hyvui-search-loading {
53
- position: absolute;
54
- right: 0.9rem;
55
- top: 50%;
56
- transform: translateY(-50%);
57
- pointer-events: none;
58
- }
59
- </style>
1
+ <script lang="ts">
2
+ import { cn } from '../../utils/cn.js';
3
+ import Input from '../inputs/Input.svelte';
4
+ import StatusDot from '../feedback/StatusDot.svelte';
5
+
6
+ interface Props {
7
+ /** Current search value (bindable). */
8
+ value?: string;
9
+ /** Placeholder text. */
10
+ placeholder?: string;
11
+ /** Shows a loading indicator. */
12
+ loading?: boolean;
13
+ /** Additional CSS classes. */
14
+ class?: string;
15
+ /** Fires on input with the current value. */
16
+ onsearch?: (value: string) => void;
17
+ }
18
+
19
+ let {
20
+ value = $bindable(''),
21
+ placeholder = 'search',
22
+ loading = false,
23
+ class: className = '',
24
+ onsearch
25
+ }: Props = $props();
26
+
27
+ function handleInput() {
28
+ onsearch?.(value);
29
+ }
30
+ </script>
31
+
32
+ <div class={cn('hyvui-search-bar', className)}>
33
+ <Input type="search" bind:value {placeholder} oninput={handleInput} />
34
+ {#if loading}
35
+ <div class="hyvui-search-loading">
36
+ <StatusDot status="pend" size={6} />
37
+ </div>
38
+ {/if}
39
+ </div>
40
+
41
+ <style>
42
+ .hyvui-search-bar {
43
+ position: relative;
44
+ width: 100%;
45
+ }
46
+
47
+ .hyvui-search-loading {
48
+ position: absolute;
49
+ right: 0.9rem;
50
+ top: 50%;
51
+ transform: translateY(-50%);
52
+ pointer-events: none;
53
+ }
54
+ </style>
@@ -1,104 +1,104 @@
1
- <script lang="ts">
2
- import { cn } from '../../utils/cn.js';
3
- import StatusLine from '../feedback/StatusLine.svelte';
4
- import { onMount } from 'svelte';
5
-
6
- interface BootLine {
7
- status: 'ok' | 'pend' | 'warn' | 'fail';
8
- message: string;
9
- }
10
-
11
- interface Props {
12
- /** Lines to display in sequence. */
13
- lines?: BootLine[];
14
- /** Initial delay before the first line appears (ms). */
15
- delay?: number;
16
- /** Interval between each line appearing (ms). */
17
- interval?: number;
18
- /** When true, shows all lines immediately. */
19
- instant?: boolean;
20
- /** Passes cursor visibility to visible lines. */
21
- showCursor?: boolean;
22
- /** Status line tone mode. */
23
- tone?: 'split' | 'line';
24
- /** Additional CSS classes. */
25
- class?: string;
26
- /** Fires when all lines have appeared. */
27
- oncomplete?: () => void;
28
- }
29
-
30
- let {
31
- lines = [],
32
- delay = 600,
33
- interval = 700,
34
- instant = false,
35
- showCursor = false,
36
- tone = 'split',
37
- class: className = '',
38
- oncomplete,
39
- }: Props = $props();
40
-
41
- let visibleCount = $state(0);
42
-
43
- onMount(() => {
44
- if (lines.length === 0) {
45
- oncomplete?.();
46
- return;
47
- }
48
-
49
- if (instant) {
50
- visibleCount = lines.length;
51
- oncomplete?.();
52
- return;
53
- }
54
-
55
- const timers: number[] = [];
56
- timers.push(
57
- window.setTimeout(() => {
58
- visibleCount = 1;
59
-
60
- if (lines.length === 1) {
61
- oncomplete?.();
62
- return;
63
- }
64
-
65
- const stepTimer = window.setInterval(() => {
66
- visibleCount += 1;
67
- if (visibleCount >= lines.length) {
68
- window.clearInterval(stepTimer);
69
- oncomplete?.();
70
- }
71
- }, interval);
72
-
73
- timers.push(stepTimer);
74
- }, delay)
75
- );
76
-
77
- return () => {
78
- for (const timer of timers) {
79
- window.clearTimeout(timer);
80
- window.clearInterval(timer);
81
- }
82
- };
83
- });
84
- </script>
85
-
86
- <div class={cn('hyvui-terminal-boot', className)}>
87
- {#each lines as line, i}
88
- <StatusLine
89
- status={line.status}
90
- message={line.message}
91
- visible={i < visibleCount}
92
- tone={tone}
93
- cursor={showCursor && i < visibleCount}
94
- />
95
- {/each}
96
- </div>
97
-
98
- <style>
99
- .hyvui-terminal-boot {
100
- display: flex;
101
- flex-direction: column;
102
- gap: 0.375rem;
103
- }
104
- </style>
1
+ <script lang="ts">
2
+ import { cn } from '../../utils/cn.js';
3
+ import StatusLine from '../feedback/StatusLine.svelte';
4
+ import { onMount } from 'svelte';
5
+
6
+ interface BootLine {
7
+ status: 'ok' | 'pend' | 'warn' | 'fail';
8
+ message: string;
9
+ }
10
+
11
+ interface Props {
12
+ /** Lines to display in sequence. */
13
+ lines?: BootLine[];
14
+ /** Initial delay before the first line appears (ms). */
15
+ delay?: number;
16
+ /** Interval between each line appearing (ms). */
17
+ interval?: number;
18
+ /** When true, shows all lines immediately. */
19
+ instant?: boolean;
20
+ /** Passes cursor visibility to visible lines. */
21
+ showCursor?: boolean;
22
+ /** Status line tone mode. */
23
+ tone?: 'split' | 'line';
24
+ /** Additional CSS classes. */
25
+ class?: string;
26
+ /** Fires when all lines have appeared. */
27
+ oncomplete?: () => void;
28
+ }
29
+
30
+ let {
31
+ lines = [],
32
+ delay = 600,
33
+ interval = 700,
34
+ instant = false,
35
+ showCursor = false,
36
+ tone = 'split',
37
+ class: className = '',
38
+ oncomplete
39
+ }: Props = $props();
40
+
41
+ let visibleCount = $state(0);
42
+
43
+ onMount(() => {
44
+ if (lines.length === 0) {
45
+ oncomplete?.();
46
+ return;
47
+ }
48
+
49
+ if (instant) {
50
+ visibleCount = lines.length;
51
+ oncomplete?.();
52
+ return;
53
+ }
54
+
55
+ const timers: number[] = [];
56
+ timers.push(
57
+ window.setTimeout(() => {
58
+ visibleCount = 1;
59
+
60
+ if (lines.length === 1) {
61
+ oncomplete?.();
62
+ return;
63
+ }
64
+
65
+ const stepTimer = window.setInterval(() => {
66
+ visibleCount += 1;
67
+ if (visibleCount >= lines.length) {
68
+ window.clearInterval(stepTimer);
69
+ oncomplete?.();
70
+ }
71
+ }, interval);
72
+
73
+ timers.push(stepTimer);
74
+ }, delay)
75
+ );
76
+
77
+ return () => {
78
+ for (const timer of timers) {
79
+ window.clearTimeout(timer);
80
+ window.clearInterval(timer);
81
+ }
82
+ };
83
+ });
84
+ </script>
85
+
86
+ <div class={cn('hyvui-terminal-boot', className)}>
87
+ {#each lines as line, i}
88
+ <StatusLine
89
+ status={line.status}
90
+ message={line.message}
91
+ visible={i < visibleCount}
92
+ {tone}
93
+ cursor={showCursor && i < visibleCount}
94
+ />
95
+ {/each}
96
+ </div>
97
+
98
+ <style>
99
+ .hyvui-terminal-boot {
100
+ display: flex;
101
+ flex-direction: column;
102
+ gap: 0.375rem;
103
+ }
104
+ </style>
@@ -1,29 +1,26 @@
1
- <script lang="ts">
2
- import { cn } from '../../utils/cn.js';
3
-
4
- interface Props {
5
- /** Line visibility strength. */
6
- strength?: 'default' | 'strong';
7
- /** Additional CSS classes. */
8
- class?: string;
9
- }
10
-
11
- let {
12
- strength = 'default',
13
- class: className = '',
14
- }: Props = $props();
15
- </script>
16
-
17
- <hr
18
- class={cn('hyvui-divider', className)}
19
- style:border-color={strength === 'strong' ? 'var(--line-strong)' : 'var(--line)'}
20
- />
21
-
22
- <style>
23
- .hyvui-divider {
24
- border: none;
25
- border-top: 1px solid;
26
- margin: 0;
27
- width: 100%;
28
- }
29
- </style>
1
+ <script lang="ts">
2
+ import { cn } from '../../utils/cn.js';
3
+
4
+ interface Props {
5
+ /** Line visibility strength. */
6
+ strength?: 'default' | 'strong';
7
+ /** Additional CSS classes. */
8
+ class?: string;
9
+ }
10
+
11
+ let { strength = 'default', class: className = '' }: Props = $props();
12
+ </script>
13
+
14
+ <hr
15
+ class={cn('hyvui-divider', className)}
16
+ style:border-color={strength === 'strong' ? 'var(--line-strong)' : 'var(--line)'}
17
+ />
18
+
19
+ <style>
20
+ .hyvui-divider {
21
+ border: none;
22
+ border-top: 1px solid;
23
+ margin: 0;
24
+ width: 100%;
25
+ }
26
+ </style>