@vvedantb/ui 0.1.0 → 0.1.2
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/LICENSE +21 -21
- package/package.json +3 -2
- package/src/ai-elements/artifact.tsx +99 -99
- package/src/ai-elements/attachments.tsx +366 -366
- package/src/ai-elements/chain-of-thought.tsx +212 -212
- package/src/ai-elements/code-block.tsx +478 -478
- package/src/ai-elements/conversation.tsx +157 -157
- package/src/ai-elements/image.tsx +25 -25
- package/src/ai-elements/inline-citation.tsx +252 -252
- package/src/ai-elements/message.tsx +269 -269
- package/src/ai-elements/model-selector.tsx +211 -211
- package/src/ai-elements/prompt-input.tsx +1018 -1018
- package/src/ai-elements/queue.tsx +251 -251
- package/src/ai-elements/reasoning.tsx +178 -178
- package/src/ai-elements/shimmer.tsx +56 -56
- package/src/ai-elements/sources.tsx +77 -77
- package/src/ai-elements/speech-input.tsx +290 -290
- package/src/ai-elements/suggestion.tsx +191 -191
- package/src/css.d.ts +2 -2
- package/src/index.ts +96 -96
- package/src/motion/presets.ts +35 -35
- package/src/motion/presets.vibot.ts +105 -105
- package/src/ui/_menu-classes.ts +30 -30
- package/src/ui/_menu-classes.vibot.ts +33 -33
- package/src/ui/accordion.tsx +81 -81
- package/src/ui/accordion.verve.tsx +56 -56
- package/src/ui/badge.tsx +34 -34
- package/src/ui/breadcrumb.tsx +83 -83
- package/src/ui/button-group.tsx +84 -84
- package/src/ui/button.tsx +57 -57
- package/src/ui/card.tsx +27 -27
- package/src/ui/carousel.tsx +211 -211
- package/src/ui/checkbox.tsx +27 -27
- package/src/ui/clear-input.tsx +170 -170
- package/src/ui/clear-input.vibot.tsx +76 -76
- package/src/ui/clearInputDissolve.ts +214 -214
- package/src/ui/collapsible.tsx +7 -7
- package/src/ui/command.tsx +148 -148
- package/src/ui/context-menu.tsx +173 -173
- package/src/ui/dialog.tsx +149 -149
- package/src/ui/dropdown-menu.tsx +178 -178
- package/src/ui/hover-card.tsx +31 -31
- package/src/ui/input-group.tsx +162 -162
- package/src/ui/input-group.verve.tsx +150 -150
- package/src/ui/input.tsx +21 -21
- package/src/ui/kbd.tsx +18 -18
- package/src/ui/label.tsx +20 -20
- package/src/ui/labeled-switch-row.tsx +53 -53
- package/src/ui/modalTransition.ts +85 -85
- package/src/ui/pagination.tsx +47 -47
- package/src/ui/popover.tsx +33 -33
- package/src/ui/progress.tsx +25 -25
- package/src/ui/radix-select.tsx +202 -202
- package/src/ui/scroll-area.tsx +55 -55
- package/src/ui/scroll-area.verve.tsx +43 -43
- package/src/ui/search-input.tsx +29 -29
- package/src/ui/select.tsx +163 -163
- package/src/ui/separator.tsx +28 -28
- package/src/ui/sheet.tsx +87 -87
- package/src/ui/skeleton.tsx +18 -18
- package/src/ui/sonner.css +16 -16
- package/src/ui/sonner.tsx +47 -47
- package/src/ui/spinner.tsx +27 -27
- package/src/ui/surface-classes.ts +55 -55
- package/src/ui/switch.tsx +26 -26
- package/src/ui/table.tsx +123 -123
- package/src/ui/tabs.tsx +140 -140
- package/src/ui/tabsSliding.ts +56 -56
- package/src/ui/textarea.tsx +21 -21
- package/src/ui/time-picker.tsx +170 -170
- package/src/ui/tooltip.tsx +25 -25
- package/src/ui/visually-hidden.tsx +3 -3
- package/src/utils/cn.ts +16 -16
- package/src/utils/ref.ts +10 -10
|
@@ -1,214 +1,214 @@
|
|
|
1
|
-
/** transitions.dev input clear with dissolve — see 13-input-clear-dissolve.md */
|
|
2
|
-
|
|
3
|
-
function readCssNumber(
|
|
4
|
-
root: HTMLElement,
|
|
5
|
-
name: string,
|
|
6
|
-
fallback: number,
|
|
7
|
-
): number {
|
|
8
|
-
const raw = getComputedStyle(root).getPropertyValue(name);
|
|
9
|
-
const parsed = parseFloat(raw);
|
|
10
|
-
return Number.isFinite(parsed) ? parsed : fallback;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
function readCssEase(root: HTMLElement, name: string): (t: number) => number {
|
|
14
|
-
const raw = getComputedStyle(root).getPropertyValue(name);
|
|
15
|
-
const match = raw.match(
|
|
16
|
-
/cubic-bezier\(([-\d.]+),([-\d.]+),([-\d.]+),([-\d.]+)\)/,
|
|
17
|
-
);
|
|
18
|
-
if (!match) {
|
|
19
|
-
return (t) => t;
|
|
20
|
-
}
|
|
21
|
-
const x1 = parseFloat(match[1] ?? "0");
|
|
22
|
-
const y1 = parseFloat(match[2] ?? "0");
|
|
23
|
-
const x2 = parseFloat(match[3] ?? "0");
|
|
24
|
-
const y2 = parseFloat(match[4] ?? "0");
|
|
25
|
-
const cx = 3 * x1;
|
|
26
|
-
const bx = 3 * (x2 - x1) - cx;
|
|
27
|
-
const ax = 1 - cx - bx;
|
|
28
|
-
const cy = 3 * y1;
|
|
29
|
-
const by = 3 * (y2 - y1) - cy;
|
|
30
|
-
const ay = 1 - cy - by;
|
|
31
|
-
return (t) => {
|
|
32
|
-
if (t <= 0) {
|
|
33
|
-
return 0;
|
|
34
|
-
}
|
|
35
|
-
if (t >= 1) {
|
|
36
|
-
return 1;
|
|
37
|
-
}
|
|
38
|
-
let sample = t;
|
|
39
|
-
for (let i = 0; i < 8; i += 1) {
|
|
40
|
-
const dx = ((ax * sample + bx) * sample + cx) * sample - t;
|
|
41
|
-
const derivative = (3 * ax * sample + 2 * bx) * sample + cx;
|
|
42
|
-
if (Math.abs(dx) < 1e-6 || derivative === 0) {
|
|
43
|
-
break;
|
|
44
|
-
}
|
|
45
|
-
sample -= dx / derivative;
|
|
46
|
-
}
|
|
47
|
-
return ((ay * sample + by) * sample + cy) * sample;
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function isDarkTheme(root: HTMLElement): boolean {
|
|
52
|
-
return (
|
|
53
|
-
root.classList.contains("dark") ||
|
|
54
|
-
root.getAttribute("data-theme") === "dark"
|
|
55
|
-
);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function measureCanvas(): CanvasRenderingContext2D | null {
|
|
59
|
-
const canvas = document.createElement("canvas");
|
|
60
|
-
return canvas.getContext("2d");
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
let sharedMeasureCanvas: CanvasRenderingContext2D | null = null;
|
|
64
|
-
|
|
65
|
-
function getMeasureCanvas(): CanvasRenderingContext2D | null {
|
|
66
|
-
if (sharedMeasureCanvas === null) {
|
|
67
|
-
sharedMeasureCanvas = measureCanvas();
|
|
68
|
-
}
|
|
69
|
-
return sharedMeasureCanvas;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export interface ClearDissolveElements {
|
|
73
|
-
wrap: HTMLElement;
|
|
74
|
-
input: HTMLInputElement;
|
|
75
|
-
mirror: HTMLElement;
|
|
76
|
-
placeholderLayer: HTMLElement;
|
|
77
|
-
glow: HTMLElement;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
function buildGlowBackground(
|
|
81
|
-
wrap: HTMLElement,
|
|
82
|
-
input: HTMLInputElement,
|
|
83
|
-
text: string,
|
|
84
|
-
root: HTMLElement,
|
|
85
|
-
): string {
|
|
86
|
-
const canvas = getMeasureCanvas();
|
|
87
|
-
if (canvas === null) {
|
|
88
|
-
return "";
|
|
89
|
-
}
|
|
90
|
-
canvas.font = getComputedStyle(input).font;
|
|
91
|
-
const dark = isDarkTheme(root);
|
|
92
|
-
const rgb = dark ? "255,255,255" : "0,0,0";
|
|
93
|
-
const width = wrap.clientWidth || 280;
|
|
94
|
-
const padLeft = parseFloat(getComputedStyle(input).paddingLeft) || 12;
|
|
95
|
-
const spread = readCssNumber(root, "--glow-spread", 1.5);
|
|
96
|
-
const layers: string[] = [];
|
|
97
|
-
let x = 0;
|
|
98
|
-
for (const segment of text.split(/(\s+)/)) {
|
|
99
|
-
const segmentWidth = canvas.measureText(segment).width;
|
|
100
|
-
if (segment.trim()) {
|
|
101
|
-
const centerX = padLeft + x + segmentWidth / 2;
|
|
102
|
-
const halfWidth = Math.max(segmentWidth * 0.45, 8) * spread;
|
|
103
|
-
const streaks: Array<[number, number, number, number]> = [
|
|
104
|
-
[0, 0.8, 7, 0.22],
|
|
105
|
-
[halfWidth * 0.45, 0.55, 8, 0.18],
|
|
106
|
-
[-halfWidth * 0.4, 0.65, 6, 0.16],
|
|
107
|
-
[halfWidth * 0.15, 0.9, 5, 0.14],
|
|
108
|
-
];
|
|
109
|
-
for (const [dx, rwm, rh, alpha] of streaks) {
|
|
110
|
-
const leftPercent = (((centerX + dx) / width) * 100).toFixed(2);
|
|
111
|
-
layers.push(
|
|
112
|
-
`radial-gradient(ellipse ${Math.max(halfWidth * rwm, 2).toFixed(1)}px ${rh}px at ${leftPercent}% 100%, rgba(${rgb},${alpha}), transparent)`,
|
|
113
|
-
);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
x += segmentWidth;
|
|
117
|
-
}
|
|
118
|
-
return layers.join(", ");
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function resetLayerStyles(
|
|
122
|
-
mirror: HTMLElement,
|
|
123
|
-
placeholderLayer: HTMLElement,
|
|
124
|
-
): void {
|
|
125
|
-
mirror.style.cssText = "";
|
|
126
|
-
placeholderLayer.style.cssText = "";
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
export function runClearInputDissolve(
|
|
130
|
-
elements: ClearDissolveElements,
|
|
131
|
-
onValueClear: () => void,
|
|
132
|
-
onDone: () => void,
|
|
133
|
-
): void {
|
|
134
|
-
const { wrap, input, mirror, placeholderLayer, glow } = elements;
|
|
135
|
-
const root = document.documentElement;
|
|
136
|
-
const text = input.value;
|
|
137
|
-
if (text.length === 0) {
|
|
138
|
-
return;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
const keepFocus = document.activeElement === input;
|
|
142
|
-
mirror.textContent = text.replace(/ /g, "\u00a0");
|
|
143
|
-
|
|
144
|
-
const total = readCssNumber(root, "--clear-dur", 1000);
|
|
145
|
-
const outDur = readCssNumber(root, "--clear-out-dur", 400);
|
|
146
|
-
const inDur = readCssNumber(root, "--clear-in-dur", 400);
|
|
147
|
-
const outFly = readCssNumber(root, "--clear-out-fly", 12);
|
|
148
|
-
const inFly = readCssNumber(root, "--clear-in-fly", 12);
|
|
149
|
-
const delay = readCssNumber(root, "--glow-delay", 50);
|
|
150
|
-
const peakAt = readCssNumber(root, "--glow-peak-at", 0.15);
|
|
151
|
-
const glowOpacity = readCssNumber(root, "--glow-opacity", 0.85);
|
|
152
|
-
const easeOut = readCssEase(root, "--clear-out-ease");
|
|
153
|
-
const easeIn = readCssEase(root, "--clear-in-ease");
|
|
154
|
-
|
|
155
|
-
onValueClear();
|
|
156
|
-
wrap.classList.remove("has-value");
|
|
157
|
-
wrap.classList.add("is-clearing");
|
|
158
|
-
glow.style.background = buildGlowBackground(
|
|
159
|
-
wrap,
|
|
160
|
-
input,
|
|
161
|
-
mirror.textContent,
|
|
162
|
-
root,
|
|
163
|
-
);
|
|
164
|
-
glow.style.opacity = "0";
|
|
165
|
-
placeholderLayer.style.transform = `translateY(-${inFly}px)`;
|
|
166
|
-
placeholderLayer.style.opacity = "0.9";
|
|
167
|
-
placeholderLayer.style.filter = "none";
|
|
168
|
-
mirror.style.filter = "none";
|
|
169
|
-
|
|
170
|
-
const startedAt = performance.now();
|
|
171
|
-
|
|
172
|
-
function tick(now: number): void {
|
|
173
|
-
const elapsed = now - startedAt;
|
|
174
|
-
const outProgress = easeOut(Math.min(1, elapsed / outDur));
|
|
175
|
-
mirror.style.transform = `translateY(${(outProgress * outFly).toFixed(1)}px)`;
|
|
176
|
-
mirror.style.opacity = (1 - outProgress).toFixed(3);
|
|
177
|
-
|
|
178
|
-
const inProgress = easeIn(Math.min(1, elapsed / inDur));
|
|
179
|
-
placeholderLayer.style.transform = `translateY(${(-inFly + inProgress * inFly).toFixed(1)}px)`;
|
|
180
|
-
placeholderLayer.style.opacity = (0.9 + inProgress * 0.1).toFixed(3);
|
|
181
|
-
|
|
182
|
-
let glowStrength = 0;
|
|
183
|
-
if (elapsed > delay) {
|
|
184
|
-
const glowProgress = Math.min(
|
|
185
|
-
1,
|
|
186
|
-
(elapsed - delay) / Math.max(1, total - delay),
|
|
187
|
-
);
|
|
188
|
-
glowStrength =
|
|
189
|
-
glowProgress < peakAt
|
|
190
|
-
? glowProgress / peakAt
|
|
191
|
-
: 1 - (glowProgress - peakAt) / (1 - peakAt);
|
|
192
|
-
}
|
|
193
|
-
glow.style.opacity = (glowStrength * glowOpacity).toFixed(3);
|
|
194
|
-
|
|
195
|
-
if (elapsed < total) {
|
|
196
|
-
requestAnimationFrame(tick);
|
|
197
|
-
return;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
wrap.classList.remove("is-clearing");
|
|
201
|
-
resetLayerStyles(mirror, placeholderLayer);
|
|
202
|
-
mirror.textContent = "";
|
|
203
|
-
glow.style.opacity = "0";
|
|
204
|
-
glow.style.background = "";
|
|
205
|
-
onDone();
|
|
206
|
-
if (keepFocus) {
|
|
207
|
-
requestAnimationFrame(() => {
|
|
208
|
-
input.focus({ preventScroll: true });
|
|
209
|
-
});
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
requestAnimationFrame(tick);
|
|
214
|
-
}
|
|
1
|
+
/** transitions.dev input clear with dissolve — see 13-input-clear-dissolve.md */
|
|
2
|
+
|
|
3
|
+
function readCssNumber(
|
|
4
|
+
root: HTMLElement,
|
|
5
|
+
name: string,
|
|
6
|
+
fallback: number,
|
|
7
|
+
): number {
|
|
8
|
+
const raw = getComputedStyle(root).getPropertyValue(name);
|
|
9
|
+
const parsed = parseFloat(raw);
|
|
10
|
+
return Number.isFinite(parsed) ? parsed : fallback;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function readCssEase(root: HTMLElement, name: string): (t: number) => number {
|
|
14
|
+
const raw = getComputedStyle(root).getPropertyValue(name);
|
|
15
|
+
const match = raw.match(
|
|
16
|
+
/cubic-bezier\(([-\d.]+),([-\d.]+),([-\d.]+),([-\d.]+)\)/,
|
|
17
|
+
);
|
|
18
|
+
if (!match) {
|
|
19
|
+
return (t) => t;
|
|
20
|
+
}
|
|
21
|
+
const x1 = parseFloat(match[1] ?? "0");
|
|
22
|
+
const y1 = parseFloat(match[2] ?? "0");
|
|
23
|
+
const x2 = parseFloat(match[3] ?? "0");
|
|
24
|
+
const y2 = parseFloat(match[4] ?? "0");
|
|
25
|
+
const cx = 3 * x1;
|
|
26
|
+
const bx = 3 * (x2 - x1) - cx;
|
|
27
|
+
const ax = 1 - cx - bx;
|
|
28
|
+
const cy = 3 * y1;
|
|
29
|
+
const by = 3 * (y2 - y1) - cy;
|
|
30
|
+
const ay = 1 - cy - by;
|
|
31
|
+
return (t) => {
|
|
32
|
+
if (t <= 0) {
|
|
33
|
+
return 0;
|
|
34
|
+
}
|
|
35
|
+
if (t >= 1) {
|
|
36
|
+
return 1;
|
|
37
|
+
}
|
|
38
|
+
let sample = t;
|
|
39
|
+
for (let i = 0; i < 8; i += 1) {
|
|
40
|
+
const dx = ((ax * sample + bx) * sample + cx) * sample - t;
|
|
41
|
+
const derivative = (3 * ax * sample + 2 * bx) * sample + cx;
|
|
42
|
+
if (Math.abs(dx) < 1e-6 || derivative === 0) {
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
sample -= dx / derivative;
|
|
46
|
+
}
|
|
47
|
+
return ((ay * sample + by) * sample + cy) * sample;
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function isDarkTheme(root: HTMLElement): boolean {
|
|
52
|
+
return (
|
|
53
|
+
root.classList.contains("dark") ||
|
|
54
|
+
root.getAttribute("data-theme") === "dark"
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function measureCanvas(): CanvasRenderingContext2D | null {
|
|
59
|
+
const canvas = document.createElement("canvas");
|
|
60
|
+
return canvas.getContext("2d");
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
let sharedMeasureCanvas: CanvasRenderingContext2D | null = null;
|
|
64
|
+
|
|
65
|
+
function getMeasureCanvas(): CanvasRenderingContext2D | null {
|
|
66
|
+
if (sharedMeasureCanvas === null) {
|
|
67
|
+
sharedMeasureCanvas = measureCanvas();
|
|
68
|
+
}
|
|
69
|
+
return sharedMeasureCanvas;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export interface ClearDissolveElements {
|
|
73
|
+
wrap: HTMLElement;
|
|
74
|
+
input: HTMLInputElement;
|
|
75
|
+
mirror: HTMLElement;
|
|
76
|
+
placeholderLayer: HTMLElement;
|
|
77
|
+
glow: HTMLElement;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function buildGlowBackground(
|
|
81
|
+
wrap: HTMLElement,
|
|
82
|
+
input: HTMLInputElement,
|
|
83
|
+
text: string,
|
|
84
|
+
root: HTMLElement,
|
|
85
|
+
): string {
|
|
86
|
+
const canvas = getMeasureCanvas();
|
|
87
|
+
if (canvas === null) {
|
|
88
|
+
return "";
|
|
89
|
+
}
|
|
90
|
+
canvas.font = getComputedStyle(input).font;
|
|
91
|
+
const dark = isDarkTheme(root);
|
|
92
|
+
const rgb = dark ? "255,255,255" : "0,0,0";
|
|
93
|
+
const width = wrap.clientWidth || 280;
|
|
94
|
+
const padLeft = parseFloat(getComputedStyle(input).paddingLeft) || 12;
|
|
95
|
+
const spread = readCssNumber(root, "--glow-spread", 1.5);
|
|
96
|
+
const layers: string[] = [];
|
|
97
|
+
let x = 0;
|
|
98
|
+
for (const segment of text.split(/(\s+)/)) {
|
|
99
|
+
const segmentWidth = canvas.measureText(segment).width;
|
|
100
|
+
if (segment.trim()) {
|
|
101
|
+
const centerX = padLeft + x + segmentWidth / 2;
|
|
102
|
+
const halfWidth = Math.max(segmentWidth * 0.45, 8) * spread;
|
|
103
|
+
const streaks: Array<[number, number, number, number]> = [
|
|
104
|
+
[0, 0.8, 7, 0.22],
|
|
105
|
+
[halfWidth * 0.45, 0.55, 8, 0.18],
|
|
106
|
+
[-halfWidth * 0.4, 0.65, 6, 0.16],
|
|
107
|
+
[halfWidth * 0.15, 0.9, 5, 0.14],
|
|
108
|
+
];
|
|
109
|
+
for (const [dx, rwm, rh, alpha] of streaks) {
|
|
110
|
+
const leftPercent = (((centerX + dx) / width) * 100).toFixed(2);
|
|
111
|
+
layers.push(
|
|
112
|
+
`radial-gradient(ellipse ${Math.max(halfWidth * rwm, 2).toFixed(1)}px ${rh}px at ${leftPercent}% 100%, rgba(${rgb},${alpha}), transparent)`,
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
x += segmentWidth;
|
|
117
|
+
}
|
|
118
|
+
return layers.join(", ");
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function resetLayerStyles(
|
|
122
|
+
mirror: HTMLElement,
|
|
123
|
+
placeholderLayer: HTMLElement,
|
|
124
|
+
): void {
|
|
125
|
+
mirror.style.cssText = "";
|
|
126
|
+
placeholderLayer.style.cssText = "";
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export function runClearInputDissolve(
|
|
130
|
+
elements: ClearDissolveElements,
|
|
131
|
+
onValueClear: () => void,
|
|
132
|
+
onDone: () => void,
|
|
133
|
+
): void {
|
|
134
|
+
const { wrap, input, mirror, placeholderLayer, glow } = elements;
|
|
135
|
+
const root = document.documentElement;
|
|
136
|
+
const text = input.value;
|
|
137
|
+
if (text.length === 0) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const keepFocus = document.activeElement === input;
|
|
142
|
+
mirror.textContent = text.replace(/ /g, "\u00a0");
|
|
143
|
+
|
|
144
|
+
const total = readCssNumber(root, "--clear-dur", 1000);
|
|
145
|
+
const outDur = readCssNumber(root, "--clear-out-dur", 400);
|
|
146
|
+
const inDur = readCssNumber(root, "--clear-in-dur", 400);
|
|
147
|
+
const outFly = readCssNumber(root, "--clear-out-fly", 12);
|
|
148
|
+
const inFly = readCssNumber(root, "--clear-in-fly", 12);
|
|
149
|
+
const delay = readCssNumber(root, "--glow-delay", 50);
|
|
150
|
+
const peakAt = readCssNumber(root, "--glow-peak-at", 0.15);
|
|
151
|
+
const glowOpacity = readCssNumber(root, "--glow-opacity", 0.85);
|
|
152
|
+
const easeOut = readCssEase(root, "--clear-out-ease");
|
|
153
|
+
const easeIn = readCssEase(root, "--clear-in-ease");
|
|
154
|
+
|
|
155
|
+
onValueClear();
|
|
156
|
+
wrap.classList.remove("has-value");
|
|
157
|
+
wrap.classList.add("is-clearing");
|
|
158
|
+
glow.style.background = buildGlowBackground(
|
|
159
|
+
wrap,
|
|
160
|
+
input,
|
|
161
|
+
mirror.textContent,
|
|
162
|
+
root,
|
|
163
|
+
);
|
|
164
|
+
glow.style.opacity = "0";
|
|
165
|
+
placeholderLayer.style.transform = `translateY(-${inFly}px)`;
|
|
166
|
+
placeholderLayer.style.opacity = "0.9";
|
|
167
|
+
placeholderLayer.style.filter = "none";
|
|
168
|
+
mirror.style.filter = "none";
|
|
169
|
+
|
|
170
|
+
const startedAt = performance.now();
|
|
171
|
+
|
|
172
|
+
function tick(now: number): void {
|
|
173
|
+
const elapsed = now - startedAt;
|
|
174
|
+
const outProgress = easeOut(Math.min(1, elapsed / outDur));
|
|
175
|
+
mirror.style.transform = `translateY(${(outProgress * outFly).toFixed(1)}px)`;
|
|
176
|
+
mirror.style.opacity = (1 - outProgress).toFixed(3);
|
|
177
|
+
|
|
178
|
+
const inProgress = easeIn(Math.min(1, elapsed / inDur));
|
|
179
|
+
placeholderLayer.style.transform = `translateY(${(-inFly + inProgress * inFly).toFixed(1)}px)`;
|
|
180
|
+
placeholderLayer.style.opacity = (0.9 + inProgress * 0.1).toFixed(3);
|
|
181
|
+
|
|
182
|
+
let glowStrength = 0;
|
|
183
|
+
if (elapsed > delay) {
|
|
184
|
+
const glowProgress = Math.min(
|
|
185
|
+
1,
|
|
186
|
+
(elapsed - delay) / Math.max(1, total - delay),
|
|
187
|
+
);
|
|
188
|
+
glowStrength =
|
|
189
|
+
glowProgress < peakAt
|
|
190
|
+
? glowProgress / peakAt
|
|
191
|
+
: 1 - (glowProgress - peakAt) / (1 - peakAt);
|
|
192
|
+
}
|
|
193
|
+
glow.style.opacity = (glowStrength * glowOpacity).toFixed(3);
|
|
194
|
+
|
|
195
|
+
if (elapsed < total) {
|
|
196
|
+
requestAnimationFrame(tick);
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
wrap.classList.remove("is-clearing");
|
|
201
|
+
resetLayerStyles(mirror, placeholderLayer);
|
|
202
|
+
mirror.textContent = "";
|
|
203
|
+
glow.style.opacity = "0";
|
|
204
|
+
glow.style.background = "";
|
|
205
|
+
onDone();
|
|
206
|
+
if (keepFocus) {
|
|
207
|
+
requestAnimationFrame(() => {
|
|
208
|
+
input.focus({ preventScroll: true });
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
requestAnimationFrame(tick);
|
|
214
|
+
}
|
package/src/ui/collapsible.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import * as CollapsiblePrimitive from "@radix-ui/react-collapsible";
|
|
2
|
-
|
|
3
|
-
const Collapsible = CollapsiblePrimitive.Root;
|
|
4
|
-
const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger;
|
|
5
|
-
const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent;
|
|
6
|
-
|
|
7
|
-
export { Collapsible, CollapsibleTrigger, CollapsibleContent };
|
|
1
|
+
import * as CollapsiblePrimitive from "@radix-ui/react-collapsible";
|
|
2
|
+
|
|
3
|
+
const Collapsible = CollapsiblePrimitive.Root;
|
|
4
|
+
const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger;
|
|
5
|
+
const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent;
|
|
6
|
+
|
|
7
|
+
export { Collapsible, CollapsibleTrigger, CollapsibleContent };
|