@joycostudio/studio 0.0.2 → 0.1.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 +68 -0
- package/dist/cli.js.map +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js.map +1 -1
- package/dist/{protocol-Bl62UeCa.d.ts → protocol-BrHDtNkL.d.ts} +2 -0
- package/dist/react.d.ts +58 -4
- package/dist/react.js +620 -282
- package/dist/react.js.map +1 -1
- package/dist/runtime.d.ts +1 -1
- package/dist/styles.css +1 -1
- package/package.json +13 -13
package/dist/react.js
CHANGED
|
@@ -7,13 +7,14 @@ import {
|
|
|
7
7
|
LoaderCircle,
|
|
8
8
|
PanelLeftClose,
|
|
9
9
|
PanelLeftOpen,
|
|
10
|
+
Pin as Pin2,
|
|
10
11
|
PlugZap,
|
|
11
12
|
Unplug
|
|
12
13
|
} from "lucide-react";
|
|
13
|
-
import { useEffect as
|
|
14
|
+
import { useEffect as useEffect4, useRef as useRef3, useState as useState7 } from "react";
|
|
14
15
|
|
|
15
16
|
// package.json
|
|
16
|
-
var version = "0.0
|
|
17
|
+
var version = "0.1.0";
|
|
17
18
|
|
|
18
19
|
// src/client/studio.ts
|
|
19
20
|
import { button } from "@joycostudio/xyz/debug";
|
|
@@ -241,9 +242,72 @@ function TooltipContent({
|
|
|
241
242
|
}
|
|
242
243
|
) });
|
|
243
244
|
}
|
|
245
|
+
function Hint({
|
|
246
|
+
children,
|
|
247
|
+
content,
|
|
248
|
+
...props
|
|
249
|
+
}) {
|
|
250
|
+
return /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
251
|
+
/* @__PURE__ */ jsx4(TooltipTrigger, { asChild: true, children }),
|
|
252
|
+
/* @__PURE__ */ jsx4(TooltipContent, { ...props, children: content })
|
|
253
|
+
] });
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// src/react/ui/panel.tsx
|
|
257
|
+
import { Slot as Slot3 } from "radix-ui";
|
|
258
|
+
import { forwardRef as forwardRef2 } from "react";
|
|
259
|
+
|
|
260
|
+
// src/react/surface.tsx
|
|
261
|
+
import { Slot as Slot2 } from "radix-ui";
|
|
262
|
+
import { forwardRef } from "react";
|
|
263
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
264
|
+
var StudioSurface = forwardRef(
|
|
265
|
+
function StudioSurface2({ asChild = false, className, ...props }, ref) {
|
|
266
|
+
const Comp = asChild ? Slot2.Root : "div";
|
|
267
|
+
return /* @__PURE__ */ jsx5(Comp, { ref, "data-slot": "studio-surface", className: cn("studio-surface", className), ...props });
|
|
268
|
+
}
|
|
269
|
+
);
|
|
270
|
+
var StudioToolbar = forwardRef(function StudioToolbar2({ className, ...props }, ref) {
|
|
271
|
+
return /* @__PURE__ */ jsx5(StudioSurface, { ref, role: "group", className: cn("studio-toolbar", className), ...props });
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
// src/react/ui/panel.tsx
|
|
275
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
276
|
+
var Panel = forwardRef2(function Panel2({ className, asChild = false, ...props }, ref) {
|
|
277
|
+
const Comp = asChild ? Slot3.Root : "div";
|
|
278
|
+
return /* @__PURE__ */ jsx6(
|
|
279
|
+
Comp,
|
|
280
|
+
{
|
|
281
|
+
ref,
|
|
282
|
+
"data-slot": "panel",
|
|
283
|
+
className: cn(
|
|
284
|
+
"rounded-lg border border-sidebar-border bg-sidebar/85 shadow-xl shadow-black/40 backdrop-blur-xl",
|
|
285
|
+
className
|
|
286
|
+
),
|
|
287
|
+
...props
|
|
288
|
+
}
|
|
289
|
+
);
|
|
290
|
+
});
|
|
291
|
+
function PanelHeader({ className, ...props }) {
|
|
292
|
+
return /* @__PURE__ */ jsx6(StudioSurface, { asChild: true, className: cn("px-3 pt-2.5 pb-2", className), children: /* @__PURE__ */ jsx6("header", { "data-slot": "panel-header", ...props }) });
|
|
293
|
+
}
|
|
294
|
+
var PanelContent = forwardRef2(function PanelContent2({ className, ...props }, ref) {
|
|
295
|
+
return /* @__PURE__ */ jsx6(
|
|
296
|
+
"div",
|
|
297
|
+
{
|
|
298
|
+
ref,
|
|
299
|
+
"data-slot": "panel-content",
|
|
300
|
+
className: cn("min-h-0 flex-1 overflow-auto px-1 py-1.5", className),
|
|
301
|
+
...props
|
|
302
|
+
}
|
|
303
|
+
);
|
|
304
|
+
});
|
|
305
|
+
function PanelFooter({ className, ...props }) {
|
|
306
|
+
return /* @__PURE__ */ jsx6(StudioSurface, { asChild: true, className: cn("grid gap-2 p-2", className), children: /* @__PURE__ */ jsx6("footer", { "data-slot": "panel-footer", ...props }) });
|
|
307
|
+
}
|
|
244
308
|
|
|
245
309
|
// src/react/inspector.tsx
|
|
246
|
-
import { jsx as
|
|
310
|
+
import { Fragment, jsx as jsx7, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
247
311
|
function describe(studio, handle) {
|
|
248
312
|
const { state } = handle;
|
|
249
313
|
if (studio.connection.phase !== "connected") return { tone: "text-faint", text: "Not persisting" };
|
|
@@ -256,7 +320,8 @@ function describe(studio, handle) {
|
|
|
256
320
|
function Inspector({
|
|
257
321
|
studio,
|
|
258
322
|
handle,
|
|
259
|
-
onCompare
|
|
323
|
+
onCompare,
|
|
324
|
+
fileHref
|
|
260
325
|
}) {
|
|
261
326
|
useStudio(studio);
|
|
262
327
|
const container = useRef(null);
|
|
@@ -299,74 +364,80 @@ function Inspector({
|
|
|
299
364
|
if (pane.current) pane.current.disabled = handle.comparing;
|
|
300
365
|
});
|
|
301
366
|
const { definition, state } = handle;
|
|
367
|
+
const ConfigFile = fileHref ? "a" : "span";
|
|
302
368
|
const status = describe(studio, handle);
|
|
303
369
|
const editable2 = studio.connection.phase === "connected" && !!state?.dirty && !handle.comparing;
|
|
304
370
|
const changes = (state?.dirty ? changedPaths(state.saved.value, state.draft.value) : []).map(
|
|
305
371
|
(path) => path.split(".").map((key) => key.charAt(0).toUpperCase() + key.slice(1)).join(" \u203A ")
|
|
306
372
|
);
|
|
307
|
-
return /* @__PURE__ */ jsxs2(
|
|
308
|
-
/* @__PURE__ */ jsxs2(
|
|
373
|
+
return /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
374
|
+
/* @__PURE__ */ jsxs2(PanelHeader, { children: [
|
|
309
375
|
/* @__PURE__ */ jsxs2("strong", { className: "flex min-w-0 items-center gap-2 text-foreground", children: [
|
|
310
|
-
/* @__PURE__ */
|
|
311
|
-
/* @__PURE__ */
|
|
376
|
+
/* @__PURE__ */ jsx7(ToolIcon, { icon: definition.icon, className: "size-3.5 shrink-0" }),
|
|
377
|
+
/* @__PURE__ */ jsx7("span", { className: "truncate", title: definition.title ?? definition.id, children: definition.title ?? definition.id })
|
|
312
378
|
] }),
|
|
313
379
|
/* @__PURE__ */ jsxs2("div", { className: "mt-1 flex items-center gap-3 pl-5.5 text-[11px]", children: [
|
|
314
|
-
/* @__PURE__ */
|
|
380
|
+
/* @__PURE__ */ jsx7(
|
|
381
|
+
ConfigFile,
|
|
382
|
+
{
|
|
383
|
+
"data-slot": "studio-config-file",
|
|
384
|
+
className: "min-w-0 flex-1 truncate text-muted-foreground",
|
|
385
|
+
href: fileHref,
|
|
386
|
+
title: fileHref ? `Open ${definition.file}` : definition.file,
|
|
387
|
+
children: definition.file
|
|
388
|
+
}
|
|
389
|
+
),
|
|
315
390
|
/* @__PURE__ */ jsxs2(
|
|
316
391
|
"span",
|
|
317
392
|
{
|
|
318
393
|
className: `flex shrink-0 items-center gap-1.5 ${status.tone}`,
|
|
319
394
|
title: state ? `Draft revision ${state.draft.revision}` : void 0,
|
|
320
395
|
children: [
|
|
321
|
-
/* @__PURE__ */
|
|
396
|
+
/* @__PURE__ */ jsx7("span", { "aria-hidden": "true", className: "size-1.5 rounded-full bg-current" }),
|
|
322
397
|
status.text
|
|
323
398
|
]
|
|
324
399
|
}
|
|
325
400
|
)
|
|
326
401
|
] })
|
|
327
402
|
] }),
|
|
328
|
-
/* @__PURE__ */
|
|
329
|
-
|
|
330
|
-
{
|
|
331
|
-
ref: container,
|
|
332
|
-
"data-slot": "studio-controls",
|
|
333
|
-
className: "min-h-0 flex-1 overflow-auto px-1 py-1.5",
|
|
334
|
-
style: tweakpaneTheme
|
|
335
|
-
}
|
|
336
|
-
),
|
|
337
|
-
/* @__PURE__ */ jsxs2("footer", { className: "grid gap-2 rounded-[calc(var(--radius-lg)-0.25rem)] bg-card p-2", children: [
|
|
338
|
-
failure && /* @__PURE__ */ jsx5("div", { className: "text-destructive", children: failure }),
|
|
403
|
+
/* @__PURE__ */ jsx7(PanelContent, { ref: container, "data-slot": "studio-controls", style: tweakpaneTheme }),
|
|
404
|
+
/* @__PURE__ */ jsxs2(PanelFooter, { children: [
|
|
405
|
+
failure && /* @__PURE__ */ jsx7("div", { className: "text-destructive", children: failure }),
|
|
339
406
|
changes.length > 0 && /* @__PURE__ */ jsxs2("div", { className: "truncate text-muted-foreground", title: changes.join(", "), children: [
|
|
340
407
|
changes.length,
|
|
341
408
|
" changed: ",
|
|
342
|
-
/* @__PURE__ */
|
|
409
|
+
/* @__PURE__ */ jsx7("span", { className: "text-foreground", children: changes.join(", ") })
|
|
343
410
|
] }),
|
|
344
411
|
/* @__PURE__ */ jsxs2("div", { className: "flex gap-2", children: [
|
|
345
|
-
/* @__PURE__ */
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
412
|
+
/* @__PURE__ */ jsx7(
|
|
413
|
+
Hint,
|
|
414
|
+
{
|
|
415
|
+
className: "flex items-center gap-2",
|
|
416
|
+
content: /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
417
|
+
"Hold to compare with saved ",
|
|
418
|
+
/* @__PURE__ */ jsx7(Kbd, { children: "\\" })
|
|
419
|
+
] }),
|
|
420
|
+
children: /* @__PURE__ */ jsx7(
|
|
421
|
+
Button,
|
|
422
|
+
{
|
|
423
|
+
variant: "secondary",
|
|
424
|
+
size: "icon-sm",
|
|
425
|
+
"aria-label": "Hold to compare with saved",
|
|
426
|
+
"aria-pressed": handle.comparing,
|
|
427
|
+
disabled: !state?.dirty,
|
|
428
|
+
className: "shrink-0 aria-pressed:bg-primary aria-pressed:text-primary-foreground",
|
|
429
|
+
onPointerDown: (event) => {
|
|
430
|
+
event.currentTarget.setPointerCapture(event.pointerId);
|
|
431
|
+
onCompare(true);
|
|
432
|
+
},
|
|
433
|
+
onPointerUp: () => onCompare(false),
|
|
434
|
+
onPointerCancel: () => onCompare(false),
|
|
435
|
+
children: /* @__PURE__ */ jsx7(SquareSplitHorizontal, {})
|
|
436
|
+
}
|
|
437
|
+
)
|
|
438
|
+
}
|
|
439
|
+
),
|
|
440
|
+
/* @__PURE__ */ jsx7(
|
|
370
441
|
Button,
|
|
371
442
|
{
|
|
372
443
|
variant: "secondary",
|
|
@@ -377,11 +448,11 @@ function Inspector({
|
|
|
377
448
|
children: "Discard"
|
|
378
449
|
}
|
|
379
450
|
),
|
|
380
|
-
state?.conflict ? /* @__PURE__ */
|
|
451
|
+
state?.conflict ? /* @__PURE__ */ jsx7(Button, { variant: "destructive", size: "sm", className: "flex-1", onClick: () => save(true), children: "Overwrite file" }) : /* @__PURE__ */ jsxs2(Button, { size: "sm", className: "flex-1", disabled: !editable2, onClick: () => save(), children: [
|
|
381
452
|
"Save",
|
|
382
453
|
/* @__PURE__ */ jsxs2(KbdGroup, { children: [
|
|
383
|
-
/* @__PURE__ */
|
|
384
|
-
/* @__PURE__ */
|
|
454
|
+
/* @__PURE__ */ jsx7(Kbd, { children: "\u2318" }),
|
|
455
|
+
/* @__PURE__ */ jsx7(Kbd, { children: "S" })
|
|
385
456
|
] })
|
|
386
457
|
] })
|
|
387
458
|
] })
|
|
@@ -390,16 +461,148 @@ function Inspector({
|
|
|
390
461
|
}
|
|
391
462
|
|
|
392
463
|
// src/react/logo.tsx
|
|
393
|
-
import { jsx as
|
|
464
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
394
465
|
function Logo(props) {
|
|
395
|
-
return /* @__PURE__ */
|
|
466
|
+
return /* @__PURE__ */ jsx8("svg", { viewBox: "0 0 352 144", fill: "currentColor", "aria-label": "JOYCO", role: "img", ...props, children: /* @__PURE__ */ jsx8("path", { d: "M328 96L280 144H0V40H176V112H192V24H0V0H352V24H328V96Z" }) });
|
|
396
467
|
}
|
|
397
468
|
|
|
469
|
+
// src/react/pinned-tools.ts
|
|
470
|
+
import { useEffect as useEffect2, useState as useState2 } from "react";
|
|
471
|
+
var STORAGE_KEY = "joyco-studio:pinned-tools";
|
|
472
|
+
var CHANGE_EVENT = "joyco-studio:pins-changed";
|
|
473
|
+
function readPins() {
|
|
474
|
+
try {
|
|
475
|
+
const value = JSON.parse(localStorage.getItem(STORAGE_KEY) ?? "[]");
|
|
476
|
+
return Array.isArray(value) ? value.filter((id) => typeof id === "string") : [];
|
|
477
|
+
} catch {
|
|
478
|
+
return [];
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
function usePinnedTools(studio) {
|
|
482
|
+
const [pins, setPins] = useState2([]);
|
|
483
|
+
useEffect2(() => {
|
|
484
|
+
setPins(readPins());
|
|
485
|
+
const onChange = (event) => setPins(event.detail);
|
|
486
|
+
const onStorage = (event) => {
|
|
487
|
+
if (event.key === STORAGE_KEY || event.key === null) setPins(readPins());
|
|
488
|
+
};
|
|
489
|
+
window.addEventListener(CHANGE_EVENT, onChange);
|
|
490
|
+
window.addEventListener("storage", onStorage);
|
|
491
|
+
return () => {
|
|
492
|
+
window.removeEventListener(CHANGE_EVENT, onChange);
|
|
493
|
+
window.removeEventListener("storage", onStorage);
|
|
494
|
+
};
|
|
495
|
+
}, []);
|
|
496
|
+
const pinned = new Set(pins);
|
|
497
|
+
const tools = [...studio.tools].sort(
|
|
498
|
+
(a, b) => Number(pinned.has(b.definition.id)) - Number(pinned.has(a.definition.id))
|
|
499
|
+
);
|
|
500
|
+
const togglePin = (id) => {
|
|
501
|
+
const next = pinned.has(id) ? pins.filter((pin) => pin !== id) : [...pins, id];
|
|
502
|
+
try {
|
|
503
|
+
localStorage.setItem(STORAGE_KEY, JSON.stringify(next));
|
|
504
|
+
} catch {
|
|
505
|
+
}
|
|
506
|
+
window.dispatchEvent(new CustomEvent(CHANGE_EVENT, { detail: next }));
|
|
507
|
+
};
|
|
508
|
+
return { tools, pinned, togglePin };
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
// src/react/preview-canvas.tsx
|
|
512
|
+
import { RotateCw } from "lucide-react";
|
|
513
|
+
import { forwardRef as forwardRef3, useImperativeHandle, useRef as useRef2, useState as useState4 } from "react";
|
|
514
|
+
|
|
515
|
+
// src/react/canvas-toolbar.tsx
|
|
516
|
+
import { Maximize, Minimize, Pin, PinOff } from "lucide-react";
|
|
517
|
+
import { useState as useState3 } from "react";
|
|
518
|
+
import { jsx as jsx9, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
519
|
+
function CanvasToolbar({ label, expanded = false, onToggle, children }) {
|
|
520
|
+
const [ghost, setGhost] = useState3(false);
|
|
521
|
+
const ExpandIcon = expanded ? Minimize : Maximize;
|
|
522
|
+
const PinIcon = ghost ? PinOff : Pin;
|
|
523
|
+
return /* @__PURE__ */ jsx9(
|
|
524
|
+
"div",
|
|
525
|
+
{
|
|
526
|
+
className: "studio-canvas-toolbar",
|
|
527
|
+
"data-slot": "canvas-toolbar",
|
|
528
|
+
"data-expanded": expanded || void 0,
|
|
529
|
+
"data-ghost": !expanded && ghost || void 0,
|
|
530
|
+
role: "group",
|
|
531
|
+
"aria-label": label,
|
|
532
|
+
children: /* @__PURE__ */ jsxs3(StudioToolbar, { className: "studio-canvas-actions", children: [
|
|
533
|
+
children,
|
|
534
|
+
onToggle && /* @__PURE__ */ jsx9("div", { className: "studio-canvas-toggle", children: /* @__PURE__ */ jsxs3("button", { "data-slot": "toolbar-action", type: "button", "aria-pressed": expanded, onClick: onToggle, children: [
|
|
535
|
+
/* @__PURE__ */ jsx9(ExpandIcon, { size: 14, strokeWidth: 1.5, "aria-hidden": true }),
|
|
536
|
+
expanded ? "Contain canvas" : "Expand"
|
|
537
|
+
] }) }),
|
|
538
|
+
!expanded && /* @__PURE__ */ jsx9(
|
|
539
|
+
"button",
|
|
540
|
+
{
|
|
541
|
+
type: "button",
|
|
542
|
+
"aria-label": `Auto-hide ${label.toLowerCase()} header`,
|
|
543
|
+
"aria-pressed": ghost,
|
|
544
|
+
title: ghost ? "Pin header" : "Auto-hide header",
|
|
545
|
+
onClick: () => setGhost(!ghost),
|
|
546
|
+
children: /* @__PURE__ */ jsx9(PinIcon, { size: 14, strokeWidth: 1.5, "aria-hidden": true })
|
|
547
|
+
}
|
|
548
|
+
)
|
|
549
|
+
] })
|
|
550
|
+
}
|
|
551
|
+
);
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
// src/react/preview-canvas.tsx
|
|
555
|
+
import { jsx as jsx10, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
556
|
+
var PreviewCanvas = forwardRef3(function PreviewCanvas2({ title = "Preview", expanded: controlled, onExpandedChange, onReload, toolbar, ...props }, ref) {
|
|
557
|
+
const [localExpanded, setExpanded] = useState4(false);
|
|
558
|
+
const expanded = controlled ?? localExpanded;
|
|
559
|
+
const frame = useRef2(null);
|
|
560
|
+
useImperativeHandle(ref, () => frame.current, []);
|
|
561
|
+
return /* @__PURE__ */ jsxs4(
|
|
562
|
+
"section",
|
|
563
|
+
{
|
|
564
|
+
className: "studio-preview-canvas",
|
|
565
|
+
"data-slot": "preview-canvas",
|
|
566
|
+
"data-expanded": expanded || void 0,
|
|
567
|
+
"aria-label": `${title} canvas`,
|
|
568
|
+
children: [
|
|
569
|
+
/* @__PURE__ */ jsxs4(
|
|
570
|
+
CanvasToolbar,
|
|
571
|
+
{
|
|
572
|
+
label: "Preview canvas",
|
|
573
|
+
expanded,
|
|
574
|
+
onToggle: () => {
|
|
575
|
+
setExpanded(!expanded);
|
|
576
|
+
onExpandedChange?.(!expanded);
|
|
577
|
+
},
|
|
578
|
+
children: [
|
|
579
|
+
/* @__PURE__ */ jsx10(
|
|
580
|
+
"button",
|
|
581
|
+
{
|
|
582
|
+
type: "button",
|
|
583
|
+
"aria-label": "Reload preview",
|
|
584
|
+
title: "Reload preview",
|
|
585
|
+
onClick: () => {
|
|
586
|
+
onReload?.();
|
|
587
|
+
if (frame.current) frame.current.src = frame.current.src;
|
|
588
|
+
},
|
|
589
|
+
children: /* @__PURE__ */ jsx10(RotateCw, { size: 14, strokeWidth: 1.5, "aria-hidden": true })
|
|
590
|
+
}
|
|
591
|
+
),
|
|
592
|
+
/* @__PURE__ */ jsx10("div", { className: "studio-preview-source", children: toolbar ?? /* @__PURE__ */ jsx10("span", { className: "studio-preview-title", children: title }) })
|
|
593
|
+
]
|
|
594
|
+
}
|
|
595
|
+
),
|
|
596
|
+
/* @__PURE__ */ jsx10("iframe", { ...props, ref: frame, title })
|
|
597
|
+
]
|
|
598
|
+
}
|
|
599
|
+
);
|
|
600
|
+
});
|
|
601
|
+
|
|
398
602
|
// src/react/ui/sidebar.tsx
|
|
399
603
|
import * as React2 from "react";
|
|
400
604
|
import { cva as cva2 } from "class-variance-authority";
|
|
401
|
-
import {
|
|
402
|
-
import { Slot as Slot2 } from "radix-ui";
|
|
605
|
+
import { Slot as Slot4 } from "radix-ui";
|
|
403
606
|
|
|
404
607
|
// src/react/ui/hooks/use-mobile.ts
|
|
405
608
|
import * as React from "react";
|
|
@@ -421,15 +624,15 @@ function useIsMobile() {
|
|
|
421
624
|
// src/react/ui/sheet.tsx
|
|
422
625
|
import { XIcon } from "lucide-react";
|
|
423
626
|
import { Dialog as SheetPrimitive } from "radix-ui";
|
|
424
|
-
import { jsx as
|
|
627
|
+
import { jsx as jsx11, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
425
628
|
function Sheet({ ...props }) {
|
|
426
|
-
return /* @__PURE__ */
|
|
629
|
+
return /* @__PURE__ */ jsx11(SheetPrimitive.Root, { "data-slot": "sheet", ...props });
|
|
427
630
|
}
|
|
428
631
|
function SheetPortal({ ...props }) {
|
|
429
|
-
return /* @__PURE__ */
|
|
632
|
+
return /* @__PURE__ */ jsx11(SheetPrimitive.Portal, { "data-slot": "sheet-portal", ...props });
|
|
430
633
|
}
|
|
431
634
|
function SheetOverlay({ className, ...props }) {
|
|
432
|
-
return /* @__PURE__ */
|
|
635
|
+
return /* @__PURE__ */ jsx11(
|
|
433
636
|
SheetPrimitive.Overlay,
|
|
434
637
|
{
|
|
435
638
|
"data-slot": "sheet-overlay",
|
|
@@ -448,9 +651,9 @@ function SheetContent({
|
|
|
448
651
|
showCloseButton = true,
|
|
449
652
|
...props
|
|
450
653
|
}) {
|
|
451
|
-
return /* @__PURE__ */
|
|
452
|
-
/* @__PURE__ */
|
|
453
|
-
/* @__PURE__ */
|
|
654
|
+
return /* @__PURE__ */ jsxs5(SheetPortal, { children: [
|
|
655
|
+
/* @__PURE__ */ jsx11(SheetOverlay, {}),
|
|
656
|
+
/* @__PURE__ */ jsxs5(
|
|
454
657
|
SheetPrimitive.Content,
|
|
455
658
|
{
|
|
456
659
|
"data-slot": "sheet-content",
|
|
@@ -465,9 +668,9 @@ function SheetContent({
|
|
|
465
668
|
...props,
|
|
466
669
|
children: [
|
|
467
670
|
children,
|
|
468
|
-
showCloseButton && /* @__PURE__ */
|
|
469
|
-
/* @__PURE__ */
|
|
470
|
-
/* @__PURE__ */
|
|
671
|
+
showCloseButton && /* @__PURE__ */ jsxs5(SheetPrimitive.Close, { className: "absolute top-4 right-4 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none data-[state=open]:bg-secondary", children: [
|
|
672
|
+
/* @__PURE__ */ jsx11(XIcon, { className: "size-4" }),
|
|
673
|
+
/* @__PURE__ */ jsx11("span", { className: "sr-only", children: "Close" })
|
|
471
674
|
] })
|
|
472
675
|
]
|
|
473
676
|
}
|
|
@@ -475,10 +678,10 @@ function SheetContent({
|
|
|
475
678
|
] });
|
|
476
679
|
}
|
|
477
680
|
function SheetHeader({ className, ...props }) {
|
|
478
|
-
return /* @__PURE__ */
|
|
681
|
+
return /* @__PURE__ */ jsx11("div", { "data-slot": "sheet-header", className: cn("flex flex-col gap-1.5 p-4", className), ...props });
|
|
479
682
|
}
|
|
480
683
|
function SheetTitle({ className, ...props }) {
|
|
481
|
-
return /* @__PURE__ */
|
|
684
|
+
return /* @__PURE__ */ jsx11(
|
|
482
685
|
SheetPrimitive.Title,
|
|
483
686
|
{
|
|
484
687
|
"data-slot": "sheet-title",
|
|
@@ -488,7 +691,7 @@ function SheetTitle({ className, ...props }) {
|
|
|
488
691
|
);
|
|
489
692
|
}
|
|
490
693
|
function SheetDescription({ className, ...props }) {
|
|
491
|
-
return /* @__PURE__ */
|
|
694
|
+
return /* @__PURE__ */ jsx11(
|
|
492
695
|
SheetPrimitive.Description,
|
|
493
696
|
{
|
|
494
697
|
"data-slot": "sheet-description",
|
|
@@ -499,7 +702,7 @@ function SheetDescription({ className, ...props }) {
|
|
|
499
702
|
}
|
|
500
703
|
|
|
501
704
|
// src/react/ui/sidebar.tsx
|
|
502
|
-
import { jsx as
|
|
705
|
+
import { jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
503
706
|
var SIDEBAR_COOKIE_NAME = "sidebar_state";
|
|
504
707
|
var SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
|
|
505
708
|
var SIDEBAR_WIDTH = "16rem";
|
|
@@ -554,7 +757,7 @@ function SidebarProvider({
|
|
|
554
757
|
}),
|
|
555
758
|
[state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar]
|
|
556
759
|
);
|
|
557
|
-
return /* @__PURE__ */
|
|
760
|
+
return /* @__PURE__ */ jsx12(SidebarContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx12(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ jsx12(
|
|
558
761
|
"div",
|
|
559
762
|
{
|
|
560
763
|
"data-slot": "sidebar-wrapper",
|
|
@@ -578,8 +781,9 @@ function Sidebar({
|
|
|
578
781
|
...props
|
|
579
782
|
}) {
|
|
580
783
|
const { isMobile, state, openMobile, setOpenMobile } = useSidebar();
|
|
784
|
+
const Surface = variant === "floating" ? Panel : "div";
|
|
581
785
|
if (collapsible === "none") {
|
|
582
|
-
return /* @__PURE__ */
|
|
786
|
+
return /* @__PURE__ */ jsx12(
|
|
583
787
|
"div",
|
|
584
788
|
{
|
|
585
789
|
"data-slot": "sidebar",
|
|
@@ -590,7 +794,7 @@ function Sidebar({
|
|
|
590
794
|
);
|
|
591
795
|
}
|
|
592
796
|
if (isMobile) {
|
|
593
|
-
return /* @__PURE__ */
|
|
797
|
+
return /* @__PURE__ */ jsx12(Sheet, { open: openMobile, onOpenChange: setOpenMobile, ...props, children: /* @__PURE__ */ jsxs6(
|
|
594
798
|
SheetContent,
|
|
595
799
|
{
|
|
596
800
|
"data-sidebar": "sidebar",
|
|
@@ -602,16 +806,16 @@ function Sidebar({
|
|
|
602
806
|
},
|
|
603
807
|
side,
|
|
604
808
|
children: [
|
|
605
|
-
/* @__PURE__ */
|
|
606
|
-
/* @__PURE__ */
|
|
607
|
-
/* @__PURE__ */
|
|
809
|
+
/* @__PURE__ */ jsxs6(SheetHeader, { className: "sr-only", children: [
|
|
810
|
+
/* @__PURE__ */ jsx12(SheetTitle, { children: "Sidebar" }),
|
|
811
|
+
/* @__PURE__ */ jsx12(SheetDescription, { children: "Displays the mobile sidebar." })
|
|
608
812
|
] }),
|
|
609
|
-
/* @__PURE__ */
|
|
813
|
+
/* @__PURE__ */ jsx12("div", { className: "flex h-full w-full flex-col", children })
|
|
610
814
|
]
|
|
611
815
|
}
|
|
612
816
|
) });
|
|
613
817
|
}
|
|
614
|
-
return /* @__PURE__ */
|
|
818
|
+
return /* @__PURE__ */ jsxs6(
|
|
615
819
|
"div",
|
|
616
820
|
{
|
|
617
821
|
className: "group peer hidden text-sidebar-foreground md:block",
|
|
@@ -621,7 +825,7 @@ function Sidebar({
|
|
|
621
825
|
"data-side": side,
|
|
622
826
|
"data-slot": "sidebar",
|
|
623
827
|
children: [
|
|
624
|
-
/* @__PURE__ */
|
|
828
|
+
/* @__PURE__ */ jsx12(
|
|
625
829
|
"div",
|
|
626
830
|
{
|
|
627
831
|
"data-slot": "sidebar-gap",
|
|
@@ -633,7 +837,7 @@ function Sidebar({
|
|
|
633
837
|
)
|
|
634
838
|
}
|
|
635
839
|
),
|
|
636
|
-
/* @__PURE__ */
|
|
840
|
+
/* @__PURE__ */ jsx12(
|
|
637
841
|
"div",
|
|
638
842
|
{
|
|
639
843
|
"data-slot": "sidebar-container",
|
|
@@ -645,12 +849,12 @@ function Sidebar({
|
|
|
645
849
|
className
|
|
646
850
|
),
|
|
647
851
|
...props,
|
|
648
|
-
children: /* @__PURE__ */
|
|
649
|
-
|
|
852
|
+
children: /* @__PURE__ */ jsx12(
|
|
853
|
+
Surface,
|
|
650
854
|
{
|
|
651
855
|
"data-sidebar": "sidebar",
|
|
652
856
|
"data-slot": "sidebar-inner",
|
|
653
|
-
className: "flex h-full w-full flex-col
|
|
857
|
+
className: cn("flex h-full w-full flex-col", variant !== "floating" && "bg-sidebar"),
|
|
654
858
|
children
|
|
655
859
|
}
|
|
656
860
|
)
|
|
@@ -661,7 +865,7 @@ function Sidebar({
|
|
|
661
865
|
);
|
|
662
866
|
}
|
|
663
867
|
function SidebarHeader({ className, ...props }) {
|
|
664
|
-
return /* @__PURE__ */
|
|
868
|
+
return /* @__PURE__ */ jsx12(
|
|
665
869
|
"div",
|
|
666
870
|
{
|
|
667
871
|
"data-slot": "sidebar-header",
|
|
@@ -672,7 +876,7 @@ function SidebarHeader({ className, ...props }) {
|
|
|
672
876
|
);
|
|
673
877
|
}
|
|
674
878
|
function SidebarFooter({ className, ...props }) {
|
|
675
|
-
return /* @__PURE__ */
|
|
879
|
+
return /* @__PURE__ */ jsx12(
|
|
676
880
|
"div",
|
|
677
881
|
{
|
|
678
882
|
"data-slot": "sidebar-footer",
|
|
@@ -683,7 +887,7 @@ function SidebarFooter({ className, ...props }) {
|
|
|
683
887
|
);
|
|
684
888
|
}
|
|
685
889
|
function SidebarContent({ className, ...props }) {
|
|
686
|
-
return /* @__PURE__ */
|
|
890
|
+
return /* @__PURE__ */ jsx12(
|
|
687
891
|
"div",
|
|
688
892
|
{
|
|
689
893
|
"data-slot": "sidebar-content",
|
|
@@ -697,7 +901,7 @@ function SidebarContent({ className, ...props }) {
|
|
|
697
901
|
);
|
|
698
902
|
}
|
|
699
903
|
function SidebarGroup({ className, ...props }) {
|
|
700
|
-
return /* @__PURE__ */
|
|
904
|
+
return /* @__PURE__ */ jsx12(
|
|
701
905
|
"div",
|
|
702
906
|
{
|
|
703
907
|
"data-slot": "sidebar-group",
|
|
@@ -708,7 +912,7 @@ function SidebarGroup({ className, ...props }) {
|
|
|
708
912
|
);
|
|
709
913
|
}
|
|
710
914
|
function SidebarMenu({ className, ...props }) {
|
|
711
|
-
return /* @__PURE__ */
|
|
915
|
+
return /* @__PURE__ */ jsx12(
|
|
712
916
|
"ul",
|
|
713
917
|
{
|
|
714
918
|
"data-slot": "sidebar-menu",
|
|
@@ -719,7 +923,7 @@ function SidebarMenu({ className, ...props }) {
|
|
|
719
923
|
);
|
|
720
924
|
}
|
|
721
925
|
function SidebarMenuItem({ className, ...props }) {
|
|
722
|
-
return /* @__PURE__ */
|
|
926
|
+
return /* @__PURE__ */ jsx12(
|
|
723
927
|
"li",
|
|
724
928
|
{
|
|
725
929
|
"data-slot": "sidebar-menu-item",
|
|
@@ -758,9 +962,9 @@ function SidebarMenuButton({
|
|
|
758
962
|
className,
|
|
759
963
|
...props
|
|
760
964
|
}) {
|
|
761
|
-
const Comp = asChild ?
|
|
965
|
+
const Comp = asChild ? Slot4.Root : "button";
|
|
762
966
|
const { isMobile, state } = useSidebar();
|
|
763
|
-
const button2 = /* @__PURE__ */
|
|
967
|
+
const button2 = /* @__PURE__ */ jsx12(
|
|
764
968
|
Comp,
|
|
765
969
|
{
|
|
766
970
|
"data-slot": "sidebar-menu-button",
|
|
@@ -771,50 +975,61 @@ function SidebarMenuButton({
|
|
|
771
975
|
...props
|
|
772
976
|
}
|
|
773
977
|
);
|
|
774
|
-
if (!tooltip)
|
|
775
|
-
|
|
776
|
-
}
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
978
|
+
if (!tooltip) return button2;
|
|
979
|
+
const { children, ...hint } = typeof tooltip === "string" ? { children: tooltip } : tooltip;
|
|
980
|
+
return /* @__PURE__ */ jsx12(Hint, { side: "right", align: "center", hidden: state !== "collapsed" || isMobile, ...hint, content: children, children: button2 });
|
|
981
|
+
}
|
|
982
|
+
function SidebarMenuAction({
|
|
983
|
+
className,
|
|
984
|
+
asChild = false,
|
|
985
|
+
showOnHover = false,
|
|
986
|
+
...props
|
|
987
|
+
}) {
|
|
988
|
+
const Comp = asChild ? Slot4.Root : "button";
|
|
989
|
+
return /* @__PURE__ */ jsx12(
|
|
990
|
+
Comp,
|
|
991
|
+
{
|
|
992
|
+
"data-slot": "sidebar-menu-action",
|
|
993
|
+
"data-sidebar": "menu-action",
|
|
994
|
+
className: cn(
|
|
995
|
+
"absolute top-1/2 right-1 flex aspect-square w-5 -translate-y-1/2 items-center justify-center rounded-md p-0 text-sidebar-foreground ring-sidebar-ring outline-hidden transition-transform peer-hover/menu-button:text-sidebar-accent-foreground hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
|
|
996
|
+
// Increases the hit area of the button on mobile.
|
|
997
|
+
"after:absolute after:-inset-2 md:after:hidden",
|
|
998
|
+
"group-data-[collapsible=icon]:hidden",
|
|
999
|
+
showOnHover && "group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 peer-data-[active=true]/menu-button:text-sidebar-accent-foreground data-[state=open]:opacity-100 md:opacity-0",
|
|
1000
|
+
className
|
|
1001
|
+
),
|
|
1002
|
+
...props
|
|
1003
|
+
}
|
|
1004
|
+
);
|
|
786
1005
|
}
|
|
787
1006
|
|
|
788
1007
|
// src/react/studio.tsx
|
|
789
|
-
import { jsx as
|
|
1008
|
+
import { Fragment as Fragment2, jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
790
1009
|
var CONNECTION = {
|
|
791
1010
|
connected: { icon: PlugZap, tone: "text-success", label: "Runtime connected" },
|
|
792
1011
|
connecting: { icon: LoaderCircle, tone: "text-warning animate-spin", label: "Connecting to runtime" },
|
|
793
1012
|
offline: { icon: Unplug, tone: "text-destructive", label: "Runtime offline" },
|
|
794
1013
|
local: { icon: Unplug, tone: "text-faint", label: "No runtime" }
|
|
795
1014
|
};
|
|
796
|
-
var PANEL = "rounded-lg border border-sidebar-border bg-sidebar/85 shadow-xl shadow-black/40 backdrop-blur-xl";
|
|
797
|
-
var PANEL_CONTAINER = cn(
|
|
798
|
-
"[&>[data-slot=sidebar-inner]]:bg-sidebar/85 [&>[data-slot=sidebar-inner]]:shadow-xl [&>[data-slot=sidebar-inner]]:shadow-black/40 [&>[data-slot=sidebar-inner]]:backdrop-blur-xl"
|
|
799
|
-
);
|
|
800
1015
|
function StudioFooter({ connection }) {
|
|
801
1016
|
const { state, toggleSidebar } = useSidebar();
|
|
802
1017
|
const { icon: Status, tone, label } = CONNECTION[connection.phase];
|
|
803
1018
|
const Toggle = state === "expanded" ? PanelLeftClose : PanelLeftOpen;
|
|
804
|
-
return /* @__PURE__ */
|
|
805
|
-
/* @__PURE__ */
|
|
806
|
-
/* @__PURE__ */
|
|
807
|
-
/* @__PURE__ */
|
|
1019
|
+
return /* @__PURE__ */ jsx13(SidebarFooter, { children: /* @__PURE__ */ jsxs7(SidebarMenu, { children: [
|
|
1020
|
+
/* @__PURE__ */ jsx13(SidebarMenuItem, { children: /* @__PURE__ */ jsxs7(SidebarMenuButton, { tooltip: label, className: "cursor-default hover:bg-transparent active:bg-transparent", children: [
|
|
1021
|
+
/* @__PURE__ */ jsx13(Status, { className: tone }),
|
|
1022
|
+
/* @__PURE__ */ jsx13("span", { className: "text-clip! group-data-[collapsible=icon]:hidden", children: label })
|
|
808
1023
|
] }) }),
|
|
809
|
-
/* @__PURE__ */
|
|
1024
|
+
/* @__PURE__ */ jsx13(SidebarMenuItem, { children: /* @__PURE__ */ jsxs7(
|
|
810
1025
|
SidebarMenuButton,
|
|
811
1026
|
{
|
|
812
1027
|
"aria-label": `${state === "expanded" ? "Collapse" : "Expand"} sidebar`,
|
|
813
1028
|
tooltip: `${state === "expanded" ? "Collapse" : "Expand"} sidebar`,
|
|
814
1029
|
onClick: toggleSidebar,
|
|
815
1030
|
children: [
|
|
816
|
-
/* @__PURE__ */
|
|
817
|
-
/* @__PURE__ */
|
|
1031
|
+
/* @__PURE__ */ jsx13(Toggle, {}),
|
|
1032
|
+
/* @__PURE__ */ jsx13("span", { className: "text-clip! group-data-[collapsible=icon]:hidden", children: "Collapse" })
|
|
818
1033
|
]
|
|
819
1034
|
}
|
|
820
1035
|
) })
|
|
@@ -836,14 +1051,16 @@ function forwardShortcuts(frame) {
|
|
|
836
1051
|
} catch {
|
|
837
1052
|
}
|
|
838
1053
|
}
|
|
839
|
-
function Studio({ studio }) {
|
|
1054
|
+
function Studio({ studio, previewComponent, getConfigFileHref }) {
|
|
840
1055
|
useStudio(studio);
|
|
841
|
-
const
|
|
842
|
-
const [
|
|
843
|
-
const [
|
|
844
|
-
const
|
|
1056
|
+
const { tools, pinned, togglePin } = usePinnedTools(studio);
|
|
1057
|
+
const [mounted, setMounted] = useState7(false);
|
|
1058
|
+
const [panelsHidden, setPanelsHidden] = useState7(false);
|
|
1059
|
+
const [selected, setSelected] = useState7(studio.tools[0]?.definition.id);
|
|
1060
|
+
const preview = useRef3(null);
|
|
845
1061
|
const handle = studio.tools.find((tool) => tool.definition.id === selected);
|
|
846
|
-
|
|
1062
|
+
const Preview = previewComponent ?? (handle?.definition.previewLayout === "custom" ? "iframe" : PreviewCanvas);
|
|
1063
|
+
useEffect4(() => {
|
|
847
1064
|
const onKey = (event) => {
|
|
848
1065
|
if (event.defaultPrevented || event.isComposing || event.altKey || !(event.metaKey || event.ctrlKey)) return;
|
|
849
1066
|
if (event.key.toLowerCase() !== "b") return;
|
|
@@ -864,10 +1081,10 @@ function Studio({ studio }) {
|
|
|
864
1081
|
handle.compare(showSaved);
|
|
865
1082
|
postCompare(preview.current?.contentWindow, handle.definition.id, showSaved);
|
|
866
1083
|
};
|
|
867
|
-
|
|
868
|
-
const current =
|
|
1084
|
+
useEffect4(() => () => handle?.compare(false), [handle]);
|
|
1085
|
+
const current = useRef3({ handle, compare });
|
|
869
1086
|
current.current = { handle, compare };
|
|
870
|
-
|
|
1087
|
+
useEffect4(() => {
|
|
871
1088
|
const onKey = (event) => {
|
|
872
1089
|
if (event.key !== COMPARE_KEY || editable(event.target) || event.repeat) return;
|
|
873
1090
|
event.preventDefault();
|
|
@@ -885,7 +1102,7 @@ function Studio({ studio }) {
|
|
|
885
1102
|
removeEventListener("blur", release);
|
|
886
1103
|
};
|
|
887
1104
|
}, []);
|
|
888
|
-
|
|
1105
|
+
useEffect4(() => {
|
|
889
1106
|
const fromHash = () => {
|
|
890
1107
|
const id = decodeURIComponent(location.hash.slice(1));
|
|
891
1108
|
if (studio.tools.some((handle2) => handle2.definition.id === id)) setSelected(id);
|
|
@@ -897,143 +1114,176 @@ function Studio({ studio }) {
|
|
|
897
1114
|
}, [studio]);
|
|
898
1115
|
if (!mounted) return null;
|
|
899
1116
|
const sidebarOpen = !document.cookie.split("; ").includes("sidebar_state=false");
|
|
900
|
-
return /* @__PURE__ */
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
"
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
{
|
|
940
|
-
side: side === "left" ? "right" : "left",
|
|
941
|
-
sideOffset: 8,
|
|
942
|
-
className: "flex items-center gap-2",
|
|
943
|
-
children: [
|
|
944
|
-
"Show Studio panels",
|
|
945
|
-
/* @__PURE__ */ jsxs5(KbdGroup, { children: [
|
|
946
|
-
/* @__PURE__ */ jsx9(Kbd, { children: "\u2318/Ctrl" }),
|
|
947
|
-
/* @__PURE__ */ jsx9(Kbd, { children: "B" })
|
|
948
|
-
] })
|
|
949
|
-
]
|
|
950
|
-
}
|
|
951
|
-
)
|
|
952
|
-
] })
|
|
953
|
-
},
|
|
954
|
-
side
|
|
955
|
-
);
|
|
956
|
-
}),
|
|
957
|
-
/* @__PURE__ */ jsxs5(
|
|
958
|
-
Sidebar,
|
|
959
|
-
{
|
|
960
|
-
collapsible: "icon",
|
|
961
|
-
variant: "floating",
|
|
962
|
-
inert: panelsHidden,
|
|
963
|
-
"aria-hidden": panelsHidden,
|
|
964
|
-
className: cn(
|
|
965
|
-
PANEL_CONTAINER,
|
|
966
|
-
"transition-[left,right,width,translate] duration-200 ease-out motion-reduce:transition-none",
|
|
967
|
-
panelsHidden && "-translate-x-[calc(100%+1rem)]"
|
|
968
|
-
),
|
|
969
|
-
children: [
|
|
970
|
-
/* @__PURE__ */ jsx9(SidebarHeader, { className: "h-10 flex-row items-center overflow-hidden py-0 pr-0 pl-4 transition-[padding] duration-200 ease-out group-data-[collapsible=icon]:pl-[calc(1.5rem-0.875rem*352/144/2)] motion-reduce:transition-none", children: /* @__PURE__ */ jsxs5("span", { className: "flex items-center gap-2.5 text-foreground", children: [
|
|
971
|
-
/* @__PURE__ */ jsx9(Logo, { className: "h-3.5 w-auto shrink-0" }),
|
|
972
|
-
/* @__PURE__ */ jsx9("strong", { className: "tracking-[0.08em] whitespace-nowrap", children: "STUDIO" }),
|
|
973
|
-
/* @__PURE__ */ jsxs5("span", { "data-slot": "studio-version", className: "text-[10px] text-faint group-data-[collapsible=icon]:hidden", children: [
|
|
974
|
-
"v",
|
|
975
|
-
version
|
|
976
|
-
] })
|
|
977
|
-
] }) }),
|
|
978
|
-
/* @__PURE__ */ jsx9(SidebarContent, { children: /* @__PURE__ */ jsx9(SidebarGroup, { children: /* @__PURE__ */ jsx9(SidebarMenu, { children: studio.tools.map(({ definition, state }) => {
|
|
979
|
-
const title = definition.title ?? definition.id;
|
|
980
|
-
return /* @__PURE__ */ jsx9(SidebarMenuItem, { children: /* @__PURE__ */ jsxs5(
|
|
981
|
-
SidebarMenuButton,
|
|
982
|
-
{
|
|
983
|
-
isActive: definition.id === selected,
|
|
984
|
-
tooltip: title,
|
|
985
|
-
onClick: () => location.hash = definition.id,
|
|
986
|
-
children: [
|
|
987
|
-
/* @__PURE__ */ jsxs5("span", { className: "relative", children: [
|
|
988
|
-
/* @__PURE__ */ jsx9(ToolIcon, { icon: definition.icon, className: "size-4" }),
|
|
989
|
-
state?.dirty && /* @__PURE__ */ jsx9(
|
|
990
|
-
"span",
|
|
991
|
-
{
|
|
992
|
-
"aria-label": state.conflict ? "Changed on disk" : "Unsaved",
|
|
993
|
-
className: cn(
|
|
994
|
-
"absolute -top-0.5 -right-0.5 size-1.5 rounded-full",
|
|
995
|
-
state.conflict ? "bg-destructive" : "bg-warning"
|
|
996
|
-
)
|
|
997
|
-
}
|
|
998
|
-
)
|
|
1117
|
+
return /* @__PURE__ */ jsxs7(
|
|
1118
|
+
SidebarProvider,
|
|
1119
|
+
{
|
|
1120
|
+
defaultOpen: sidebarOpen,
|
|
1121
|
+
"data-preview-layout": previewComponent ? "canvas" : handle?.definition.previewLayout ?? "canvas",
|
|
1122
|
+
className: "studio-workspace relative h-svh min-h-0 overflow-hidden text-xs",
|
|
1123
|
+
children: [
|
|
1124
|
+
handle?.definition.preview ? /* @__PURE__ */ jsx13(
|
|
1125
|
+
Preview,
|
|
1126
|
+
{
|
|
1127
|
+
"data-slot": "studio-preview",
|
|
1128
|
+
ref: preview,
|
|
1129
|
+
src: handle.definition.preview,
|
|
1130
|
+
title: handle.definition.title ?? handle.definition.id,
|
|
1131
|
+
onLoad: (event) => forwardShortcuts(event.currentTarget)
|
|
1132
|
+
},
|
|
1133
|
+
handle.definition.id
|
|
1134
|
+
) : /* @__PURE__ */ jsx13("div", { className: "absolute inset-0 grid place-items-center text-faint", children: handle ? "This tool has no preview" : "No tools registered" }),
|
|
1135
|
+
panelsHidden && ["left", "right"].map((side) => {
|
|
1136
|
+
const Chevron = side === "left" ? ChevronRight : ChevronLeft;
|
|
1137
|
+
return /* @__PURE__ */ jsx13(
|
|
1138
|
+
"div",
|
|
1139
|
+
{
|
|
1140
|
+
"data-slot": "studio-panel-edge",
|
|
1141
|
+
"data-side": side,
|
|
1142
|
+
className: cn("group/edge absolute inset-y-0 z-20 w-8", side === "left" ? "left-0" : "right-0"),
|
|
1143
|
+
children: /* @__PURE__ */ jsx13(
|
|
1144
|
+
Hint,
|
|
1145
|
+
{
|
|
1146
|
+
side: side === "left" ? "right" : "left",
|
|
1147
|
+
sideOffset: 8,
|
|
1148
|
+
className: "flex items-center gap-2",
|
|
1149
|
+
content: /* @__PURE__ */ jsxs7(Fragment2, { children: [
|
|
1150
|
+
"Show Studio panels",
|
|
1151
|
+
" ",
|
|
1152
|
+
/* @__PURE__ */ jsxs7(KbdGroup, { children: [
|
|
1153
|
+
/* @__PURE__ */ jsx13(Kbd, { children: "\u2318/Ctrl" }),
|
|
1154
|
+
/* @__PURE__ */ jsx13(Kbd, { children: "B" })
|
|
1155
|
+
] })
|
|
999
1156
|
] }),
|
|
1000
|
-
/* @__PURE__ */
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1157
|
+
children: /* @__PURE__ */ jsx13(Panel, { asChild: true, children: /* @__PURE__ */ jsx13(
|
|
1158
|
+
Button,
|
|
1159
|
+
{
|
|
1160
|
+
"data-slot": "studio-panel-reveal",
|
|
1161
|
+
variant: "ghost",
|
|
1162
|
+
size: "icon",
|
|
1163
|
+
"aria-label": "Show Studio panels",
|
|
1164
|
+
onClick: () => setPanelsHidden(false),
|
|
1165
|
+
className: cn(
|
|
1166
|
+
"absolute top-1/2 h-16 w-6 -translate-y-1/2 cursor-pointer px-0 text-sidebar-foreground opacity-0 transition-[translate,opacity] duration-200 ease-out hover:bg-sidebar/95 hover:text-foreground focus:translate-x-0 focus:opacity-100 group-hover/edge:translate-x-0 group-hover/edge:opacity-100 motion-reduce:transition-none [@media(hover:none)]:translate-x-0 [@media(hover:none)]:opacity-100",
|
|
1167
|
+
side === "left" ? "left-1 -translate-x-[calc(100%+0.25rem)]" : "right-1 translate-x-[calc(100%+0.25rem)]"
|
|
1168
|
+
),
|
|
1169
|
+
children: /* @__PURE__ */ jsx13(Chevron, { "aria-hidden": true })
|
|
1170
|
+
}
|
|
1171
|
+
) })
|
|
1172
|
+
}
|
|
1173
|
+
)
|
|
1174
|
+
},
|
|
1175
|
+
side
|
|
1176
|
+
);
|
|
1177
|
+
}),
|
|
1178
|
+
/* @__PURE__ */ jsxs7(
|
|
1179
|
+
Sidebar,
|
|
1180
|
+
{
|
|
1181
|
+
collapsible: "icon",
|
|
1182
|
+
variant: "floating",
|
|
1183
|
+
inert: panelsHidden,
|
|
1184
|
+
"aria-hidden": panelsHidden,
|
|
1185
|
+
className: cn(
|
|
1186
|
+
"transition-[left,right,width,translate] duration-200 ease-out motion-reduce:transition-none",
|
|
1187
|
+
panelsHidden && "-translate-x-[calc(100%+1rem)]"
|
|
1188
|
+
),
|
|
1189
|
+
children: [
|
|
1190
|
+
/* @__PURE__ */ jsx13(SidebarHeader, { className: "h-10 flex-row items-center overflow-hidden py-0 pr-0 pl-4 transition-[padding] duration-200 ease-out group-data-[collapsible=icon]:pl-[calc(1.5rem-0.875rem*352/144/2)] motion-reduce:transition-none", children: /* @__PURE__ */ jsxs7("span", { className: "flex items-center gap-2.5 text-foreground", children: [
|
|
1191
|
+
/* @__PURE__ */ jsx13(Logo, { className: "h-3.5 w-auto shrink-0" }),
|
|
1192
|
+
/* @__PURE__ */ jsx13("strong", { className: "tracking-[0.08em] whitespace-nowrap", children: "STUDIO" }),
|
|
1193
|
+
/* @__PURE__ */ jsxs7("span", { "data-slot": "studio-version", className: "text-[10px] text-faint group-data-[collapsible=icon]:hidden", children: [
|
|
1194
|
+
"v",
|
|
1195
|
+
version
|
|
1196
|
+
] })
|
|
1197
|
+
] }) }),
|
|
1198
|
+
/* @__PURE__ */ jsx13(SidebarContent, { children: /* @__PURE__ */ jsx13(SidebarGroup, { children: /* @__PURE__ */ jsx13(SidebarMenu, { children: tools.map(({ definition, state }) => {
|
|
1199
|
+
const title = definition.title ?? definition.id;
|
|
1200
|
+
const isPinned = pinned.has(definition.id);
|
|
1201
|
+
const pinLabel = `${isPinned ? "Unpin" : "Pin"} ${title}`;
|
|
1202
|
+
return /* @__PURE__ */ jsxs7(SidebarMenuItem, { children: [
|
|
1203
|
+
/* @__PURE__ */ jsxs7(
|
|
1204
|
+
SidebarMenuButton,
|
|
1205
|
+
{
|
|
1206
|
+
isActive: definition.id === selected,
|
|
1207
|
+
tooltip: title,
|
|
1208
|
+
onClick: () => location.hash = definition.id,
|
|
1209
|
+
children: [
|
|
1210
|
+
/* @__PURE__ */ jsxs7("span", { className: "relative", children: [
|
|
1211
|
+
/* @__PURE__ */ jsx13(ToolIcon, { icon: definition.icon, className: "size-4" }),
|
|
1212
|
+
state?.dirty && /* @__PURE__ */ jsx13(
|
|
1213
|
+
"span",
|
|
1214
|
+
{
|
|
1215
|
+
"aria-label": state.conflict ? "Changed on disk" : "Unsaved",
|
|
1216
|
+
className: cn(
|
|
1217
|
+
"absolute -top-0.5 -right-0.5 size-1.5 rounded-full",
|
|
1218
|
+
state.conflict ? "bg-destructive" : "bg-warning"
|
|
1219
|
+
)
|
|
1220
|
+
}
|
|
1221
|
+
)
|
|
1222
|
+
] }),
|
|
1223
|
+
/* @__PURE__ */ jsx13("span", { className: "text-clip! group-data-[collapsible=icon]:hidden", children: title })
|
|
1224
|
+
]
|
|
1225
|
+
}
|
|
1226
|
+
),
|
|
1227
|
+
/* @__PURE__ */ jsx13(Hint, { content: pinLabel, side: "right", children: /* @__PURE__ */ jsx13(
|
|
1228
|
+
SidebarMenuAction,
|
|
1229
|
+
{
|
|
1230
|
+
type: "button",
|
|
1231
|
+
"aria-label": pinLabel,
|
|
1232
|
+
"aria-pressed": isPinned,
|
|
1233
|
+
showOnHover: !isPinned,
|
|
1234
|
+
onClick: () => togglePin(definition.id),
|
|
1235
|
+
className: cn(
|
|
1236
|
+
"cursor-pointer [&>svg]:size-3 [@media(hover:none)]:opacity-100",
|
|
1237
|
+
isPinned && "text-sidebar-primary"
|
|
1238
|
+
),
|
|
1239
|
+
children: /* @__PURE__ */ jsx13(Pin2, { "aria-hidden": true, fill: isPinned ? "currentColor" : "none" })
|
|
1240
|
+
}
|
|
1241
|
+
) })
|
|
1242
|
+
] }, definition.id);
|
|
1243
|
+
}) }) }) }),
|
|
1244
|
+
/* @__PURE__ */ jsx13(StudioFooter, { connection: studio.connection })
|
|
1245
|
+
]
|
|
1246
|
+
}
|
|
1019
1247
|
),
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1248
|
+
handle && /* @__PURE__ */ jsx13(Panel, { asChild: true, children: /* @__PURE__ */ jsx13(
|
|
1249
|
+
"aside",
|
|
1250
|
+
{
|
|
1251
|
+
"data-slot": "studio-inspector",
|
|
1252
|
+
inert: panelsHidden,
|
|
1253
|
+
"aria-hidden": panelsHidden,
|
|
1254
|
+
className: cn(
|
|
1255
|
+
"absolute inset-y-2 right-2 z-10 flex w-(--studio-inspector-width) flex-col gap-1 p-1 transition-transform duration-200 ease-out motion-reduce:transition-none",
|
|
1256
|
+
panelsHidden && "translate-x-[calc(100%+1rem)]"
|
|
1257
|
+
),
|
|
1258
|
+
children: /* @__PURE__ */ jsx13(
|
|
1259
|
+
Inspector,
|
|
1260
|
+
{
|
|
1261
|
+
studio,
|
|
1262
|
+
handle,
|
|
1263
|
+
onCompare: compare,
|
|
1264
|
+
fileHref: getConfigFileHref?.(handle.definition.file)
|
|
1265
|
+
},
|
|
1266
|
+
handle.definition.id
|
|
1267
|
+
)
|
|
1268
|
+
}
|
|
1269
|
+
) })
|
|
1270
|
+
]
|
|
1271
|
+
}
|
|
1272
|
+
);
|
|
1024
1273
|
}
|
|
1025
1274
|
|
|
1026
1275
|
// src/react/command-menu.tsx
|
|
1276
|
+
import { Pin as Pin3 } from "lucide-react";
|
|
1027
1277
|
import { Dialog } from "radix-ui";
|
|
1028
|
-
import { useEffect as
|
|
1278
|
+
import { useEffect as useEffect5, useRef as useRef4, useState as useState8 } from "react";
|
|
1029
1279
|
|
|
1030
1280
|
// src/react/ui/command.tsx
|
|
1031
1281
|
import * as React3 from "react";
|
|
1032
1282
|
import { Command as CommandPrimitive } from "cmdk";
|
|
1033
1283
|
import { SearchIcon } from "lucide-react";
|
|
1034
|
-
import { jsx as
|
|
1284
|
+
import { jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1035
1285
|
function Command({ className, ...props }) {
|
|
1036
|
-
return /* @__PURE__ */
|
|
1286
|
+
return /* @__PURE__ */ jsx14(
|
|
1037
1287
|
CommandPrimitive,
|
|
1038
1288
|
{
|
|
1039
1289
|
"data-slot": "command",
|
|
@@ -1046,9 +1296,9 @@ function Command({ className, ...props }) {
|
|
|
1046
1296
|
);
|
|
1047
1297
|
}
|
|
1048
1298
|
var CommandInput = React3.forwardRef(function CommandInput2({ className, ...props }, ref) {
|
|
1049
|
-
return /* @__PURE__ */
|
|
1050
|
-
/* @__PURE__ */
|
|
1051
|
-
/* @__PURE__ */
|
|
1299
|
+
return /* @__PURE__ */ jsxs8("div", { "data-slot": "command-input-wrapper", className: "flex h-9 items-center gap-2 border-b px-3", children: [
|
|
1300
|
+
/* @__PURE__ */ jsx14(SearchIcon, { "aria-hidden": true, className: "size-4 shrink-0 opacity-50" }),
|
|
1301
|
+
/* @__PURE__ */ jsx14(
|
|
1052
1302
|
CommandPrimitive.Input,
|
|
1053
1303
|
{
|
|
1054
1304
|
ref,
|
|
@@ -1063,7 +1313,7 @@ var CommandInput = React3.forwardRef(function CommandInput2({ className, ...prop
|
|
|
1063
1313
|
] });
|
|
1064
1314
|
});
|
|
1065
1315
|
function CommandList({ className, ...props }) {
|
|
1066
|
-
return /* @__PURE__ */
|
|
1316
|
+
return /* @__PURE__ */ jsx14(
|
|
1067
1317
|
CommandPrimitive.List,
|
|
1068
1318
|
{
|
|
1069
1319
|
"data-slot": "command-list",
|
|
@@ -1073,10 +1323,10 @@ function CommandList({ className, ...props }) {
|
|
|
1073
1323
|
);
|
|
1074
1324
|
}
|
|
1075
1325
|
function CommandEmpty({ ...props }) {
|
|
1076
|
-
return /* @__PURE__ */
|
|
1326
|
+
return /* @__PURE__ */ jsx14(CommandPrimitive.Empty, { "data-slot": "command-empty", className: "py-6 text-center text-sm", ...props });
|
|
1077
1327
|
}
|
|
1078
1328
|
function CommandItem({ className, ...props }) {
|
|
1079
|
-
return /* @__PURE__ */
|
|
1329
|
+
return /* @__PURE__ */ jsx14(
|
|
1080
1330
|
CommandPrimitive.Item,
|
|
1081
1331
|
{
|
|
1082
1332
|
"data-slot": "command-item",
|
|
@@ -1090,12 +1340,13 @@ function CommandItem({ className, ...props }) {
|
|
|
1090
1340
|
}
|
|
1091
1341
|
|
|
1092
1342
|
// src/react/command-menu.tsx
|
|
1093
|
-
import { jsx as
|
|
1343
|
+
import { jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1094
1344
|
function StudioCommandMenu({ studio, studioPath = "/studio", navigate }) {
|
|
1095
|
-
const
|
|
1096
|
-
const
|
|
1097
|
-
const
|
|
1098
|
-
|
|
1345
|
+
const { tools, pinned } = usePinnedTools(studio);
|
|
1346
|
+
const [open, setOpen] = useState8(false);
|
|
1347
|
+
const opener = useRef4(null);
|
|
1348
|
+
const input = useRef4(null);
|
|
1349
|
+
useEffect5(() => {
|
|
1099
1350
|
if (window.frameElement?.getAttribute("data-slot") === "studio-preview") return;
|
|
1100
1351
|
const onKey = (event) => {
|
|
1101
1352
|
if (event.defaultPrevented || event.isComposing || event.altKey || !(event.metaKey || event.ctrlKey)) return;
|
|
@@ -1119,9 +1370,9 @@ function StudioCommandMenu({ studio, studioPath = "/studio", navigate }) {
|
|
|
1119
1370
|
window.location.assign(target.href);
|
|
1120
1371
|
}
|
|
1121
1372
|
};
|
|
1122
|
-
return /* @__PURE__ */
|
|
1123
|
-
/* @__PURE__ */
|
|
1124
|
-
/* @__PURE__ */
|
|
1373
|
+
return /* @__PURE__ */ jsx15(Dialog.Root, { open, onOpenChange: setOpen, children: /* @__PURE__ */ jsxs9(Dialog.Portal, { children: [
|
|
1374
|
+
/* @__PURE__ */ jsx15(Dialog.Overlay, { "data-slot": "studio-command-overlay" }),
|
|
1375
|
+
/* @__PURE__ */ jsxs9(
|
|
1125
1376
|
Dialog.Content,
|
|
1126
1377
|
{
|
|
1127
1378
|
"data-slot": "studio-command-menu",
|
|
@@ -1135,43 +1386,44 @@ function StudioCommandMenu({ studio, studioPath = "/studio", navigate }) {
|
|
|
1135
1386
|
opener.current?.focus();
|
|
1136
1387
|
},
|
|
1137
1388
|
children: [
|
|
1138
|
-
/* @__PURE__ */
|
|
1139
|
-
/* @__PURE__ */
|
|
1140
|
-
/* @__PURE__ */
|
|
1141
|
-
/* @__PURE__ */
|
|
1389
|
+
/* @__PURE__ */ jsxs9("div", { "data-slot": "studio-command-heading", children: [
|
|
1390
|
+
/* @__PURE__ */ jsxs9(Dialog.Title, { "aria-label": "Studio tools", children: [
|
|
1391
|
+
/* @__PURE__ */ jsx15(Logo, { "aria-hidden": true }),
|
|
1392
|
+
/* @__PURE__ */ jsx15("strong", { children: "STUDIO" })
|
|
1142
1393
|
] }),
|
|
1143
|
-
/* @__PURE__ */
|
|
1394
|
+
/* @__PURE__ */ jsx15(Dialog.Close, { "aria-label": "Close tool menu", children: /* @__PURE__ */ jsx15(Kbd, { children: "esc" }) })
|
|
1144
1395
|
] }),
|
|
1145
|
-
/* @__PURE__ */
|
|
1146
|
-
/* @__PURE__ */
|
|
1147
|
-
/* @__PURE__ */
|
|
1148
|
-
/* @__PURE__ */
|
|
1149
|
-
/* @__PURE__ */
|
|
1150
|
-
|
|
1396
|
+
/* @__PURE__ */ jsx15(Dialog.Description, { "data-slot": "studio-command-description", children: "Open a tool in Studio." }),
|
|
1397
|
+
/* @__PURE__ */ jsxs9(Command, { label: "Studio tools", loop: true, vimBindings: false, children: [
|
|
1398
|
+
/* @__PURE__ */ jsx15(CommandInput, { ref: input, placeholder: "Search tools\u2026" }),
|
|
1399
|
+
/* @__PURE__ */ jsxs9(CommandList, { children: [
|
|
1400
|
+
/* @__PURE__ */ jsx15(CommandEmpty, { children: studio.tools.length ? "No tools found." : "No tools registered yet." }),
|
|
1401
|
+
tools.map(({ definition: tool }) => /* @__PURE__ */ jsxs9(
|
|
1151
1402
|
CommandItem,
|
|
1152
1403
|
{
|
|
1153
1404
|
value: tool.id,
|
|
1154
1405
|
keywords: [tool.title ?? tool.id],
|
|
1155
1406
|
onSelect: () => select(tool.id),
|
|
1156
1407
|
children: [
|
|
1157
|
-
/* @__PURE__ */
|
|
1158
|
-
/* @__PURE__ */
|
|
1408
|
+
/* @__PURE__ */ jsx15(ToolIcon, { icon: tool.icon }),
|
|
1409
|
+
/* @__PURE__ */ jsx15("span", { "data-slot": "studio-command-label", children: tool.title ?? tool.id }),
|
|
1410
|
+
pinned.has(tool.id) && /* @__PURE__ */ jsx15(Pin3, { "aria-hidden": true })
|
|
1159
1411
|
]
|
|
1160
1412
|
},
|
|
1161
1413
|
tool.id
|
|
1162
1414
|
))
|
|
1163
1415
|
] })
|
|
1164
1416
|
] }),
|
|
1165
|
-
/* @__PURE__ */
|
|
1166
|
-
/* @__PURE__ */
|
|
1167
|
-
/* @__PURE__ */
|
|
1168
|
-
/* @__PURE__ */
|
|
1169
|
-
/* @__PURE__ */
|
|
1417
|
+
/* @__PURE__ */ jsxs9("div", { "data-slot": "studio-command-footer", "aria-hidden": true, children: [
|
|
1418
|
+
/* @__PURE__ */ jsxs9("span", { children: [
|
|
1419
|
+
/* @__PURE__ */ jsxs9(KbdGroup, { children: [
|
|
1420
|
+
/* @__PURE__ */ jsx15(Kbd, { children: "\u2191" }),
|
|
1421
|
+
/* @__PURE__ */ jsx15(Kbd, { children: "\u2193" })
|
|
1170
1422
|
] }),
|
|
1171
1423
|
"navigate"
|
|
1172
1424
|
] }),
|
|
1173
|
-
/* @__PURE__ */
|
|
1174
|
-
/* @__PURE__ */
|
|
1425
|
+
/* @__PURE__ */ jsxs9("span", { children: [
|
|
1426
|
+
/* @__PURE__ */ jsx15(Kbd, { children: "\u21B5" }),
|
|
1175
1427
|
" open tool"
|
|
1176
1428
|
] })
|
|
1177
1429
|
] })
|
|
@@ -1180,9 +1432,95 @@ function StudioCommandMenu({ studio, studioPath = "/studio", navigate }) {
|
|
|
1180
1432
|
)
|
|
1181
1433
|
] }) });
|
|
1182
1434
|
}
|
|
1435
|
+
|
|
1436
|
+
// src/react/select.tsx
|
|
1437
|
+
import { Check, ChevronDown, ChevronUp } from "lucide-react";
|
|
1438
|
+
import { Select } from "radix-ui";
|
|
1439
|
+
import { jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1440
|
+
function StudioSelect({ label, title, className, children, ...props }) {
|
|
1441
|
+
return /* @__PURE__ */ jsxs10(Select.Root, { ...props, children: [
|
|
1442
|
+
/* @__PURE__ */ jsxs10(
|
|
1443
|
+
Select.Trigger,
|
|
1444
|
+
{
|
|
1445
|
+
"data-slot": "select-trigger",
|
|
1446
|
+
"aria-label": label,
|
|
1447
|
+
title,
|
|
1448
|
+
className: cn(
|
|
1449
|
+
"border-input text-foreground focus-visible:border-ring focus-visible:ring-ring/50 flex h-7 max-w-full shrink-0 items-center justify-between gap-2 rounded-md border bg-(--field) px-2 text-xs whitespace-nowrap transition-[color,box-shadow] outline-none hover:bg-(--field-hover) focus-visible:ring-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span:first-child]:truncate",
|
|
1450
|
+
className
|
|
1451
|
+
),
|
|
1452
|
+
children: [
|
|
1453
|
+
/* @__PURE__ */ jsx16(Select.Value, {}),
|
|
1454
|
+
/* @__PURE__ */ jsx16(Select.Icon, { children: /* @__PURE__ */ jsx16(ChevronDown, { className: "shrink-0 text-muted-foreground", size: 14, strokeWidth: 1.5, "aria-hidden": true }) })
|
|
1455
|
+
]
|
|
1456
|
+
}
|
|
1457
|
+
),
|
|
1458
|
+
/* @__PURE__ */ jsx16(Select.Portal, { children: /* @__PURE__ */ jsxs10(
|
|
1459
|
+
Select.Content,
|
|
1460
|
+
{
|
|
1461
|
+
className: "relative z-50 max-h-(--radix-select-content-available-height) min-w-(--radix-select-trigger-width) overflow-hidden rounded-md border border-border bg-popover font-(family-name:--studio-font) text-xs font-normal text-popover-foreground shadow-md",
|
|
1462
|
+
"data-slot": "select-content",
|
|
1463
|
+
position: "popper",
|
|
1464
|
+
align: "end",
|
|
1465
|
+
sideOffset: 6,
|
|
1466
|
+
children: [
|
|
1467
|
+
/* @__PURE__ */ jsx16(Select.ScrollUpButton, { className: "flex justify-center py-1", children: /* @__PURE__ */ jsx16(ChevronUp, { size: 14, "aria-hidden": true }) }),
|
|
1468
|
+
/* @__PURE__ */ jsx16(Select.Viewport, { className: "p-1", children }),
|
|
1469
|
+
/* @__PURE__ */ jsx16(Select.ScrollDownButton, { className: "flex justify-center py-1", children: /* @__PURE__ */ jsx16(ChevronDown, { size: 14, "aria-hidden": true }) })
|
|
1470
|
+
]
|
|
1471
|
+
}
|
|
1472
|
+
) })
|
|
1473
|
+
] });
|
|
1474
|
+
}
|
|
1475
|
+
function StudioSelectItem({ className, children, ...props }) {
|
|
1476
|
+
return /* @__PURE__ */ jsxs10(
|
|
1477
|
+
Select.Item,
|
|
1478
|
+
{
|
|
1479
|
+
"data-slot": "select-item",
|
|
1480
|
+
className: cn(
|
|
1481
|
+
"relative flex min-h-7 cursor-default items-center rounded-sm py-1.5 pr-8 pl-2 outline-none select-none data-[highlighted]:bg-(--field-hover) data-[highlighted]:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
1482
|
+
className
|
|
1483
|
+
),
|
|
1484
|
+
...props,
|
|
1485
|
+
children: [
|
|
1486
|
+
/* @__PURE__ */ jsx16(Select.ItemText, { children }),
|
|
1487
|
+
/* @__PURE__ */ jsx16(Select.ItemIndicator, { className: "absolute right-2", children: /* @__PURE__ */ jsx16(Check, { size: 14, strokeWidth: 1.5, "aria-hidden": true }) })
|
|
1488
|
+
]
|
|
1489
|
+
}
|
|
1490
|
+
);
|
|
1491
|
+
}
|
|
1492
|
+
|
|
1493
|
+
// src/react/ui/input.tsx
|
|
1494
|
+
import { forwardRef as forwardRef5 } from "react";
|
|
1495
|
+
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
1496
|
+
var Input = forwardRef5(function Input2({ className, ...props }, ref) {
|
|
1497
|
+
return /* @__PURE__ */ jsx17(
|
|
1498
|
+
"input",
|
|
1499
|
+
{
|
|
1500
|
+
ref,
|
|
1501
|
+
"data-slot": "input",
|
|
1502
|
+
className: cn(
|
|
1503
|
+
"border-input text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 h-8 w-full min-w-0 rounded-md border bg-transparent py-1 ps-3 pe-3 text-sm transition-[color,box-shadow] outline-none focus-visible:ring-2 disabled:cursor-not-allowed disabled:opacity-50",
|
|
1504
|
+
className
|
|
1505
|
+
),
|
|
1506
|
+
...props
|
|
1507
|
+
}
|
|
1508
|
+
);
|
|
1509
|
+
});
|
|
1183
1510
|
export {
|
|
1511
|
+
CanvasToolbar,
|
|
1512
|
+
PreviewCanvas,
|
|
1184
1513
|
Studio,
|
|
1185
1514
|
StudioCommandMenu,
|
|
1515
|
+
Input as StudioInput,
|
|
1516
|
+
Panel as StudioPanel,
|
|
1517
|
+
PanelContent as StudioPanelContent,
|
|
1518
|
+
PanelFooter as StudioPanelFooter,
|
|
1519
|
+
PanelHeader as StudioPanelHeader,
|
|
1520
|
+
StudioSelect,
|
|
1521
|
+
StudioSelectItem,
|
|
1522
|
+
StudioSurface,
|
|
1523
|
+
StudioToolbar,
|
|
1186
1524
|
useStudio,
|
|
1187
1525
|
useToolConfig
|
|
1188
1526
|
};
|