hyperframes 0.8.82 → 0.8.83
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/dist/backgroundChecksWorker.js +1 -1
- package/dist/cli.js +1921 -1560
- package/dist/fontLocalizeCli.js +304 -217
- package/dist/hyperframe-runtime.js +81 -56
- package/dist/hyperframe.manifest.json +1 -1
- package/dist/hyperframe.runtime.iife.js +81 -56
- package/dist/hyperframes-player.global.js +1 -1
- package/dist/studio/assets/{hyperframes-player-zGIbZhLJ.js → hyperframes-player-BAerMCex.js} +1 -1
- package/dist/studio/assets/{index-BiLCTunu.js → index-BUhcVhNy.js} +1 -1
- package/dist/studio/assets/{index-DSazIt7R.js → index-BYhK_KMc.js} +193 -193
- package/dist/studio/assets/{index-DStmfnpZ.js → index-Iv0HI7eM.js} +1 -1
- package/dist/studio/{chunk-I7XNAIOF.js → chunk-3IOCVWB6.js} +6 -97
- package/dist/studio/chunk-3IOCVWB6.js.map +1 -0
- package/dist/studio/chunk-62DDWOSH.js +189 -0
- package/dist/studio/chunk-62DDWOSH.js.map +1 -0
- package/dist/studio/chunk-LPZMAGS7.js +1871 -0
- package/dist/studio/chunk-LPZMAGS7.js.map +1 -0
- package/dist/studio/chunk-QZ6HNNFG.js +934 -0
- package/dist/studio/chunk-QZ6HNNFG.js.map +1 -0
- package/dist/studio/chunk-S65AQH6M.js +101 -0
- package/dist/studio/chunk-S65AQH6M.js.map +1 -0
- package/dist/studio/{domEditingLayers-MHFDKAQ7.js → domEditingLayers-ZOOMN7CQ.js} +3 -2
- package/dist/studio/index.d.ts +669 -330
- package/dist/studio/index.html +1 -1
- package/dist/studio/index.js +20501 -23167
- package/dist/studio/index.js.map +1 -1
- package/dist/studio/player.d.ts +30 -0
- package/dist/studio/player.js +10 -0
- package/dist/studio/player.js.map +1 -0
- package/dist/studio/ui.d.ts +294 -0
- package/dist/studio/ui.js +66 -0
- package/dist/studio/ui.js.map +1 -0
- package/package.json +1 -1
- package/dist/studio/chunk-I7XNAIOF.js.map +0 -1
- /package/dist/studio/{domEditingLayers-MHFDKAQ7.js.map → domEditingLayers-ZOOMN7CQ.js.map} +0 -0
|
@@ -0,0 +1,934 @@
|
|
|
1
|
+
// src/components/ui/cn.ts
|
|
2
|
+
import { createCn } from "cn/config";
|
|
3
|
+
var isTypeStep = (value) => /^step-\d+$/.test(value);
|
|
4
|
+
var isControlSize = (value) => /^ctl(-sm|-lg)?$/.test(value);
|
|
5
|
+
var cn = createCn({
|
|
6
|
+
extend: {
|
|
7
|
+
classGroups: {
|
|
8
|
+
"font-size": [{ text: [isTypeStep] }],
|
|
9
|
+
h: [{ h: [isControlSize] }],
|
|
10
|
+
w: [{ w: [isControlSize] }],
|
|
11
|
+
size: [{ size: [isControlSize] }],
|
|
12
|
+
"min-h": [{ "min-h": [isControlSize] }],
|
|
13
|
+
"min-w": [{ "min-w": [isControlSize] }]
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
// src/components/ui/Button.tsx
|
|
19
|
+
import { forwardRef } from "react";
|
|
20
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
21
|
+
var buttonBase = cn(
|
|
22
|
+
"inline-flex items-center justify-center select-none cursor-pointer whitespace-nowrap",
|
|
23
|
+
"transition-[background-color,border-color,color,filter,transform] ease-out-quint duration-press",
|
|
24
|
+
"disabled:opacity-40 disabled:cursor-not-allowed",
|
|
25
|
+
"outline-hidden",
|
|
26
|
+
"focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-accent",
|
|
27
|
+
"data-[preview-state=focus]:outline-solid data-[preview-state=focus]:outline-2 data-[preview-state=focus]:outline-offset-1 data-[preview-state=focus]:outline-accent"
|
|
28
|
+
);
|
|
29
|
+
var buttonVariants = {
|
|
30
|
+
primary: cn(
|
|
31
|
+
"bg-accent text-bg-0 font-semibold",
|
|
32
|
+
"enabled:hover:brightness-110 data-[preview-state=hover]:brightness-110",
|
|
33
|
+
"enabled:active:scale-[0.98] data-[preview-state=active]:scale-[0.98]"
|
|
34
|
+
),
|
|
35
|
+
secondary: cn(
|
|
36
|
+
"bg-transparent text-text-1 font-medium border border-border-strong",
|
|
37
|
+
"enabled:hover:bg-hover enabled:hover:text-text-0 data-[preview-state=hover]:bg-hover data-[preview-state=hover]:text-text-0",
|
|
38
|
+
"enabled:active:scale-[0.98] data-[preview-state=active]:scale-[0.98]"
|
|
39
|
+
),
|
|
40
|
+
danger: cn(
|
|
41
|
+
"bg-danger text-text-0 font-medium",
|
|
42
|
+
"enabled:hover:brightness-110 data-[preview-state=hover]:brightness-110",
|
|
43
|
+
"enabled:active:scale-[0.98] data-[preview-state=active]:scale-[0.98]"
|
|
44
|
+
),
|
|
45
|
+
ghost: cn(
|
|
46
|
+
"bg-transparent text-text-2 font-medium",
|
|
47
|
+
"enabled:hover:bg-hover enabled:hover:text-text-0 data-[preview-state=hover]:bg-hover data-[preview-state=hover]:text-text-0",
|
|
48
|
+
"enabled:active:scale-[0.98] data-[preview-state=active]:scale-[0.98]"
|
|
49
|
+
)
|
|
50
|
+
};
|
|
51
|
+
var buttonSizes = {
|
|
52
|
+
sm: "h-ctl-sm px-2 gap-1 rounded-sm text-step-11",
|
|
53
|
+
md: "h-ctl px-3 gap-1.5 rounded-md text-step-12",
|
|
54
|
+
lg: "h-ctl-lg px-4 gap-2 rounded-md text-step-13"
|
|
55
|
+
};
|
|
56
|
+
function Spinner() {
|
|
57
|
+
return /* @__PURE__ */ jsxs("svg", { className: "animate-spin size-3.5", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: [
|
|
58
|
+
/* @__PURE__ */ jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
|
|
59
|
+
/* @__PURE__ */ jsx(
|
|
60
|
+
"path",
|
|
61
|
+
{
|
|
62
|
+
className: "opacity-75",
|
|
63
|
+
fill: "currentColor",
|
|
64
|
+
d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
|
|
65
|
+
}
|
|
66
|
+
)
|
|
67
|
+
] });
|
|
68
|
+
}
|
|
69
|
+
var Button = forwardRef(
|
|
70
|
+
({ variant = "secondary", size = "md", loading, icon, children, className, disabled, ...props }, ref) => {
|
|
71
|
+
const isDisabled = disabled || loading;
|
|
72
|
+
let leading = null;
|
|
73
|
+
if (loading) leading = /* @__PURE__ */ jsx(Spinner, {});
|
|
74
|
+
else if (icon) leading = /* @__PURE__ */ jsx("span", { className: "shrink-0", children: icon });
|
|
75
|
+
return /* @__PURE__ */ jsxs(
|
|
76
|
+
"button",
|
|
77
|
+
{
|
|
78
|
+
ref,
|
|
79
|
+
disabled: isDisabled,
|
|
80
|
+
"aria-disabled": isDisabled || void 0,
|
|
81
|
+
className: cn(buttonBase, buttonVariants[variant], buttonSizes[size], className),
|
|
82
|
+
...props,
|
|
83
|
+
children: [
|
|
84
|
+
leading,
|
|
85
|
+
children
|
|
86
|
+
]
|
|
87
|
+
}
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
);
|
|
91
|
+
Button.displayName = "Button";
|
|
92
|
+
|
|
93
|
+
// src/components/ui/IconButton.tsx
|
|
94
|
+
import { forwardRef as forwardRef2 } from "react";
|
|
95
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
96
|
+
var iconSizeStyles = {
|
|
97
|
+
sm: "size-ctl-sm rounded-sm",
|
|
98
|
+
md: "size-ctl rounded-md",
|
|
99
|
+
lg: "size-ctl-lg rounded-md"
|
|
100
|
+
};
|
|
101
|
+
var IconButton = forwardRef2(
|
|
102
|
+
({ icon, size = "md", variant = "ghost", className, disabled, ...props }, ref) => {
|
|
103
|
+
return /* @__PURE__ */ jsx2(
|
|
104
|
+
"button",
|
|
105
|
+
{
|
|
106
|
+
ref,
|
|
107
|
+
disabled,
|
|
108
|
+
"aria-disabled": disabled || void 0,
|
|
109
|
+
className: cn(buttonBase, buttonVariants[variant], iconSizeStyles[size], className),
|
|
110
|
+
...props,
|
|
111
|
+
children: icon
|
|
112
|
+
}
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
);
|
|
116
|
+
IconButton.displayName = "IconButton";
|
|
117
|
+
|
|
118
|
+
// src/components/ui/Tabs.tsx
|
|
119
|
+
import { Tabs as BaseTabs } from "@base-ui/react/tabs";
|
|
120
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
121
|
+
function Tabs(props) {
|
|
122
|
+
return /* @__PURE__ */ jsx3(BaseTabs.Root, { ...props });
|
|
123
|
+
}
|
|
124
|
+
function TabsList({ className, ...props }) {
|
|
125
|
+
return /* @__PURE__ */ jsx3(
|
|
126
|
+
BaseTabs.List,
|
|
127
|
+
{
|
|
128
|
+
activateOnFocus: true,
|
|
129
|
+
className: cn("inline-flex items-center gap-0.5 rounded-lg bg-surface-alt p-1", className),
|
|
130
|
+
...props
|
|
131
|
+
}
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
function Tab({ value, className, ...props }) {
|
|
135
|
+
return /* @__PURE__ */ jsx3(
|
|
136
|
+
BaseTabs.Tab,
|
|
137
|
+
{
|
|
138
|
+
value,
|
|
139
|
+
"data-tab-id": value,
|
|
140
|
+
className: cn(
|
|
141
|
+
"inline-flex h-ctl-sm cursor-pointer select-none items-center justify-center rounded-sm px-2.5",
|
|
142
|
+
"text-step-11 font-semibold whitespace-nowrap text-text-3",
|
|
143
|
+
"transition-[background-color,color] ease-out-quint duration-hover",
|
|
144
|
+
"hover:text-text-1 data-[preview-state=hover]:text-text-1",
|
|
145
|
+
"aria-selected:bg-hover aria-selected:text-text-0",
|
|
146
|
+
"outline-hidden focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-accent",
|
|
147
|
+
"data-[preview-state=focus]:outline-solid data-[preview-state=focus]:outline-2 data-[preview-state=focus]:outline-offset-1 data-[preview-state=focus]:outline-accent",
|
|
148
|
+
className
|
|
149
|
+
),
|
|
150
|
+
...props
|
|
151
|
+
}
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
function TabPanel({ className, ...props }) {
|
|
155
|
+
return /* @__PURE__ */ jsx3(BaseTabs.Panel, { className: cn("outline-hidden", className), ...props });
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// src/components/ui/HyperframesMark.tsx
|
|
159
|
+
import { useId } from "react";
|
|
160
|
+
import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
161
|
+
function HyperframesMark({ viewBox = "0 0 100 100", ...props }) {
|
|
162
|
+
const gradientId = useId();
|
|
163
|
+
const leftGradient = `${gradientId}-left`;
|
|
164
|
+
const rightGradient = `${gradientId}-right`;
|
|
165
|
+
return /* @__PURE__ */ jsxs2(
|
|
166
|
+
"svg",
|
|
167
|
+
{
|
|
168
|
+
viewBox,
|
|
169
|
+
fill: "none",
|
|
170
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
171
|
+
"aria-hidden": "true",
|
|
172
|
+
...props,
|
|
173
|
+
children: [
|
|
174
|
+
/* @__PURE__ */ jsx4("g", { transform: "translate(50 50)", opacity: ".92", children: /* @__PURE__ */ jsxs2("g", { transform: "translate(-50 -50)", children: [
|
|
175
|
+
/* @__PURE__ */ jsx4(
|
|
176
|
+
"path",
|
|
177
|
+
{
|
|
178
|
+
d: "M10.1851 57.8021L33.1145 73.8313C36.2202 75.9978 41.5173 73.5433 42.4816 69.4984L51.7611 30.4271C52.7253 26.3822 48.5802 23.9277 44.4602 26.0942L13.917 42.1235C6.96677 45.7676 4.97564 54.1579 10.1851 57.8021Z",
|
|
179
|
+
fill: `url(#${leftGradient})`
|
|
180
|
+
}
|
|
181
|
+
),
|
|
182
|
+
/* @__PURE__ */ jsx4(
|
|
183
|
+
"path",
|
|
184
|
+
{
|
|
185
|
+
d: "M87.5129 57.5141L56.9696 73.5433C52.8371 75.7098 48.7046 73.2553 49.6688 69.2104L58.9483 30.1391C59.9125 26.0942 65.2097 23.6397 68.3154 25.8062L91.2447 41.8354C96.4668 45.4796 94.4631 53.8699 87.5129 57.5141Z",
|
|
186
|
+
fill: `url(#${rightGradient})`
|
|
187
|
+
}
|
|
188
|
+
)
|
|
189
|
+
] }) }),
|
|
190
|
+
/* @__PURE__ */ jsxs2("defs", { children: [
|
|
191
|
+
/* @__PURE__ */ jsxs2(
|
|
192
|
+
"linearGradient",
|
|
193
|
+
{
|
|
194
|
+
id: leftGradient,
|
|
195
|
+
x1: "48.5676",
|
|
196
|
+
y1: "25",
|
|
197
|
+
x2: "44.7804",
|
|
198
|
+
y2: "71.9384",
|
|
199
|
+
gradientUnits: "userSpaceOnUse",
|
|
200
|
+
children: [
|
|
201
|
+
/* @__PURE__ */ jsx4("stop", { stopColor: "#06E3FA" }),
|
|
202
|
+
/* @__PURE__ */ jsx4("stop", { offset: "1", stopColor: "#4FDB5E" })
|
|
203
|
+
]
|
|
204
|
+
}
|
|
205
|
+
),
|
|
206
|
+
/* @__PURE__ */ jsxs2(
|
|
207
|
+
"linearGradient",
|
|
208
|
+
{
|
|
209
|
+
id: rightGradient,
|
|
210
|
+
x1: "54.8282",
|
|
211
|
+
y1: "73.8392",
|
|
212
|
+
x2: "72.0989",
|
|
213
|
+
y2: "32.8932",
|
|
214
|
+
gradientUnits: "userSpaceOnUse",
|
|
215
|
+
children: [
|
|
216
|
+
/* @__PURE__ */ jsx4("stop", { stopColor: "#06E3FA" }),
|
|
217
|
+
/* @__PURE__ */ jsx4("stop", { offset: "1", stopColor: "#4FDB5E" })
|
|
218
|
+
]
|
|
219
|
+
}
|
|
220
|
+
)
|
|
221
|
+
] })
|
|
222
|
+
]
|
|
223
|
+
}
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// src/components/ui/HyperframesLoader.tsx
|
|
228
|
+
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
229
|
+
function HyperframesLoader({
|
|
230
|
+
title,
|
|
231
|
+
detail,
|
|
232
|
+
mono,
|
|
233
|
+
size = 64,
|
|
234
|
+
progress
|
|
235
|
+
}) {
|
|
236
|
+
const boundedProgress = typeof progress === "number" && Number.isFinite(progress) ? Math.min(1, Math.max(0, progress)) : void 0;
|
|
237
|
+
const markFrameSize = Math.round(size * 1.16);
|
|
238
|
+
return /* @__PURE__ */ jsxs3("div", { className: "hf-loader", role: "status", draggable: false, children: [
|
|
239
|
+
/* @__PURE__ */ jsx5(
|
|
240
|
+
"div",
|
|
241
|
+
{
|
|
242
|
+
className: "hf-loader-mark-frame",
|
|
243
|
+
style: { width: markFrameSize, height: markFrameSize },
|
|
244
|
+
draggable: false,
|
|
245
|
+
children: /* @__PURE__ */ jsx5(HyperframesMark, { className: "hf-loader-mark", width: size, height: size })
|
|
246
|
+
}
|
|
247
|
+
),
|
|
248
|
+
/* @__PURE__ */ jsx5("div", { className: "hf-loader-title", children: title }),
|
|
249
|
+
detail && /* @__PURE__ */ jsx5("div", { className: "hf-loader-detail", children: detail }),
|
|
250
|
+
boundedProgress !== void 0 && /* @__PURE__ */ jsx5(
|
|
251
|
+
"div",
|
|
252
|
+
{
|
|
253
|
+
className: "hf-loader-progress",
|
|
254
|
+
role: "progressbar",
|
|
255
|
+
"aria-valuemin": 0,
|
|
256
|
+
"aria-valuemax": 100,
|
|
257
|
+
"aria-valuenow": Math.round(boundedProgress * 100),
|
|
258
|
+
children: /* @__PURE__ */ jsx5(
|
|
259
|
+
"div",
|
|
260
|
+
{
|
|
261
|
+
className: "hf-loader-progress__fill",
|
|
262
|
+
style: { transform: `scaleX(${boundedProgress})` }
|
|
263
|
+
}
|
|
264
|
+
)
|
|
265
|
+
}
|
|
266
|
+
),
|
|
267
|
+
mono && /* @__PURE__ */ jsx5("div", { className: "hf-loader-mono", children: mono })
|
|
268
|
+
] });
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// src/components/ui/Menu.tsx
|
|
272
|
+
import { ContextMenu as BaseContextMenu } from "@base-ui/react/context-menu";
|
|
273
|
+
import { Menu as BaseMenu } from "@base-ui/react/menu";
|
|
274
|
+
import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
275
|
+
var SIDE_OFFSET = 6;
|
|
276
|
+
var VIEWPORT_MARGIN = 8;
|
|
277
|
+
function floatingMotion(openDuration) {
|
|
278
|
+
return cn(
|
|
279
|
+
"origin-[var(--transform-origin)] outline-hidden",
|
|
280
|
+
"transition-[opacity,transform] ease-out-quint",
|
|
281
|
+
openDuration,
|
|
282
|
+
"data-[ending-style]:duration-close data-[ending-style]:ease-in",
|
|
283
|
+
"data-[starting-style]:[opacity:var(--popup-enter-opacity)]",
|
|
284
|
+
"data-[starting-style]:[scale:var(--popup-enter-scale)]",
|
|
285
|
+
"data-[ending-style]:opacity-0"
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
var popupSurface = cn(
|
|
289
|
+
"rounded-lg border border-border-input bg-surface",
|
|
290
|
+
floatingMotion("duration-open"),
|
|
291
|
+
"data-[preview-state=open]:opacity-100 data-[preview-state=open]:scale-100"
|
|
292
|
+
);
|
|
293
|
+
var POPUP_LAYER = "z-200";
|
|
294
|
+
var menuPopup = cn(popupSurface, "min-w-36 p-1 shadow-menu");
|
|
295
|
+
var itemBase = cn(
|
|
296
|
+
"flex cursor-default select-none items-center justify-between gap-6 rounded-sm px-2 py-1.5",
|
|
297
|
+
"text-step-11 whitespace-nowrap text-text-1",
|
|
298
|
+
"outline-hidden transition-colors ease-out-quint duration-hover",
|
|
299
|
+
"data-[highlighted]:bg-hover data-[highlighted]:text-text-0",
|
|
300
|
+
"data-[preview-state=hover]:bg-hover data-[preview-state=hover]:text-text-0",
|
|
301
|
+
"data-[disabled]:pointer-events-none data-[disabled]:opacity-40"
|
|
302
|
+
);
|
|
303
|
+
var itemDanger = cn("text-danger data-[highlighted]:bg-danger/15 data-[highlighted]:text-danger");
|
|
304
|
+
function Menu({
|
|
305
|
+
trigger,
|
|
306
|
+
children,
|
|
307
|
+
side = "bottom",
|
|
308
|
+
align = "start",
|
|
309
|
+
sideOffset = SIDE_OFFSET,
|
|
310
|
+
container,
|
|
311
|
+
className,
|
|
312
|
+
"aria-label": ariaLabel,
|
|
313
|
+
"data-preview-state": previewState,
|
|
314
|
+
...root
|
|
315
|
+
}) {
|
|
316
|
+
return /* @__PURE__ */ jsxs4(BaseMenu.Root, { ...root, children: [
|
|
317
|
+
/* @__PURE__ */ jsx6(BaseMenu.Trigger, { render: trigger }),
|
|
318
|
+
/* @__PURE__ */ jsx6(BaseMenu.Portal, { container, children: /* @__PURE__ */ jsx6(
|
|
319
|
+
BaseMenu.Positioner,
|
|
320
|
+
{
|
|
321
|
+
side,
|
|
322
|
+
align,
|
|
323
|
+
sideOffset,
|
|
324
|
+
collisionPadding: VIEWPORT_MARGIN,
|
|
325
|
+
className: POPUP_LAYER,
|
|
326
|
+
children: /* @__PURE__ */ jsx6(
|
|
327
|
+
BaseMenu.Popup,
|
|
328
|
+
{
|
|
329
|
+
"aria-label": ariaLabel,
|
|
330
|
+
"data-preview-state": previewState,
|
|
331
|
+
className: cn(menuPopup, className),
|
|
332
|
+
children
|
|
333
|
+
}
|
|
334
|
+
)
|
|
335
|
+
}
|
|
336
|
+
) })
|
|
337
|
+
] });
|
|
338
|
+
}
|
|
339
|
+
function ContextMenu({
|
|
340
|
+
trigger,
|
|
341
|
+
children,
|
|
342
|
+
container,
|
|
343
|
+
className,
|
|
344
|
+
"aria-label": ariaLabel,
|
|
345
|
+
"data-preview-state": previewState,
|
|
346
|
+
...root
|
|
347
|
+
}) {
|
|
348
|
+
return /* @__PURE__ */ jsxs4(BaseContextMenu.Root, { ...root, children: [
|
|
349
|
+
/* @__PURE__ */ jsx6(BaseContextMenu.Trigger, { render: trigger }),
|
|
350
|
+
/* @__PURE__ */ jsx6(BaseContextMenu.Portal, { container, children: /* @__PURE__ */ jsx6(BaseContextMenu.Positioner, { collisionPadding: VIEWPORT_MARGIN, className: POPUP_LAYER, children: /* @__PURE__ */ jsx6(
|
|
351
|
+
BaseContextMenu.Popup,
|
|
352
|
+
{
|
|
353
|
+
"aria-label": ariaLabel,
|
|
354
|
+
"data-preview-state": previewState,
|
|
355
|
+
className: cn(menuPopup, className),
|
|
356
|
+
children
|
|
357
|
+
}
|
|
358
|
+
) }) })
|
|
359
|
+
] });
|
|
360
|
+
}
|
|
361
|
+
function MenuShortcut({ className, ...props }) {
|
|
362
|
+
return /* @__PURE__ */ jsx6(
|
|
363
|
+
"span",
|
|
364
|
+
{
|
|
365
|
+
className: cn("shrink-0 font-mono text-step-10 tabular-nums text-text-4", className),
|
|
366
|
+
"aria-hidden": "true",
|
|
367
|
+
...props
|
|
368
|
+
}
|
|
369
|
+
);
|
|
370
|
+
}
|
|
371
|
+
function MenuItem({ shortcut, tone, className, children, ...props }) {
|
|
372
|
+
return /* @__PURE__ */ jsxs4(BaseMenu.Item, { className: cn(itemBase, tone === "danger" && itemDanger, className), ...props, children: [
|
|
373
|
+
/* @__PURE__ */ jsx6("span", { className: "truncate", children }),
|
|
374
|
+
shortcut ? /* @__PURE__ */ jsx6(MenuShortcut, { children: shortcut }) : null
|
|
375
|
+
] });
|
|
376
|
+
}
|
|
377
|
+
function MenuRadioGroup(props) {
|
|
378
|
+
return /* @__PURE__ */ jsx6(BaseMenu.RadioGroup, { ...props });
|
|
379
|
+
}
|
|
380
|
+
function MenuRadioItem({ className, children, ...props }) {
|
|
381
|
+
return /* @__PURE__ */ jsxs4(BaseMenu.RadioItem, { className: cn(itemBase, className), ...props, children: [
|
|
382
|
+
/* @__PURE__ */ jsx6("span", { className: "truncate", children }),
|
|
383
|
+
/* @__PURE__ */ jsx6("span", { className: "flex size-3 shrink-0 items-center justify-center", children: /* @__PURE__ */ jsx6(BaseMenu.RadioItemIndicator, { className: "size-1.5 rounded-full bg-accent" }) })
|
|
384
|
+
] });
|
|
385
|
+
}
|
|
386
|
+
function MenuCheckboxItem({
|
|
387
|
+
className,
|
|
388
|
+
children,
|
|
389
|
+
...props
|
|
390
|
+
}) {
|
|
391
|
+
return /* @__PURE__ */ jsxs4(BaseMenu.CheckboxItem, { className: cn(itemBase, className), ...props, children: [
|
|
392
|
+
/* @__PURE__ */ jsx6("span", { className: "truncate", children }),
|
|
393
|
+
/* @__PURE__ */ jsx6("span", { className: "flex size-3 shrink-0 items-center justify-center text-accent", children: /* @__PURE__ */ jsx6(BaseMenu.CheckboxItemIndicator, { children: "\u2713" }) })
|
|
394
|
+
] });
|
|
395
|
+
}
|
|
396
|
+
function MenuSeparator({ className, ...props }) {
|
|
397
|
+
return /* @__PURE__ */ jsx6(BaseMenu.Separator, { className: cn("my-1 h-px bg-hairline", className), ...props });
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// src/components/ui/Tooltip.tsx
|
|
401
|
+
import { Tooltip as BaseTooltip } from "@base-ui/react/tooltip";
|
|
402
|
+
import { cloneElement, useId as useId2, useRef, useState } from "react";
|
|
403
|
+
import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
404
|
+
var SIDE_OFFSET2 = 6;
|
|
405
|
+
var VIEWPORT_MARGIN2 = 8;
|
|
406
|
+
function Tooltip({ label, children, delay = 400, side = "top" }) {
|
|
407
|
+
const [open, setOpen] = useState(false);
|
|
408
|
+
const boxRef = useRef(null);
|
|
409
|
+
const tooltipId = useId2();
|
|
410
|
+
return /* @__PURE__ */ jsxs5(BaseTooltip.Root, { open, onOpenChange: setOpen, children: [
|
|
411
|
+
/* @__PURE__ */ jsx7(BaseTooltip.Trigger, { delay, render: /* @__PURE__ */ jsx7("span", { ref: boxRef, className: "contents" }), children: cloneElement(children, {
|
|
412
|
+
"aria-describedby": open ? tooltipId : children.props["aria-describedby"]
|
|
413
|
+
}) }),
|
|
414
|
+
/* @__PURE__ */ jsx7(BaseTooltip.Portal, { children: /* @__PURE__ */ jsx7(
|
|
415
|
+
BaseTooltip.Positioner,
|
|
416
|
+
{
|
|
417
|
+
anchor: () => boxRef.current?.firstElementChild ?? null,
|
|
418
|
+
side,
|
|
419
|
+
sideOffset: SIDE_OFFSET2,
|
|
420
|
+
collisionPadding: VIEWPORT_MARGIN2,
|
|
421
|
+
className: "z-200",
|
|
422
|
+
children: /* @__PURE__ */ jsx7(
|
|
423
|
+
BaseTooltip.Popup,
|
|
424
|
+
{
|
|
425
|
+
id: tooltipId,
|
|
426
|
+
role: "tooltip",
|
|
427
|
+
className: cn(
|
|
428
|
+
"pointer-events-none rounded-md border border-border-input bg-surface px-2 py-1 text-step-10 font-medium text-text-1 whitespace-nowrap shadow-menu",
|
|
429
|
+
floatingMotion("duration-tooltip")
|
|
430
|
+
),
|
|
431
|
+
children: label
|
|
432
|
+
}
|
|
433
|
+
)
|
|
434
|
+
}
|
|
435
|
+
) })
|
|
436
|
+
] });
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
// src/components/ui/Popover.tsx
|
|
440
|
+
import { Popover as BasePopover } from "@base-ui/react/popover";
|
|
441
|
+
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
442
|
+
var SIDE_OFFSET3 = 6;
|
|
443
|
+
var VIEWPORT_MARGIN3 = 8;
|
|
444
|
+
function Popover({
|
|
445
|
+
trigger,
|
|
446
|
+
children,
|
|
447
|
+
side = "bottom",
|
|
448
|
+
align = "center",
|
|
449
|
+
sideOffset = SIDE_OFFSET3,
|
|
450
|
+
container,
|
|
451
|
+
className,
|
|
452
|
+
initialFocus,
|
|
453
|
+
"aria-label": ariaLabel,
|
|
454
|
+
"data-preview-state": previewState,
|
|
455
|
+
...root
|
|
456
|
+
}) {
|
|
457
|
+
return /* @__PURE__ */ jsxs6(BasePopover.Root, { ...root, children: [
|
|
458
|
+
/* @__PURE__ */ jsx8(BasePopover.Trigger, { render: trigger }),
|
|
459
|
+
/* @__PURE__ */ jsx8(BasePopover.Portal, { container, children: /* @__PURE__ */ jsx8(
|
|
460
|
+
BasePopover.Positioner,
|
|
461
|
+
{
|
|
462
|
+
side,
|
|
463
|
+
align,
|
|
464
|
+
sideOffset,
|
|
465
|
+
collisionPadding: VIEWPORT_MARGIN3,
|
|
466
|
+
className: "z-200",
|
|
467
|
+
children: /* @__PURE__ */ jsx8(
|
|
468
|
+
BasePopover.Popup,
|
|
469
|
+
{
|
|
470
|
+
"aria-label": ariaLabel,
|
|
471
|
+
initialFocus,
|
|
472
|
+
"data-preview-state": previewState,
|
|
473
|
+
className: cn(popupSurface, "p-3 text-step-11 text-text-1 shadow-popover", className),
|
|
474
|
+
children
|
|
475
|
+
}
|
|
476
|
+
)
|
|
477
|
+
}
|
|
478
|
+
) })
|
|
479
|
+
] });
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
// src/components/ui/Input.tsx
|
|
483
|
+
import { Input as BaseInput } from "@base-ui/react/input";
|
|
484
|
+
import { useEffect, useRef as useRef2, useState as useState2 } from "react";
|
|
485
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
486
|
+
var fieldBase = cn(
|
|
487
|
+
"flex min-w-0 items-center gap-1.5 h-ctl px-2 rounded-md",
|
|
488
|
+
"bg-input border border-border-input text-step-11 font-medium text-text-1",
|
|
489
|
+
"transition-[border-color,background-color] ease-standard duration-focus",
|
|
490
|
+
"hover:border-border-strong data-[preview-state=hover]:border-border-strong",
|
|
491
|
+
"outline-hidden",
|
|
492
|
+
"focus-within:outline-solid focus-within:outline-2 focus-within:outline-offset-1 focus-within:outline-accent",
|
|
493
|
+
"data-[preview-state=focus]:outline-solid data-[preview-state=focus]:outline-2 data-[preview-state=focus]:outline-offset-1 data-[preview-state=focus]:outline-accent",
|
|
494
|
+
// `aria-invalid` is not one of Tailwind's built-in aria variants, so the
|
|
495
|
+
// arbitrary form is the one that compiles. The token gate would have caught
|
|
496
|
+
// the bare `aria-invalid:` spelling as a class that resolves to nothing.
|
|
497
|
+
"aria-[invalid]:border-danger",
|
|
498
|
+
"has-[:disabled]:opacity-40 has-[:disabled]:cursor-not-allowed"
|
|
499
|
+
);
|
|
500
|
+
var fieldText = cn(
|
|
501
|
+
"min-w-0 w-full bg-transparent text-inherit outline-hidden",
|
|
502
|
+
"placeholder:text-text-5 disabled:cursor-not-allowed"
|
|
503
|
+
);
|
|
504
|
+
function Input({
|
|
505
|
+
value,
|
|
506
|
+
onCommit,
|
|
507
|
+
onTrack,
|
|
508
|
+
invalid,
|
|
509
|
+
disabled,
|
|
510
|
+
className,
|
|
511
|
+
"data-preview-state": previewState,
|
|
512
|
+
...props
|
|
513
|
+
}) {
|
|
514
|
+
const [draft, setDraft] = useState2(value);
|
|
515
|
+
const valueRef = useRef2(value);
|
|
516
|
+
valueRef.current = value;
|
|
517
|
+
const dirtyRef = useRef2(false);
|
|
518
|
+
useEffect(() => {
|
|
519
|
+
if (!dirtyRef.current) setDraft(value);
|
|
520
|
+
}, [value]);
|
|
521
|
+
const commit = (next) => {
|
|
522
|
+
dirtyRef.current = false;
|
|
523
|
+
if (next === valueRef.current) return;
|
|
524
|
+
onCommit(next);
|
|
525
|
+
onTrack?.();
|
|
526
|
+
};
|
|
527
|
+
return /* @__PURE__ */ jsx9(
|
|
528
|
+
"div",
|
|
529
|
+
{
|
|
530
|
+
className: cn(fieldBase, className),
|
|
531
|
+
"aria-invalid": invalid || void 0,
|
|
532
|
+
"data-preview-state": previewState,
|
|
533
|
+
children: /* @__PURE__ */ jsx9(
|
|
534
|
+
BaseInput,
|
|
535
|
+
{
|
|
536
|
+
value: draft,
|
|
537
|
+
disabled,
|
|
538
|
+
"aria-invalid": invalid || void 0,
|
|
539
|
+
className: fieldText,
|
|
540
|
+
onValueChange: (next) => {
|
|
541
|
+
dirtyRef.current = true;
|
|
542
|
+
setDraft(next);
|
|
543
|
+
},
|
|
544
|
+
onBlur: () => commit(draft),
|
|
545
|
+
onKeyDown: (event) => {
|
|
546
|
+
if (event.key === "Enter") {
|
|
547
|
+
event.preventDefault();
|
|
548
|
+
commit(draft);
|
|
549
|
+
return;
|
|
550
|
+
}
|
|
551
|
+
if (event.key === "Escape") {
|
|
552
|
+
event.preventDefault();
|
|
553
|
+
event.stopPropagation();
|
|
554
|
+
dirtyRef.current = false;
|
|
555
|
+
setDraft(valueRef.current);
|
|
556
|
+
event.currentTarget.blur();
|
|
557
|
+
}
|
|
558
|
+
},
|
|
559
|
+
...props
|
|
560
|
+
}
|
|
561
|
+
)
|
|
562
|
+
}
|
|
563
|
+
);
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
// src/components/ui/NumberField.tsx
|
|
567
|
+
import { NumberField as BaseNumberField } from "@base-ui/react/number-field";
|
|
568
|
+
import { useEffect as useEffect2, useRef as useRef3, useState as useState3 } from "react";
|
|
569
|
+
import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
570
|
+
function NumberField({
|
|
571
|
+
label,
|
|
572
|
+
value,
|
|
573
|
+
onCommit,
|
|
574
|
+
onTrack,
|
|
575
|
+
unit,
|
|
576
|
+
min,
|
|
577
|
+
max,
|
|
578
|
+
step,
|
|
579
|
+
disabled,
|
|
580
|
+
className,
|
|
581
|
+
"data-preview-state": previewState
|
|
582
|
+
}) {
|
|
583
|
+
const [draft, setDraft] = useState3(value);
|
|
584
|
+
const [invalid, setInvalid] = useState3(false);
|
|
585
|
+
const inputRef = useRef3(null);
|
|
586
|
+
const committedRef = useRef3(value);
|
|
587
|
+
const valueRef = useRef3(value);
|
|
588
|
+
valueRef.current = value;
|
|
589
|
+
useEffect2(() => {
|
|
590
|
+
committedRef.current = value;
|
|
591
|
+
setDraft(value);
|
|
592
|
+
setInvalid(false);
|
|
593
|
+
}, [value]);
|
|
594
|
+
const commit = (next) => {
|
|
595
|
+
if (next === null || !Number.isFinite(next)) {
|
|
596
|
+
setInvalid(true);
|
|
597
|
+
return;
|
|
598
|
+
}
|
|
599
|
+
setInvalid(false);
|
|
600
|
+
if (next === committedRef.current) return;
|
|
601
|
+
committedRef.current = next;
|
|
602
|
+
onCommit(next);
|
|
603
|
+
onTrack?.();
|
|
604
|
+
};
|
|
605
|
+
const commitFromText = () => {
|
|
606
|
+
const text = inputRef.current?.value.trim() ?? "";
|
|
607
|
+
commit(text === "" ? null : Number(text));
|
|
608
|
+
};
|
|
609
|
+
return /* @__PURE__ */ jsx10(
|
|
610
|
+
BaseNumberField.Root,
|
|
611
|
+
{
|
|
612
|
+
value: draft,
|
|
613
|
+
min,
|
|
614
|
+
max,
|
|
615
|
+
step,
|
|
616
|
+
disabled,
|
|
617
|
+
onValueChange: (next) => {
|
|
618
|
+
setDraft(next);
|
|
619
|
+
if (next !== null) setInvalid(false);
|
|
620
|
+
},
|
|
621
|
+
onValueCommitted: (next) => commit(next),
|
|
622
|
+
children: /* @__PURE__ */ jsxs7(
|
|
623
|
+
BaseNumberField.Group,
|
|
624
|
+
{
|
|
625
|
+
className: cn(fieldBase, className),
|
|
626
|
+
"aria-invalid": invalid || void 0,
|
|
627
|
+
"data-preview-state": previewState,
|
|
628
|
+
children: [
|
|
629
|
+
/* @__PURE__ */ jsx10(
|
|
630
|
+
BaseNumberField.Input,
|
|
631
|
+
{
|
|
632
|
+
ref: inputRef,
|
|
633
|
+
"aria-label": label,
|
|
634
|
+
"aria-invalid": invalid || void 0,
|
|
635
|
+
className: cn(fieldText, "tabular-nums"),
|
|
636
|
+
onKeyDown: (event) => {
|
|
637
|
+
if (event.key !== "Enter") return;
|
|
638
|
+
event.preventDefault();
|
|
639
|
+
commitFromText();
|
|
640
|
+
},
|
|
641
|
+
onBlur: () => {
|
|
642
|
+
const text = inputRef.current?.value.trim() ?? "";
|
|
643
|
+
if (text === "" || !Number.isFinite(Number(text))) setInvalid(true);
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
),
|
|
647
|
+
unit && /* @__PURE__ */ jsx10("span", { className: "shrink-0 select-none text-step-10 text-text-4", "aria-hidden": "true", children: unit })
|
|
648
|
+
]
|
|
649
|
+
}
|
|
650
|
+
)
|
|
651
|
+
}
|
|
652
|
+
);
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
// src/components/ui/Select.tsx
|
|
656
|
+
import { Select as BaseSelect } from "@base-ui/react/select";
|
|
657
|
+
import { jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
658
|
+
function Select({
|
|
659
|
+
label,
|
|
660
|
+
value,
|
|
661
|
+
options,
|
|
662
|
+
onCommit,
|
|
663
|
+
onTrack,
|
|
664
|
+
disabled,
|
|
665
|
+
className,
|
|
666
|
+
"data-preview-state": previewState
|
|
667
|
+
}) {
|
|
668
|
+
return /* @__PURE__ */ jsxs8(
|
|
669
|
+
BaseSelect.Root,
|
|
670
|
+
{
|
|
671
|
+
value,
|
|
672
|
+
disabled,
|
|
673
|
+
items: options,
|
|
674
|
+
onValueChange: (next) => {
|
|
675
|
+
const chosen = String(next);
|
|
676
|
+
if (chosen === value) return;
|
|
677
|
+
onCommit(chosen);
|
|
678
|
+
onTrack?.();
|
|
679
|
+
},
|
|
680
|
+
children: [
|
|
681
|
+
/* @__PURE__ */ jsxs8(
|
|
682
|
+
BaseSelect.Trigger,
|
|
683
|
+
{
|
|
684
|
+
"aria-label": label,
|
|
685
|
+
className: cn(
|
|
686
|
+
fieldBase,
|
|
687
|
+
"w-full cursor-pointer justify-between text-left",
|
|
688
|
+
"data-[popup-open]:border-border-strong",
|
|
689
|
+
className
|
|
690
|
+
),
|
|
691
|
+
"data-preview-state": previewState,
|
|
692
|
+
children: [
|
|
693
|
+
/* @__PURE__ */ jsx11(BaseSelect.Value, { className: "truncate" }),
|
|
694
|
+
/* @__PURE__ */ jsx11(BaseSelect.Icon, { className: "shrink-0 text-text-4", "aria-hidden": "true", children: /* @__PURE__ */ jsx11("svg", { width: "8", height: "5", viewBox: "0 0 8 5", fill: "none", children: /* @__PURE__ */ jsx11(
|
|
695
|
+
"path",
|
|
696
|
+
{
|
|
697
|
+
d: "M1 1L4 4L7 1",
|
|
698
|
+
stroke: "currentColor",
|
|
699
|
+
strokeWidth: "1.5",
|
|
700
|
+
strokeLinecap: "round",
|
|
701
|
+
strokeLinejoin: "round"
|
|
702
|
+
}
|
|
703
|
+
) }) })
|
|
704
|
+
]
|
|
705
|
+
}
|
|
706
|
+
),
|
|
707
|
+
/* @__PURE__ */ jsx11(BaseSelect.Portal, { children: /* @__PURE__ */ jsx11(BaseSelect.Positioner, { sideOffset: 4, alignItemWithTrigger: false, children: /* @__PURE__ */ jsx11(
|
|
708
|
+
BaseSelect.Popup,
|
|
709
|
+
{
|
|
710
|
+
className: cn(
|
|
711
|
+
"min-w-[var(--anchor-width)] rounded-md border border-border bg-surface py-1 shadow-menu",
|
|
712
|
+
floatingMotion("duration-open")
|
|
713
|
+
),
|
|
714
|
+
children: /* @__PURE__ */ jsx11(BaseSelect.List, { children: options.map((option) => /* @__PURE__ */ jsx11(
|
|
715
|
+
BaseSelect.Item,
|
|
716
|
+
{
|
|
717
|
+
value: option.value,
|
|
718
|
+
disabled: option.disabled,
|
|
719
|
+
className: cn(
|
|
720
|
+
"flex h-ctl-sm cursor-pointer select-none items-center gap-2 px-2.5",
|
|
721
|
+
"text-step-11 text-text-2 outline-hidden",
|
|
722
|
+
"data-[highlighted]:bg-hover data-[highlighted]:text-text-0",
|
|
723
|
+
"data-[selected]:text-text-0",
|
|
724
|
+
"data-[disabled]:cursor-not-allowed data-[disabled]:opacity-40"
|
|
725
|
+
),
|
|
726
|
+
children: /* @__PURE__ */ jsx11(BaseSelect.ItemText, { className: "truncate", children: option.label })
|
|
727
|
+
},
|
|
728
|
+
option.value
|
|
729
|
+
)) })
|
|
730
|
+
}
|
|
731
|
+
) }) })
|
|
732
|
+
]
|
|
733
|
+
}
|
|
734
|
+
);
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
// src/components/ui/Slider.tsx
|
|
738
|
+
import { Slider as BaseSlider } from "@base-ui/react/slider";
|
|
739
|
+
import { useEffect as useEffect3, useRef as useRef4, useState as useState4 } from "react";
|
|
740
|
+
import { jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
741
|
+
var first = (next) => Array.isArray(next) ? next[0] : next;
|
|
742
|
+
function Slider({
|
|
743
|
+
label,
|
|
744
|
+
value,
|
|
745
|
+
min,
|
|
746
|
+
max,
|
|
747
|
+
step,
|
|
748
|
+
onPreview,
|
|
749
|
+
onCommit,
|
|
750
|
+
onTrack,
|
|
751
|
+
disabled,
|
|
752
|
+
className,
|
|
753
|
+
"data-preview-state": previewState
|
|
754
|
+
}) {
|
|
755
|
+
const [draft, setDraft] = useState4(value);
|
|
756
|
+
const draggingRef = useRef4(false);
|
|
757
|
+
const abortedRef = useRef4(false);
|
|
758
|
+
const dragStartRef = useRef4(value);
|
|
759
|
+
const committedRef = useRef4(value);
|
|
760
|
+
const valueRef = useRef4(value);
|
|
761
|
+
valueRef.current = value;
|
|
762
|
+
useEffect3(() => {
|
|
763
|
+
if (draggingRef.current) return;
|
|
764
|
+
committedRef.current = value;
|
|
765
|
+
setDraft(value);
|
|
766
|
+
}, [value]);
|
|
767
|
+
const commit = (next) => {
|
|
768
|
+
if (next === committedRef.current) return;
|
|
769
|
+
committedRef.current = next;
|
|
770
|
+
onCommit(next);
|
|
771
|
+
};
|
|
772
|
+
const abort = () => {
|
|
773
|
+
if (!draggingRef.current) return;
|
|
774
|
+
abortedRef.current = true;
|
|
775
|
+
const start = dragStartRef.current;
|
|
776
|
+
setDraft(start);
|
|
777
|
+
onPreview?.(start);
|
|
778
|
+
commit(start);
|
|
779
|
+
};
|
|
780
|
+
return /* @__PURE__ */ jsx12(
|
|
781
|
+
BaseSlider.Root,
|
|
782
|
+
{
|
|
783
|
+
value: draft,
|
|
784
|
+
min,
|
|
785
|
+
max,
|
|
786
|
+
step,
|
|
787
|
+
disabled,
|
|
788
|
+
onValueChange: (next, details) => {
|
|
789
|
+
if (abortedRef.current) {
|
|
790
|
+
details.cancel();
|
|
791
|
+
return;
|
|
792
|
+
}
|
|
793
|
+
const n = first(next);
|
|
794
|
+
setDraft(n);
|
|
795
|
+
onPreview?.(n);
|
|
796
|
+
},
|
|
797
|
+
onValueCommitted: (next) => {
|
|
798
|
+
draggingRef.current = false;
|
|
799
|
+
if (abortedRef.current) {
|
|
800
|
+
abortedRef.current = false;
|
|
801
|
+
return;
|
|
802
|
+
}
|
|
803
|
+
commit(first(next));
|
|
804
|
+
onTrack?.();
|
|
805
|
+
},
|
|
806
|
+
className: cn("flex min-w-0 items-center", className),
|
|
807
|
+
"data-preview-state": previewState,
|
|
808
|
+
children: /* @__PURE__ */ jsx12(
|
|
809
|
+
BaseSlider.Control,
|
|
810
|
+
{
|
|
811
|
+
"data-slider-control": "true",
|
|
812
|
+
className: "flex h-6 w-full min-w-0 touch-none select-none items-center",
|
|
813
|
+
onPointerDown: () => {
|
|
814
|
+
draggingRef.current = true;
|
|
815
|
+
abortedRef.current = false;
|
|
816
|
+
dragStartRef.current = valueRef.current;
|
|
817
|
+
},
|
|
818
|
+
onContextMenu: (event) => {
|
|
819
|
+
if (!draggingRef.current) return;
|
|
820
|
+
event.preventDefault();
|
|
821
|
+
abort();
|
|
822
|
+
},
|
|
823
|
+
onKeyDown: (event) => {
|
|
824
|
+
if (event.key !== "Escape" || !draggingRef.current) return;
|
|
825
|
+
event.preventDefault();
|
|
826
|
+
abort();
|
|
827
|
+
},
|
|
828
|
+
children: /* @__PURE__ */ jsxs9(BaseSlider.Track, { className: "h-0.5 w-full rounded-full bg-hover", children: [
|
|
829
|
+
/* @__PURE__ */ jsx12(BaseSlider.Indicator, { className: "rounded-full bg-text-5" }),
|
|
830
|
+
/* @__PURE__ */ jsx12(
|
|
831
|
+
BaseSlider.Thumb,
|
|
832
|
+
{
|
|
833
|
+
"aria-label": label,
|
|
834
|
+
className: cn(
|
|
835
|
+
// The ring separates the thumb from the track behind it. A drop
|
|
836
|
+
// shadow would need a raw colour literal, which R5 does not allow
|
|
837
|
+
// outside the token file, and no shadow token fits a 10px dot.
|
|
838
|
+
"size-2.5 rounded-full bg-text-0 ring-2 ring-bg-1",
|
|
839
|
+
"cursor-grab active:cursor-grabbing data-[preview-state=active]:cursor-grabbing",
|
|
840
|
+
"hover:scale-110 data-[preview-state=hover]:scale-110",
|
|
841
|
+
"transition-transform ease-standard duration-hover",
|
|
842
|
+
"has-[:focus-visible]:outline-solid has-[:focus-visible]:outline-2 has-[:focus-visible]:outline-offset-2 has-[:focus-visible]:outline-accent",
|
|
843
|
+
"data-[preview-state=focus]:outline-solid data-[preview-state=focus]:outline-2 data-[preview-state=focus]:outline-offset-2 data-[preview-state=focus]:outline-accent"
|
|
844
|
+
)
|
|
845
|
+
}
|
|
846
|
+
)
|
|
847
|
+
] })
|
|
848
|
+
}
|
|
849
|
+
)
|
|
850
|
+
}
|
|
851
|
+
);
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
// src/components/ui/Toggle.tsx
|
|
855
|
+
import { Switch } from "@base-ui/react/switch";
|
|
856
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
857
|
+
function Toggle({
|
|
858
|
+
label,
|
|
859
|
+
checked,
|
|
860
|
+
onCommit,
|
|
861
|
+
onTrack,
|
|
862
|
+
disabled,
|
|
863
|
+
className,
|
|
864
|
+
"data-preview-state": previewState
|
|
865
|
+
}) {
|
|
866
|
+
return /* @__PURE__ */ jsx13(
|
|
867
|
+
Switch.Root,
|
|
868
|
+
{
|
|
869
|
+
"aria-label": label,
|
|
870
|
+
checked,
|
|
871
|
+
disabled,
|
|
872
|
+
onCheckedChange: (next) => {
|
|
873
|
+
onCommit(next);
|
|
874
|
+
onTrack?.();
|
|
875
|
+
},
|
|
876
|
+
"data-preview-state": previewState,
|
|
877
|
+
className: cn(
|
|
878
|
+
"relative inline-flex h-4 w-7 shrink-0 cursor-pointer items-center rounded-full p-0.5",
|
|
879
|
+
"border border-border-input bg-input",
|
|
880
|
+
"transition-[background-color,border-color] ease-standard duration-press",
|
|
881
|
+
"hover:border-border-strong data-[preview-state=hover]:border-border-strong",
|
|
882
|
+
"data-[checked]:border-accent data-[checked]:bg-accent",
|
|
883
|
+
"outline-hidden focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-accent",
|
|
884
|
+
"data-[preview-state=focus]:outline-solid data-[preview-state=focus]:outline-2 data-[preview-state=focus]:outline-offset-1 data-[preview-state=focus]:outline-accent",
|
|
885
|
+
"disabled:cursor-not-allowed disabled:opacity-40",
|
|
886
|
+
className
|
|
887
|
+
),
|
|
888
|
+
children: /* @__PURE__ */ jsx13(
|
|
889
|
+
Switch.Thumb,
|
|
890
|
+
{
|
|
891
|
+
className: cn(
|
|
892
|
+
"size-3 rounded-full bg-text-3",
|
|
893
|
+
"transition-[transform,background-color] ease-standard duration-press",
|
|
894
|
+
"data-[checked]:translate-x-3 data-[checked]:bg-bg-0"
|
|
895
|
+
)
|
|
896
|
+
}
|
|
897
|
+
)
|
|
898
|
+
}
|
|
899
|
+
);
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
export {
|
|
903
|
+
cn,
|
|
904
|
+
buttonBase,
|
|
905
|
+
buttonVariants,
|
|
906
|
+
buttonSizes,
|
|
907
|
+
Button,
|
|
908
|
+
IconButton,
|
|
909
|
+
Tabs,
|
|
910
|
+
TabsList,
|
|
911
|
+
Tab,
|
|
912
|
+
TabPanel,
|
|
913
|
+
HyperframesMark,
|
|
914
|
+
HyperframesLoader,
|
|
915
|
+
popupSurface,
|
|
916
|
+
Menu,
|
|
917
|
+
ContextMenu,
|
|
918
|
+
MenuShortcut,
|
|
919
|
+
MenuItem,
|
|
920
|
+
MenuRadioGroup,
|
|
921
|
+
MenuRadioItem,
|
|
922
|
+
MenuCheckboxItem,
|
|
923
|
+
MenuSeparator,
|
|
924
|
+
Tooltip,
|
|
925
|
+
Popover,
|
|
926
|
+
fieldBase,
|
|
927
|
+
fieldText,
|
|
928
|
+
Input,
|
|
929
|
+
NumberField,
|
|
930
|
+
Select,
|
|
931
|
+
Slider,
|
|
932
|
+
Toggle
|
|
933
|
+
};
|
|
934
|
+
//# sourceMappingURL=chunk-QZ6HNNFG.js.map
|