@toriistudio/v0-playground 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +4 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +108 -38
- package/dist/index.mjs +99 -30
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -31,6 +31,9 @@ type ControlType = {
|
|
|
31
31
|
render?: () => React.ReactNode;
|
|
32
32
|
};
|
|
33
33
|
type ControlsSchema = Record<string, ControlType>;
|
|
34
|
+
declare const ControlsProvider: ({ children }: {
|
|
35
|
+
children: ReactNode;
|
|
36
|
+
}) => react_jsx_runtime.JSX.Element;
|
|
34
37
|
declare const useControls: <T extends ControlsSchema>(schema: T, options?: {
|
|
35
38
|
componentName?: string;
|
|
36
39
|
}) => { [K in keyof T]: T[K] extends {
|
|
@@ -52,4 +55,4 @@ declare const useUrlSyncedControls: <T extends ControlsSchema>(schema: T, option
|
|
|
52
55
|
jsx: () => string;
|
|
53
56
|
};
|
|
54
57
|
|
|
55
|
-
export { type ControlType, type ControlsSchema, Playground, useControls, useUrlSyncedControls };
|
|
58
|
+
export { type ControlType, ControlsProvider, type ControlsSchema, Playground, useControls, useUrlSyncedControls };
|
package/dist/index.d.ts
CHANGED
|
@@ -31,6 +31,9 @@ type ControlType = {
|
|
|
31
31
|
render?: () => React.ReactNode;
|
|
32
32
|
};
|
|
33
33
|
type ControlsSchema = Record<string, ControlType>;
|
|
34
|
+
declare const ControlsProvider: ({ children }: {
|
|
35
|
+
children: ReactNode;
|
|
36
|
+
}) => react_jsx_runtime.JSX.Element;
|
|
34
37
|
declare const useControls: <T extends ControlsSchema>(schema: T, options?: {
|
|
35
38
|
componentName?: string;
|
|
36
39
|
}) => { [K in keyof T]: T[K] extends {
|
|
@@ -52,4 +55,4 @@ declare const useUrlSyncedControls: <T extends ControlsSchema>(schema: T, option
|
|
|
52
55
|
jsx: () => string;
|
|
53
56
|
};
|
|
54
57
|
|
|
55
|
-
export { type ControlType, type ControlsSchema, Playground, useControls, useUrlSyncedControls };
|
|
58
|
+
export { type ControlType, ControlsProvider, type ControlsSchema, Playground, useControls, useUrlSyncedControls };
|
package/dist/index.js
CHANGED
|
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var src_exports = {};
|
|
32
32
|
__export(src_exports, {
|
|
33
|
+
ControlsProvider: () => ControlsProvider,
|
|
33
34
|
Playground: () => Playground,
|
|
34
35
|
useControls: () => useControls,
|
|
35
36
|
useUrlSyncedControls: () => useUrlSyncedControls
|
|
@@ -207,7 +208,7 @@ var useControls = (schema, options) => {
|
|
|
207
208
|
}
|
|
208
209
|
}, [JSON.stringify(schema), JSON.stringify(ctx.values)]);
|
|
209
210
|
const typedValues = ctx.values;
|
|
210
|
-
const
|
|
211
|
+
const jsx12 = (0, import_react2.useCallback)(() => {
|
|
211
212
|
if (!options?.componentName) return "";
|
|
212
213
|
const props = Object.entries(typedValues).map(([key, val]) => {
|
|
213
214
|
if (typeof val === "string") return `${key}="${val}"`;
|
|
@@ -221,7 +222,7 @@ var useControls = (schema, options) => {
|
|
|
221
222
|
controls: ctx.values,
|
|
222
223
|
schema: ctx.schema,
|
|
223
224
|
setValue: ctx.setValue,
|
|
224
|
-
jsx:
|
|
225
|
+
jsx: jsx12
|
|
225
226
|
};
|
|
226
227
|
};
|
|
227
228
|
var useUrlSyncedControls = (schema, options) => {
|
|
@@ -481,8 +482,53 @@ var SelectSeparator = React8.forwardRef(({ className, ...props }, ref) => /* @__
|
|
|
481
482
|
));
|
|
482
483
|
SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
|
|
483
484
|
|
|
484
|
-
// src/components/
|
|
485
|
+
// src/components/ui/button.tsx
|
|
486
|
+
var React9 = __toESM(require("react"));
|
|
487
|
+
var import_react_slot = require("@radix-ui/react-slot");
|
|
488
|
+
var import_class_variance_authority2 = require("class-variance-authority");
|
|
485
489
|
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
490
|
+
var buttonVariants = (0, import_class_variance_authority2.cva)(
|
|
491
|
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
492
|
+
{
|
|
493
|
+
variants: {
|
|
494
|
+
variant: {
|
|
495
|
+
default: "bg-primary text-primary-foreground shadow hover:bg-primary/90",
|
|
496
|
+
destructive: "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
|
|
497
|
+
outline: "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
|
|
498
|
+
secondary: "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
|
|
499
|
+
ghost: "bg-gray-800 hover:bg-gray-900",
|
|
500
|
+
link: "text-primary underline-offset-4 hover:underline"
|
|
501
|
+
},
|
|
502
|
+
size: {
|
|
503
|
+
default: "h-9 px-4 py-2",
|
|
504
|
+
sm: "h-8 rounded-md px-3 text-xs",
|
|
505
|
+
lg: "h-10 rounded-md px-8",
|
|
506
|
+
icon: "h-9 w-9"
|
|
507
|
+
}
|
|
508
|
+
},
|
|
509
|
+
defaultVariants: {
|
|
510
|
+
variant: "default",
|
|
511
|
+
size: "default"
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
);
|
|
515
|
+
var Button = React9.forwardRef(
|
|
516
|
+
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
517
|
+
const Comp = asChild ? import_react_slot.Slot : "button";
|
|
518
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
519
|
+
Comp,
|
|
520
|
+
{
|
|
521
|
+
className: cn(buttonVariants({ variant, size, className })),
|
|
522
|
+
ref,
|
|
523
|
+
...props
|
|
524
|
+
}
|
|
525
|
+
);
|
|
526
|
+
}
|
|
527
|
+
);
|
|
528
|
+
Button.displayName = "Button";
|
|
529
|
+
|
|
530
|
+
// src/components/ControlPanel/ControlPanel.tsx
|
|
531
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
486
532
|
var ControlPanel = () => {
|
|
487
533
|
const [copied, setCopied] = (0, import_react4.useState)(false);
|
|
488
534
|
const { leftPanelWidth, isDesktop, isHydrated, sidebarNarrow } = useResizableLayout();
|
|
@@ -493,7 +539,17 @@ var ControlPanel = () => {
|
|
|
493
539
|
const buttonControls = Object.entries(schema).filter(
|
|
494
540
|
([, control]) => control.type === "button"
|
|
495
541
|
);
|
|
496
|
-
const
|
|
542
|
+
const previewUrl = (0, import_react4.useMemo)(() => {
|
|
543
|
+
const params = new URLSearchParams();
|
|
544
|
+
params.set("nocontrols", "true");
|
|
545
|
+
for (const [key, value] of Object.entries(values)) {
|
|
546
|
+
if (value !== void 0 && value !== null) {
|
|
547
|
+
params.set(key, value.toString());
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
return `${window.location.pathname}?${params.toString()}`;
|
|
551
|
+
}, [values]);
|
|
552
|
+
const jsx12 = (0, import_react4.useMemo)(() => {
|
|
497
553
|
if (!componentName) return "";
|
|
498
554
|
const props = Object.entries(values).map(([key, val]) => {
|
|
499
555
|
if (typeof val === "string") return `${key}="${val}"`;
|
|
@@ -502,7 +558,7 @@ var ControlPanel = () => {
|
|
|
502
558
|
}).join(" ");
|
|
503
559
|
return `<${componentName} ${props} />`;
|
|
504
560
|
}, [componentName, values]);
|
|
505
|
-
return /* @__PURE__ */ (0,
|
|
561
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
506
562
|
"div",
|
|
507
563
|
{
|
|
508
564
|
className: `order-2 md:order-1 w-full md:h-auto p-2 md:p-4 bg-stone-900 font-mono text-stone-300 transition-opacity duration-300 ${!isHydrated ? "opacity-0" : "opacity-100"}`,
|
|
@@ -519,19 +575,19 @@ var ControlPanel = () => {
|
|
|
519
575
|
overflowY: "auto"
|
|
520
576
|
} : {}
|
|
521
577
|
},
|
|
522
|
-
children: /* @__PURE__ */ (0,
|
|
523
|
-
/* @__PURE__ */ (0,
|
|
524
|
-
/* @__PURE__ */ (0,
|
|
578
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "space-y-4 p-2 md:p-4 border border-stone-700 rounded-md", children: [
|
|
579
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "space-y-1", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h1", { className: "text-lg text-stone-100 font-bold", children: "Controls" }) }),
|
|
580
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "space-y-4 pt-2", children: [
|
|
525
581
|
normalControls.map(([key, control]) => {
|
|
526
582
|
const value = values[key];
|
|
527
583
|
switch (control.type) {
|
|
528
584
|
case "boolean":
|
|
529
|
-
return /* @__PURE__ */ (0,
|
|
585
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
530
586
|
"div",
|
|
531
587
|
{
|
|
532
588
|
className: "flex items-center space-x-4 border-t border-stone-700 pt-4",
|
|
533
589
|
children: [
|
|
534
|
-
/* @__PURE__ */ (0,
|
|
590
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
535
591
|
Switch,
|
|
536
592
|
{
|
|
537
593
|
id: key,
|
|
@@ -540,19 +596,19 @@ var ControlPanel = () => {
|
|
|
540
596
|
className: "data-[state=checked]:bg-stone-700 data-[state=unchecked]:bg-stone-700/40"
|
|
541
597
|
}
|
|
542
598
|
),
|
|
543
|
-
/* @__PURE__ */ (0,
|
|
599
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Label, { htmlFor: key, className: "cursor-pointer", children: key })
|
|
544
600
|
]
|
|
545
601
|
},
|
|
546
602
|
key
|
|
547
603
|
);
|
|
548
604
|
case "number":
|
|
549
|
-
return /* @__PURE__ */ (0,
|
|
550
|
-
/* @__PURE__ */ (0,
|
|
605
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "space-y-2 w-full", children: [
|
|
606
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "flex items-center justify-between pb-1", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Label, { className: "text-stone-300", htmlFor: key, children: [
|
|
551
607
|
key,
|
|
552
608
|
": ",
|
|
553
609
|
value
|
|
554
610
|
] }) }),
|
|
555
|
-
/* @__PURE__ */ (0,
|
|
611
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
556
612
|
Slider,
|
|
557
613
|
{
|
|
558
614
|
id: key,
|
|
@@ -566,7 +622,7 @@ var ControlPanel = () => {
|
|
|
566
622
|
)
|
|
567
623
|
] }, key);
|
|
568
624
|
case "string":
|
|
569
|
-
return /* @__PURE__ */ (0,
|
|
625
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
570
626
|
Input,
|
|
571
627
|
{
|
|
572
628
|
id: key,
|
|
@@ -578,9 +634,9 @@ var ControlPanel = () => {
|
|
|
578
634
|
key
|
|
579
635
|
);
|
|
580
636
|
case "color":
|
|
581
|
-
return /* @__PURE__ */ (0,
|
|
582
|
-
/* @__PURE__ */ (0,
|
|
583
|
-
/* @__PURE__ */ (0,
|
|
637
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "space-y-2 w-full", children: [
|
|
638
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "flex items-center justify-between pb-1", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Label, { className: "text-stone-300", htmlFor: key, children: key }) }),
|
|
639
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
584
640
|
"input",
|
|
585
641
|
{
|
|
586
642
|
type: "color",
|
|
@@ -592,20 +648,20 @@ var ControlPanel = () => {
|
|
|
592
648
|
)
|
|
593
649
|
] }, key);
|
|
594
650
|
case "select":
|
|
595
|
-
return /* @__PURE__ */ (0,
|
|
651
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
596
652
|
"div",
|
|
597
653
|
{
|
|
598
654
|
className: "space-y-2 border-t border-stone-700 pt-4",
|
|
599
655
|
children: [
|
|
600
|
-
/* @__PURE__ */ (0,
|
|
601
|
-
/* @__PURE__ */ (0,
|
|
656
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Label, { className: "text-stone-300", htmlFor: key, children: key }),
|
|
657
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
602
658
|
Select,
|
|
603
659
|
{
|
|
604
660
|
value,
|
|
605
661
|
onValueChange: (val) => setValue(key, val),
|
|
606
662
|
children: [
|
|
607
|
-
/* @__PURE__ */ (0,
|
|
608
|
-
/* @__PURE__ */ (0,
|
|
663
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SelectTrigger, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SelectValue, { placeholder: "Select option" }) }),
|
|
664
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SelectContent, { children: control.options.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SelectItem, { value: opt, children: opt }, opt)) })
|
|
609
665
|
]
|
|
610
666
|
}
|
|
611
667
|
)
|
|
@@ -617,31 +673,31 @@ var ControlPanel = () => {
|
|
|
617
673
|
return null;
|
|
618
674
|
}
|
|
619
675
|
}),
|
|
620
|
-
(buttonControls.length > 0 ||
|
|
621
|
-
|
|
676
|
+
(buttonControls.length > 0 || jsx12) && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "border-t border-stone-700", children: [
|
|
677
|
+
jsx12 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "flex-1 pt-4", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
622
678
|
"button",
|
|
623
679
|
{
|
|
624
680
|
onClick: () => {
|
|
625
|
-
navigator.clipboard.writeText(
|
|
681
|
+
navigator.clipboard.writeText(jsx12);
|
|
626
682
|
setCopied(true);
|
|
627
683
|
setTimeout(() => setCopied(false), 5e3);
|
|
628
684
|
},
|
|
629
685
|
className: "w-full px-4 py-2 text-sm bg-stone-700 hover:bg-stone-600 text-white rounded flex items-center justify-center gap-2",
|
|
630
|
-
children: copied ? /* @__PURE__ */ (0,
|
|
631
|
-
/* @__PURE__ */ (0,
|
|
686
|
+
children: copied ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
687
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react3.Check, { className: "w-4 h-4" }),
|
|
632
688
|
"Copied"
|
|
633
|
-
] }) : /* @__PURE__ */ (0,
|
|
634
|
-
/* @__PURE__ */ (0,
|
|
689
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
690
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react3.Copy, { className: "w-4 h-4" }),
|
|
635
691
|
"Copy to Clipboard"
|
|
636
692
|
] })
|
|
637
693
|
}
|
|
638
694
|
) }, "control-panel-jsx"),
|
|
639
|
-
buttonControls.length > 0 && /* @__PURE__ */ (0,
|
|
640
|
-
([key, control]) => control.type === "button" ? /* @__PURE__ */ (0,
|
|
695
|
+
buttonControls.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "flex flex-wrap gap-2 pt-4", children: buttonControls.map(
|
|
696
|
+
([key, control]) => control.type === "button" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
641
697
|
"div",
|
|
642
698
|
{
|
|
643
699
|
className: "flex-1",
|
|
644
|
-
children: control.render ? control.render() : /* @__PURE__ */ (0,
|
|
700
|
+
children: control.render ? control.render() : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
645
701
|
"button",
|
|
646
702
|
{
|
|
647
703
|
onClick: control.onClick,
|
|
@@ -654,7 +710,20 @@ var ControlPanel = () => {
|
|
|
654
710
|
) : null
|
|
655
711
|
) })
|
|
656
712
|
] })
|
|
657
|
-
] })
|
|
713
|
+
] }),
|
|
714
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
715
|
+
"a",
|
|
716
|
+
{
|
|
717
|
+
href: previewUrl,
|
|
718
|
+
target: "_blank",
|
|
719
|
+
rel: "noopener noreferrer",
|
|
720
|
+
className: "w-full px-4 py-2 text-sm text-center bg-stone-800 hover:bg-stone-700 text-white rounded",
|
|
721
|
+
children: [
|
|
722
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react3.SquareArrowOutUpRight, {}),
|
|
723
|
+
" Open in a New Tab"
|
|
724
|
+
]
|
|
725
|
+
}
|
|
726
|
+
) })
|
|
658
727
|
] })
|
|
659
728
|
}
|
|
660
729
|
);
|
|
@@ -662,20 +731,21 @@ var ControlPanel = () => {
|
|
|
662
731
|
var ControlPanel_default = ControlPanel;
|
|
663
732
|
|
|
664
733
|
// src/components/Playground/Playground.tsx
|
|
665
|
-
var
|
|
734
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
666
735
|
var NO_CONTROLS_PARAM = "nocontrols";
|
|
667
736
|
function Playground({ children }) {
|
|
668
737
|
const hideControls = (0, import_react5.useMemo)(() => {
|
|
669
738
|
if (typeof window === "undefined") return false;
|
|
670
739
|
return new URLSearchParams(window.location.search).get(NO_CONTROLS_PARAM) === "true";
|
|
671
740
|
}, []);
|
|
672
|
-
return /* @__PURE__ */ (0,
|
|
673
|
-
/* @__PURE__ */ (0,
|
|
674
|
-
!hideControls && /* @__PURE__ */ (0,
|
|
741
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ResizableLayout, { hideControls, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(ControlsProvider, { children: [
|
|
742
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PreviewContainer_default, { hideControls, children }),
|
|
743
|
+
!hideControls && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ControlPanel_default, {})
|
|
675
744
|
] }) });
|
|
676
745
|
}
|
|
677
746
|
// Annotate the CommonJS export names for ESM import in node:
|
|
678
747
|
0 && (module.exports = {
|
|
748
|
+
ControlsProvider,
|
|
679
749
|
Playground,
|
|
680
750
|
useControls,
|
|
681
751
|
useUrlSyncedControls
|
package/dist/index.mjs
CHANGED
|
@@ -182,7 +182,7 @@ var useControls = (schema, options) => {
|
|
|
182
182
|
}
|
|
183
183
|
}, [JSON.stringify(schema), JSON.stringify(ctx.values)]);
|
|
184
184
|
const typedValues = ctx.values;
|
|
185
|
-
const
|
|
185
|
+
const jsx12 = useCallback(() => {
|
|
186
186
|
if (!options?.componentName) return "";
|
|
187
187
|
const props = Object.entries(typedValues).map(([key, val]) => {
|
|
188
188
|
if (typeof val === "string") return `${key}="${val}"`;
|
|
@@ -196,7 +196,7 @@ var useControls = (schema, options) => {
|
|
|
196
196
|
controls: ctx.values,
|
|
197
197
|
schema: ctx.schema,
|
|
198
198
|
setValue: ctx.setValue,
|
|
199
|
-
jsx:
|
|
199
|
+
jsx: jsx12
|
|
200
200
|
};
|
|
201
201
|
};
|
|
202
202
|
var useUrlSyncedControls = (schema, options) => {
|
|
@@ -248,7 +248,7 @@ var PreviewContainer_default = PreviewContainer;
|
|
|
248
248
|
|
|
249
249
|
// src/components/ControlPanel/ControlPanel.tsx
|
|
250
250
|
import { useState as useState3, useMemo as useMemo2 } from "react";
|
|
251
|
-
import { Check as Check2, Copy } from "lucide-react";
|
|
251
|
+
import { Check as Check2, Copy, SquareArrowOutUpRight } from "lucide-react";
|
|
252
252
|
|
|
253
253
|
// src/components/ui/switch.tsx
|
|
254
254
|
import * as React4 from "react";
|
|
@@ -456,8 +456,53 @@ var SelectSeparator = React8.forwardRef(({ className, ...props }, ref) => /* @__
|
|
|
456
456
|
));
|
|
457
457
|
SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
|
|
458
458
|
|
|
459
|
+
// src/components/ui/button.tsx
|
|
460
|
+
import * as React9 from "react";
|
|
461
|
+
import { Slot } from "@radix-ui/react-slot";
|
|
462
|
+
import { cva as cva2 } from "class-variance-authority";
|
|
463
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
464
|
+
var buttonVariants = cva2(
|
|
465
|
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
466
|
+
{
|
|
467
|
+
variants: {
|
|
468
|
+
variant: {
|
|
469
|
+
default: "bg-primary text-primary-foreground shadow hover:bg-primary/90",
|
|
470
|
+
destructive: "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
|
|
471
|
+
outline: "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
|
|
472
|
+
secondary: "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
|
|
473
|
+
ghost: "bg-gray-800 hover:bg-gray-900",
|
|
474
|
+
link: "text-primary underline-offset-4 hover:underline"
|
|
475
|
+
},
|
|
476
|
+
size: {
|
|
477
|
+
default: "h-9 px-4 py-2",
|
|
478
|
+
sm: "h-8 rounded-md px-3 text-xs",
|
|
479
|
+
lg: "h-10 rounded-md px-8",
|
|
480
|
+
icon: "h-9 w-9"
|
|
481
|
+
}
|
|
482
|
+
},
|
|
483
|
+
defaultVariants: {
|
|
484
|
+
variant: "default",
|
|
485
|
+
size: "default"
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
);
|
|
489
|
+
var Button = React9.forwardRef(
|
|
490
|
+
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
491
|
+
const Comp = asChild ? Slot : "button";
|
|
492
|
+
return /* @__PURE__ */ jsx9(
|
|
493
|
+
Comp,
|
|
494
|
+
{
|
|
495
|
+
className: cn(buttonVariants({ variant, size, className })),
|
|
496
|
+
ref,
|
|
497
|
+
...props
|
|
498
|
+
}
|
|
499
|
+
);
|
|
500
|
+
}
|
|
501
|
+
);
|
|
502
|
+
Button.displayName = "Button";
|
|
503
|
+
|
|
459
504
|
// src/components/ControlPanel/ControlPanel.tsx
|
|
460
|
-
import { Fragment, jsx as
|
|
505
|
+
import { Fragment, jsx as jsx10, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
461
506
|
var ControlPanel = () => {
|
|
462
507
|
const [copied, setCopied] = useState3(false);
|
|
463
508
|
const { leftPanelWidth, isDesktop, isHydrated, sidebarNarrow } = useResizableLayout();
|
|
@@ -468,7 +513,17 @@ var ControlPanel = () => {
|
|
|
468
513
|
const buttonControls = Object.entries(schema).filter(
|
|
469
514
|
([, control]) => control.type === "button"
|
|
470
515
|
);
|
|
471
|
-
const
|
|
516
|
+
const previewUrl = useMemo2(() => {
|
|
517
|
+
const params = new URLSearchParams();
|
|
518
|
+
params.set("nocontrols", "true");
|
|
519
|
+
for (const [key, value] of Object.entries(values)) {
|
|
520
|
+
if (value !== void 0 && value !== null) {
|
|
521
|
+
params.set(key, value.toString());
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
return `${window.location.pathname}?${params.toString()}`;
|
|
525
|
+
}, [values]);
|
|
526
|
+
const jsx12 = useMemo2(() => {
|
|
472
527
|
if (!componentName) return "";
|
|
473
528
|
const props = Object.entries(values).map(([key, val]) => {
|
|
474
529
|
if (typeof val === "string") return `${key}="${val}"`;
|
|
@@ -477,7 +532,7 @@ var ControlPanel = () => {
|
|
|
477
532
|
}).join(" ");
|
|
478
533
|
return `<${componentName} ${props} />`;
|
|
479
534
|
}, [componentName, values]);
|
|
480
|
-
return /* @__PURE__ */
|
|
535
|
+
return /* @__PURE__ */ jsx10(
|
|
481
536
|
"div",
|
|
482
537
|
{
|
|
483
538
|
className: `order-2 md:order-1 w-full md:h-auto p-2 md:p-4 bg-stone-900 font-mono text-stone-300 transition-opacity duration-300 ${!isHydrated ? "opacity-0" : "opacity-100"}`,
|
|
@@ -495,7 +550,7 @@ var ControlPanel = () => {
|
|
|
495
550
|
} : {}
|
|
496
551
|
},
|
|
497
552
|
children: /* @__PURE__ */ jsxs4("div", { className: "space-y-4 p-2 md:p-4 border border-stone-700 rounded-md", children: [
|
|
498
|
-
/* @__PURE__ */
|
|
553
|
+
/* @__PURE__ */ jsx10("div", { className: "space-y-1", children: /* @__PURE__ */ jsx10("h1", { className: "text-lg text-stone-100 font-bold", children: "Controls" }) }),
|
|
499
554
|
/* @__PURE__ */ jsxs4("div", { className: "space-y-4 pt-2", children: [
|
|
500
555
|
normalControls.map(([key, control]) => {
|
|
501
556
|
const value = values[key];
|
|
@@ -506,7 +561,7 @@ var ControlPanel = () => {
|
|
|
506
561
|
{
|
|
507
562
|
className: "flex items-center space-x-4 border-t border-stone-700 pt-4",
|
|
508
563
|
children: [
|
|
509
|
-
/* @__PURE__ */
|
|
564
|
+
/* @__PURE__ */ jsx10(
|
|
510
565
|
Switch,
|
|
511
566
|
{
|
|
512
567
|
id: key,
|
|
@@ -515,19 +570,19 @@ var ControlPanel = () => {
|
|
|
515
570
|
className: "data-[state=checked]:bg-stone-700 data-[state=unchecked]:bg-stone-700/40"
|
|
516
571
|
}
|
|
517
572
|
),
|
|
518
|
-
/* @__PURE__ */
|
|
573
|
+
/* @__PURE__ */ jsx10(Label, { htmlFor: key, className: "cursor-pointer", children: key })
|
|
519
574
|
]
|
|
520
575
|
},
|
|
521
576
|
key
|
|
522
577
|
);
|
|
523
578
|
case "number":
|
|
524
579
|
return /* @__PURE__ */ jsxs4("div", { className: "space-y-2 w-full", children: [
|
|
525
|
-
/* @__PURE__ */
|
|
580
|
+
/* @__PURE__ */ jsx10("div", { className: "flex items-center justify-between pb-1", children: /* @__PURE__ */ jsxs4(Label, { className: "text-stone-300", htmlFor: key, children: [
|
|
526
581
|
key,
|
|
527
582
|
": ",
|
|
528
583
|
value
|
|
529
584
|
] }) }),
|
|
530
|
-
/* @__PURE__ */
|
|
585
|
+
/* @__PURE__ */ jsx10(
|
|
531
586
|
Slider,
|
|
532
587
|
{
|
|
533
588
|
id: key,
|
|
@@ -541,7 +596,7 @@ var ControlPanel = () => {
|
|
|
541
596
|
)
|
|
542
597
|
] }, key);
|
|
543
598
|
case "string":
|
|
544
|
-
return /* @__PURE__ */
|
|
599
|
+
return /* @__PURE__ */ jsx10(
|
|
545
600
|
Input,
|
|
546
601
|
{
|
|
547
602
|
id: key,
|
|
@@ -554,8 +609,8 @@ var ControlPanel = () => {
|
|
|
554
609
|
);
|
|
555
610
|
case "color":
|
|
556
611
|
return /* @__PURE__ */ jsxs4("div", { className: "space-y-2 w-full", children: [
|
|
557
|
-
/* @__PURE__ */
|
|
558
|
-
/* @__PURE__ */
|
|
612
|
+
/* @__PURE__ */ jsx10("div", { className: "flex items-center justify-between pb-1", children: /* @__PURE__ */ jsx10(Label, { className: "text-stone-300", htmlFor: key, children: key }) }),
|
|
613
|
+
/* @__PURE__ */ jsx10(
|
|
559
614
|
"input",
|
|
560
615
|
{
|
|
561
616
|
type: "color",
|
|
@@ -572,15 +627,15 @@ var ControlPanel = () => {
|
|
|
572
627
|
{
|
|
573
628
|
className: "space-y-2 border-t border-stone-700 pt-4",
|
|
574
629
|
children: [
|
|
575
|
-
/* @__PURE__ */
|
|
630
|
+
/* @__PURE__ */ jsx10(Label, { className: "text-stone-300", htmlFor: key, children: key }),
|
|
576
631
|
/* @__PURE__ */ jsxs4(
|
|
577
632
|
Select,
|
|
578
633
|
{
|
|
579
634
|
value,
|
|
580
635
|
onValueChange: (val) => setValue(key, val),
|
|
581
636
|
children: [
|
|
582
|
-
/* @__PURE__ */
|
|
583
|
-
/* @__PURE__ */
|
|
637
|
+
/* @__PURE__ */ jsx10(SelectTrigger, { children: /* @__PURE__ */ jsx10(SelectValue, { placeholder: "Select option" }) }),
|
|
638
|
+
/* @__PURE__ */ jsx10(SelectContent, { children: control.options.map((opt) => /* @__PURE__ */ jsx10(SelectItem, { value: opt, children: opt }, opt)) })
|
|
584
639
|
]
|
|
585
640
|
}
|
|
586
641
|
)
|
|
@@ -592,31 +647,31 @@ var ControlPanel = () => {
|
|
|
592
647
|
return null;
|
|
593
648
|
}
|
|
594
649
|
}),
|
|
595
|
-
(buttonControls.length > 0 ||
|
|
596
|
-
|
|
650
|
+
(buttonControls.length > 0 || jsx12) && /* @__PURE__ */ jsxs4("div", { className: "border-t border-stone-700", children: [
|
|
651
|
+
jsx12 && /* @__PURE__ */ jsx10("div", { className: "flex-1 pt-4", children: /* @__PURE__ */ jsx10(
|
|
597
652
|
"button",
|
|
598
653
|
{
|
|
599
654
|
onClick: () => {
|
|
600
|
-
navigator.clipboard.writeText(
|
|
655
|
+
navigator.clipboard.writeText(jsx12);
|
|
601
656
|
setCopied(true);
|
|
602
657
|
setTimeout(() => setCopied(false), 5e3);
|
|
603
658
|
},
|
|
604
659
|
className: "w-full px-4 py-2 text-sm bg-stone-700 hover:bg-stone-600 text-white rounded flex items-center justify-center gap-2",
|
|
605
660
|
children: copied ? /* @__PURE__ */ jsxs4(Fragment, { children: [
|
|
606
|
-
/* @__PURE__ */
|
|
661
|
+
/* @__PURE__ */ jsx10(Check2, { className: "w-4 h-4" }),
|
|
607
662
|
"Copied"
|
|
608
663
|
] }) : /* @__PURE__ */ jsxs4(Fragment, { children: [
|
|
609
|
-
/* @__PURE__ */
|
|
664
|
+
/* @__PURE__ */ jsx10(Copy, { className: "w-4 h-4" }),
|
|
610
665
|
"Copy to Clipboard"
|
|
611
666
|
] })
|
|
612
667
|
}
|
|
613
668
|
) }, "control-panel-jsx"),
|
|
614
|
-
buttonControls.length > 0 && /* @__PURE__ */
|
|
615
|
-
([key, control]) => control.type === "button" ? /* @__PURE__ */
|
|
669
|
+
buttonControls.length > 0 && /* @__PURE__ */ jsx10("div", { className: "flex flex-wrap gap-2 pt-4", children: buttonControls.map(
|
|
670
|
+
([key, control]) => control.type === "button" ? /* @__PURE__ */ jsx10(
|
|
616
671
|
"div",
|
|
617
672
|
{
|
|
618
673
|
className: "flex-1",
|
|
619
|
-
children: control.render ? control.render() : /* @__PURE__ */
|
|
674
|
+
children: control.render ? control.render() : /* @__PURE__ */ jsx10(
|
|
620
675
|
"button",
|
|
621
676
|
{
|
|
622
677
|
onClick: control.onClick,
|
|
@@ -629,7 +684,20 @@ var ControlPanel = () => {
|
|
|
629
684
|
) : null
|
|
630
685
|
) })
|
|
631
686
|
] })
|
|
632
|
-
] })
|
|
687
|
+
] }),
|
|
688
|
+
/* @__PURE__ */ jsx10(Button, { asChild: true, children: /* @__PURE__ */ jsxs4(
|
|
689
|
+
"a",
|
|
690
|
+
{
|
|
691
|
+
href: previewUrl,
|
|
692
|
+
target: "_blank",
|
|
693
|
+
rel: "noopener noreferrer",
|
|
694
|
+
className: "w-full px-4 py-2 text-sm text-center bg-stone-800 hover:bg-stone-700 text-white rounded",
|
|
695
|
+
children: [
|
|
696
|
+
/* @__PURE__ */ jsx10(SquareArrowOutUpRight, {}),
|
|
697
|
+
" Open in a New Tab"
|
|
698
|
+
]
|
|
699
|
+
}
|
|
700
|
+
) })
|
|
633
701
|
] })
|
|
634
702
|
}
|
|
635
703
|
);
|
|
@@ -637,19 +705,20 @@ var ControlPanel = () => {
|
|
|
637
705
|
var ControlPanel_default = ControlPanel;
|
|
638
706
|
|
|
639
707
|
// src/components/Playground/Playground.tsx
|
|
640
|
-
import { jsx as
|
|
708
|
+
import { jsx as jsx11, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
641
709
|
var NO_CONTROLS_PARAM = "nocontrols";
|
|
642
710
|
function Playground({ children }) {
|
|
643
711
|
const hideControls = useMemo3(() => {
|
|
644
712
|
if (typeof window === "undefined") return false;
|
|
645
713
|
return new URLSearchParams(window.location.search).get(NO_CONTROLS_PARAM) === "true";
|
|
646
714
|
}, []);
|
|
647
|
-
return /* @__PURE__ */
|
|
648
|
-
/* @__PURE__ */
|
|
649
|
-
!hideControls && /* @__PURE__ */
|
|
715
|
+
return /* @__PURE__ */ jsx11(ResizableLayout, { hideControls, children: /* @__PURE__ */ jsxs5(ControlsProvider, { children: [
|
|
716
|
+
/* @__PURE__ */ jsx11(PreviewContainer_default, { hideControls, children }),
|
|
717
|
+
!hideControls && /* @__PURE__ */ jsx11(ControlPanel_default, {})
|
|
650
718
|
] }) });
|
|
651
719
|
}
|
|
652
720
|
export {
|
|
721
|
+
ControlsProvider,
|
|
653
722
|
Playground,
|
|
654
723
|
useControls,
|
|
655
724
|
useUrlSyncedControls
|