@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.
- package/README.md +264 -253
- package/dist/components/ambient/CornerBrackets.svelte +83 -87
- package/dist/components/ambient/DataStream.svelte +111 -94
- package/dist/components/ambient/GlyphMark.svelte +69 -69
- package/dist/components/ambient/GridOverlay.svelte +26 -28
- package/dist/components/ambient/ParallaxLayer.svelte +37 -41
- package/dist/components/ambient/ScanBand.svelte +95 -91
- package/dist/components/ambient/SignalRing.svelte +100 -100
- package/dist/components/ambient/ThreadLine.svelte +71 -78
- package/dist/components/ambient/Vignette.svelte +24 -26
- package/dist/components/depth/DepthLayer.svelte +22 -27
- package/dist/components/depth/DepthStage.svelte +63 -62
- package/dist/components/depth/FloatCard.svelte +113 -104
- package/dist/components/depth/HorizonGrid.svelte +216 -160
- package/dist/components/depth/Plinth.svelte +52 -57
- package/dist/components/display/Avatar.svelte +64 -69
- package/dist/components/display/Badge.svelte +59 -63
- package/dist/components/display/Blockquote.svelte +31 -34
- package/dist/components/display/CodeBlock.svelte +71 -76
- package/dist/components/display/MetricCard.svelte +77 -83
- package/dist/components/display/Table.svelte +99 -104
- package/dist/components/feedback/Alert.svelte +71 -76
- package/dist/components/feedback/EmptyState.svelte +68 -68
- package/dist/components/feedback/ErrorState.svelte +73 -73
- package/dist/components/feedback/Skeleton.svelte +52 -52
- package/dist/components/feedback/StatusDot.svelte +49 -54
- package/dist/components/feedback/StatusLine.svelte +122 -122
- package/dist/components/feedback/Toast.svelte +130 -136
- package/dist/components/inputs/Button.svelte +240 -237
- package/dist/components/inputs/Checkbox.svelte +104 -105
- package/dist/components/inputs/FileUpload.svelte +165 -163
- package/dist/components/inputs/Input.svelte +145 -147
- package/dist/components/inputs/Select.svelte +156 -150
- package/dist/components/inputs/Textarea.svelte +153 -154
- package/dist/components/inputs/Toggle.svelte +120 -120
- package/dist/components/layout/Card.svelte +70 -76
- package/dist/components/layout/Drawer.svelte +133 -109
- package/dist/components/layout/Grid.svelte +118 -43
- package/dist/components/layout/Grid.svelte.d.ts +8 -2
- package/dist/components/layout/Modal.svelte +176 -159
- package/dist/components/layout/Panel.svelte +49 -54
- package/dist/components/layout/Popover.svelte +178 -67
- package/dist/components/layout/Popover.svelte.d.ts +10 -1
- package/dist/components/layout/Stack.svelte +53 -53
- package/dist/components/navigation/Breadcrumb.svelte +70 -73
- package/dist/components/navigation/DropdownMenu.svelte +167 -124
- package/dist/components/navigation/DropdownMenu.svelte.d.ts +12 -2
- package/dist/components/navigation/SidebarNav.svelte +86 -90
- package/dist/components/navigation/Tabs.svelte +81 -86
- package/dist/components/navigation/Topbar.svelte +85 -85
- package/dist/components/patterns/ActionBar.svelte +71 -76
- package/dist/components/patterns/ConfirmDialog.svelte +63 -64
- package/dist/components/patterns/PageHeader.svelte +109 -114
- package/dist/components/patterns/SearchBar.svelte +54 -59
- package/dist/components/patterns/TerminalBoot.svelte +104 -104
- package/dist/components/primitives/Divider.svelte +26 -29
- package/dist/components/primitives/Icon.svelte +44 -49
- package/dist/components/primitives/Label.svelte +39 -44
- package/dist/components/primitives/Surface.svelte +89 -87
- package/dist/components/primitives/Text.svelte +98 -98
- package/dist/components/scenes/ArchiveScene.svelte +92 -95
- package/dist/components/scenes/ArchiveScene.svelte.d.ts +7 -1
- package/dist/components/scenes/LogScene.svelte +72 -77
- package/dist/components/scenes/NarrativeScene.svelte +91 -92
- package/dist/components/scenes/ReadoutScene.svelte +120 -107
- package/dist/components/scenes/ReadoutScene.svelte.d.ts +3 -1
- package/dist/components/scenes/StageScene.svelte +97 -104
- package/dist/examples/FieldReport.svelte +226 -223
- package/dist/examples/ObservationDeck.svelte +333 -317
- package/dist/examples/SignalLost.svelte +191 -191
- package/dist/styles.css +113 -0
- package/dist/system/actions/echo.js +9 -9
- package/dist/system/actions/resolve.js +9 -9
- package/dist/system/actions/reveal.js +1 -1
- package/dist/system/actions/surface.js +13 -1
- package/dist/system/depth/depth.css +49 -49
- package/dist/system/depth/depth.js +1 -1
- package/dist/system/expressions.css +80 -80
- package/dist/system/override-template.css +72 -72
- package/dist/system/register.css +74 -74
- package/dist/system/scroll-lock.d.ts +6 -0
- package/dist/system/scroll-lock.js +23 -0
- package/dist/tokens/tokens.css +100 -86
- package/dist/tokens/tokens.js +4 -4
- package/dist/utils/motion.js +1 -1
- package/package.json +67 -60
|
@@ -1,191 +1,191 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
EXAMPLE: Signal Lost
|
|
3
|
-
REGISTER: field-notebook
|
|
4
|
-
CONCEPT: a 404 page that feels like arriving at coordinates where something used to be
|
|
5
|
-
DEMONSTRATES: FloatCard, HorizonGrid, TerminalBoot, StatusDot, CornerBrackets, SignalRing, Text expressions, surface action, depth system
|
|
6
|
-
INSPIRED BY: the last transmission log of a deep-space relay station
|
|
7
|
-
-->
|
|
8
|
-
<script lang="ts">
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
</script>
|
|
46
|
-
|
|
47
|
-
<div class="signal-lost">
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
</div>
|
|
106
|
-
|
|
107
|
-
<style>
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
</style>
|
|
1
|
+
<!--
|
|
2
|
+
EXAMPLE: Signal Lost
|
|
3
|
+
REGISTER: field-notebook
|
|
4
|
+
CONCEPT: a 404 page that feels like arriving at coordinates where something used to be
|
|
5
|
+
DEMONSTRATES: FloatCard, HorizonGrid, TerminalBoot, StatusDot, CornerBrackets, SignalRing, Text expressions, surface action, depth system
|
|
6
|
+
INSPIRED BY: the last transmission log of a deep-space relay station
|
|
7
|
+
-->
|
|
8
|
+
<script lang="ts">
|
|
9
|
+
import {
|
|
10
|
+
Text,
|
|
11
|
+
Label,
|
|
12
|
+
Button,
|
|
13
|
+
StatusDot,
|
|
14
|
+
CornerBrackets,
|
|
15
|
+
TerminalBoot,
|
|
16
|
+
FloatCard,
|
|
17
|
+
HorizonGrid,
|
|
18
|
+
DepthStage,
|
|
19
|
+
DepthLayer,
|
|
20
|
+
SignalRing,
|
|
21
|
+
GlyphMark,
|
|
22
|
+
surface,
|
|
23
|
+
applyRegister
|
|
24
|
+
} from '../index.js';
|
|
25
|
+
import { onMount } from 'svelte';
|
|
26
|
+
|
|
27
|
+
let bootComplete = $state(false);
|
|
28
|
+
|
|
29
|
+
const bootLines: { status: 'ok' | 'pend' | 'warn' | 'fail'; message: string }[] = [
|
|
30
|
+
{ status: 'ok', message: 'local systems nominal' },
|
|
31
|
+
{ status: 'ok', message: 'navigation subsystem online' },
|
|
32
|
+
{ status: 'ok', message: 'scanning frequency range' },
|
|
33
|
+
{ status: 'pend', message: 'attempting signal acquisition' },
|
|
34
|
+
{ status: 'warn', message: 'no response on primary band' },
|
|
35
|
+
{ status: 'warn', message: 'sweeping secondary frequencies' },
|
|
36
|
+
{ status: 'fail', message: 'target signal not found at these coordinates' }
|
|
37
|
+
];
|
|
38
|
+
|
|
39
|
+
onMount(() => {
|
|
40
|
+
applyRegister('field-notebook');
|
|
41
|
+
return () => {
|
|
42
|
+
document.body.removeAttribute('data-register');
|
|
43
|
+
};
|
|
44
|
+
});
|
|
45
|
+
</script>
|
|
46
|
+
|
|
47
|
+
<div class="signal-lost">
|
|
48
|
+
<div class="signal-lost-bg">
|
|
49
|
+
<HorizonGrid animated rows={20} cols={14} vanishY={0.32} />
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
<div class="signal-lost-ring" aria-hidden="true">
|
|
53
|
+
<SignalRing active size={400} />
|
|
54
|
+
</div>
|
|
55
|
+
|
|
56
|
+
<DepthStage perspective="mid" class="signal-lost-stage">
|
|
57
|
+
<DepthLayer level="ground" class="signal-lost-terminal">
|
|
58
|
+
<div class="signal-lost-terminal-inner" use:surface={{ delay: 800 }}>
|
|
59
|
+
<TerminalBoot
|
|
60
|
+
lines={bootLines}
|
|
61
|
+
delay={1200}
|
|
62
|
+
interval={900}
|
|
63
|
+
oncomplete={() => (bootComplete = true)}
|
|
64
|
+
/>
|
|
65
|
+
</div>
|
|
66
|
+
</DepthLayer>
|
|
67
|
+
|
|
68
|
+
<DepthLayer level="raised" class="signal-lost-center">
|
|
69
|
+
<FloatCard tiltMax={6} class="signal-lost-card">
|
|
70
|
+
<div class="signal-lost-content" style:position="relative">
|
|
71
|
+
<CornerBrackets size={28} color="rgba(199, 156, 87, 0.2)" />
|
|
72
|
+
|
|
73
|
+
<div class="signal-lost-status" use:surface={{ delay: 200 }}>
|
|
74
|
+
<StatusDot status="fail" size={8} pulse />
|
|
75
|
+
<Label color="muted">transmission ended</Label>
|
|
76
|
+
</div>
|
|
77
|
+
|
|
78
|
+
<div use:surface={{ delay: 400 }}>
|
|
79
|
+
<Text variant="heading" expression="title-card" as="h1" color="primary">
|
|
80
|
+
the coordinates are empty now
|
|
81
|
+
</Text>
|
|
82
|
+
</div>
|
|
83
|
+
|
|
84
|
+
<div use:surface={{ delay: 600 }}>
|
|
85
|
+
<Text expression="manifesto">
|
|
86
|
+
something was broadcasting from here. the frequency is right, the heading is right.
|
|
87
|
+
but the source has gone quiet.
|
|
88
|
+
</Text>
|
|
89
|
+
</div>
|
|
90
|
+
|
|
91
|
+
<div class="signal-lost-meta" use:surface={{ delay: 700 }}>
|
|
92
|
+
<GlyphMark variant="coord" size={16} color="var(--muted-strong)" />
|
|
93
|
+
<Label color="muted">bearing 047.2 | range unknown | last contact 7h ago</Label>
|
|
94
|
+
</div>
|
|
95
|
+
|
|
96
|
+
<div class="signal-lost-action" use:surface={{ delay: 900 }}>
|
|
97
|
+
<Button variant="ghost" onclick={() => window.history.back()}>
|
|
98
|
+
return to last known position
|
|
99
|
+
</Button>
|
|
100
|
+
</div>
|
|
101
|
+
</div>
|
|
102
|
+
</FloatCard>
|
|
103
|
+
</DepthLayer>
|
|
104
|
+
</DepthStage>
|
|
105
|
+
</div>
|
|
106
|
+
|
|
107
|
+
<style>
|
|
108
|
+
.signal-lost {
|
|
109
|
+
position: relative;
|
|
110
|
+
min-height: 100dvh;
|
|
111
|
+
background-color: var(--bg);
|
|
112
|
+
display: flex;
|
|
113
|
+
align-items: center;
|
|
114
|
+
justify-content: center;
|
|
115
|
+
overflow: hidden;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.signal-lost-bg {
|
|
119
|
+
position: absolute;
|
|
120
|
+
inset: 0;
|
|
121
|
+
opacity: 0.5;
|
|
122
|
+
pointer-events: none;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.signal-lost-ring {
|
|
126
|
+
position: absolute;
|
|
127
|
+
top: 50%;
|
|
128
|
+
left: 50%;
|
|
129
|
+
transform: translate(-50%, -50%);
|
|
130
|
+
opacity: 0.3;
|
|
131
|
+
pointer-events: none;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
:global(.signal-lost-stage) {
|
|
135
|
+
position: relative;
|
|
136
|
+
z-index: 1;
|
|
137
|
+
display: flex;
|
|
138
|
+
flex-direction: column;
|
|
139
|
+
align-items: center;
|
|
140
|
+
gap: 2rem;
|
|
141
|
+
padding: var(--space-scene);
|
|
142
|
+
width: 100%;
|
|
143
|
+
max-width: 52rem;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
:global(.signal-lost-center) {
|
|
147
|
+
width: 100%;
|
|
148
|
+
display: flex;
|
|
149
|
+
justify-content: center;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
:global(.signal-lost-card) {
|
|
153
|
+
max-width: 36rem;
|
|
154
|
+
width: 100%;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.signal-lost-content {
|
|
158
|
+
display: flex;
|
|
159
|
+
flex-direction: column;
|
|
160
|
+
gap: 1.5rem;
|
|
161
|
+
padding: 1rem;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.signal-lost-status {
|
|
165
|
+
display: flex;
|
|
166
|
+
align-items: center;
|
|
167
|
+
gap: 0.625rem;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
.signal-lost-meta {
|
|
171
|
+
display: flex;
|
|
172
|
+
align-items: center;
|
|
173
|
+
gap: 0.5rem;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.signal-lost-action {
|
|
177
|
+
margin-top: 0.5rem;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
:global(.signal-lost-terminal) {
|
|
181
|
+
width: 100%;
|
|
182
|
+
max-width: 36rem;
|
|
183
|
+
align-self: center;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.signal-lost-terminal-inner {
|
|
187
|
+
padding: 1rem 0;
|
|
188
|
+
border-left: 2px solid rgba(121, 166, 163, 0.14);
|
|
189
|
+
padding-left: 1.25rem;
|
|
190
|
+
}
|
|
191
|
+
</style>
|
package/dist/styles.css
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/* hyvui — base stylesheet entrypoint
|
|
2
|
+
*
|
|
3
|
+
* This file is meant to be imported by consuming applications:
|
|
4
|
+
* import '@hyvnt/hyvui/styles.css';
|
|
5
|
+
*
|
|
6
|
+
* It intentionally contains NO Tailwind directives, so it can be used in
|
|
7
|
+
* non-Tailwind projects. Tailwind theme mapping stays in app-level CSS.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
@import './tokens/tokens.css';
|
|
11
|
+
@import './system/register.css';
|
|
12
|
+
@import './system/expressions.css';
|
|
13
|
+
@import './system/depth/depth.css';
|
|
14
|
+
|
|
15
|
+
/* ── base reset ─────────────────────────────────────────────────────── */
|
|
16
|
+
*,
|
|
17
|
+
*::before,
|
|
18
|
+
*::after {
|
|
19
|
+
box-sizing: border-box;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
html {
|
|
23
|
+
/* Critical fallback paint (also duplicated inline in app.html for FOUC) */
|
|
24
|
+
background-color: #08090b;
|
|
25
|
+
color: var(--text);
|
|
26
|
+
font-family: var(--font-body);
|
|
27
|
+
font-size: 16px;
|
|
28
|
+
-webkit-font-smoothing: antialiased;
|
|
29
|
+
-moz-osx-font-smoothing: grayscale;
|
|
30
|
+
scrollbar-gutter: stable;
|
|
31
|
+
color-scheme: dark;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
body {
|
|
35
|
+
margin: 0;
|
|
36
|
+
min-height: 100dvh;
|
|
37
|
+
background: transparent;
|
|
38
|
+
color: var(--text);
|
|
39
|
+
overflow-x: hidden;
|
|
40
|
+
|
|
41
|
+
/* Ensure our fixed background layer can sit behind content without leaking
|
|
42
|
+
under <html> in weird stacking contexts. */
|
|
43
|
+
isolation: isolate;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/* Avoid scroll-jank from `background-attachment: fixed` by using a fixed layer. */
|
|
47
|
+
body::before {
|
|
48
|
+
content: '';
|
|
49
|
+
position: fixed;
|
|
50
|
+
inset: 0;
|
|
51
|
+
z-index: -1;
|
|
52
|
+
pointer-events: none;
|
|
53
|
+
|
|
54
|
+
/* atmospheric layered background — never a flat fill */
|
|
55
|
+
background:
|
|
56
|
+
radial-gradient(circle at top, rgba(198, 166, 112, 0.08), transparent 26%),
|
|
57
|
+
radial-gradient(circle at 20% 20%, rgba(121, 166, 163, 0.06), transparent 24%),
|
|
58
|
+
linear-gradient(180deg, #090b0d 0%, #08090b 35%, #050607 100%);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
body > div {
|
|
62
|
+
min-height: 100dvh;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
a {
|
|
66
|
+
color: inherit;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
button,
|
|
70
|
+
input,
|
|
71
|
+
select,
|
|
72
|
+
textarea {
|
|
73
|
+
font: inherit;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
img,
|
|
77
|
+
svg,
|
|
78
|
+
canvas {
|
|
79
|
+
display: block;
|
|
80
|
+
max-width: 100%;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
:focus-visible {
|
|
84
|
+
outline: none;
|
|
85
|
+
box-shadow: var(--focus-ring);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
::selection {
|
|
89
|
+
background-color: rgba(199, 156, 87, 0.28);
|
|
90
|
+
color: var(--text);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/* ── shared animations ──────────────────────────────────────────────── */
|
|
94
|
+
@keyframes pulse-dot {
|
|
95
|
+
0%,
|
|
96
|
+
100% {
|
|
97
|
+
opacity: 0.4;
|
|
98
|
+
transform: scale(1);
|
|
99
|
+
}
|
|
100
|
+
50% {
|
|
101
|
+
opacity: 1;
|
|
102
|
+
transform: scale(1.3);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
@keyframes shimmer {
|
|
107
|
+
0% {
|
|
108
|
+
background-position: -200% 0;
|
|
109
|
+
}
|
|
110
|
+
100% {
|
|
111
|
+
background-position: 200% 0;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
@@ -15,14 +15,14 @@ export function echo(node) {
|
|
|
15
15
|
const x = ((e.clientX - rect.left) / rect.width) * 100;
|
|
16
16
|
const y = ((e.clientY - rect.top) / rect.height) * 100;
|
|
17
17
|
const overlay = document.createElement('span');
|
|
18
|
-
overlay.style.cssText = `
|
|
19
|
-
position: absolute;
|
|
20
|
-
inset: 0;
|
|
21
|
-
border-radius: inherit;
|
|
22
|
-
pointer-events: none;
|
|
23
|
-
background: radial-gradient(circle at ${x}% ${y}%, rgba(199, 156, 87, 0.22), transparent 70%);
|
|
24
|
-
opacity: 0;
|
|
25
|
-
transition: opacity 0.15s ease-out;
|
|
18
|
+
overlay.style.cssText = `
|
|
19
|
+
position: absolute;
|
|
20
|
+
inset: 0;
|
|
21
|
+
border-radius: inherit;
|
|
22
|
+
pointer-events: none;
|
|
23
|
+
background: radial-gradient(circle at ${x}% ${y}%, rgba(199, 156, 87, 0.22), transparent 70%);
|
|
24
|
+
opacity: 0;
|
|
25
|
+
transition: opacity 0.15s ease-out;
|
|
26
26
|
`;
|
|
27
27
|
const position = getComputedStyle(node).position;
|
|
28
28
|
if (position === 'static')
|
|
@@ -41,6 +41,6 @@ export function echo(node) {
|
|
|
41
41
|
return {
|
|
42
42
|
destroy() {
|
|
43
43
|
node.removeEventListener('click', handleClick);
|
|
44
|
-
}
|
|
44
|
+
}
|
|
45
45
|
};
|
|
46
46
|
}
|
|
@@ -2,7 +2,7 @@ const statusColors = {
|
|
|
2
2
|
ok: 'var(--status-ok)',
|
|
3
3
|
warn: 'var(--status-warn)',
|
|
4
4
|
fail: 'var(--status-fail)',
|
|
5
|
-
pend: 'var(--status-pend)'
|
|
5
|
+
pend: 'var(--status-pend)'
|
|
6
6
|
};
|
|
7
7
|
/**
|
|
8
8
|
* Animates a status change on an element. A brief overlay flash in the
|
|
@@ -32,14 +32,14 @@ export function resolve(node, register) {
|
|
|
32
32
|
return;
|
|
33
33
|
}
|
|
34
34
|
const overlay = document.createElement('span');
|
|
35
|
-
overlay.style.cssText = `
|
|
36
|
-
position: absolute;
|
|
37
|
-
inset: 0;
|
|
38
|
-
pointer-events: none;
|
|
39
|
-
background: ${statusColors[status]};
|
|
40
|
-
opacity: 0;
|
|
41
|
-
border-radius: inherit;
|
|
42
|
-
transition: opacity 0.12s ease-out;
|
|
35
|
+
overlay.style.cssText = `
|
|
36
|
+
position: absolute;
|
|
37
|
+
inset: 0;
|
|
38
|
+
pointer-events: none;
|
|
39
|
+
background: ${statusColors[status]};
|
|
40
|
+
opacity: 0;
|
|
41
|
+
border-radius: inherit;
|
|
42
|
+
transition: opacity 0.12s ease-out;
|
|
43
43
|
`;
|
|
44
44
|
node.appendChild(overlay);
|
|
45
45
|
requestAnimationFrame(() => {
|
|
@@ -10,16 +10,28 @@ export function surface(node, options = {}) {
|
|
|
10
10
|
const prefersReduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
11
11
|
if (prefersReduced)
|
|
12
12
|
return {};
|
|
13
|
+
node.style.willChange = 'opacity, transform';
|
|
13
14
|
node.style.opacity = '0';
|
|
14
15
|
node.style.transform = 'translateY(6px)';
|
|
15
16
|
node.style.transition = `opacity 0.5s ease-out ${delay}ms, transform 0.5s ease-out ${delay}ms`;
|
|
17
|
+
function onEnd(e) {
|
|
18
|
+
if (e.propertyName !== 'transform')
|
|
19
|
+
return;
|
|
20
|
+
node.removeEventListener('transitionend', onEnd);
|
|
21
|
+
// Clear transforms to avoid creating containing blocks for fixed/floating UI.
|
|
22
|
+
node.style.transform = 'none';
|
|
23
|
+
node.style.transition = '';
|
|
24
|
+
node.style.willChange = '';
|
|
25
|
+
}
|
|
26
|
+
node.addEventListener('transitionend', onEnd);
|
|
16
27
|
const frame = requestAnimationFrame(() => {
|
|
17
28
|
node.style.opacity = '1';
|
|
18
29
|
node.style.transform = 'translateY(0)';
|
|
19
30
|
});
|
|
20
31
|
return {
|
|
21
32
|
destroy() {
|
|
33
|
+
node.removeEventListener('transitionend', onEnd);
|
|
22
34
|
cancelAnimationFrame(frame);
|
|
23
|
-
}
|
|
35
|
+
}
|
|
24
36
|
};
|
|
25
37
|
}
|