@joycostudio/studio 0.1.2 → 0.1.4
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 +199 -50
- package/dist/chunk-2RGQF5X5.js +470 -0
- package/dist/chunk-2RGQF5X5.js.map +1 -0
- package/dist/{chunk-X4YLM5HA.js → chunk-DEJYGBPJ.js} +22 -1
- package/dist/chunk-DEJYGBPJ.js.map +1 -0
- package/dist/chunk-HVGJXFXT.js +314 -0
- package/dist/chunk-HVGJXFXT.js.map +1 -0
- package/dist/cli.js +878 -56
- package/dist/cli.js.map +1 -1
- package/dist/client.d.ts +7 -4
- package/dist/client.js +5 -458
- package/dist/client.js.map +1 -1
- package/dist/command-menu.css +4 -1
- package/dist/controls.d.ts +1 -0
- package/dist/controls.js +3 -0
- package/dist/controls.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +6 -12
- package/dist/index.js.map +1 -1
- package/dist/next-config.d.ts +4 -0
- package/dist/next-config.js +135 -0
- package/dist/next-config.js.map +1 -0
- package/dist/next.d.ts +8 -0
- package/dist/next.js +15 -0
- package/dist/next.js.map +1 -0
- package/dist/{protocol-BrHDtNkL.d.ts → protocol-DjrMADPm.d.ts} +66 -15
- package/dist/react.d.ts +40 -17
- package/dist/react.js +418 -274
- package/dist/react.js.map +1 -1
- package/dist/runtime.d.ts +33 -5
- package/dist/runtime.js +106 -87
- package/dist/runtime.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +27 -7
- package/dist/chunk-X4YLM5HA.js.map +0 -1
package/dist/react.js
CHANGED
|
@@ -11,10 +11,10 @@ import {
|
|
|
11
11
|
PlugZap,
|
|
12
12
|
Unplug
|
|
13
13
|
} from "lucide-react";
|
|
14
|
-
import { useEffect as
|
|
14
|
+
import { useEffect as useEffect5, useRef as useRef3, useState as useState9 } from "react";
|
|
15
15
|
|
|
16
16
|
// package.json
|
|
17
|
-
var version = "0.1.
|
|
17
|
+
var version = "0.1.4";
|
|
18
18
|
|
|
19
19
|
// src/client/studio.ts
|
|
20
20
|
import {
|
|
@@ -43,6 +43,13 @@ function resetSlidersOnDoubleClick(handle) {
|
|
|
43
43
|
return () => folder.element.removeEventListener("dblclick", onDoubleClick);
|
|
44
44
|
};
|
|
45
45
|
}
|
|
46
|
+
function everyFrame(refresh) {
|
|
47
|
+
let frame = requestAnimationFrame(function tick() {
|
|
48
|
+
refresh();
|
|
49
|
+
frame = requestAnimationFrame(tick);
|
|
50
|
+
});
|
|
51
|
+
return () => cancelAnimationFrame(frame);
|
|
52
|
+
}
|
|
46
53
|
var instances = globalThis.__joycoStudio ??= /* @__PURE__ */ new Map();
|
|
47
54
|
|
|
48
55
|
// src/react/hooks.ts
|
|
@@ -67,7 +74,7 @@ function useToolConfig(handle) {
|
|
|
67
74
|
// src/react/inspector.tsx
|
|
68
75
|
import { bindDebugSchema } from "@joycostudio/xyz/debug";
|
|
69
76
|
import { SquareSplitHorizontal } from "lucide-react";
|
|
70
|
-
import { useEffect, useRef, useState } from "react";
|
|
77
|
+
import { useEffect, useRef, useState as useState2 } from "react";
|
|
71
78
|
|
|
72
79
|
// src/react/theme.ts
|
|
73
80
|
var tweakpaneTheme = {
|
|
@@ -218,48 +225,126 @@ function KbdGroup({ className, ...props }) {
|
|
|
218
225
|
}
|
|
219
226
|
|
|
220
227
|
// src/react/ui/tooltip.tsx
|
|
221
|
-
import { Tooltip as TooltipPrimitive } from "
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
228
|
+
import { Tooltip as TooltipPrimitive } from "@base-ui/react/tooltip";
|
|
229
|
+
|
|
230
|
+
// src/react/shadow-root.tsx
|
|
231
|
+
import { createContext, useCallback, useContext, useState } from "react";
|
|
232
|
+
import { createPortal } from "react-dom";
|
|
233
|
+
|
|
234
|
+
// src/react/generated/studio.css
|
|
235
|
+
var studio_default = `/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
|
|
236
|
+
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial;--tw-content:"";--tw-animation-delay:0s;--tw-animation-direction:normal;--tw-animation-duration:initial;--tw-animation-fill-mode:none;--tw-animation-iteration-count:1;--tw-enter-blur:0;--tw-enter-opacity:1;--tw-enter-rotate:0;--tw-enter-scale:1;--tw-enter-translate-x:0;--tw-enter-translate-y:0;--tw-exit-blur:0;--tw-exit-opacity:1;--tw-exit-rotate:0;--tw-exit-scale:1;--tw-exit-translate-x:0;--tw-exit-translate-y:0}}}@layer theme{:root,:host{--color-sky-400:oklch(74.6% .16 232.661);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-sm:24rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--radius-xs:.125rem;--radius-lg:calc(var(--radius) + 2px);--ease-out:cubic-bezier(0, 0, .2, 1);--ease-in-out:cubic-bezier(.4, 0, .2, 1);--animate-spin:spin 1s linear infinite;--blur-xl:24px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--studio-font);--default-mono-font-family:var(--studio-font);--color-border:var(--border);--color-sidebar:var(--sidebar)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring:where(:not(iframe)){outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}*{border-color:var(--border);outline-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){*{outline-color:color-mix(in oklab, var(--ring) 50%, transparent)}}body{background-color:var(--background);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));color:var(--foreground)}}@layer components{.studio-surface{border-radius:calc(var(--radius) - 2px);background:var(--card);padding:6px}.studio-toolbar{pointer-events:auto;flex-wrap:wrap;align-items:center;gap:4px;display:flex}.studio-toolbar>button:not([data-slot=select-trigger]),.studio-toolbar [data-slot=toolbar-action]{border-radius:calc(var(--radius) - 2px);min-height:28px;color:var(--muted-foreground);font:inherit;white-space:nowrap;cursor:pointer;background:0 0;border:1px solid #0000;align-items:center;gap:6px;padding:4px 8px;font-size:11px;display:inline-flex}:is(.studio-toolbar>button:not([data-slot=select-trigger]),.studio-toolbar [data-slot=toolbar-action]):hover{color:var(--foreground);background:var(--field-hover)}:is(.studio-toolbar>button:not([data-slot=select-trigger]),.studio-toolbar [data-slot=toolbar-action]):is(:active,[aria-pressed=true]){color:var(--foreground);background:var(--field-active)}:is(.studio-toolbar>button:not([data-slot=select-trigger]),.studio-toolbar [data-slot=toolbar-action]):focus-visible{outline:2px solid var(--ring);outline-offset:2px}.studio-canvas-toolbar{z-index:20;min-width:0;color:var(--muted-foreground);pointer-events:none;flex-shrink:0;position:relative}.studio-canvas-actions{opacity:1;transition:opacity .2s ease-out,translate .2s ease-out;translate:0}.studio-canvas-toolbar[data-ghost]{position:absolute;inset:4px 4px auto}.studio-canvas-toolbar[data-ghost]:before{content:"";pointer-events:auto;height:24px;position:absolute;inset:-4px 0 auto}.studio-canvas-toolbar[data-ghost] .studio-canvas-actions{-webkit-backdrop-filter:blur(24px);backdrop-filter:blur(24px);opacity:0;transition-delay:3s;translate:0 calc(-100% - 8px)}.studio-canvas-toolbar[data-ghost]:is(:hover,:has(:focus-visible,[aria-expanded=true],[data-state=open])) .studio-canvas-actions{opacity:1;transition-delay:0s;translate:0}@media (hover:none){.studio-canvas-toolbar[data-ghost] .studio-canvas-actions{opacity:1;translate:0}}.studio-canvas-toolbar[data-expanded]{height:80px;position:absolute;inset:0 0 auto}.studio-canvas-toolbar[data-expanded] .studio-canvas-actions{pointer-events:none;background:0 0;height:100%;padding:0}.studio-canvas-toolbar[data-expanded] .studio-canvas-actions>:not(.studio-canvas-toggle){display:none}.studio-canvas-toolbar[data-expanded] .studio-canvas-toggle{width:min(280px,100%);height:100%;padding-top:max(12px, env(safe-area-inset-top));pointer-events:auto;justify-content:center;align-items:flex-start;margin-inline:auto;display:flex}.studio-canvas-toolbar[data-expanded] .studio-canvas-toggle>button{border-color:var(--sidebar-border);border-radius:var(--radius);min-height:30px;color:var(--foreground);background:var(--sidebar)}@supports (color:color-mix(in lab, red, red)){.studio-canvas-toolbar[data-expanded] .studio-canvas-toggle>button{background:color-mix(in srgb, var(--sidebar) 85%, transparent)}}.studio-canvas-toolbar[data-expanded] .studio-canvas-toggle>button{-webkit-backdrop-filter:blur(24px);backdrop-filter:blur(24px);font-size:inherit;opacity:0;transition:opacity .2s ease-out 3s,translate .2s ease-out 3s;translate:0 -8px;box-shadow:0 4px 12px #0006}.studio-canvas-toolbar[data-expanded] .studio-canvas-toggle>button:hover{background:var(--field-hover)}.studio-canvas-toolbar[data-expanded] .studio-canvas-toggle:hover>button,.studio-canvas-toolbar[data-expanded] .studio-canvas-toggle>button:focus-visible{opacity:1;transition-delay:0s;translate:0}@media (hover:none){.studio-canvas-toolbar[data-expanded] .studio-canvas-toggle>button{opacity:1;translate:0}}@media (prefers-reduced-motion:reduce){.studio-canvas-actions,.studio-canvas-toolbar[data-expanded] .studio-canvas-toggle>button{transition-duration:0s}}.studio-preview-canvas{border:1px solid var(--sidebar-border);border-radius:calc(var(--radius) + 2px);background:var(--sidebar);flex-direction:column;gap:4px;min-width:0;min-height:0;padding:4px;display:flex;position:relative;overflow:hidden}@supports (color:color-mix(in lab, red, red)){.studio-preview-canvas{background:color-mix(in srgb, var(--sidebar) 85%, transparent)}}.studio-preview-canvas{font:12px/1.5 var(--studio-font);box-shadow:0 12px 24px #0006}.studio-preview-source{align-items:center;min-width:0;margin-right:auto;display:flex}.studio-preview-title{padding-inline:8px}.studio-preview-canvas>iframe{border-radius:calc(var(--radius) - 2px);background:var(--background);border:0;flex:1;width:100%;min-height:0}.studio-preview-canvas[data-expanded]{z-index:30;background:var(--background);border:0;border-radius:0;padding:0;position:fixed;inset:0}.studio-preview-canvas[data-expanded]>iframe{border-radius:0}}@layer utilities{.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{inset:0}.inset-x-0{inset-inline:0}.inset-y-0{inset-block:0}.inset-y-2{inset-block:calc(var(--spacing) * 2)}.-top-0\\.5{top:calc(var(--spacing) * -.5)}.top-0{top:0}.top-1\\/2{top:50%}.top-4{top:calc(var(--spacing) * 4)}.-right-0\\.5{right:calc(var(--spacing) * -.5)}.right-0{right:0}.right-1{right:var(--spacing)}.right-2{right:calc(var(--spacing) * 2)}.right-4{right:calc(var(--spacing) * 4)}.bottom-0{bottom:0}.left-0{left:0}.left-1{left:var(--spacing)}.isolate{isolation:isolate}.z-10{z-index:10}.z-20{z-index:20}.z-50{z-index:50}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.mt-1{margin-top:var(--spacing)}.mt-auto{margin-top:auto}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-flex{display:inline-flex}.aspect-square{aspect-ratio:1}.size-1\\.5{width:calc(var(--spacing) * 1.5);height:calc(var(--spacing) * 1.5)}.size-2\\.5{width:calc(var(--spacing) * 2.5);height:calc(var(--spacing) * 2.5)}.size-3\\.5{width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.size-6{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6)}.size-8{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}.size-9{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9)}.size-10{width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10)}.h-3\\.5{height:calc(var(--spacing) * 3.5)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.h-12{height:calc(var(--spacing) * 12)}.h-16{height:calc(var(--spacing) * 16)}.h-auto{height:auto}.h-full{height:100%}.h-svh{height:100svh}.max-h-\\(--available-height\\){max-height:var(--available-height)}.max-h-\\[300px\\]{max-height:300px}.min-h-0{min-height:0}.min-h-7{min-height:calc(var(--spacing) * 7)}.min-h-svh{min-height:100svh}.w-\\(--sidebar-width\\){width:var(--sidebar-width)}.w-\\(--studio-inspector-width\\){width:var(--studio-inspector-width)}.w-3\\/4{width:75%}.w-5{width:calc(var(--spacing) * 5)}.w-6{width:calc(var(--spacing) * 6)}.w-8{width:calc(var(--spacing) * 8)}.w-auto{width:auto}.w-fit{width:fit-content}.w-full{width:100%}.max-w-full{max-width:100%}.min-w-\\(--anchor-width\\){min-width:var(--anchor-width)}.min-w-0{min-width:0}.min-w-5{min-width:calc(var(--spacing) * 5)}.flex-1{flex:1}.shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.origin-\\(--transform-origin\\){transform-origin:var(--transform-origin)}.-translate-x-\\[calc\\(100\\%\\+0\\.25rem\\)\\]{--tw-translate-x:calc(calc(100% + .25rem) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-x-\\[calc\\(100\\%\\+1rem\\)\\]{--tw-translate-x:calc(calc(100% + 1rem) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-x-\\[calc\\(100\\%\\+0\\.25rem\\)\\]{--tw-translate-x:calc(100% + .25rem);translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-x-\\[calc\\(100\\%\\+1rem\\)\\]{--tw-translate-x:calc(100% + 1rem);translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-1\\/2{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-y-\\[calc\\(-50\\%-2px\\)\\]{--tw-translate-y:calc(-50% - 2px);translate:var(--tw-translate-x) var(--tw-translate-y)}.rotate-45{rotate:45deg}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-spin{animation:var(--animate-spin)}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.scroll-py-1{scroll-padding-block:var(--spacing)}.flex-col{flex-direction:column}.flex-row{flex-direction:row}.place-items-center{place-items:center}.items-center{align-items:center}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-1{gap:var(--spacing)}.gap-1\\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.rounded-\\[2px\\]{border-radius:2px}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:calc(var(--radius) + 2px)}.rounded-md{border-radius:var(--radius)}.rounded-sm{border-radius:calc(var(--radius) - 2px)}.rounded-xs{border-radius:var(--radius-xs)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-border{border-color:var(--border)}.border-input{border-color:var(--input)}.border-sidebar-border{border-color:var(--sidebar-border)}.bg-\\(--field\\){background-color:var(--field)}.bg-background{background-color:var(--background)}.bg-black\\/50{background-color:#00000080}@supports (color:color-mix(in lab, red, red)){.bg-black\\/50{background-color:color-mix(in oklab, var(--color-black) 50%, transparent)}}.bg-current{background-color:currentColor}.bg-destructive{background-color:var(--destructive)}.bg-foreground{background-color:var(--foreground)}.bg-muted{background-color:var(--muted)}.bg-popover{background-color:var(--popover)}.bg-primary{background-color:var(--primary)}.bg-secondary{background-color:var(--secondary)}.bg-sidebar,.bg-sidebar\\/85{background-color:var(--sidebar)}@supports (color:color-mix(in lab, red, red)){.bg-sidebar\\/85{background-color:color-mix(in oklab, var(--sidebar) 85%, transparent)}}.bg-transparent{background-color:#0000}.bg-warning{background-color:var(--warning)}.fill-foreground{fill:var(--foreground)}.p-0{padding:0}.p-1{padding:var(--spacing)}.p-2{padding:calc(var(--spacing) * 2)}.p-4{padding:calc(var(--spacing) * 4)}.px-0{padding-inline:0}.px-1{padding-inline:var(--spacing)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-6{padding-inline:calc(var(--spacing) * 6)}.py-0{padding-block:0}.py-1{padding-block:var(--spacing)}.py-1\\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-6{padding-block:calc(var(--spacing) * 6)}.ps-3{padding-inline-start:calc(var(--spacing) * 3)}.pe-3{padding-inline-end:calc(var(--spacing) * 3)}.pt-2\\.5{padding-top:calc(var(--spacing) * 2.5)}.pr-0{padding-right:0}.pr-8{padding-right:calc(var(--spacing) * 8)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pl-2{padding-left:calc(var(--spacing) * 2)}.pl-4{padding-left:calc(var(--spacing) * 4)}.pl-5\\.5{padding-left:calc(var(--spacing) * 5.5)}.text-center{text-align:center}.text-left{text-align:left}.font-\\(family-name\\:--studio-font\\),.font-mono{font-family:var(--studio-font)}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\\[10px\\]{font-size:10px}.text-\\[11px\\]{font-size:11px}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-\\[0\\.08em\\]{--tw-tracking:.08em;letter-spacing:.08em}.text-balance{text-wrap:balance}.text-clip\\!{text-overflow:clip!important}.whitespace-nowrap{white-space:nowrap}.text-background{color:var(--background)}.text-destructive{color:var(--destructive)}.text-faint{color:var(--faint)}.text-foreground{color:var(--foreground)}.text-muted-foreground{color:var(--muted-foreground)}.text-popover-foreground{color:var(--popover-foreground)}.text-primary{color:var(--primary)}.text-primary-foreground{color:var(--primary-foreground)}.text-secondary-foreground{color:var(--secondary-foreground)}.text-sidebar-foreground{color:var(--sidebar-foreground)}.text-sidebar-primary{color:var(--sidebar-primary)}.text-sky-400{color:var(--color-sky-400)}.text-success{color:var(--success)}.text-warning{color:var(--warning)}.text-white{color:var(--color-white)}.underline-offset-4{text-underline-offset:4px}.opacity-0{opacity:0}.opacity-50{opacity:.5}.opacity-70{opacity:.7}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\\[0_0_0_1px_var\\(--sidebar-border\\)\\]{--tw-shadow:0 0 0 1px var(--tw-shadow-color,var(--sidebar-border));box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a), 0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-xs{--tw-shadow:0 1px 2px 0 var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-black\\/40{--tw-shadow-color:#0006}@supports (color:color-mix(in lab, red, red)){.shadow-black\\/40{--tw-shadow-color:color-mix(in oklab, color-mix(in oklab, var(--color-black) 40%, transparent) var(--tw-shadow-alpha), transparent)}}.ring-sidebar-ring{--tw-ring-color:var(--sidebar-ring)}.ring-offset-background{--tw-ring-offset-color:var(--background)}.outline-hidden{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.outline-hidden{outline-offset:2px;outline:2px solid #0000}}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.blur{--tw-blur:blur(8px);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.backdrop-blur-xl{--tw-backdrop-blur:blur(var(--blur-xl));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\\[color\\,box-shadow\\]{transition-property:color,box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\\[left\\,right\\,width\\,translate\\]{transition-property:left,right,width,translate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\\[left\\,right\\,width\\]{transition-property:left,right,width;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\\[padding\\]{transition-property:padding;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\\[translate\\,opacity\\]{transition-property:translate,opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\\[width\\,height\\,padding\\]{transition-property:width,height,padding;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\\[width\\]{transition-property:width;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-200{--tw-duration:.2s;transition-duration:.2s}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.ease-linear{--tw-ease:linear;transition-timing-function:linear}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.paused{animation-play-state:paused}.running{animation-play-state:running}.group-focus-within\\/menu-item\\:opacity-100:is(:where(.group\\/menu-item):focus-within *){opacity:1}@media (hover:hover){.group-hover\\/edge\\:translate-x-0:is(:where(.group\\/edge):hover *){--tw-translate-x:0px;translate:var(--tw-translate-x) var(--tw-translate-y)}.group-hover\\/edge\\:opacity-100:is(:where(.group\\/edge):hover *),.group-hover\\/menu-item\\:opacity-100:is(:where(.group\\/menu-item):hover *){opacity:1}}.group-has-data-\\[sidebar\\=menu-action\\]\\/menu-item\\:pr-8:is(:where(.group\\/menu-item):has([data-sidebar=menu-action]) *){padding-right:calc(var(--spacing) * 8)}.group-data-\\[collapsible\\=icon\\]\\:hidden:is(:where(.group)[data-collapsible=icon] *){display:none}.group-data-\\[collapsible\\=icon\\]\\:size-8\\!:is(:where(.group)[data-collapsible=icon] *){width:calc(var(--spacing) * 8)!important;height:calc(var(--spacing) * 8)!important}.group-data-\\[collapsible\\=icon\\]\\:w-\\(--sidebar-width-icon\\):is(:where(.group)[data-collapsible=icon] *){width:var(--sidebar-width-icon)}.group-data-\\[collapsible\\=icon\\]\\:w-\\[calc\\(var\\(--sidebar-width-icon\\)\\+\\(--spacing\\(4\\)\\)\\)\\]:is(:where(.group)[data-collapsible=icon] *){width:calc(var(--sidebar-width-icon) + (calc(var(--spacing) * 4)))}.group-data-\\[collapsible\\=icon\\]\\:w-\\[calc\\(var\\(--sidebar-width-icon\\)\\+\\(--spacing\\(4\\)\\)\\+2px\\)\\]:is(:where(.group)[data-collapsible=icon] *){width:calc(var(--sidebar-width-icon) + (calc(var(--spacing) * 4)) + 2px)}.group-data-\\[collapsible\\=icon\\]\\:overflow-hidden:is(:where(.group)[data-collapsible=icon] *){overflow:hidden}.group-data-\\[collapsible\\=icon\\]\\:p-0\\!:is(:where(.group)[data-collapsible=icon] *){padding:0!important}.group-data-\\[collapsible\\=icon\\]\\:p-2\\!:is(:where(.group)[data-collapsible=icon] *){padding:calc(var(--spacing) * 2)!important}.group-data-\\[collapsible\\=icon\\]\\:pl-\\[calc\\(1\\.5rem-0\\.875rem\\*352\\/144\\/2\\)\\]:is(:where(.group)[data-collapsible=icon] *){padding-left:.430556rem}.group-data-\\[collapsible\\=offcanvas\\]\\:right-\\[calc\\(var\\(--sidebar-width\\)\\*-1\\)\\]:is(:where(.group)[data-collapsible=offcanvas] *){right:calc(var(--sidebar-width) * -1)}.group-data-\\[collapsible\\=offcanvas\\]\\:left-\\[calc\\(var\\(--sidebar-width\\)\\*-1\\)\\]:is(:where(.group)[data-collapsible=offcanvas] *){left:calc(var(--sidebar-width) * -1)}.group-data-\\[collapsible\\=offcanvas\\]\\:w-0:is(:where(.group)[data-collapsible=offcanvas] *){width:0}.group-data-\\[side\\=left\\]\\:border-r:is(:where(.group)[data-side=left] *){border-right-style:var(--tw-border-style);border-right-width:1px}.group-data-\\[side\\=right\\]\\:rotate-180:is(:where(.group)[data-side=right] *){rotate:180deg}.group-data-\\[side\\=right\\]\\:border-l:is(:where(.group)[data-side=right] *){border-left-style:var(--tw-border-style);border-left-width:1px}@media (hover:hover){.peer-hover\\/menu-button\\:text-sidebar-accent-foreground:is(:where(.peer\\/menu-button):hover~*){color:var(--sidebar-accent-foreground)}}.peer-data-\\[active\\=true\\]\\/menu-button\\:text-sidebar-accent-foreground:is(:where(.peer\\/menu-button)[data-active=true]~*){color:var(--sidebar-accent-foreground)}.placeholder\\:text-muted-foreground::placeholder{color:var(--muted-foreground)}.after\\:absolute:after{content:var(--tw-content);position:absolute}.after\\:-inset-2:after{content:var(--tw-content);inset:calc(var(--spacing) * -2)}@media (hover:hover){.hover\\:bg-\\(--field-hover\\):hover{background-color:var(--field-hover)}.hover\\:bg-accent:hover{background-color:var(--accent)}.hover\\:bg-destructive\\/90:hover{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-destructive\\/90:hover{background-color:color-mix(in oklab, var(--destructive) 90%, transparent)}}.hover\\:bg-primary\\/90:hover{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-primary\\/90:hover{background-color:color-mix(in oklab, var(--primary) 90%, transparent)}}.hover\\:bg-secondary\\/80:hover{background-color:var(--secondary)}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-secondary\\/80:hover{background-color:color-mix(in oklab, var(--secondary) 80%, transparent)}}.hover\\:bg-sidebar-accent:hover{background-color:var(--sidebar-accent)}.hover\\:bg-sidebar\\/95:hover{background-color:var(--sidebar)}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-sidebar\\/95:hover{background-color:color-mix(in oklab, var(--sidebar) 95%, transparent)}}.hover\\:bg-transparent:hover{background-color:#0000}.hover\\:text-accent-foreground:hover{color:var(--accent-foreground)}.hover\\:text-foreground:hover{color:var(--foreground)}.hover\\:text-sidebar-accent-foreground:hover{color:var(--sidebar-accent-foreground)}.hover\\:underline:hover{text-decoration-line:underline}.hover\\:opacity-100:hover{opacity:1}.hover\\:shadow-\\[0_0_0_1px_var\\(--sidebar-accent\\)\\]:hover{--tw-shadow:0 0 0 1px var(--tw-shadow-color,var(--sidebar-accent));box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}}.focus\\:translate-x-0:focus{--tw-translate-x:0px;translate:var(--tw-translate-x) var(--tw-translate-y)}.focus\\:opacity-100:focus{opacity:1}.focus\\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus\\:ring-ring:focus{--tw-ring-color:var(--ring)}.focus\\:ring-offset-2:focus{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.focus\\:outline-hidden:focus{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.focus\\:outline-hidden:focus{outline-offset:2px;outline:2px solid #0000}}.focus-visible\\:border-ring:focus-visible{border-color:var(--ring)}.focus-visible\\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\\:ring-\\[3px\\]:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\\:ring-destructive\\/20:focus-visible{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.focus-visible\\:ring-destructive\\/20:focus-visible{--tw-ring-color:color-mix(in oklab, var(--destructive) 20%, transparent)}}.focus-visible\\:ring-ring\\/50:focus-visible{--tw-ring-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){.focus-visible\\:ring-ring\\/50:focus-visible{--tw-ring-color:color-mix(in oklab, var(--ring) 50%, transparent)}}.active\\:bg-sidebar-accent:active{background-color:var(--sidebar-accent)}.active\\:bg-transparent:active{background-color:#0000}.active\\:text-sidebar-accent-foreground:active{color:var(--sidebar-accent-foreground)}.disabled\\:pointer-events-none:disabled{pointer-events:none}.disabled\\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\\:opacity-50:disabled{opacity:.5}.has-data-\\[variant\\=inset\\]\\:bg-sidebar:has([data-variant=inset]){background-color:var(--sidebar)}.has-\\[\\>svg\\]\\:px-1\\.5:has(>svg){padding-inline:calc(var(--spacing) * 1.5)}.has-\\[\\>svg\\]\\:px-2\\.5:has(>svg){padding-inline:calc(var(--spacing) * 2.5)}.has-\\[\\>svg\\]\\:px-3:has(>svg){padding-inline:calc(var(--spacing) * 3)}.has-\\[\\>svg\\]\\:px-4:has(>svg){padding-inline:calc(var(--spacing) * 4)}.aria-disabled\\:pointer-events-none[aria-disabled=true]{pointer-events:none}.aria-disabled\\:opacity-50[aria-disabled=true]{opacity:.5}.aria-invalid\\:border-destructive[aria-invalid=true]{border-color:var(--destructive)}.aria-invalid\\:ring-destructive\\/20[aria-invalid=true]{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.aria-invalid\\:ring-destructive\\/20[aria-invalid=true]{--tw-ring-color:color-mix(in oklab, var(--destructive) 20%, transparent)}}.aria-pressed\\:bg-primary[aria-pressed=true]{background-color:var(--primary)}.aria-pressed\\:text-primary-foreground[aria-pressed=true]{color:var(--primary-foreground)}.data-closed\\:animate-out[data-closed]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}.data-closed\\:duration-300[data-closed]{--tw-duration:.3s;transition-duration:.3s}.data-closed\\:fade-out-0[data-closed]{--tw-exit-opacity:0}.data-closed\\:zoom-out-95[data-closed]{--tw-exit-scale:.95}.data-closed\\:slide-out-to-bottom[data-closed]{--tw-exit-translate-y:100%}.data-closed\\:slide-out-to-left[data-closed]{--tw-exit-translate-x:-100%}.data-closed\\:slide-out-to-right[data-closed]{--tw-exit-translate-x:100%}.data-closed\\:slide-out-to-top[data-closed]{--tw-exit-translate-y:-100%}.data-open\\:animate-in[data-open]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}.data-open\\:duration-500[data-open]{--tw-duration:.5s;transition-duration:.5s}.data-open\\:fade-in-0[data-open]{--tw-enter-opacity:0}.data-open\\:zoom-in-95[data-open]{--tw-enter-scale:.95}.data-open\\:slide-in-from-bottom[data-open]{--tw-enter-translate-y:100%}.data-open\\:slide-in-from-left[data-open]{--tw-enter-translate-x:-100%}.data-open\\:slide-in-from-right[data-open]{--tw-enter-translate-x:100%}.data-open\\:slide-in-from-top[data-open]{--tw-enter-translate-y:-100%}.data-\\[active\\=true\\]\\:bg-sidebar-accent[data-active=true]{background-color:var(--sidebar-accent)}.data-\\[active\\=true\\]\\:font-medium[data-active=true]{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.data-\\[active\\=true\\]\\:text-sidebar-accent-foreground[data-active=true]{color:var(--sidebar-accent-foreground)}.data-\\[disabled\\]\\:pointer-events-none[data-disabled]{pointer-events:none}.data-\\[disabled\\]\\:opacity-50[data-disabled]{opacity:.5}.data-\\[disabled\\=true\\]\\:pointer-events-none[data-disabled=true]{pointer-events:none}.data-\\[disabled\\=true\\]\\:opacity-50[data-disabled=true]{opacity:.5}.data-\\[highlighted\\]\\:bg-\\(--field-hover\\)[data-highlighted]{background-color:var(--field-hover)}.data-\\[highlighted\\]\\:text-accent-foreground[data-highlighted]{color:var(--accent-foreground)}.data-\\[instant\\]\\:animate-none[data-instant]{animation:none}.data-\\[selected\\=true\\]\\:bg-accent[data-selected=true]{background-color:var(--accent)}.data-\\[selected\\=true\\]\\:text-accent-foreground[data-selected=true]{color:var(--accent-foreground)}.data-\\[side\\=bottom\\]\\:top-1[data-side=bottom]{top:var(--spacing)}.data-\\[side\\=bottom\\]\\:slide-in-from-top-2[data-side=bottom]{--tw-enter-translate-y:calc(2*var(--spacing)*-1)}.data-\\[side\\=left\\]\\:top-1\\/2\\![data-side=left]{top:50%!important}.data-\\[side\\=left\\]\\:-right-1[data-side=left]{right:calc(var(--spacing) * -1)}.data-\\[side\\=left\\]\\:-translate-y-1\\/2[data-side=left]{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\\[side\\=left\\]\\:slide-in-from-right-2[data-side=left]{--tw-enter-translate-x:calc(2*var(--spacing))}.data-\\[side\\=right\\]\\:top-1\\/2\\![data-side=right]{top:50%!important}.data-\\[side\\=right\\]\\:-left-1[data-side=right]{left:calc(var(--spacing) * -1)}.data-\\[side\\=right\\]\\:-translate-y-1\\/2[data-side=right]{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\\[side\\=right\\]\\:slide-in-from-left-2[data-side=right]{--tw-enter-translate-x:calc(2*var(--spacing)*-1)}.data-\\[side\\=top\\]\\:-bottom-2\\.5[data-side=top]{bottom:calc(var(--spacing) * -2.5)}.data-\\[side\\=top\\]\\:slide-in-from-bottom-2[data-side=top]{--tw-enter-translate-y:calc(2*var(--spacing))}.data-\\[state\\=open\\]\\:opacity-100[data-state=open]{opacity:1}@media (hover:hover){.data-\\[state\\=open\\]\\:hover\\:bg-sidebar-accent[data-state=open]:hover{background-color:var(--sidebar-accent)}.data-\\[state\\=open\\]\\:hover\\:text-sidebar-accent-foreground[data-state=open]:hover{color:var(--sidebar-accent-foreground)}}@media (prefers-reduced-motion:reduce){.motion-reduce\\:transition-none{transition-property:none}}@media (min-width:40rem){.sm\\:max-w-sm{max-width:var(--container-sm)}}@media (min-width:48rem){.md\\:block{display:block}.md\\:flex{display:flex}.md\\:opacity-0{opacity:0}.md\\:after\\:hidden:after{content:var(--tw-content);display:none}}@media (prefers-color-scheme:dark){.dark\\:border-input{border-color:var(--input)}.dark\\:bg-destructive\\/60{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\\:bg-destructive\\/60{background-color:color-mix(in oklab, var(--destructive) 60%, transparent)}}.dark\\:bg-input\\/30{background-color:var(--input)}@supports (color:color-mix(in lab, red, red)){.dark\\:bg-input\\/30{background-color:color-mix(in oklab, var(--input) 30%, transparent)}}@media (hover:hover){.dark\\:hover\\:bg-accent\\/50:hover{background-color:var(--accent)}@supports (color:color-mix(in lab, red, red)){.dark\\:hover\\:bg-accent\\/50:hover{background-color:color-mix(in oklab, var(--accent) 50%, transparent)}}.dark\\:hover\\:bg-input\\/50:hover{background-color:var(--input)}@supports (color:color-mix(in lab, red, red)){.dark\\:hover\\:bg-input\\/50:hover{background-color:color-mix(in oklab, var(--input) 50%, transparent)}}}.dark\\:focus-visible\\:ring-destructive\\/40:focus-visible{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\\:focus-visible\\:ring-destructive\\/40:focus-visible{--tw-ring-color:color-mix(in oklab, var(--destructive) 40%, transparent)}}.dark\\:aria-invalid\\:ring-destructive\\/40[aria-invalid=true]{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\\:aria-invalid\\:ring-destructive\\/40[aria-invalid=true]{--tw-ring-color:color-mix(in oklab, var(--destructive) 40%, transparent)}}}.\\[\\&_svg\\]\\:pointer-events-none svg{pointer-events:none}.\\[\\&_svg\\]\\:shrink-0 svg{flex-shrink:0}.\\[\\&_svg\\:not\\(\\[class\\*\\=\\'size-\\'\\]\\)\\]\\:size-3 svg:not([class*=size-]){width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.\\[\\&_svg\\:not\\(\\[class\\*\\=\\'size-\\'\\]\\)\\]\\:size-4 svg:not([class*=size-]){width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\\[\\&_svg\\:not\\(\\[class\\*\\=\\'text-\\'\\]\\)\\]\\:text-muted-foreground svg:not([class*=text-]){color:var(--muted-foreground)}.\\[\\&\\>button\\]\\:hidden>button{display:none}.\\[\\&\\>span\\:first-child\\]\\:truncate>span:first-child,.\\[\\&\\>span\\:last-child\\]\\:truncate>span:last-child{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.\\[\\&\\>svg\\]\\:size-3>svg{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.\\[\\&\\>svg\\]\\:size-4>svg{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\\[\\&\\>svg\\]\\:shrink-0>svg{flex-shrink:0}@media (hover:none){.\\[\\@media\\(hover\\:none\\)\\]\\:translate-x-0{--tw-translate-x:0px;translate:var(--tw-translate-x) var(--tw-translate-y)}.\\[\\@media\\(hover\\:none\\)\\]\\:opacity-100{opacity:1}}[data-slot=tooltip-content] .\\[\\[data-slot\\=tooltip-content\\]_\\&\\]\\:bg-background\\/20{background-color:var(--background)}@supports (color:color-mix(in lab, red, red)){[data-slot=tooltip-content] .\\[\\[data-slot\\=tooltip-content\\]_\\&\\]\\:bg-background\\/20{background-color:color-mix(in oklab, var(--background) 20%, transparent)}}[data-slot=tooltip-content] .\\[\\[data-slot\\=tooltip-content\\]_\\&\\]\\:text-background{color:var(--background)}@media (prefers-color-scheme:dark){[data-slot=tooltip-content] .dark\\:\\[\\[data-slot\\=tooltip-content\\]_\\&\\]\\:bg-background\\/10{background-color:var(--background)}@supports (color:color-mix(in lab, red, red)){[data-slot=tooltip-content] .dark\\:\\[\\[data-slot\\=tooltip-content\\]_\\&\\]\\:bg-background\\/10{background-color:color-mix(in oklab, var(--background) 10%, transparent)}}}}@property --tw-animation-delay{syntax:"*";inherits:false;initial-value:0s}@property --tw-animation-direction{syntax:"*";inherits:false;initial-value:normal}@property --tw-animation-duration{syntax:"*";inherits:false}@property --tw-animation-fill-mode{syntax:"*";inherits:false;initial-value:none}@property --tw-animation-iteration-count{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-blur{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-opacity{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-rotate{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-scale{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-blur{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-opacity{syntax:"*";inherits:false;initial-value:1}@property --tw-exit-rotate{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-scale{syntax:"*";inherits:false;initial-value:1}@property --tw-exit-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-translate-y{syntax:"*";inherits:false;initial-value:0}.studio-workspace{color:var(--foreground);background:var(--background);font:12px/1.5 var(--studio-font);cursor:default}.studio-workspace [data-slot=studio-config-file][href]{cursor:pointer;text-underline-offset:3px;text-decoration:none}.studio-workspace [data-slot=studio-config-file][href]:is(:hover,:focus-visible){text-decoration-line:underline}.studio-workspace [data-slot=studio-config-file][href]:focus-visible{outline:2px solid var(--ring);outline-offset:2px}.studio-workspace :is([data-slot=sidebar-header],[data-slot=sidebar-footer]){isolation:isolate;flex-shrink:0;position:relative}.studio-workspace :is([data-slot=sidebar-header],[data-slot=sidebar-footer]):before{content:"";z-index:-1;border-radius:calc(var(--radius-lg) - .25rem);background:var(--card);pointer-events:none;position:absolute;inset:4px}.studio-workspace [data-slot=sidebar-content] [data-slot=sidebar-menu-button]{min-height:36px;color:var(--muted-foreground);gap:10px;font-size:13px;line-height:20px}.studio-workspace [data-slot=sidebar-content] [data-slot=sidebar-menu-button]>span:first-child{flex-shrink:0;display:flex}.studio-workspace [data-slot=sidebar-content] [data-slot=sidebar-menu-button]:is(:hover,:focus-visible,[data-active=true]){color:var(--sidebar-accent-foreground)}.studio-workspace{--studio-inspector-width:20rem;--preview-left:8px;--preview-right:8px;--preview-bottom:8px;position:relative}@media (min-width:768px){.studio-workspace[data-sidebar-panel=shown]{--preview-left:var(--sidebar-width)}.studio-workspace[data-sidebar-panel=shown]:has([data-slot=sidebar][data-state=collapsed]){--preview-left:calc(var(--sidebar-width-icon) + 1rem + 2px)}}@media (min-width:1024px){.studio-workspace:has([data-slot=studio-inspector][aria-hidden=false]){--preview-right:calc(var(--studio-inspector-width) + 1rem)}}@media (max-width:1023px){.studio-workspace:is(:has(>[data-slot=preview-canvas]:not([data-expanded])),[data-preview-layout=custom]):has([data-slot=studio-inspector][aria-hidden=false]){--preview-bottom:40%}.studio-workspace:is(:has(>[data-slot=preview-canvas]:not([data-expanded])),[data-preview-layout=custom]) [data-slot=studio-inspector]{inset:calc(60% + 8px) 8px 8px var(--preview-left);width:auto}}.studio-workspace>[data-slot=preview-canvas]{z-index:0}.studio-workspace>[data-slot=preview-canvas]:not([data-expanded]){inset:8px var(--preview-right) var(--preview-bottom) var(--preview-left);position:absolute}.studio-workspace>iframe[data-slot=studio-preview]{background:var(--background);border:0;width:100%;height:100%;position:absolute;inset:0}.studio-workspace[data-preview-layout=custom]>iframe[data-slot=studio-preview]{inset:0 calc(var(--preview-right) - 8px) calc(var(--preview-bottom) - 8px) calc(var(--preview-left) - 8px);width:calc(100% - var(--preview-left) - var(--preview-right) + 16px);height:calc(100% - var(--preview-bottom) + 8px)}:root{--background:#000;--foreground:#d6d7dc;--card:#ffffff0a;--card-foreground:#d6d7dc;--popover:#18191c;--popover-foreground:#d6d7dc;--primary:#e6e7ea;--primary-foreground:#000;--secondary:#ffffff14;--secondary-foreground:#d6d7dc;--muted:#18191c;--muted-foreground:#8b8c94;--faint:#5d5e66;--accent:#18191c;--accent-foreground:#d6d7dc;--destructive:#f87171;--success:#4ade80;--warning:#facc15;--border:#26272b;--input:#26272b;--ring:#5d5e66;--radius:.5rem;--field:#ffffff0f;--field-hover:#ffffff17;--field-active:#ffffff1f;--knob:#4a4b52;--knob-hover:#5a5b63;--sidebar:#000;--sidebar-foreground:#8b8c94;--sidebar-primary:#e6e7ea;--sidebar-primary-foreground:#000;--sidebar-accent:#ffffff14;--sidebar-accent-foreground:#d6d7dc;--sidebar-border:#26272b;--sidebar-ring:#5d5e66;--studio-font:ui-monospace, SFMono-Regular, Menlo, monospace;color-scheme:dark}[data-slot=studio-controls] :is(.tp-lblv_l,.tp-fldv_t):first-letter{text-transform:uppercase}[data-slot=studio-command-overlay]{z-index:1000;background:#0000004d;position:fixed;inset:0}[data-slot=studio-command-menu]{z-index:1001;border:1px solid var(--sidebar-border);border-radius:calc(var(--radius) + 2px);background:var(--sidebar);width:min(480px,100vw - 32px);max-height:calc(100dvh - min(20vh,160px) - 16px);position:fixed;top:min(20vh,160px);left:50%;overflow:auto;transform:translate(-50%)}@supports (color:color-mix(in lab, red, red)){[data-slot=studio-command-menu]{background:color-mix(in srgb, var(--sidebar) 85%, transparent)}}[data-slot=studio-command-menu]{color:var(--foreground);color-scheme:dark;font:12px/1.5 var(--studio-font);-webkit-backdrop-filter:blur(24px);backdrop-filter:blur(24px);box-shadow:0 20px 25px -5px #0006,0 8px 10px -6px #0006}[data-slot=studio-command-menu],[data-slot=studio-command-menu] *{box-sizing:border-box}[data-slot=studio-command-menu] svg{width:16px;height:16px;color:inherit;flex-shrink:0}[data-slot=studio-command-menu] [data-slot=kbd]{pointer-events:none;border:1px solid var(--border);border-radius:calc(var(--radius) - 2px);background:var(--muted);width:fit-content;min-width:20px;height:20px;font:inherit;color:var(--muted-foreground);-webkit-user-select:none;user-select:none;border-bottom-width:2px;justify-content:center;align-items:center;gap:4px;padding:0 4px;font-size:12px;font-weight:400;display:inline-flex}[data-slot=studio-command-menu] [data-slot=kbd-group]{align-items:center;gap:4px;display:inline-flex}[data-slot=studio-command-menu] button{font:inherit;color:inherit;cursor:pointer;background:0 0;border:0;border-radius:4px}[data-slot=studio-command-menu] button:focus-visible{outline:2px solid var(--sidebar-ring);outline-offset:2px}[data-slot=studio-command-menu] [data-slot=studio-command-heading]{align-items:center;gap:8px;height:40px;padding:0 12px 0 16px;display:flex}[data-slot=studio-command-menu] [data-slot=studio-command-heading] h2{font:inherit;flex:1;align-items:center;gap:10px;margin:0;display:flex}[data-slot=studio-command-menu] [data-slot=studio-command-heading] svg{width:auto;height:14px}[data-slot=studio-command-menu] [data-slot=studio-command-heading] strong{letter-spacing:.08em;white-space:nowrap;font-weight:700}[data-slot=studio-command-menu] [data-slot=studio-command-heading] button{padding:0}[data-slot=studio-command-menu] [data-slot=studio-command-heading] button:hover{background:var(--sidebar-accent)}[data-slot=studio-command-menu] [data-slot=studio-command-description]{display:none}[data-slot=studio-command-menu] [data-slot=command]{height:auto;color:inherit;background:0 0;flex-direction:column;display:flex;overflow:hidden}[data-slot=studio-command-menu] [data-slot=command-input-wrapper]{border-radius:var(--radius);background:var(--field);height:36px;color:var(--muted-foreground);border:1px solid #0000;align-items:center;gap:8px;margin:8px;padding:0 8px;display:flex}[data-slot=studio-command-menu] [data-slot=command-input-wrapper]:focus-within{border-color:var(--sidebar-ring)}[data-slot=studio-command-menu] [data-slot=command-input-wrapper] svg{opacity:1}[data-slot=studio-command-menu] [data-slot=command-input]{width:100%;min-width:0;height:100%;color:var(--sidebar-primary);font:inherit;background:0 0;border:0;outline:none;padding:0}[data-slot=studio-command-menu] [data-slot=command-input]::placeholder{color:var(--muted-foreground)}[data-slot=studio-command-menu] [data-slot=command-list]{overscroll-behavior:contain;max-height:300px;padding:0 8px 8px;scroll-padding:4px;overflow-y:auto}[data-slot=studio-command-menu] [data-slot=command-item]{border-radius:calc(var(--radius) - 2px);min-height:36px;font:inherit;color:var(--sidebar-foreground);cursor:pointer;align-items:center;gap:8px;padding:8px;display:flex}[data-slot=studio-command-menu] [data-slot=command-item][data-selected=true]{background:var(--sidebar-accent);color:var(--sidebar-accent-foreground)}[data-slot=studio-command-menu] [data-slot=studio-command-label]{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;overflow:hidden}[data-slot=studio-command-menu] [data-slot=command-empty]{text-align:center;font:inherit;color:var(--muted-foreground);padding:24px 8px}[data-slot=studio-command-menu] [data-slot=studio-command-footer]{border-top:1px solid var(--sidebar-border);color:var(--muted-foreground);align-items:center;gap:16px;padding:8px 12px;font-size:10px;display:flex}[data-slot=studio-command-menu] [data-slot=studio-command-footer]>span{align-items:center;gap:6px;display:inline-flex}[data-studio-root]{all:initial;color:var(--foreground);font:12px/1.5 var(--studio-font);color-scheme:dark;display:contents}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@keyframes spin{to{transform:rotate(360deg)}}@keyframes enter{0%{opacity:var(--tw-enter-opacity,1);transform:translate3d(var(--tw-enter-translate-x,0),var(--tw-enter-translate-y,0),0)scale3d(var(--tw-enter-scale,1),var(--tw-enter-scale,1),var(--tw-enter-scale,1))rotate(var(--tw-enter-rotate,0));filter:blur(var(--tw-enter-blur,0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity,1);transform:translate3d(var(--tw-exit-translate-x,0),var(--tw-exit-translate-y,0),0)scale3d(var(--tw-exit-scale,1),var(--tw-exit-scale,1),var(--tw-exit-scale,1))rotate(var(--tw-exit-rotate,0));filter:blur(var(--tw-exit-blur,0))}}`;
|
|
237
|
+
|
|
238
|
+
// src/react/shadow-css.ts
|
|
239
|
+
var ROOT_FONT_SIZE = 16;
|
|
240
|
+
function toShadowCss(css) {
|
|
241
|
+
const defaults = [...css.matchAll(/@property\s*(--[\w-]+)\s*\{([^}]*)\}/g)].flatMap(([, name, body]) => {
|
|
242
|
+
const value = /initial-value:\s*([^;}]+)/.exec(body)?.[1]?.trim();
|
|
243
|
+
return value ? [`${name}:${value}`] : [];
|
|
244
|
+
});
|
|
245
|
+
const scoped = css.replace(/(^|[{};])\s*:root(?:\s*,\s*:host)?\s*\{/g, "$1[data-studio-root]{");
|
|
246
|
+
const pinned = scoped.replace(
|
|
247
|
+
/[^{};]+(?=[;}])/g,
|
|
248
|
+
(declaration) => declaration.replace(/(?<![\w.\\])(-?\d*\.?\d+)rem\b/g, (_, value) => `${+value * ROOT_FONT_SIZE}px`)
|
|
249
|
+
);
|
|
250
|
+
if (!defaults.length) return pinned;
|
|
251
|
+
return `${pinned}
|
|
252
|
+
@layer properties{*,::before,::after,::backdrop{${defaults.join(";")}}}`;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// src/react/shadow-root.tsx
|
|
256
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
257
|
+
var sheet;
|
|
258
|
+
function studioStyleSheet() {
|
|
259
|
+
if (!sheet) {
|
|
260
|
+
sheet = new CSSStyleSheet();
|
|
261
|
+
sheet.replaceSync(toShadowCss(studio_default));
|
|
262
|
+
}
|
|
263
|
+
return sheet;
|
|
264
|
+
}
|
|
265
|
+
var PortalContainer = createContext(null);
|
|
266
|
+
var usePortalContainer = () => useContext(PortalContainer) ?? void 0;
|
|
267
|
+
function StudioShadowRoot({ children }) {
|
|
268
|
+
const [root, setRoot] = useState(null);
|
|
269
|
+
const attach = useCallback((host) => {
|
|
270
|
+
if (!host) return;
|
|
271
|
+
let shadow = host.shadowRoot;
|
|
272
|
+
if (!shadow) {
|
|
273
|
+
shadow = host.attachShadow({ mode: "open" });
|
|
274
|
+
shadow.adoptedStyleSheets = [studioStyleSheet()];
|
|
275
|
+
const container = document.createElement("div");
|
|
276
|
+
container.setAttribute("data-studio-root", "");
|
|
277
|
+
shadow.append(container);
|
|
278
|
+
}
|
|
279
|
+
setRoot(shadow.querySelector("[data-studio-root]"));
|
|
280
|
+
}, []);
|
|
281
|
+
return (
|
|
282
|
+
// `display: contents` keeps the host out of layout; inline so host stylesheets can't override it.
|
|
283
|
+
/* @__PURE__ */ jsx4("div", { ref: attach, "data-studio-host": "", style: { display: "contents" }, children: root && createPortal(/* @__PURE__ */ jsx4(PortalContainer.Provider, { value: root, children }), root) })
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
function activeElement() {
|
|
287
|
+
let element = document.activeElement;
|
|
288
|
+
while (element?.shadowRoot?.activeElement) element = element.shadowRoot.activeElement;
|
|
289
|
+
return element;
|
|
290
|
+
}
|
|
291
|
+
var eventTarget = (event) => event.composedPath()[0] ?? event.target;
|
|
292
|
+
|
|
293
|
+
// src/react/ui/tooltip.tsx
|
|
294
|
+
import { jsx as jsx5, jsxs } from "react/jsx-runtime";
|
|
295
|
+
function TooltipProvider({ delay = 0, ...props }) {
|
|
296
|
+
return /* @__PURE__ */ jsx5(TooltipPrimitive.Provider, { "data-slot": "tooltip-provider", delay, ...props });
|
|
225
297
|
}
|
|
226
298
|
function Tooltip({ ...props }) {
|
|
227
|
-
return /* @__PURE__ */
|
|
299
|
+
return /* @__PURE__ */ jsx5(TooltipPrimitive.Root, { "data-slot": "tooltip", ...props });
|
|
228
300
|
}
|
|
229
301
|
function TooltipTrigger({ ...props }) {
|
|
230
|
-
return /* @__PURE__ */
|
|
302
|
+
return /* @__PURE__ */ jsx5(TooltipPrimitive.Trigger, { "data-slot": "tooltip-trigger", ...props });
|
|
231
303
|
}
|
|
232
304
|
function TooltipContent({
|
|
233
305
|
className,
|
|
306
|
+
side = "top",
|
|
234
307
|
sideOffset = 0,
|
|
308
|
+
align = "center",
|
|
309
|
+
alignOffset = 0,
|
|
235
310
|
children,
|
|
236
311
|
...props
|
|
237
312
|
}) {
|
|
238
|
-
return /* @__PURE__ */
|
|
239
|
-
TooltipPrimitive.
|
|
313
|
+
return /* @__PURE__ */ jsx5(TooltipPrimitive.Portal, { container: usePortalContainer(), children: /* @__PURE__ */ jsx5(
|
|
314
|
+
TooltipPrimitive.Positioner,
|
|
240
315
|
{
|
|
241
|
-
|
|
316
|
+
align,
|
|
317
|
+
alignOffset,
|
|
318
|
+
side,
|
|
242
319
|
sideOffset,
|
|
243
|
-
className:
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
320
|
+
className: "isolate z-50",
|
|
321
|
+
children: /* @__PURE__ */ jsxs(
|
|
322
|
+
TooltipPrimitive.Popup,
|
|
323
|
+
{
|
|
324
|
+
"data-slot": "tooltip-content",
|
|
325
|
+
className: cn(
|
|
326
|
+
"z-50 w-fit origin-(--transform-origin) rounded-md bg-foreground px-3 py-1.5 text-xs text-balance text-background data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[instant]:animate-none data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
|
|
327
|
+
className
|
|
328
|
+
),
|
|
329
|
+
...props,
|
|
330
|
+
children: [
|
|
331
|
+
children,
|
|
332
|
+
/* @__PURE__ */ jsx5(TooltipPrimitive.Arrow, { className: "z-50 size-2.5 translate-y-[calc(-50%-2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground data-[side=bottom]:top-1 data-[side=left]:top-1/2! data-[side=left]:-right-1 data-[side=left]:-translate-y-1/2 data-[side=right]:top-1/2! data-[side=right]:-left-1 data-[side=right]:-translate-y-1/2 data-[side=top]:-bottom-2.5" })
|
|
333
|
+
]
|
|
334
|
+
}
|
|
335
|
+
)
|
|
252
336
|
}
|
|
253
337
|
) });
|
|
254
338
|
}
|
|
255
339
|
function Hint({
|
|
256
340
|
children,
|
|
257
341
|
content,
|
|
342
|
+
disabled,
|
|
258
343
|
...props
|
|
259
344
|
}) {
|
|
260
|
-
return /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
261
|
-
/* @__PURE__ */
|
|
262
|
-
/* @__PURE__ */
|
|
345
|
+
return /* @__PURE__ */ jsxs(Tooltip, { disabled, children: [
|
|
346
|
+
/* @__PURE__ */ jsx5(TooltipTrigger, { render: children }),
|
|
347
|
+
/* @__PURE__ */ jsx5(TooltipContent, { ...props, children: content })
|
|
263
348
|
] });
|
|
264
349
|
}
|
|
265
350
|
|
|
@@ -270,22 +355,22 @@ import { forwardRef as forwardRef2 } from "react";
|
|
|
270
355
|
// src/react/surface.tsx
|
|
271
356
|
import { Slot as Slot2 } from "radix-ui";
|
|
272
357
|
import { forwardRef } from "react";
|
|
273
|
-
import { jsx as
|
|
358
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
274
359
|
var StudioSurface = forwardRef(
|
|
275
360
|
function StudioSurface2({ asChild = false, className, ...props }, ref) {
|
|
276
361
|
const Comp = asChild ? Slot2.Root : "div";
|
|
277
|
-
return /* @__PURE__ */
|
|
362
|
+
return /* @__PURE__ */ jsx6(Comp, { ref, "data-slot": "studio-surface", className: cn("studio-surface", className), ...props });
|
|
278
363
|
}
|
|
279
364
|
);
|
|
280
365
|
var StudioToolbar = forwardRef(function StudioToolbar2({ className, ...props }, ref) {
|
|
281
|
-
return /* @__PURE__ */
|
|
366
|
+
return /* @__PURE__ */ jsx6(StudioSurface, { ref, role: "group", className: cn("studio-toolbar", className), ...props });
|
|
282
367
|
});
|
|
283
368
|
|
|
284
369
|
// src/react/ui/panel.tsx
|
|
285
|
-
import { jsx as
|
|
370
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
286
371
|
var Panel = forwardRef2(function Panel2({ className, asChild = false, ...props }, ref) {
|
|
287
372
|
const Comp = asChild ? Slot3.Root : "div";
|
|
288
|
-
return /* @__PURE__ */
|
|
373
|
+
return /* @__PURE__ */ jsx7(
|
|
289
374
|
Comp,
|
|
290
375
|
{
|
|
291
376
|
ref,
|
|
@@ -299,10 +384,10 @@ var Panel = forwardRef2(function Panel2({ className, asChild = false, ...props }
|
|
|
299
384
|
);
|
|
300
385
|
});
|
|
301
386
|
function PanelHeader({ className, ...props }) {
|
|
302
|
-
return /* @__PURE__ */
|
|
387
|
+
return /* @__PURE__ */ jsx7(StudioSurface, { asChild: true, className: cn("px-3 pt-2.5 pb-2", className), children: /* @__PURE__ */ jsx7("header", { "data-slot": "panel-header", ...props }) });
|
|
303
388
|
}
|
|
304
389
|
var PanelContent = forwardRef2(function PanelContent2({ className, ...props }, ref) {
|
|
305
|
-
return /* @__PURE__ */
|
|
390
|
+
return /* @__PURE__ */ jsx7(
|
|
306
391
|
"div",
|
|
307
392
|
{
|
|
308
393
|
ref,
|
|
@@ -313,11 +398,11 @@ var PanelContent = forwardRef2(function PanelContent2({ className, ...props }, r
|
|
|
313
398
|
);
|
|
314
399
|
});
|
|
315
400
|
function PanelFooter({ className, ...props }) {
|
|
316
|
-
return /* @__PURE__ */
|
|
401
|
+
return /* @__PURE__ */ jsx7(StudioSurface, { asChild: true, className: cn("grid gap-2 p-2", className), children: /* @__PURE__ */ jsx7("footer", { "data-slot": "panel-footer", ...props }) });
|
|
317
402
|
}
|
|
318
403
|
|
|
319
404
|
// src/react/inspector.tsx
|
|
320
|
-
import { Fragment, jsx as
|
|
405
|
+
import { Fragment, jsx as jsx8, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
321
406
|
function describe(studio, handle) {
|
|
322
407
|
const { state } = handle;
|
|
323
408
|
if (handle.comparing) return { tone: "text-sky-400", text: "Showing saved" };
|
|
@@ -327,6 +412,13 @@ function describe(studio, handle) {
|
|
|
327
412
|
if (state.dirty) return { tone: "text-warning", text: "Unsaved" };
|
|
328
413
|
return { tone: "text-success", text: state.saved.hash ? "Saved" : "Not on disk yet" };
|
|
329
414
|
}
|
|
415
|
+
function adoptTweakpaneStyles(container) {
|
|
416
|
+
const root = container.getRootNode();
|
|
417
|
+
if (!(root instanceof ShadowRoot)) return;
|
|
418
|
+
for (const style of document.head.querySelectorAll("style[data-tp-style]")) {
|
|
419
|
+
if (!root.querySelector(`style[data-tp-style="${style.dataset.tpStyle}"]`)) root.append(style.cloneNode(true));
|
|
420
|
+
}
|
|
421
|
+
}
|
|
330
422
|
function Inspector({
|
|
331
423
|
studio,
|
|
332
424
|
handle,
|
|
@@ -336,7 +428,7 @@ function Inspector({
|
|
|
336
428
|
useStudio(studio);
|
|
337
429
|
const container = useRef(null);
|
|
338
430
|
const pane = useRef(null);
|
|
339
|
-
const [failure, setFailure] =
|
|
431
|
+
const [failure, setFailure] = useState2(null);
|
|
340
432
|
const run = (action) => void action.then((result) => setFailure(result.ok ? null : result.message ?? result.error));
|
|
341
433
|
const save = (force = false) => run(handle.save({ force }));
|
|
342
434
|
useEffect(() => {
|
|
@@ -351,6 +443,7 @@ function Inspector({
|
|
|
351
443
|
schema: () => handle.controls(),
|
|
352
444
|
extend: resetSlidersOnDoubleClick(handle)
|
|
353
445
|
});
|
|
446
|
+
adoptTweakpaneStyles(container.current);
|
|
354
447
|
const unsubscribe = handle.subscribe(() => bound.refresh());
|
|
355
448
|
teardown = () => {
|
|
356
449
|
unsubscribe();
|
|
@@ -386,11 +479,11 @@ function Inspector({
|
|
|
386
479
|
return /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
387
480
|
/* @__PURE__ */ jsxs2(PanelHeader, { children: [
|
|
388
481
|
/* @__PURE__ */ jsxs2("strong", { className: "flex min-w-0 items-center gap-2 text-foreground", children: [
|
|
389
|
-
/* @__PURE__ */
|
|
390
|
-
/* @__PURE__ */
|
|
482
|
+
/* @__PURE__ */ jsx8(ToolIcon, { icon: definition.icon, className: "size-3.5 shrink-0" }),
|
|
483
|
+
/* @__PURE__ */ jsx8("span", { className: "truncate", title: definition.title ?? definition.id, children: definition.title ?? definition.id })
|
|
391
484
|
] }),
|
|
392
485
|
/* @__PURE__ */ jsxs2("div", { className: "mt-1 flex items-center gap-3 pl-5.5 text-[11px]", children: [
|
|
393
|
-
/* @__PURE__ */
|
|
486
|
+
/* @__PURE__ */ jsx8(
|
|
394
487
|
ConfigFile,
|
|
395
488
|
{
|
|
396
489
|
"data-slot": "studio-config-file",
|
|
@@ -406,31 +499,31 @@ function Inspector({
|
|
|
406
499
|
className: `flex shrink-0 items-center gap-1.5 ${status.tone}`,
|
|
407
500
|
title: state ? `Draft revision ${state.draft.revision}` : void 0,
|
|
408
501
|
children: [
|
|
409
|
-
/* @__PURE__ */
|
|
502
|
+
/* @__PURE__ */ jsx8("span", { "aria-hidden": "true", className: "size-1.5 rounded-full bg-current" }),
|
|
410
503
|
status.text
|
|
411
504
|
]
|
|
412
505
|
}
|
|
413
506
|
)
|
|
414
507
|
] })
|
|
415
508
|
] }),
|
|
416
|
-
/* @__PURE__ */
|
|
509
|
+
/* @__PURE__ */ jsx8(PanelContent, { ref: container, "data-slot": "studio-controls", style: tweakpaneTheme }),
|
|
417
510
|
/* @__PURE__ */ jsxs2(PanelFooter, { children: [
|
|
418
|
-
failure && /* @__PURE__ */
|
|
511
|
+
failure && /* @__PURE__ */ jsx8("div", { className: "text-destructive", children: failure }),
|
|
419
512
|
changes.length > 0 && /* @__PURE__ */ jsxs2("div", { className: "truncate text-muted-foreground", title: changes.join(", "), children: [
|
|
420
513
|
changes.length,
|
|
421
514
|
" changed: ",
|
|
422
|
-
/* @__PURE__ */
|
|
515
|
+
/* @__PURE__ */ jsx8("span", { className: "text-foreground", children: changes.join(", ") })
|
|
423
516
|
] }),
|
|
424
517
|
/* @__PURE__ */ jsxs2("div", { className: "flex gap-2", children: [
|
|
425
|
-
/* @__PURE__ */
|
|
518
|
+
/* @__PURE__ */ jsx8(
|
|
426
519
|
Hint,
|
|
427
520
|
{
|
|
428
521
|
className: "flex items-center gap-2",
|
|
429
522
|
content: /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
430
523
|
"Hold to compare with saved ",
|
|
431
|
-
/* @__PURE__ */
|
|
524
|
+
/* @__PURE__ */ jsx8(Kbd, { children: "\\" })
|
|
432
525
|
] }),
|
|
433
|
-
children: /* @__PURE__ */
|
|
526
|
+
children: /* @__PURE__ */ jsx8(
|
|
434
527
|
Button,
|
|
435
528
|
{
|
|
436
529
|
variant: "secondary",
|
|
@@ -445,12 +538,12 @@ function Inspector({
|
|
|
445
538
|
},
|
|
446
539
|
onPointerUp: () => onCompare(false),
|
|
447
540
|
onPointerCancel: () => onCompare(false),
|
|
448
|
-
children: /* @__PURE__ */
|
|
541
|
+
children: /* @__PURE__ */ jsx8(SquareSplitHorizontal, {})
|
|
449
542
|
}
|
|
450
543
|
)
|
|
451
544
|
}
|
|
452
545
|
),
|
|
453
|
-
/* @__PURE__ */
|
|
546
|
+
/* @__PURE__ */ jsx8(
|
|
454
547
|
Button,
|
|
455
548
|
{
|
|
456
549
|
variant: "secondary",
|
|
@@ -461,11 +554,11 @@ function Inspector({
|
|
|
461
554
|
children: "Discard"
|
|
462
555
|
}
|
|
463
556
|
),
|
|
464
|
-
state?.conflict ? /* @__PURE__ */
|
|
557
|
+
state?.conflict ? /* @__PURE__ */ jsx8(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: [
|
|
465
558
|
"Save",
|
|
466
559
|
/* @__PURE__ */ jsxs2(KbdGroup, { children: [
|
|
467
|
-
/* @__PURE__ */
|
|
468
|
-
/* @__PURE__ */
|
|
560
|
+
/* @__PURE__ */ jsx8(Kbd, { children: "\u2318" }),
|
|
561
|
+
/* @__PURE__ */ jsx8(Kbd, { children: "S" })
|
|
469
562
|
] })
|
|
470
563
|
] })
|
|
471
564
|
] })
|
|
@@ -474,13 +567,13 @@ function Inspector({
|
|
|
474
567
|
}
|
|
475
568
|
|
|
476
569
|
// src/react/logo.tsx
|
|
477
|
-
import { jsx as
|
|
570
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
478
571
|
function Logo(props) {
|
|
479
|
-
return /* @__PURE__ */
|
|
572
|
+
return /* @__PURE__ */ jsx9("svg", { viewBox: "0 0 352 144", fill: "currentColor", "aria-label": "JOYCO", role: "img", ...props, children: /* @__PURE__ */ jsx9("path", { d: "M328 96L280 144H0V40H176V112H192V24H0V0H352V24H328V96Z" }) });
|
|
480
573
|
}
|
|
481
574
|
|
|
482
575
|
// src/react/pinned-tools.ts
|
|
483
|
-
import { useEffect as useEffect2, useState as
|
|
576
|
+
import { useEffect as useEffect2, useState as useState3 } from "react";
|
|
484
577
|
var STORAGE_KEY = "joyco-studio:pinned-tools";
|
|
485
578
|
var CHANGE_EVENT = "joyco-studio:pins-changed";
|
|
486
579
|
function readPins() {
|
|
@@ -492,7 +585,7 @@ function readPins() {
|
|
|
492
585
|
}
|
|
493
586
|
}
|
|
494
587
|
function usePinnedTools(studio) {
|
|
495
|
-
const [pins, setPins] =
|
|
588
|
+
const [pins, setPins] = useState3([]);
|
|
496
589
|
useEffect2(() => {
|
|
497
590
|
setPins(readPins());
|
|
498
591
|
const onChange = (event) => setPins(event.detail);
|
|
@@ -507,9 +600,7 @@ function usePinnedTools(studio) {
|
|
|
507
600
|
};
|
|
508
601
|
}, []);
|
|
509
602
|
const pinned = new Set(pins);
|
|
510
|
-
const tools = [...studio.
|
|
511
|
-
(a, b) => Number(pinned.has(b.definition.id)) - Number(pinned.has(a.definition.id))
|
|
512
|
-
);
|
|
603
|
+
const tools = [...studio.definitions].sort((a, b) => Number(pinned.has(b.id)) - Number(pinned.has(a.id)));
|
|
513
604
|
const togglePin = (id) => {
|
|
514
605
|
const next = pinned.has(id) ? pins.filter((pin) => pin !== id) : [...pins, id];
|
|
515
606
|
try {
|
|
@@ -523,17 +614,17 @@ function usePinnedTools(studio) {
|
|
|
523
614
|
|
|
524
615
|
// src/react/preview-canvas.tsx
|
|
525
616
|
import { RotateCw } from "lucide-react";
|
|
526
|
-
import { forwardRef as forwardRef3, useImperativeHandle, useRef as useRef2, useState as
|
|
617
|
+
import { forwardRef as forwardRef3, useImperativeHandle, useRef as useRef2, useState as useState5 } from "react";
|
|
527
618
|
|
|
528
619
|
// src/react/canvas-toolbar.tsx
|
|
529
620
|
import { Maximize, Minimize, Pin, PinOff } from "lucide-react";
|
|
530
|
-
import { useState as
|
|
531
|
-
import { jsx as
|
|
621
|
+
import { useState as useState4 } from "react";
|
|
622
|
+
import { jsx as jsx10, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
532
623
|
function CanvasToolbar({ label, expanded = false, onToggle, children }) {
|
|
533
|
-
const [ghost, setGhost] =
|
|
624
|
+
const [ghost, setGhost] = useState4(false);
|
|
534
625
|
const ExpandIcon = expanded ? Minimize : Maximize;
|
|
535
626
|
const PinIcon = ghost ? PinOff : Pin;
|
|
536
|
-
return /* @__PURE__ */
|
|
627
|
+
return /* @__PURE__ */ jsx10(
|
|
537
628
|
"div",
|
|
538
629
|
{
|
|
539
630
|
className: "studio-canvas-toolbar",
|
|
@@ -544,11 +635,11 @@ function CanvasToolbar({ label, expanded = false, onToggle, children }) {
|
|
|
544
635
|
"aria-label": label,
|
|
545
636
|
children: /* @__PURE__ */ jsxs3(StudioToolbar, { className: "studio-canvas-actions", children: [
|
|
546
637
|
children,
|
|
547
|
-
onToggle && /* @__PURE__ */
|
|
548
|
-
/* @__PURE__ */
|
|
638
|
+
onToggle && /* @__PURE__ */ jsx10("div", { className: "studio-canvas-toggle", children: /* @__PURE__ */ jsxs3("button", { "data-slot": "toolbar-action", type: "button", "aria-pressed": expanded, onClick: onToggle, children: [
|
|
639
|
+
/* @__PURE__ */ jsx10(ExpandIcon, { size: 14, strokeWidth: 1.5, "aria-hidden": true }),
|
|
549
640
|
expanded ? "Contain canvas" : "Expand"
|
|
550
641
|
] }) }),
|
|
551
|
-
!expanded && /* @__PURE__ */
|
|
642
|
+
!expanded && /* @__PURE__ */ jsx10(
|
|
552
643
|
"button",
|
|
553
644
|
{
|
|
554
645
|
type: "button",
|
|
@@ -556,7 +647,7 @@ function CanvasToolbar({ label, expanded = false, onToggle, children }) {
|
|
|
556
647
|
"aria-pressed": ghost,
|
|
557
648
|
title: ghost ? "Pin header" : "Auto-hide header",
|
|
558
649
|
onClick: () => setGhost(!ghost),
|
|
559
|
-
children: /* @__PURE__ */
|
|
650
|
+
children: /* @__PURE__ */ jsx10(PinIcon, { size: 14, strokeWidth: 1.5, "aria-hidden": true })
|
|
560
651
|
}
|
|
561
652
|
)
|
|
562
653
|
] })
|
|
@@ -565,9 +656,9 @@ function CanvasToolbar({ label, expanded = false, onToggle, children }) {
|
|
|
565
656
|
}
|
|
566
657
|
|
|
567
658
|
// src/react/preview-canvas.tsx
|
|
568
|
-
import { jsx as
|
|
659
|
+
import { jsx as jsx11, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
569
660
|
var PreviewCanvas = forwardRef3(function PreviewCanvas2({ title = "Preview", expanded: controlled, onExpandedChange, onReload, toolbar, ...props }, ref) {
|
|
570
|
-
const [localExpanded, setExpanded] =
|
|
661
|
+
const [localExpanded, setExpanded] = useState5(false);
|
|
571
662
|
const expanded = controlled ?? localExpanded;
|
|
572
663
|
const frame = useRef2(null);
|
|
573
664
|
useImperativeHandle(ref, () => frame.current, []);
|
|
@@ -589,7 +680,7 @@ var PreviewCanvas = forwardRef3(function PreviewCanvas2({ title = "Preview", exp
|
|
|
589
680
|
onExpandedChange?.(!expanded);
|
|
590
681
|
},
|
|
591
682
|
children: [
|
|
592
|
-
/* @__PURE__ */
|
|
683
|
+
/* @__PURE__ */ jsx11(
|
|
593
684
|
"button",
|
|
594
685
|
{
|
|
595
686
|
type: "button",
|
|
@@ -599,19 +690,38 @@ var PreviewCanvas = forwardRef3(function PreviewCanvas2({ title = "Preview", exp
|
|
|
599
690
|
onReload?.();
|
|
600
691
|
if (frame.current) frame.current.src = frame.current.src;
|
|
601
692
|
},
|
|
602
|
-
children: /* @__PURE__ */
|
|
693
|
+
children: /* @__PURE__ */ jsx11(RotateCw, { size: 14, strokeWidth: 1.5, "aria-hidden": true })
|
|
603
694
|
}
|
|
604
695
|
),
|
|
605
|
-
/* @__PURE__ */
|
|
696
|
+
/* @__PURE__ */ jsx11("div", { className: "studio-preview-source", children: toolbar ?? /* @__PURE__ */ jsx11("span", { className: "studio-preview-title", children: title }) })
|
|
606
697
|
]
|
|
607
698
|
}
|
|
608
699
|
),
|
|
609
|
-
/* @__PURE__ */
|
|
700
|
+
/* @__PURE__ */ jsx11("iframe", { ...props, ref: frame, title })
|
|
610
701
|
]
|
|
611
702
|
}
|
|
612
703
|
);
|
|
613
704
|
});
|
|
614
705
|
|
|
706
|
+
// src/react/session-flag.ts
|
|
707
|
+
import { useEffect as useEffect3, useState as useState6 } from "react";
|
|
708
|
+
function useSessionFlag(key) {
|
|
709
|
+
const [value, setValue] = useState6(() => {
|
|
710
|
+
try {
|
|
711
|
+
return sessionStorage.getItem(key) === "true";
|
|
712
|
+
} catch {
|
|
713
|
+
return false;
|
|
714
|
+
}
|
|
715
|
+
});
|
|
716
|
+
useEffect3(() => {
|
|
717
|
+
try {
|
|
718
|
+
sessionStorage.setItem(key, String(value));
|
|
719
|
+
} catch {
|
|
720
|
+
}
|
|
721
|
+
}, [key, value]);
|
|
722
|
+
return [value, setValue];
|
|
723
|
+
}
|
|
724
|
+
|
|
615
725
|
// src/react/ui/sidebar.tsx
|
|
616
726
|
import * as React2 from "react";
|
|
617
727
|
import { cva as cva2 } from "class-variance-authority";
|
|
@@ -636,21 +746,21 @@ function useIsMobile() {
|
|
|
636
746
|
|
|
637
747
|
// src/react/ui/sheet.tsx
|
|
638
748
|
import { XIcon } from "lucide-react";
|
|
639
|
-
import { Dialog as SheetPrimitive } from "
|
|
640
|
-
import { jsx as
|
|
749
|
+
import { Dialog as SheetPrimitive } from "@base-ui/react/dialog";
|
|
750
|
+
import { jsx as jsx12, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
641
751
|
function Sheet({ ...props }) {
|
|
642
|
-
return /* @__PURE__ */
|
|
752
|
+
return /* @__PURE__ */ jsx12(SheetPrimitive.Root, { "data-slot": "sheet", ...props });
|
|
643
753
|
}
|
|
644
754
|
function SheetPortal({ ...props }) {
|
|
645
|
-
return /* @__PURE__ */
|
|
755
|
+
return /* @__PURE__ */ jsx12(SheetPrimitive.Portal, { "data-slot": "sheet-portal", container: usePortalContainer(), ...props });
|
|
646
756
|
}
|
|
647
757
|
function SheetOverlay({ className, ...props }) {
|
|
648
|
-
return /* @__PURE__ */
|
|
649
|
-
SheetPrimitive.
|
|
758
|
+
return /* @__PURE__ */ jsx12(
|
|
759
|
+
SheetPrimitive.Backdrop,
|
|
650
760
|
{
|
|
651
761
|
"data-slot": "sheet-overlay",
|
|
652
762
|
className: cn(
|
|
653
|
-
"fixed inset-0 z-50 bg-black/50 data-
|
|
763
|
+
"fixed inset-0 z-50 bg-black/50 data-closed:animate-out data-closed:fade-out-0 data-open:animate-in data-open:fade-in-0",
|
|
654
764
|
className
|
|
655
765
|
),
|
|
656
766
|
...props
|
|
@@ -665,25 +775,25 @@ function SheetContent({
|
|
|
665
775
|
...props
|
|
666
776
|
}) {
|
|
667
777
|
return /* @__PURE__ */ jsxs5(SheetPortal, { children: [
|
|
668
|
-
/* @__PURE__ */
|
|
778
|
+
/* @__PURE__ */ jsx12(SheetOverlay, {}),
|
|
669
779
|
/* @__PURE__ */ jsxs5(
|
|
670
|
-
SheetPrimitive.
|
|
780
|
+
SheetPrimitive.Popup,
|
|
671
781
|
{
|
|
672
782
|
"data-slot": "sheet-content",
|
|
673
783
|
className: cn(
|
|
674
|
-
"fixed z-50 flex flex-col gap-4 bg-background shadow-lg transition ease-in-out data-
|
|
675
|
-
side === "right" && "inset-y-0 right-0 h-full w-3/4 border-l data-
|
|
676
|
-
side === "left" && "inset-y-0 left-0 h-full w-3/4 border-r data-
|
|
677
|
-
side === "top" && "inset-x-0 top-0 h-auto border-b data-
|
|
678
|
-
side === "bottom" && "inset-x-0 bottom-0 h-auto border-t data-
|
|
784
|
+
"fixed z-50 flex flex-col gap-4 bg-background shadow-lg transition ease-in-out data-closed:animate-out data-closed:duration-300 data-open:animate-in data-open:duration-500",
|
|
785
|
+
side === "right" && "inset-y-0 right-0 h-full w-3/4 border-l data-closed:slide-out-to-right data-open:slide-in-from-right sm:max-w-sm",
|
|
786
|
+
side === "left" && "inset-y-0 left-0 h-full w-3/4 border-r data-closed:slide-out-to-left data-open:slide-in-from-left sm:max-w-sm",
|
|
787
|
+
side === "top" && "inset-x-0 top-0 h-auto border-b data-closed:slide-out-to-top data-open:slide-in-from-top",
|
|
788
|
+
side === "bottom" && "inset-x-0 bottom-0 h-auto border-t data-closed:slide-out-to-bottom data-open:slide-in-from-bottom",
|
|
679
789
|
className
|
|
680
790
|
),
|
|
681
791
|
...props,
|
|
682
792
|
children: [
|
|
683
793
|
children,
|
|
684
|
-
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
|
|
685
|
-
/* @__PURE__ */
|
|
686
|
-
/* @__PURE__ */
|
|
794
|
+
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", children: [
|
|
795
|
+
/* @__PURE__ */ jsx12(XIcon, { className: "size-4" }),
|
|
796
|
+
/* @__PURE__ */ jsx12("span", { className: "sr-only", children: "Close" })
|
|
687
797
|
] })
|
|
688
798
|
]
|
|
689
799
|
}
|
|
@@ -691,10 +801,10 @@ function SheetContent({
|
|
|
691
801
|
] });
|
|
692
802
|
}
|
|
693
803
|
function SheetHeader({ className, ...props }) {
|
|
694
|
-
return /* @__PURE__ */
|
|
804
|
+
return /* @__PURE__ */ jsx12("div", { "data-slot": "sheet-header", className: cn("flex flex-col gap-1.5 p-4", className), ...props });
|
|
695
805
|
}
|
|
696
806
|
function SheetTitle({ className, ...props }) {
|
|
697
|
-
return /* @__PURE__ */
|
|
807
|
+
return /* @__PURE__ */ jsx12(
|
|
698
808
|
SheetPrimitive.Title,
|
|
699
809
|
{
|
|
700
810
|
"data-slot": "sheet-title",
|
|
@@ -704,7 +814,7 @@ function SheetTitle({ className, ...props }) {
|
|
|
704
814
|
);
|
|
705
815
|
}
|
|
706
816
|
function SheetDescription({ className, ...props }) {
|
|
707
|
-
return /* @__PURE__ */
|
|
817
|
+
return /* @__PURE__ */ jsx12(
|
|
708
818
|
SheetPrimitive.Description,
|
|
709
819
|
{
|
|
710
820
|
"data-slot": "sheet-description",
|
|
@@ -715,12 +825,12 @@ function SheetDescription({ className, ...props }) {
|
|
|
715
825
|
}
|
|
716
826
|
|
|
717
827
|
// src/react/ui/sidebar.tsx
|
|
718
|
-
import { jsx as
|
|
828
|
+
import { jsx as jsx13, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
719
829
|
var SIDEBAR_COOKIE_NAME = "sidebar_state";
|
|
720
830
|
var SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
|
|
721
|
-
var SIDEBAR_WIDTH = "
|
|
722
|
-
var SIDEBAR_WIDTH_MOBILE = "
|
|
723
|
-
var SIDEBAR_WIDTH_ICON = "
|
|
831
|
+
var SIDEBAR_WIDTH = "256px";
|
|
832
|
+
var SIDEBAR_WIDTH_MOBILE = "288px";
|
|
833
|
+
var SIDEBAR_WIDTH_ICON = "48px";
|
|
724
834
|
var SidebarContext = React2.createContext(null);
|
|
725
835
|
function useSidebar() {
|
|
726
836
|
const context = React2.useContext(SidebarContext);
|
|
@@ -770,7 +880,7 @@ function SidebarProvider({
|
|
|
770
880
|
}),
|
|
771
881
|
[state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar]
|
|
772
882
|
);
|
|
773
|
-
return /* @__PURE__ */
|
|
883
|
+
return /* @__PURE__ */ jsx13(SidebarContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx13(TooltipProvider, { delay: 0, children: /* @__PURE__ */ jsx13(
|
|
774
884
|
"div",
|
|
775
885
|
{
|
|
776
886
|
"data-slot": "sidebar-wrapper",
|
|
@@ -796,7 +906,7 @@ function Sidebar({
|
|
|
796
906
|
const { isMobile, state, openMobile, setOpenMobile } = useSidebar();
|
|
797
907
|
const Surface = variant === "floating" ? Panel : "div";
|
|
798
908
|
if (collapsible === "none") {
|
|
799
|
-
return /* @__PURE__ */
|
|
909
|
+
return /* @__PURE__ */ jsx13(
|
|
800
910
|
"div",
|
|
801
911
|
{
|
|
802
912
|
"data-slot": "sidebar",
|
|
@@ -807,7 +917,7 @@ function Sidebar({
|
|
|
807
917
|
);
|
|
808
918
|
}
|
|
809
919
|
if (isMobile) {
|
|
810
|
-
return /* @__PURE__ */
|
|
920
|
+
return /* @__PURE__ */ jsx13(Sheet, { open: openMobile, onOpenChange: setOpenMobile, ...props, children: /* @__PURE__ */ jsxs6(
|
|
811
921
|
SheetContent,
|
|
812
922
|
{
|
|
813
923
|
"data-sidebar": "sidebar",
|
|
@@ -820,10 +930,10 @@ function Sidebar({
|
|
|
820
930
|
side,
|
|
821
931
|
children: [
|
|
822
932
|
/* @__PURE__ */ jsxs6(SheetHeader, { className: "sr-only", children: [
|
|
823
|
-
/* @__PURE__ */
|
|
824
|
-
/* @__PURE__ */
|
|
933
|
+
/* @__PURE__ */ jsx13(SheetTitle, { children: "Sidebar" }),
|
|
934
|
+
/* @__PURE__ */ jsx13(SheetDescription, { children: "Displays the mobile sidebar." })
|
|
825
935
|
] }),
|
|
826
|
-
/* @__PURE__ */
|
|
936
|
+
/* @__PURE__ */ jsx13("div", { className: "flex h-full w-full flex-col", children })
|
|
827
937
|
]
|
|
828
938
|
}
|
|
829
939
|
) });
|
|
@@ -838,7 +948,7 @@ function Sidebar({
|
|
|
838
948
|
"data-side": side,
|
|
839
949
|
"data-slot": "sidebar",
|
|
840
950
|
children: [
|
|
841
|
-
/* @__PURE__ */
|
|
951
|
+
/* @__PURE__ */ jsx13(
|
|
842
952
|
"div",
|
|
843
953
|
{
|
|
844
954
|
"data-slot": "sidebar-gap",
|
|
@@ -850,7 +960,7 @@ function Sidebar({
|
|
|
850
960
|
)
|
|
851
961
|
}
|
|
852
962
|
),
|
|
853
|
-
/* @__PURE__ */
|
|
963
|
+
/* @__PURE__ */ jsx13(
|
|
854
964
|
"div",
|
|
855
965
|
{
|
|
856
966
|
"data-slot": "sidebar-container",
|
|
@@ -862,7 +972,7 @@ function Sidebar({
|
|
|
862
972
|
className
|
|
863
973
|
),
|
|
864
974
|
...props,
|
|
865
|
-
children: /* @__PURE__ */
|
|
975
|
+
children: /* @__PURE__ */ jsx13(
|
|
866
976
|
Surface,
|
|
867
977
|
{
|
|
868
978
|
"data-sidebar": "sidebar",
|
|
@@ -878,7 +988,7 @@ function Sidebar({
|
|
|
878
988
|
);
|
|
879
989
|
}
|
|
880
990
|
function SidebarHeader({ className, ...props }) {
|
|
881
|
-
return /* @__PURE__ */
|
|
991
|
+
return /* @__PURE__ */ jsx13(
|
|
882
992
|
"div",
|
|
883
993
|
{
|
|
884
994
|
"data-slot": "sidebar-header",
|
|
@@ -889,7 +999,7 @@ function SidebarHeader({ className, ...props }) {
|
|
|
889
999
|
);
|
|
890
1000
|
}
|
|
891
1001
|
function SidebarFooter({ className, ...props }) {
|
|
892
|
-
return /* @__PURE__ */
|
|
1002
|
+
return /* @__PURE__ */ jsx13(
|
|
893
1003
|
"div",
|
|
894
1004
|
{
|
|
895
1005
|
"data-slot": "sidebar-footer",
|
|
@@ -900,7 +1010,7 @@ function SidebarFooter({ className, ...props }) {
|
|
|
900
1010
|
);
|
|
901
1011
|
}
|
|
902
1012
|
function SidebarContent({ className, ...props }) {
|
|
903
|
-
return /* @__PURE__ */
|
|
1013
|
+
return /* @__PURE__ */ jsx13(
|
|
904
1014
|
"div",
|
|
905
1015
|
{
|
|
906
1016
|
"data-slot": "sidebar-content",
|
|
@@ -914,7 +1024,7 @@ function SidebarContent({ className, ...props }) {
|
|
|
914
1024
|
);
|
|
915
1025
|
}
|
|
916
1026
|
function SidebarGroup({ className, ...props }) {
|
|
917
|
-
return /* @__PURE__ */
|
|
1027
|
+
return /* @__PURE__ */ jsx13(
|
|
918
1028
|
"div",
|
|
919
1029
|
{
|
|
920
1030
|
"data-slot": "sidebar-group",
|
|
@@ -925,7 +1035,7 @@ function SidebarGroup({ className, ...props }) {
|
|
|
925
1035
|
);
|
|
926
1036
|
}
|
|
927
1037
|
function SidebarMenu({ className, ...props }) {
|
|
928
|
-
return /* @__PURE__ */
|
|
1038
|
+
return /* @__PURE__ */ jsx13(
|
|
929
1039
|
"ul",
|
|
930
1040
|
{
|
|
931
1041
|
"data-slot": "sidebar-menu",
|
|
@@ -936,7 +1046,7 @@ function SidebarMenu({ className, ...props }) {
|
|
|
936
1046
|
);
|
|
937
1047
|
}
|
|
938
1048
|
function SidebarMenuItem({ className, ...props }) {
|
|
939
|
-
return /* @__PURE__ */
|
|
1049
|
+
return /* @__PURE__ */ jsx13(
|
|
940
1050
|
"li",
|
|
941
1051
|
{
|
|
942
1052
|
"data-slot": "sidebar-menu-item",
|
|
@@ -977,7 +1087,7 @@ function SidebarMenuButton({
|
|
|
977
1087
|
}) {
|
|
978
1088
|
const Comp = asChild ? Slot4.Root : "button";
|
|
979
1089
|
const { isMobile, state } = useSidebar();
|
|
980
|
-
const button2 = /* @__PURE__ */
|
|
1090
|
+
const button2 = /* @__PURE__ */ jsx13(
|
|
981
1091
|
Comp,
|
|
982
1092
|
{
|
|
983
1093
|
"data-slot": "sidebar-menu-button",
|
|
@@ -990,7 +1100,7 @@ function SidebarMenuButton({
|
|
|
990
1100
|
);
|
|
991
1101
|
if (!tooltip) return button2;
|
|
992
1102
|
const { children, ...hint } = typeof tooltip === "string" ? { children: tooltip } : tooltip;
|
|
993
|
-
return /* @__PURE__ */
|
|
1103
|
+
return /* @__PURE__ */ jsx13(Hint, { side: "right", align: "center", disabled: state !== "collapsed" || isMobile, ...hint, content: children, children: button2 });
|
|
994
1104
|
}
|
|
995
1105
|
function SidebarMenuAction({
|
|
996
1106
|
className,
|
|
@@ -999,7 +1109,7 @@ function SidebarMenuAction({
|
|
|
999
1109
|
...props
|
|
1000
1110
|
}) {
|
|
1001
1111
|
const Comp = asChild ? Slot4.Root : "button";
|
|
1002
|
-
return /* @__PURE__ */
|
|
1112
|
+
return /* @__PURE__ */ jsx13(
|
|
1003
1113
|
Comp,
|
|
1004
1114
|
{
|
|
1005
1115
|
"data-slot": "sidebar-menu-action",
|
|
@@ -1018,7 +1128,7 @@ function SidebarMenuAction({
|
|
|
1018
1128
|
}
|
|
1019
1129
|
|
|
1020
1130
|
// src/react/studio.tsx
|
|
1021
|
-
import { Fragment as Fragment2, jsx as
|
|
1131
|
+
import { Fragment as Fragment2, jsx as jsx14, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1022
1132
|
var CONNECTION = {
|
|
1023
1133
|
connected: { icon: PlugZap, tone: "text-success", label: "Runtime connected" },
|
|
1024
1134
|
connecting: { icon: LoaderCircle, tone: "text-warning animate-spin", label: "Connecting to runtime" },
|
|
@@ -1029,20 +1139,20 @@ function StudioFooter({ connection }) {
|
|
|
1029
1139
|
const { state, toggleSidebar } = useSidebar();
|
|
1030
1140
|
const { icon: Status, tone, label } = CONNECTION[connection.phase];
|
|
1031
1141
|
const Toggle = state === "expanded" ? PanelLeftClose : PanelLeftOpen;
|
|
1032
|
-
return /* @__PURE__ */
|
|
1033
|
-
/* @__PURE__ */
|
|
1034
|
-
/* @__PURE__ */
|
|
1035
|
-
/* @__PURE__ */
|
|
1142
|
+
return /* @__PURE__ */ jsx14(SidebarFooter, { children: /* @__PURE__ */ jsxs7(SidebarMenu, { children: [
|
|
1143
|
+
/* @__PURE__ */ jsx14(SidebarMenuItem, { children: /* @__PURE__ */ jsxs7(SidebarMenuButton, { tooltip: label, className: "cursor-default hover:bg-transparent active:bg-transparent", children: [
|
|
1144
|
+
/* @__PURE__ */ jsx14(Status, { className: tone }),
|
|
1145
|
+
/* @__PURE__ */ jsx14("span", { className: "text-clip! group-data-[collapsible=icon]:hidden", children: label })
|
|
1036
1146
|
] }) }),
|
|
1037
|
-
/* @__PURE__ */
|
|
1147
|
+
/* @__PURE__ */ jsx14(SidebarMenuItem, { children: /* @__PURE__ */ jsxs7(
|
|
1038
1148
|
SidebarMenuButton,
|
|
1039
1149
|
{
|
|
1040
1150
|
"aria-label": `${state === "expanded" ? "Collapse" : "Expand"} sidebar`,
|
|
1041
1151
|
tooltip: `${state === "expanded" ? "Collapse" : "Expand"} sidebar`,
|
|
1042
1152
|
onClick: toggleSidebar,
|
|
1043
1153
|
children: [
|
|
1044
|
-
/* @__PURE__ */
|
|
1045
|
-
/* @__PURE__ */
|
|
1154
|
+
/* @__PURE__ */ jsx14(Toggle, {}),
|
|
1155
|
+
/* @__PURE__ */ jsx14("span", { className: "text-clip! group-data-[collapsible=icon]:hidden", children: "Collapse" })
|
|
1046
1156
|
]
|
|
1047
1157
|
}
|
|
1048
1158
|
) })
|
|
@@ -1050,13 +1160,13 @@ function StudioFooter({ connection }) {
|
|
|
1050
1160
|
}
|
|
1051
1161
|
var SHORTCUTS = /* @__PURE__ */ new Set(["b", "s", "k"]);
|
|
1052
1162
|
var COMPARE_KEY = "\\";
|
|
1053
|
-
var editable = (
|
|
1163
|
+
var editable = (event) => !!eventTarget(event)?.matches?.("input, textarea, select, [contenteditable]");
|
|
1054
1164
|
var historyAction = (event) => {
|
|
1055
|
-
if (!(event.metaKey || event.ctrlKey) || event.altKey || editable(event
|
|
1165
|
+
if (!(event.metaKey || event.ctrlKey) || event.altKey || editable(event)) return null;
|
|
1056
1166
|
const key = event.key.toLowerCase();
|
|
1057
1167
|
return key === "z" ? event.shiftKey ? "redo" : "undo" : key === "y" ? "redo" : null;
|
|
1058
1168
|
};
|
|
1059
|
-
var isShortcut = (event) => (event.metaKey || event.ctrlKey) && SHORTCUTS.has(event.key.toLowerCase()) || event.key === COMPARE_KEY && !editable(event
|
|
1169
|
+
var isShortcut = (event) => (event.metaKey || event.ctrlKey) && SHORTCUTS.has(event.key.toLowerCase()) || event.key === COMPARE_KEY && !editable(event) || !!historyAction(event);
|
|
1060
1170
|
function forwardShortcuts(frame) {
|
|
1061
1171
|
const forward = (event) => {
|
|
1062
1172
|
if (event.defaultPrevented || !isShortcut(event)) return;
|
|
@@ -1072,24 +1182,33 @@ function forwardShortcuts(frame) {
|
|
|
1072
1182
|
function Studio({ studio, previewComponent, getConfigFileHref }) {
|
|
1073
1183
|
useStudio(studio);
|
|
1074
1184
|
const { tools, pinned, togglePin } = usePinnedTools(studio);
|
|
1075
|
-
const [mounted, setMounted] =
|
|
1076
|
-
const [
|
|
1077
|
-
const [
|
|
1185
|
+
const [mounted, setMounted] = useState9(false);
|
|
1186
|
+
const [sidebarHidden, setSidebarHidden] = useSessionFlag("joyco-studio:sidebar-hidden");
|
|
1187
|
+
const [inspectorHidden, setInspectorHidden] = useSessionFlag("joyco-studio:inspector-hidden");
|
|
1188
|
+
const [canvasExpanded, setCanvasExpanded] = useSessionFlag("joyco-studio:canvas-expanded");
|
|
1189
|
+
const [selected, setSelected] = useState9(studio.definitions[0]?.id);
|
|
1078
1190
|
const preview = useRef3(null);
|
|
1191
|
+
const definition = studio.definitions.find((tool) => tool.id === selected);
|
|
1079
1192
|
const handle = studio.tools.find((tool) => tool.definition.id === selected);
|
|
1080
|
-
const Preview = previewComponent ?? (
|
|
1081
|
-
|
|
1193
|
+
const Preview = previewComponent ?? (definition?.previewLayout === "custom" ? "iframe" : PreviewCanvas);
|
|
1194
|
+
const hidden = { left: sidebarHidden, right: inspectorHidden || !handle };
|
|
1195
|
+
const show = { left: () => setSidebarHidden(false), right: () => setInspectorHidden(false) };
|
|
1196
|
+
const layout = useRef3(hidden);
|
|
1197
|
+
layout.current = hidden;
|
|
1198
|
+
useEffect5(() => {
|
|
1082
1199
|
const onKey = (event) => {
|
|
1083
1200
|
if (event.defaultPrevented || event.isComposing || event.altKey || !(event.metaKey || event.ctrlKey)) return;
|
|
1084
1201
|
if (event.key.toLowerCase() !== "b") return;
|
|
1085
1202
|
event.preventDefault();
|
|
1086
1203
|
if (event.repeat) return;
|
|
1087
|
-
const active =
|
|
1204
|
+
const active = activeElement();
|
|
1088
1205
|
if (active instanceof HTMLElement && active.closest('[data-slot="sidebar-container"], [data-slot="studio-inspector"]')) {
|
|
1089
1206
|
active.blur();
|
|
1090
1207
|
preview.current?.focus();
|
|
1091
1208
|
}
|
|
1092
|
-
|
|
1209
|
+
const hide = !layout.current.left || !layout.current.right;
|
|
1210
|
+
setSidebarHidden(hide);
|
|
1211
|
+
setInspectorHidden(hide);
|
|
1093
1212
|
};
|
|
1094
1213
|
window.addEventListener("keydown", onKey);
|
|
1095
1214
|
return () => window.removeEventListener("keydown", onKey);
|
|
@@ -1099,12 +1218,12 @@ function Studio({ studio, previewComponent, getConfigFileHref }) {
|
|
|
1099
1218
|
handle.compare(showSaved);
|
|
1100
1219
|
postCompare(preview.current?.contentWindow, handle.definition.id, showSaved);
|
|
1101
1220
|
};
|
|
1102
|
-
|
|
1221
|
+
useEffect5(() => () => handle?.compare(false), [handle]);
|
|
1103
1222
|
const current = useRef3({ handle, compare });
|
|
1104
1223
|
current.current = { handle, compare };
|
|
1105
|
-
|
|
1224
|
+
useEffect5(() => {
|
|
1106
1225
|
const onKey = (event) => {
|
|
1107
|
-
if (event.key !== COMPARE_KEY || editable(event
|
|
1226
|
+
if (event.key !== COMPARE_KEY || editable(event) || event.repeat) return;
|
|
1108
1227
|
event.preventDefault();
|
|
1109
1228
|
const { handle: handle2, compare: compare2 } = current.current;
|
|
1110
1229
|
compare2(event.type === "keydown" && !!handle2?.dirty);
|
|
@@ -1120,7 +1239,7 @@ function Studio({ studio, previewComponent, getConfigFileHref }) {
|
|
|
1120
1239
|
removeEventListener("blur", release);
|
|
1121
1240
|
};
|
|
1122
1241
|
}, []);
|
|
1123
|
-
|
|
1242
|
+
useEffect5(() => {
|
|
1124
1243
|
const onKey = (event) => {
|
|
1125
1244
|
const action = event.defaultPrevented ? null : historyAction(event);
|
|
1126
1245
|
if (!action) return;
|
|
@@ -1130,10 +1249,10 @@ function Studio({ studio, previewComponent, getConfigFileHref }) {
|
|
|
1130
1249
|
addEventListener("keydown", onKey);
|
|
1131
1250
|
return () => removeEventListener("keydown", onKey);
|
|
1132
1251
|
}, []);
|
|
1133
|
-
|
|
1252
|
+
useEffect5(() => {
|
|
1134
1253
|
const fromHash = () => {
|
|
1135
1254
|
const id = decodeURIComponent(location.hash.slice(1));
|
|
1136
|
-
if (studio.
|
|
1255
|
+
if (studio.definitions.some((tool) => tool.id === id)) setSelected(id);
|
|
1137
1256
|
};
|
|
1138
1257
|
setMounted(true);
|
|
1139
1258
|
fromHash();
|
|
@@ -1142,59 +1261,63 @@ function Studio({ studio, previewComponent, getConfigFileHref }) {
|
|
|
1142
1261
|
}, [studio]);
|
|
1143
1262
|
if (!mounted) return null;
|
|
1144
1263
|
const sidebarOpen = !document.cookie.split("; ").includes("sidebar_state=false");
|
|
1145
|
-
return /* @__PURE__ */ jsxs7(
|
|
1264
|
+
return /* @__PURE__ */ jsx14(StudioShadowRoot, { children: /* @__PURE__ */ jsxs7(
|
|
1146
1265
|
SidebarProvider,
|
|
1147
1266
|
{
|
|
1148
1267
|
defaultOpen: sidebarOpen,
|
|
1149
|
-
"data-preview-layout": previewComponent ? "canvas" :
|
|
1268
|
+
"data-preview-layout": previewComponent ? "canvas" : definition?.previewLayout ?? "canvas",
|
|
1269
|
+
"data-sidebar-panel": hidden.left ? "hidden" : "shown",
|
|
1150
1270
|
className: "studio-workspace relative h-svh min-h-0 overflow-hidden text-xs",
|
|
1151
1271
|
children: [
|
|
1152
|
-
|
|
1272
|
+
definition?.preview ? /* @__PURE__ */ jsx14(
|
|
1153
1273
|
Preview,
|
|
1154
1274
|
{
|
|
1155
1275
|
"data-slot": "studio-preview",
|
|
1156
1276
|
ref: preview,
|
|
1157
|
-
src:
|
|
1158
|
-
title:
|
|
1159
|
-
onLoad: (event) => forwardShortcuts(event.currentTarget)
|
|
1277
|
+
src: definition.preview,
|
|
1278
|
+
title: definition.title ?? definition.id,
|
|
1279
|
+
onLoad: (event) => forwardShortcuts(event.currentTarget),
|
|
1280
|
+
...Preview === PreviewCanvas && { expanded: canvasExpanded, onExpandedChange: setCanvasExpanded }
|
|
1160
1281
|
},
|
|
1161
|
-
|
|
1162
|
-
) : /* @__PURE__ */
|
|
1163
|
-
|
|
1282
|
+
definition.id
|
|
1283
|
+
) : /* @__PURE__ */ jsx14("div", { className: "absolute inset-0 grid place-items-center text-faint", children: definition ? "This tool has no preview" : "No tools registered" }),
|
|
1284
|
+
["left", "right"].filter((side) => hidden[side] && (side === "left" || handle)).map((side) => {
|
|
1164
1285
|
const Chevron = side === "left" ? ChevronRight : ChevronLeft;
|
|
1165
|
-
|
|
1286
|
+
const label = side === "left" ? "Show tools" : "Show inspector";
|
|
1287
|
+
return /* @__PURE__ */ jsx14(
|
|
1166
1288
|
"div",
|
|
1167
1289
|
{
|
|
1168
1290
|
"data-slot": "studio-panel-edge",
|
|
1169
1291
|
"data-side": side,
|
|
1170
1292
|
className: cn("group/edge absolute inset-y-0 z-20 w-8", side === "left" ? "left-0" : "right-0"),
|
|
1171
|
-
children: /* @__PURE__ */
|
|
1293
|
+
children: /* @__PURE__ */ jsx14(
|
|
1172
1294
|
Hint,
|
|
1173
1295
|
{
|
|
1174
1296
|
side: side === "left" ? "right" : "left",
|
|
1175
1297
|
sideOffset: 8,
|
|
1176
1298
|
className: "flex items-center gap-2",
|
|
1177
1299
|
content: /* @__PURE__ */ jsxs7(Fragment2, { children: [
|
|
1178
|
-
|
|
1300
|
+
label,
|
|
1179
1301
|
" ",
|
|
1302
|
+
/* @__PURE__ */ jsx14("span", { className: "text-faint", children: "\xB7 both" }),
|
|
1180
1303
|
/* @__PURE__ */ jsxs7(KbdGroup, { children: [
|
|
1181
|
-
/* @__PURE__ */
|
|
1182
|
-
/* @__PURE__ */
|
|
1304
|
+
/* @__PURE__ */ jsx14(Kbd, { children: "\u2318/Ctrl" }),
|
|
1305
|
+
/* @__PURE__ */ jsx14(Kbd, { children: "B" })
|
|
1183
1306
|
] })
|
|
1184
1307
|
] }),
|
|
1185
|
-
children: /* @__PURE__ */
|
|
1308
|
+
children: /* @__PURE__ */ jsx14(Panel, { asChild: true, children: /* @__PURE__ */ jsx14(
|
|
1186
1309
|
Button,
|
|
1187
1310
|
{
|
|
1188
1311
|
"data-slot": "studio-panel-reveal",
|
|
1189
1312
|
variant: "ghost",
|
|
1190
1313
|
size: "icon",
|
|
1191
|
-
"aria-label":
|
|
1192
|
-
onClick:
|
|
1314
|
+
"aria-label": label,
|
|
1315
|
+
onClick: show[side],
|
|
1193
1316
|
className: cn(
|
|
1194
1317
|
"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",
|
|
1195
1318
|
side === "left" ? "left-1 -translate-x-[calc(100%+0.25rem)]" : "right-1 translate-x-[calc(100%+0.25rem)]"
|
|
1196
1319
|
),
|
|
1197
|
-
children: /* @__PURE__ */
|
|
1320
|
+
children: /* @__PURE__ */ jsx14(Chevron, { "aria-hidden": true })
|
|
1198
1321
|
}
|
|
1199
1322
|
) })
|
|
1200
1323
|
}
|
|
@@ -1208,36 +1331,37 @@ function Studio({ studio, previewComponent, getConfigFileHref }) {
|
|
|
1208
1331
|
{
|
|
1209
1332
|
collapsible: "icon",
|
|
1210
1333
|
variant: "floating",
|
|
1211
|
-
inert:
|
|
1212
|
-
"aria-hidden":
|
|
1334
|
+
inert: hidden.left,
|
|
1335
|
+
"aria-hidden": hidden.left,
|
|
1213
1336
|
className: cn(
|
|
1214
1337
|
"transition-[left,right,width,translate] duration-200 ease-out motion-reduce:transition-none",
|
|
1215
|
-
|
|
1338
|
+
hidden.left && "-translate-x-[calc(100%+1rem)]"
|
|
1216
1339
|
),
|
|
1217
1340
|
children: [
|
|
1218
|
-
/* @__PURE__ */
|
|
1219
|
-
/* @__PURE__ */
|
|
1220
|
-
/* @__PURE__ */
|
|
1341
|
+
/* @__PURE__ */ jsx14(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: [
|
|
1342
|
+
/* @__PURE__ */ jsx14(Logo, { className: "h-3.5 w-auto shrink-0" }),
|
|
1343
|
+
/* @__PURE__ */ jsx14("strong", { className: "tracking-[0.08em] whitespace-nowrap", children: "STUDIO" }),
|
|
1221
1344
|
/* @__PURE__ */ jsxs7("span", { "data-slot": "studio-version", className: "text-[10px] text-faint group-data-[collapsible=icon]:hidden", children: [
|
|
1222
1345
|
"v",
|
|
1223
1346
|
version
|
|
1224
1347
|
] })
|
|
1225
1348
|
] }) }),
|
|
1226
|
-
/* @__PURE__ */
|
|
1227
|
-
const title =
|
|
1228
|
-
const isPinned = pinned.has(
|
|
1349
|
+
/* @__PURE__ */ jsx14(SidebarContent, { children: /* @__PURE__ */ jsx14(SidebarGroup, { children: /* @__PURE__ */ jsx14(SidebarMenu, { children: tools.map((tool) => {
|
|
1350
|
+
const title = tool.title ?? tool.id;
|
|
1351
|
+
const isPinned = pinned.has(tool.id);
|
|
1352
|
+
const { state, dirty } = studio.tools.find((handle2) => handle2.definition.id === tool.id) ?? {};
|
|
1229
1353
|
const pinLabel = `${isPinned ? "Unpin" : "Pin"} ${title}`;
|
|
1230
1354
|
return /* @__PURE__ */ jsxs7(SidebarMenuItem, { children: [
|
|
1231
1355
|
/* @__PURE__ */ jsxs7(
|
|
1232
1356
|
SidebarMenuButton,
|
|
1233
1357
|
{
|
|
1234
|
-
isActive:
|
|
1358
|
+
isActive: tool.id === selected,
|
|
1235
1359
|
tooltip: title,
|
|
1236
|
-
onClick: () => location.hash =
|
|
1360
|
+
onClick: () => location.hash = tool.id,
|
|
1237
1361
|
children: [
|
|
1238
1362
|
/* @__PURE__ */ jsxs7("span", { className: "relative", children: [
|
|
1239
|
-
/* @__PURE__ */
|
|
1240
|
-
dirty && /* @__PURE__ */
|
|
1363
|
+
/* @__PURE__ */ jsx14(ToolIcon, { icon: tool.icon, className: "size-4" }),
|
|
1364
|
+
dirty && /* @__PURE__ */ jsx14(
|
|
1241
1365
|
"span",
|
|
1242
1366
|
{
|
|
1243
1367
|
"aria-label": state?.conflict ? "Changed on disk" : "Unsaved",
|
|
@@ -1248,42 +1372,42 @@ function Studio({ studio, previewComponent, getConfigFileHref }) {
|
|
|
1248
1372
|
}
|
|
1249
1373
|
)
|
|
1250
1374
|
] }),
|
|
1251
|
-
/* @__PURE__ */
|
|
1375
|
+
/* @__PURE__ */ jsx14("span", { className: "text-clip! group-data-[collapsible=icon]:hidden", children: title })
|
|
1252
1376
|
]
|
|
1253
1377
|
}
|
|
1254
1378
|
),
|
|
1255
|
-
/* @__PURE__ */
|
|
1379
|
+
/* @__PURE__ */ jsx14(Hint, { content: pinLabel, side: "right", children: /* @__PURE__ */ jsx14(
|
|
1256
1380
|
SidebarMenuAction,
|
|
1257
1381
|
{
|
|
1258
1382
|
type: "button",
|
|
1259
1383
|
"aria-label": pinLabel,
|
|
1260
1384
|
"aria-pressed": isPinned,
|
|
1261
1385
|
showOnHover: !isPinned,
|
|
1262
|
-
onClick: () => togglePin(
|
|
1386
|
+
onClick: () => togglePin(tool.id),
|
|
1263
1387
|
className: cn(
|
|
1264
1388
|
"cursor-pointer [&>svg]:size-3 [@media(hover:none)]:opacity-100",
|
|
1265
1389
|
isPinned && "text-sidebar-primary"
|
|
1266
1390
|
),
|
|
1267
|
-
children: /* @__PURE__ */
|
|
1391
|
+
children: /* @__PURE__ */ jsx14(Pin2, { "aria-hidden": true, fill: isPinned ? "currentColor" : "none" })
|
|
1268
1392
|
}
|
|
1269
1393
|
) })
|
|
1270
|
-
] },
|
|
1394
|
+
] }, tool.id);
|
|
1271
1395
|
}) }) }) }),
|
|
1272
|
-
/* @__PURE__ */
|
|
1396
|
+
/* @__PURE__ */ jsx14(StudioFooter, { connection: studio.connection })
|
|
1273
1397
|
]
|
|
1274
1398
|
}
|
|
1275
1399
|
),
|
|
1276
|
-
handle && /* @__PURE__ */
|
|
1400
|
+
handle && /* @__PURE__ */ jsx14(Panel, { asChild: true, children: /* @__PURE__ */ jsx14(
|
|
1277
1401
|
"aside",
|
|
1278
1402
|
{
|
|
1279
1403
|
"data-slot": "studio-inspector",
|
|
1280
|
-
inert:
|
|
1281
|
-
"aria-hidden":
|
|
1404
|
+
inert: hidden.right,
|
|
1405
|
+
"aria-hidden": hidden.right,
|
|
1282
1406
|
className: cn(
|
|
1283
1407
|
"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",
|
|
1284
|
-
|
|
1408
|
+
hidden.right && "translate-x-[calc(100%+1rem)]"
|
|
1285
1409
|
),
|
|
1286
|
-
children: /* @__PURE__ */
|
|
1410
|
+
children: /* @__PURE__ */ jsx14(
|
|
1287
1411
|
Inspector,
|
|
1288
1412
|
{
|
|
1289
1413
|
studio,
|
|
@@ -1297,21 +1421,36 @@ function Studio({ studio, previewComponent, getConfigFileHref }) {
|
|
|
1297
1421
|
) })
|
|
1298
1422
|
]
|
|
1299
1423
|
}
|
|
1300
|
-
);
|
|
1424
|
+
) });
|
|
1425
|
+
}
|
|
1426
|
+
|
|
1427
|
+
// src/react/debug.tsx
|
|
1428
|
+
import { DebugManager } from "@joycostudio/xyz/debug";
|
|
1429
|
+
import { useEffect as useEffect6 } from "react";
|
|
1430
|
+
function StudioDebug({ studio }) {
|
|
1431
|
+
useEffect6(() => {
|
|
1432
|
+
const debug = new DebugManager({
|
|
1433
|
+
createPane: async () => new (await import("tweakpane")).Pane({ title: "debug" }),
|
|
1434
|
+
binding: { registerFrame: everyFrame }
|
|
1435
|
+
});
|
|
1436
|
+
for (const tool of studio.tools) debug.register(tool);
|
|
1437
|
+
return () => debug.dispose();
|
|
1438
|
+
}, [studio]);
|
|
1439
|
+
return null;
|
|
1301
1440
|
}
|
|
1302
1441
|
|
|
1303
1442
|
// src/react/command-menu.tsx
|
|
1443
|
+
import { Dialog } from "@base-ui/react/dialog";
|
|
1304
1444
|
import { Pin as Pin3 } from "lucide-react";
|
|
1305
|
-
import {
|
|
1306
|
-
import { useEffect as useEffect5, useRef as useRef4, useState as useState8 } from "react";
|
|
1445
|
+
import { useEffect as useEffect7, useRef as useRef4, useState as useState10 } from "react";
|
|
1307
1446
|
|
|
1308
1447
|
// src/react/ui/command.tsx
|
|
1309
1448
|
import * as React3 from "react";
|
|
1310
1449
|
import { Command as CommandPrimitive } from "cmdk";
|
|
1311
1450
|
import { SearchIcon } from "lucide-react";
|
|
1312
|
-
import { jsx as
|
|
1451
|
+
import { jsx as jsx15, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1313
1452
|
function Command({ className, ...props }) {
|
|
1314
|
-
return /* @__PURE__ */
|
|
1453
|
+
return /* @__PURE__ */ jsx15(
|
|
1315
1454
|
CommandPrimitive,
|
|
1316
1455
|
{
|
|
1317
1456
|
"data-slot": "command",
|
|
@@ -1325,8 +1464,8 @@ function Command({ className, ...props }) {
|
|
|
1325
1464
|
}
|
|
1326
1465
|
var CommandInput = React3.forwardRef(function CommandInput2({ className, ...props }, ref) {
|
|
1327
1466
|
return /* @__PURE__ */ jsxs8("div", { "data-slot": "command-input-wrapper", className: "flex h-9 items-center gap-2 border-b px-3", children: [
|
|
1328
|
-
/* @__PURE__ */
|
|
1329
|
-
/* @__PURE__ */
|
|
1467
|
+
/* @__PURE__ */ jsx15(SearchIcon, { "aria-hidden": true, className: "size-4 shrink-0 opacity-50" }),
|
|
1468
|
+
/* @__PURE__ */ jsx15(
|
|
1330
1469
|
CommandPrimitive.Input,
|
|
1331
1470
|
{
|
|
1332
1471
|
ref,
|
|
@@ -1341,7 +1480,7 @@ var CommandInput = React3.forwardRef(function CommandInput2({ className, ...prop
|
|
|
1341
1480
|
] });
|
|
1342
1481
|
});
|
|
1343
1482
|
function CommandList({ className, ...props }) {
|
|
1344
|
-
return /* @__PURE__ */
|
|
1483
|
+
return /* @__PURE__ */ jsx15(
|
|
1345
1484
|
CommandPrimitive.List,
|
|
1346
1485
|
{
|
|
1347
1486
|
"data-slot": "command-list",
|
|
@@ -1351,10 +1490,10 @@ function CommandList({ className, ...props }) {
|
|
|
1351
1490
|
);
|
|
1352
1491
|
}
|
|
1353
1492
|
function CommandEmpty({ ...props }) {
|
|
1354
|
-
return /* @__PURE__ */
|
|
1493
|
+
return /* @__PURE__ */ jsx15(CommandPrimitive.Empty, { "data-slot": "command-empty", className: "py-6 text-center text-sm", ...props });
|
|
1355
1494
|
}
|
|
1356
1495
|
function CommandItem({ className, ...props }) {
|
|
1357
|
-
return /* @__PURE__ */
|
|
1496
|
+
return /* @__PURE__ */ jsx15(
|
|
1358
1497
|
CommandPrimitive.Item,
|
|
1359
1498
|
{
|
|
1360
1499
|
"data-slot": "command-item",
|
|
@@ -1368,26 +1507,35 @@ function CommandItem({ className, ...props }) {
|
|
|
1368
1507
|
}
|
|
1369
1508
|
|
|
1370
1509
|
// src/react/command-menu.tsx
|
|
1371
|
-
import { jsx as
|
|
1372
|
-
function StudioCommandMenu(
|
|
1510
|
+
import { jsx as jsx16, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1511
|
+
function StudioCommandMenu(props) {
|
|
1512
|
+
return /* @__PURE__ */ jsx16(StudioShadowRoot, { children: /* @__PURE__ */ jsx16(CommandMenu, { ...props }) });
|
|
1513
|
+
}
|
|
1514
|
+
function CommandMenu({ studio, studioPath = "/studio", navigate }) {
|
|
1373
1515
|
const { tools, pinned } = usePinnedTools(studio);
|
|
1374
|
-
const [open, setOpen] =
|
|
1375
|
-
const
|
|
1516
|
+
const [open, setOpen] = useState10(false);
|
|
1517
|
+
const [session, setSession] = useState10(0);
|
|
1518
|
+
const isOpen = useRef4(open);
|
|
1519
|
+
isOpen.current = open;
|
|
1520
|
+
const show = (next) => {
|
|
1521
|
+
if (next && !isOpen.current) setSession((count) => count + 1);
|
|
1522
|
+
setOpen(next);
|
|
1523
|
+
};
|
|
1376
1524
|
const input = useRef4(null);
|
|
1377
|
-
|
|
1525
|
+
useEffect7(() => {
|
|
1378
1526
|
if (window.frameElement?.getAttribute("data-slot") === "studio-preview") return;
|
|
1379
1527
|
const onKey = (event) => {
|
|
1380
1528
|
if (event.defaultPrevented || event.isComposing || event.altKey || !(event.metaKey || event.ctrlKey)) return;
|
|
1381
1529
|
if (event.key.toLowerCase() !== "k") return;
|
|
1382
1530
|
event.preventDefault();
|
|
1383
1531
|
if (event.repeat) return;
|
|
1384
|
-
|
|
1532
|
+
show(!isOpen.current);
|
|
1385
1533
|
};
|
|
1386
1534
|
window.addEventListener("keydown", onKey);
|
|
1387
1535
|
return () => window.removeEventListener("keydown", onKey);
|
|
1388
1536
|
}, []);
|
|
1389
1537
|
const select = (id) => {
|
|
1390
|
-
|
|
1538
|
+
show(false);
|
|
1391
1539
|
const target = new URL(studioPath, window.location.href);
|
|
1392
1540
|
target.hash = id;
|
|
1393
1541
|
if (target.pathname === window.location.pathname) {
|
|
@@ -1398,75 +1546,73 @@ function StudioCommandMenu({ studio, studioPath = "/studio", navigate }) {
|
|
|
1398
1546
|
window.location.assign(target.href);
|
|
1399
1547
|
}
|
|
1400
1548
|
};
|
|
1401
|
-
return /* @__PURE__ */
|
|
1402
|
-
/* @__PURE__ */
|
|
1403
|
-
/* @__PURE__ */ jsxs9(
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
/* @__PURE__ */ jsx15("span", { "data-slot": "studio-command-label", children: tool.title ?? tool.id }),
|
|
1438
|
-
pinned.has(tool.id) && /* @__PURE__ */ jsx15(Pin3, { "aria-hidden": true })
|
|
1439
|
-
]
|
|
1440
|
-
},
|
|
1441
|
-
tool.id
|
|
1442
|
-
))
|
|
1443
|
-
] })
|
|
1549
|
+
return /* @__PURE__ */ jsx16(Dialog.Root, { open, onOpenChange: show, children: /* @__PURE__ */ jsxs9(Dialog.Portal, { container: usePortalContainer(), children: [
|
|
1550
|
+
/* @__PURE__ */ jsx16(Dialog.Backdrop, { "data-slot": "studio-command-overlay" }),
|
|
1551
|
+
/* @__PURE__ */ jsxs9(Dialog.Popup, { "data-slot": "studio-command-menu", initialFocus: input, children: [
|
|
1552
|
+
/* @__PURE__ */ jsxs9("div", { "data-slot": "studio-command-heading", children: [
|
|
1553
|
+
/* @__PURE__ */ jsxs9(Dialog.Title, { "aria-label": "Studio tools", children: [
|
|
1554
|
+
/* @__PURE__ */ jsx16(Logo, { "aria-hidden": true }),
|
|
1555
|
+
/* @__PURE__ */ jsx16("strong", { children: "STUDIO" })
|
|
1556
|
+
] }),
|
|
1557
|
+
/* @__PURE__ */ jsx16(Dialog.Close, { "aria-label": "Close tool menu", children: /* @__PURE__ */ jsx16(Kbd, { children: "esc" }) })
|
|
1558
|
+
] }),
|
|
1559
|
+
/* @__PURE__ */ jsx16(Dialog.Description, { "data-slot": "studio-command-description", children: "Open a tool in Studio." }),
|
|
1560
|
+
/* @__PURE__ */ jsxs9(Command, { label: "Studio tools", loop: true, vimBindings: false, children: [
|
|
1561
|
+
/* @__PURE__ */ jsx16(CommandInput, { ref: input, placeholder: "Search tools\u2026" }),
|
|
1562
|
+
/* @__PURE__ */ jsxs9(CommandList, { children: [
|
|
1563
|
+
/* @__PURE__ */ jsx16(CommandEmpty, { children: studio.definitions.length ? "No tools found." : "No tools registered yet." }),
|
|
1564
|
+
tools.map((tool) => /* @__PURE__ */ jsxs9(
|
|
1565
|
+
CommandItem,
|
|
1566
|
+
{
|
|
1567
|
+
value: tool.id,
|
|
1568
|
+
keywords: [tool.title ?? tool.id],
|
|
1569
|
+
onSelect: () => select(tool.id),
|
|
1570
|
+
children: [
|
|
1571
|
+
/* @__PURE__ */ jsx16(ToolIcon, { icon: tool.icon }),
|
|
1572
|
+
/* @__PURE__ */ jsx16("span", { "data-slot": "studio-command-label", children: tool.title ?? tool.id }),
|
|
1573
|
+
pinned.has(tool.id) && /* @__PURE__ */ jsx16(Pin3, { "aria-hidden": true })
|
|
1574
|
+
]
|
|
1575
|
+
},
|
|
1576
|
+
tool.id
|
|
1577
|
+
))
|
|
1578
|
+
] })
|
|
1579
|
+
] }, session),
|
|
1580
|
+
/* @__PURE__ */ jsxs9("div", { "data-slot": "studio-command-footer", "aria-hidden": true, children: [
|
|
1581
|
+
/* @__PURE__ */ jsxs9("span", { children: [
|
|
1582
|
+
/* @__PURE__ */ jsxs9(KbdGroup, { children: [
|
|
1583
|
+
/* @__PURE__ */ jsx16(Kbd, { children: "\u2191" }),
|
|
1584
|
+
/* @__PURE__ */ jsx16(Kbd, { children: "\u2193" })
|
|
1444
1585
|
] }),
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
/* @__PURE__ */ jsxs9("span", { children: [
|
|
1454
|
-
/* @__PURE__ */ jsx15(Kbd, { children: "\u21B5" }),
|
|
1455
|
-
" open tool"
|
|
1456
|
-
] })
|
|
1457
|
-
] })
|
|
1458
|
-
]
|
|
1459
|
-
}
|
|
1460
|
-
)
|
|
1586
|
+
"navigate"
|
|
1587
|
+
] }),
|
|
1588
|
+
/* @__PURE__ */ jsxs9("span", { children: [
|
|
1589
|
+
/* @__PURE__ */ jsx16(Kbd, { children: "\u21B5" }),
|
|
1590
|
+
" open tool"
|
|
1591
|
+
] })
|
|
1592
|
+
] })
|
|
1593
|
+
] })
|
|
1461
1594
|
] }) });
|
|
1462
1595
|
}
|
|
1463
1596
|
|
|
1464
1597
|
// src/react/select.tsx
|
|
1598
|
+
import { Select } from "@base-ui/react/select";
|
|
1465
1599
|
import { Check, ChevronDown, ChevronUp } from "lucide-react";
|
|
1466
|
-
|
|
1467
|
-
|
|
1600
|
+
|
|
1601
|
+
// src/react/select-labels.ts
|
|
1602
|
+
import { Children, isValidElement } from "react";
|
|
1603
|
+
function itemLabels(children, labels = {}) {
|
|
1604
|
+
Children.forEach(children, (child) => {
|
|
1605
|
+
if (!isValidElement(child)) return;
|
|
1606
|
+
if (typeof child.props.value === "string") labels[child.props.value] = child.props.children;
|
|
1607
|
+
else itemLabels(child.props.children, labels);
|
|
1608
|
+
});
|
|
1609
|
+
return labels;
|
|
1610
|
+
}
|
|
1611
|
+
|
|
1612
|
+
// src/react/select.tsx
|
|
1613
|
+
import { jsx as jsx17, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1468
1614
|
function StudioSelect({ label, title, className, children, ...props }) {
|
|
1469
|
-
return /* @__PURE__ */ jsxs10(Select.Root, { ...props, children: [
|
|
1615
|
+
return /* @__PURE__ */ jsxs10(Select.Root, { items: itemLabels(children), ...props, children: [
|
|
1470
1616
|
/* @__PURE__ */ jsxs10(
|
|
1471
1617
|
Select.Trigger,
|
|
1472
1618
|
{
|
|
@@ -1478,26 +1624,23 @@ function StudioSelect({ label, title, className, children, ...props }) {
|
|
|
1478
1624
|
className
|
|
1479
1625
|
),
|
|
1480
1626
|
children: [
|
|
1481
|
-
/* @__PURE__ */
|
|
1482
|
-
/* @__PURE__ */
|
|
1627
|
+
/* @__PURE__ */ jsx17(Select.Value, {}),
|
|
1628
|
+
/* @__PURE__ */ jsx17(Select.Icon, { children: /* @__PURE__ */ jsx17(ChevronDown, { className: "shrink-0 text-muted-foreground", size: 14, strokeWidth: 1.5, "aria-hidden": true }) })
|
|
1483
1629
|
]
|
|
1484
1630
|
}
|
|
1485
1631
|
),
|
|
1486
|
-
/* @__PURE__ */
|
|
1487
|
-
Select.
|
|
1632
|
+
/* @__PURE__ */ jsx17(Select.Portal, { container: usePortalContainer(), children: /* @__PURE__ */ jsx17(Select.Positioner, { align: "end", sideOffset: 6, alignItemWithTrigger: false, className: "isolate z-50", children: /* @__PURE__ */ jsxs10(
|
|
1633
|
+
Select.Popup,
|
|
1488
1634
|
{
|
|
1489
|
-
className: "relative
|
|
1635
|
+
className: "relative max-h-(--available-height) min-w-(--anchor-width) overflow-y-auto rounded-md border border-border bg-popover p-1 font-(family-name:--studio-font) text-xs font-normal text-popover-foreground shadow-md outline-none",
|
|
1490
1636
|
"data-slot": "select-content",
|
|
1491
|
-
position: "popper",
|
|
1492
|
-
align: "end",
|
|
1493
|
-
sideOffset: 6,
|
|
1494
1637
|
children: [
|
|
1495
|
-
/* @__PURE__ */
|
|
1496
|
-
/* @__PURE__ */
|
|
1497
|
-
/* @__PURE__ */
|
|
1638
|
+
/* @__PURE__ */ jsx17(Select.ScrollUpArrow, { className: "sticky top-0 z-10 flex w-full justify-center bg-popover py-1", children: /* @__PURE__ */ jsx17(ChevronUp, { size: 14, "aria-hidden": true }) }),
|
|
1639
|
+
/* @__PURE__ */ jsx17(Select.List, { children }),
|
|
1640
|
+
/* @__PURE__ */ jsx17(Select.ScrollDownArrow, { className: "sticky bottom-0 z-10 flex w-full justify-center bg-popover py-1", children: /* @__PURE__ */ jsx17(ChevronDown, { size: 14, "aria-hidden": true }) })
|
|
1498
1641
|
]
|
|
1499
1642
|
}
|
|
1500
|
-
) })
|
|
1643
|
+
) }) })
|
|
1501
1644
|
] });
|
|
1502
1645
|
}
|
|
1503
1646
|
function StudioSelectItem({ className, children, ...props }) {
|
|
@@ -1511,8 +1654,8 @@ function StudioSelectItem({ className, children, ...props }) {
|
|
|
1511
1654
|
),
|
|
1512
1655
|
...props,
|
|
1513
1656
|
children: [
|
|
1514
|
-
/* @__PURE__ */
|
|
1515
|
-
/* @__PURE__ */
|
|
1657
|
+
/* @__PURE__ */ jsx17(Select.ItemText, { children }),
|
|
1658
|
+
/* @__PURE__ */ jsx17(Select.ItemIndicator, { className: "absolute right-2", children: /* @__PURE__ */ jsx17(Check, { size: 14, strokeWidth: 1.5, "aria-hidden": true }) })
|
|
1516
1659
|
]
|
|
1517
1660
|
}
|
|
1518
1661
|
);
|
|
@@ -1520,9 +1663,9 @@ function StudioSelectItem({ className, children, ...props }) {
|
|
|
1520
1663
|
|
|
1521
1664
|
// src/react/ui/input.tsx
|
|
1522
1665
|
import { forwardRef as forwardRef5 } from "react";
|
|
1523
|
-
import { jsx as
|
|
1666
|
+
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
1524
1667
|
var Input = forwardRef5(function Input2({ className, ...props }, ref) {
|
|
1525
|
-
return /* @__PURE__ */
|
|
1668
|
+
return /* @__PURE__ */ jsx18(
|
|
1526
1669
|
"input",
|
|
1527
1670
|
{
|
|
1528
1671
|
ref,
|
|
@@ -1540,6 +1683,7 @@ export {
|
|
|
1540
1683
|
PreviewCanvas,
|
|
1541
1684
|
Studio,
|
|
1542
1685
|
StudioCommandMenu,
|
|
1686
|
+
StudioDebug,
|
|
1543
1687
|
Input as StudioInput,
|
|
1544
1688
|
Panel as StudioPanel,
|
|
1545
1689
|
PanelContent as StudioPanelContent,
|