@toriistudio/v0-playground 0.7.0 → 0.7.1
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 +21 -1
- package/dist/index.d.ts +21 -1
- package/dist/index.js +499 -147
- package/dist/index.mjs +502 -137
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
// src/components/Playground
|
|
2
|
-
import { useEffect as
|
|
1
|
+
// src/components/Playground.tsx
|
|
2
|
+
import { useEffect as useEffect7, useMemo as useMemo5, useState as useState5 } from "react";
|
|
3
3
|
import { Check as Check3, Copy as Copy2 } from "lucide-react";
|
|
4
4
|
|
|
5
5
|
// src/context/ResizableLayout.tsx
|
|
@@ -435,17 +435,30 @@ var ControlsProvider = ({ children }) => {
|
|
|
435
435
|
setComponentName(opts.componentName);
|
|
436
436
|
}
|
|
437
437
|
if (opts?.config) {
|
|
438
|
-
const {
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
...otherConfig
|
|
442
|
-
|
|
438
|
+
const {
|
|
439
|
+
addAdvancedPaletteControl,
|
|
440
|
+
addMediaUploadControl,
|
|
441
|
+
...otherConfig
|
|
442
|
+
} = opts.config;
|
|
443
|
+
setConfig((prev) => {
|
|
444
|
+
const nextConfig = {
|
|
445
|
+
...prev,
|
|
446
|
+
...otherConfig
|
|
447
|
+
};
|
|
448
|
+
if (Object.prototype.hasOwnProperty.call(
|
|
443
449
|
opts.config,
|
|
444
450
|
"addAdvancedPaletteControl"
|
|
445
|
-
)
|
|
446
|
-
addAdvancedPaletteControl
|
|
447
|
-
}
|
|
448
|
-
|
|
451
|
+
)) {
|
|
452
|
+
nextConfig.addAdvancedPaletteControl = addAdvancedPaletteControl ? resolveAdvancedPaletteConfig(addAdvancedPaletteControl) : void 0;
|
|
453
|
+
}
|
|
454
|
+
if (Object.prototype.hasOwnProperty.call(
|
|
455
|
+
opts.config,
|
|
456
|
+
"addMediaUploadControl"
|
|
457
|
+
)) {
|
|
458
|
+
nextConfig.addMediaUploadControl = addMediaUploadControl ? { ...addMediaUploadControl } : void 0;
|
|
459
|
+
}
|
|
460
|
+
return nextConfig;
|
|
461
|
+
});
|
|
449
462
|
}
|
|
450
463
|
setSchema((prevSchema) => ({ ...prevSchema, ...newSchema }));
|
|
451
464
|
setValues((prevValues) => {
|
|
@@ -610,7 +623,7 @@ var useControls = (schema, options) => {
|
|
|
610
623
|
resolvedAdvancedConfig.onPaletteChange(clonePalette(palette));
|
|
611
624
|
}, [ctx.values, resolvedAdvancedConfig]);
|
|
612
625
|
const typedValues = ctx.values;
|
|
613
|
-
const
|
|
626
|
+
const jsx15 = useCallback(() => {
|
|
614
627
|
if (!options?.componentName) return "";
|
|
615
628
|
const props = Object.entries(typedValues).map(([key, val]) => {
|
|
616
629
|
if (typeof val === "string") return `${key}="${val}"`;
|
|
@@ -624,13 +637,19 @@ var useControls = (schema, options) => {
|
|
|
624
637
|
controls: ctx.values,
|
|
625
638
|
schema: ctx.schema,
|
|
626
639
|
setValue: ctx.setValue,
|
|
627
|
-
jsx:
|
|
640
|
+
jsx: jsx15
|
|
628
641
|
};
|
|
629
642
|
};
|
|
630
643
|
var useUrlSyncedControls = useControls;
|
|
631
644
|
|
|
632
|
-
// src/components/ControlPanel
|
|
633
|
-
import {
|
|
645
|
+
// src/components/ControlPanel.tsx
|
|
646
|
+
import {
|
|
647
|
+
useState as useState4,
|
|
648
|
+
useMemo as useMemo4,
|
|
649
|
+
useCallback as useCallback4,
|
|
650
|
+
useEffect as useEffect6,
|
|
651
|
+
useRef as useRef5
|
|
652
|
+
} from "react";
|
|
634
653
|
import {
|
|
635
654
|
Check as Check2,
|
|
636
655
|
Copy,
|
|
@@ -912,7 +931,7 @@ Button.displayName = "Button";
|
|
|
912
931
|
// src/constants/layout.ts
|
|
913
932
|
var MOBILE_CONTROL_PANEL_PEEK = 112;
|
|
914
933
|
|
|
915
|
-
// src/components/AdvancedPaletteControl
|
|
934
|
+
// src/components/AdvancedPaletteControl.tsx
|
|
916
935
|
import {
|
|
917
936
|
useCallback as useCallback2,
|
|
918
937
|
useEffect as useEffect4,
|
|
@@ -1065,8 +1084,316 @@ var AdvancedPaletteControl = ({
|
|
|
1065
1084
|
};
|
|
1066
1085
|
var AdvancedPaletteControl_default = AdvancedPaletteControl;
|
|
1067
1086
|
|
|
1068
|
-
// src/components/
|
|
1069
|
-
import {
|
|
1087
|
+
// src/components/MediaUploadControl.tsx
|
|
1088
|
+
import {
|
|
1089
|
+
useCallback as useCallback3,
|
|
1090
|
+
useEffect as useEffect5,
|
|
1091
|
+
useId,
|
|
1092
|
+
useMemo as useMemo3,
|
|
1093
|
+
useRef as useRef4,
|
|
1094
|
+
useSyncExternalStore
|
|
1095
|
+
} from "react";
|
|
1096
|
+
import { X } from "lucide-react";
|
|
1097
|
+
|
|
1098
|
+
// src/state/mediaSelectionStore.ts
|
|
1099
|
+
var snapshot = {
|
|
1100
|
+
media: null,
|
|
1101
|
+
error: null
|
|
1102
|
+
};
|
|
1103
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
1104
|
+
var emitChange = () => {
|
|
1105
|
+
for (const listener of listeners) {
|
|
1106
|
+
listener();
|
|
1107
|
+
}
|
|
1108
|
+
};
|
|
1109
|
+
var mediaSelectionStore = {
|
|
1110
|
+
subscribe: (listener) => {
|
|
1111
|
+
listeners.add(listener);
|
|
1112
|
+
return () => {
|
|
1113
|
+
listeners.delete(listener);
|
|
1114
|
+
};
|
|
1115
|
+
},
|
|
1116
|
+
getSnapshot: () => snapshot,
|
|
1117
|
+
setSnapshot: (next) => {
|
|
1118
|
+
snapshot = next;
|
|
1119
|
+
emitChange();
|
|
1120
|
+
}
|
|
1121
|
+
};
|
|
1122
|
+
|
|
1123
|
+
// src/components/MediaUploadControl.tsx
|
|
1124
|
+
import { jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1125
|
+
var DEFAULT_PRESET_MEDIA = [
|
|
1126
|
+
{
|
|
1127
|
+
src: "https://res.cloudinary.com/dz8kk1l4r/image/upload/v1763233793/astronaut_q84mbj.png",
|
|
1128
|
+
label: "Astronaut",
|
|
1129
|
+
type: "image"
|
|
1130
|
+
},
|
|
1131
|
+
{
|
|
1132
|
+
src: "https://res.cloudinary.com/dz8kk1l4r/image/upload/v1763233793/surreal-head_r0ozcd.png",
|
|
1133
|
+
label: "Futuristic",
|
|
1134
|
+
type: "image"
|
|
1135
|
+
},
|
|
1136
|
+
{
|
|
1137
|
+
src: "https://res.cloudinary.com/dz8kk1l4r/image/upload/v1763233797/futuristic_bpwdzt.png",
|
|
1138
|
+
label: "Surreal",
|
|
1139
|
+
type: "image"
|
|
1140
|
+
},
|
|
1141
|
+
{
|
|
1142
|
+
src: "https://res.cloudinary.com/dz8kk1l4r/image/upload/v1763233793/portrait_hd7dyc.png",
|
|
1143
|
+
label: "Portrait",
|
|
1144
|
+
type: "image"
|
|
1145
|
+
}
|
|
1146
|
+
];
|
|
1147
|
+
function MediaUploadControl({
|
|
1148
|
+
onSelectMedia,
|
|
1149
|
+
onClear,
|
|
1150
|
+
presetMedia,
|
|
1151
|
+
maxPresetCount
|
|
1152
|
+
}) {
|
|
1153
|
+
const inputId = useId();
|
|
1154
|
+
const inputRef = useRef4(null);
|
|
1155
|
+
const uploadedUrlRef = useRef4(null);
|
|
1156
|
+
const { media, error } = useSyncExternalStore(
|
|
1157
|
+
mediaSelectionStore.subscribe,
|
|
1158
|
+
mediaSelectionStore.getSnapshot,
|
|
1159
|
+
mediaSelectionStore.getSnapshot
|
|
1160
|
+
);
|
|
1161
|
+
const VIDEO_EXTENSIONS = useMemo3(
|
|
1162
|
+
() => [".mp4", ".webm", ".ogg", ".ogv", ".mov", ".m4v"],
|
|
1163
|
+
[]
|
|
1164
|
+
);
|
|
1165
|
+
const setSelection = useCallback3(
|
|
1166
|
+
(next) => {
|
|
1167
|
+
mediaSelectionStore.setSnapshot(next);
|
|
1168
|
+
},
|
|
1169
|
+
[]
|
|
1170
|
+
);
|
|
1171
|
+
const handleFileChange = (event) => {
|
|
1172
|
+
const file = event.target.files?.[0];
|
|
1173
|
+
if (!file) {
|
|
1174
|
+
return;
|
|
1175
|
+
}
|
|
1176
|
+
if (uploadedUrlRef.current) {
|
|
1177
|
+
URL.revokeObjectURL(uploadedUrlRef.current);
|
|
1178
|
+
uploadedUrlRef.current = null;
|
|
1179
|
+
}
|
|
1180
|
+
const objectUrl = URL.createObjectURL(file);
|
|
1181
|
+
uploadedUrlRef.current = objectUrl;
|
|
1182
|
+
const lowerName = file.name?.toLowerCase() ?? "";
|
|
1183
|
+
const hasVideoExtension = VIDEO_EXTENSIONS.some(
|
|
1184
|
+
(ext) => lowerName.endsWith(ext)
|
|
1185
|
+
);
|
|
1186
|
+
const isVideo = file.type.startsWith("video/") || hasVideoExtension;
|
|
1187
|
+
if (isVideo) {
|
|
1188
|
+
setSelection({
|
|
1189
|
+
media: null,
|
|
1190
|
+
error: "Videos are not supported in this effect yet."
|
|
1191
|
+
});
|
|
1192
|
+
return;
|
|
1193
|
+
}
|
|
1194
|
+
const nextMedia = { src: objectUrl, type: "image" };
|
|
1195
|
+
setSelection({ media: nextMedia, error: null });
|
|
1196
|
+
onSelectMedia(nextMedia);
|
|
1197
|
+
};
|
|
1198
|
+
const handleClearSelection = () => {
|
|
1199
|
+
if (uploadedUrlRef.current) {
|
|
1200
|
+
URL.revokeObjectURL(uploadedUrlRef.current);
|
|
1201
|
+
uploadedUrlRef.current = null;
|
|
1202
|
+
}
|
|
1203
|
+
setSelection({ media: null, error: null });
|
|
1204
|
+
onClear();
|
|
1205
|
+
};
|
|
1206
|
+
const handlePresetSelect = (entry) => {
|
|
1207
|
+
if (entry.type === "video") {
|
|
1208
|
+
setSelection({
|
|
1209
|
+
media: null,
|
|
1210
|
+
error: "Videos are not supported in this effect yet."
|
|
1211
|
+
});
|
|
1212
|
+
return;
|
|
1213
|
+
}
|
|
1214
|
+
const nextMedia = { src: entry.src, type: entry.type };
|
|
1215
|
+
setSelection({ media: nextMedia, error: null });
|
|
1216
|
+
onSelectMedia(nextMedia);
|
|
1217
|
+
};
|
|
1218
|
+
useEffect5(() => {
|
|
1219
|
+
return () => {
|
|
1220
|
+
if (uploadedUrlRef.current) {
|
|
1221
|
+
URL.revokeObjectURL(uploadedUrlRef.current);
|
|
1222
|
+
uploadedUrlRef.current = null;
|
|
1223
|
+
}
|
|
1224
|
+
};
|
|
1225
|
+
}, []);
|
|
1226
|
+
const presets = useMemo3(() => {
|
|
1227
|
+
const source = presetMedia ?? DEFAULT_PRESET_MEDIA;
|
|
1228
|
+
if (typeof maxPresetCount === "number" && Number.isFinite(maxPresetCount)) {
|
|
1229
|
+
const safeCount = Math.max(0, Math.floor(maxPresetCount));
|
|
1230
|
+
return source.slice(0, safeCount);
|
|
1231
|
+
}
|
|
1232
|
+
return source;
|
|
1233
|
+
}, [presetMedia, maxPresetCount]);
|
|
1234
|
+
return /* @__PURE__ */ jsxs5(
|
|
1235
|
+
"div",
|
|
1236
|
+
{
|
|
1237
|
+
style: {
|
|
1238
|
+
display: "flex",
|
|
1239
|
+
flexDirection: "column",
|
|
1240
|
+
gap: "0.5rem"
|
|
1241
|
+
},
|
|
1242
|
+
children: [
|
|
1243
|
+
/* @__PURE__ */ jsx10("label", { htmlFor: inputId, style: { fontSize: "0.85rem", fontWeight: 500 }, children: "Upload media" }),
|
|
1244
|
+
/* @__PURE__ */ jsx10(
|
|
1245
|
+
"input",
|
|
1246
|
+
{
|
|
1247
|
+
id: inputId,
|
|
1248
|
+
type: "file",
|
|
1249
|
+
accept: "image/*",
|
|
1250
|
+
ref: inputRef,
|
|
1251
|
+
style: { display: "none" },
|
|
1252
|
+
onChange: handleFileChange
|
|
1253
|
+
}
|
|
1254
|
+
),
|
|
1255
|
+
/* @__PURE__ */ jsxs5(
|
|
1256
|
+
"div",
|
|
1257
|
+
{
|
|
1258
|
+
style: {
|
|
1259
|
+
display: "flex",
|
|
1260
|
+
alignItems: "center",
|
|
1261
|
+
gap: "0.75rem"
|
|
1262
|
+
},
|
|
1263
|
+
children: [
|
|
1264
|
+
/* @__PURE__ */ jsx10(
|
|
1265
|
+
"button",
|
|
1266
|
+
{
|
|
1267
|
+
type: "button",
|
|
1268
|
+
onClick: () => inputRef.current?.click(),
|
|
1269
|
+
style: {
|
|
1270
|
+
padding: "0.35rem 0.75rem",
|
|
1271
|
+
borderRadius: "0.4rem",
|
|
1272
|
+
border: "1px solid rgba(255, 255, 255, 0.25)",
|
|
1273
|
+
background: "rgba(255, 255, 255, 0.08)",
|
|
1274
|
+
color: "inherit",
|
|
1275
|
+
cursor: "pointer"
|
|
1276
|
+
},
|
|
1277
|
+
children: "Choose file"
|
|
1278
|
+
}
|
|
1279
|
+
),
|
|
1280
|
+
media ? /* @__PURE__ */ jsx10(
|
|
1281
|
+
"div",
|
|
1282
|
+
{
|
|
1283
|
+
style: {
|
|
1284
|
+
width: 36,
|
|
1285
|
+
height: 36,
|
|
1286
|
+
borderRadius: "0.35rem",
|
|
1287
|
+
overflow: "hidden",
|
|
1288
|
+
border: "1px solid rgba(255, 255, 255, 0.15)"
|
|
1289
|
+
},
|
|
1290
|
+
children: /* @__PURE__ */ jsx10(
|
|
1291
|
+
"img",
|
|
1292
|
+
{
|
|
1293
|
+
src: media.src,
|
|
1294
|
+
alt: "Thumbnail",
|
|
1295
|
+
style: {
|
|
1296
|
+
width: "100%",
|
|
1297
|
+
height: "100%",
|
|
1298
|
+
objectFit: "cover",
|
|
1299
|
+
display: "block"
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
)
|
|
1303
|
+
}
|
|
1304
|
+
) : null,
|
|
1305
|
+
media ? /* @__PURE__ */ jsx10(
|
|
1306
|
+
"button",
|
|
1307
|
+
{
|
|
1308
|
+
type: "button",
|
|
1309
|
+
onClick: handleClearSelection,
|
|
1310
|
+
style: {
|
|
1311
|
+
display: "flex",
|
|
1312
|
+
alignItems: "center",
|
|
1313
|
+
justifyContent: "center",
|
|
1314
|
+
padding: "0.3rem",
|
|
1315
|
+
borderRadius: "0.4rem",
|
|
1316
|
+
border: "1px solid rgba(255,255,255,0.2)",
|
|
1317
|
+
background: "transparent",
|
|
1318
|
+
color: "inherit",
|
|
1319
|
+
cursor: "pointer"
|
|
1320
|
+
},
|
|
1321
|
+
"aria-label": "Clear selection",
|
|
1322
|
+
title: "Clear selection",
|
|
1323
|
+
children: /* @__PURE__ */ jsx10(X, { size: 16, strokeWidth: 2 })
|
|
1324
|
+
}
|
|
1325
|
+
) : null
|
|
1326
|
+
]
|
|
1327
|
+
}
|
|
1328
|
+
),
|
|
1329
|
+
presets.length > 0 ? /* @__PURE__ */ jsx10(
|
|
1330
|
+
"div",
|
|
1331
|
+
{
|
|
1332
|
+
style: {
|
|
1333
|
+
display: "grid",
|
|
1334
|
+
gridTemplateColumns: "repeat(2, minmax(0, 1fr))",
|
|
1335
|
+
gap: "0.5rem"
|
|
1336
|
+
},
|
|
1337
|
+
children: presets.map((entry) => {
|
|
1338
|
+
const isSelected = media?.src === entry.src && media?.type === entry.type;
|
|
1339
|
+
return /* @__PURE__ */ jsxs5(
|
|
1340
|
+
"button",
|
|
1341
|
+
{
|
|
1342
|
+
type: "button",
|
|
1343
|
+
onClick: () => handlePresetSelect(entry),
|
|
1344
|
+
style: {
|
|
1345
|
+
width: "100%",
|
|
1346
|
+
borderRadius: "0.4rem",
|
|
1347
|
+
border: "1px solid rgba(255,255,255,0.25)",
|
|
1348
|
+
outline: isSelected ? "2px solid #fff" : "none",
|
|
1349
|
+
outlineOffset: 2,
|
|
1350
|
+
padding: 0,
|
|
1351
|
+
overflow: "hidden",
|
|
1352
|
+
background: "transparent",
|
|
1353
|
+
cursor: "pointer"
|
|
1354
|
+
},
|
|
1355
|
+
children: [
|
|
1356
|
+
/* @__PURE__ */ jsx10(
|
|
1357
|
+
"img",
|
|
1358
|
+
{
|
|
1359
|
+
src: entry.src,
|
|
1360
|
+
alt: entry.label,
|
|
1361
|
+
style: {
|
|
1362
|
+
width: "100%",
|
|
1363
|
+
height: 100,
|
|
1364
|
+
objectFit: "cover",
|
|
1365
|
+
display: "block"
|
|
1366
|
+
}
|
|
1367
|
+
}
|
|
1368
|
+
),
|
|
1369
|
+
/* @__PURE__ */ jsx10(
|
|
1370
|
+
"span",
|
|
1371
|
+
{
|
|
1372
|
+
style: {
|
|
1373
|
+
display: "block",
|
|
1374
|
+
padding: "0.35rem",
|
|
1375
|
+
fontSize: "0.75rem",
|
|
1376
|
+
textAlign: "left",
|
|
1377
|
+
background: "rgba(0,0,0,0.45)"
|
|
1378
|
+
},
|
|
1379
|
+
children: entry.label
|
|
1380
|
+
}
|
|
1381
|
+
)
|
|
1382
|
+
]
|
|
1383
|
+
},
|
|
1384
|
+
`${entry.src}-${entry.type}`
|
|
1385
|
+
);
|
|
1386
|
+
})
|
|
1387
|
+
}
|
|
1388
|
+
) : null,
|
|
1389
|
+
error ? /* @__PURE__ */ jsx10("p", { style: { color: "#ff9da4", fontSize: "0.8rem" }, children: error }) : null
|
|
1390
|
+
]
|
|
1391
|
+
}
|
|
1392
|
+
);
|
|
1393
|
+
}
|
|
1394
|
+
|
|
1395
|
+
// src/components/ControlPanel.tsx
|
|
1396
|
+
import { Fragment, jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1070
1397
|
var splitPropsString = (input) => {
|
|
1071
1398
|
const props = [];
|
|
1072
1399
|
let current = "";
|
|
@@ -1273,7 +1600,7 @@ var highlightJsx = (input) => {
|
|
|
1273
1600
|
nodes.push(token.value);
|
|
1274
1601
|
} else {
|
|
1275
1602
|
nodes.push(
|
|
1276
|
-
/* @__PURE__ */
|
|
1603
|
+
/* @__PURE__ */ jsx11("span", { className: TOKEN_CLASS_MAP[token.type], children: token.value }, `token-${index}`)
|
|
1277
1604
|
);
|
|
1278
1605
|
}
|
|
1279
1606
|
});
|
|
@@ -1284,12 +1611,12 @@ var ControlPanel = () => {
|
|
|
1284
1611
|
const [codeCopied, setCodeCopied] = useState4(false);
|
|
1285
1612
|
const [isCodeVisible, setIsCodeVisible] = useState4(false);
|
|
1286
1613
|
const [folderStates, setFolderStates] = useState4({});
|
|
1287
|
-
const codeCopyTimeoutRef =
|
|
1614
|
+
const codeCopyTimeoutRef = useRef5(null);
|
|
1288
1615
|
const { leftPanelWidth, isDesktop, isHydrated } = useResizableLayout();
|
|
1289
1616
|
const { schema, setValue, values, componentName, config } = useControlsContext();
|
|
1290
1617
|
const isControlsOnlyView = typeof window !== "undefined" && new URLSearchParams(window.location.search).get(CONTROLS_ONLY_PARAM) === "true";
|
|
1291
1618
|
const previewUrl = usePreviewUrl(values);
|
|
1292
|
-
const buildUrl =
|
|
1619
|
+
const buildUrl = useCallback4(
|
|
1293
1620
|
(modifier) => {
|
|
1294
1621
|
if (!previewUrl) return "";
|
|
1295
1622
|
const [path, search = ""] = previewUrl.split("?");
|
|
@@ -1300,13 +1627,13 @@ var ControlPanel = () => {
|
|
|
1300
1627
|
},
|
|
1301
1628
|
[previewUrl]
|
|
1302
1629
|
);
|
|
1303
|
-
const presentationUrl =
|
|
1630
|
+
const presentationUrl = useMemo4(() => {
|
|
1304
1631
|
if (!previewUrl) return "";
|
|
1305
1632
|
return buildUrl((params) => {
|
|
1306
1633
|
params.set(PRESENTATION_PARAM, "true");
|
|
1307
1634
|
});
|
|
1308
1635
|
}, [buildUrl, previewUrl]);
|
|
1309
|
-
const controlsOnlyUrl =
|
|
1636
|
+
const controlsOnlyUrl = useMemo4(() => {
|
|
1310
1637
|
if (!previewUrl) return "";
|
|
1311
1638
|
return buildUrl((params) => {
|
|
1312
1639
|
params.delete(NO_CONTROLS_PARAM);
|
|
@@ -1314,7 +1641,7 @@ var ControlPanel = () => {
|
|
|
1314
1641
|
params.set(CONTROLS_ONLY_PARAM, "true");
|
|
1315
1642
|
});
|
|
1316
1643
|
}, [buildUrl, previewUrl]);
|
|
1317
|
-
const handlePresentationClick =
|
|
1644
|
+
const handlePresentationClick = useCallback4(() => {
|
|
1318
1645
|
if (typeof window === "undefined" || !presentationUrl) return;
|
|
1319
1646
|
window.open(presentationUrl, "_blank", "noopener,noreferrer");
|
|
1320
1647
|
if (controlsOnlyUrl) {
|
|
@@ -1322,10 +1649,7 @@ var ControlPanel = () => {
|
|
|
1322
1649
|
const viewportHeight = window.innerHeight || 900;
|
|
1323
1650
|
const controlsWidth = Math.max(
|
|
1324
1651
|
320,
|
|
1325
|
-
Math.min(
|
|
1326
|
-
600,
|
|
1327
|
-
Math.round(viewportWidth * leftPanelWidth / 100)
|
|
1328
|
-
)
|
|
1652
|
+
Math.min(600, Math.round(viewportWidth * leftPanelWidth / 100))
|
|
1329
1653
|
);
|
|
1330
1654
|
const controlsHeight = Math.max(600, viewportHeight);
|
|
1331
1655
|
const controlsFeatures = [
|
|
@@ -1341,7 +1665,7 @@ var ControlPanel = () => {
|
|
|
1341
1665
|
window.open(controlsOnlyUrl, "v0-controls", controlsFeatures);
|
|
1342
1666
|
}
|
|
1343
1667
|
}, [controlsOnlyUrl, leftPanelWidth, presentationUrl]);
|
|
1344
|
-
const
|
|
1668
|
+
const jsx15 = useMemo4(() => {
|
|
1345
1669
|
if (!componentName) return "";
|
|
1346
1670
|
const props = Object.entries(values).map(([key, val]) => {
|
|
1347
1671
|
if (typeof val === "string") return `${key}="${val}"`;
|
|
@@ -1386,7 +1710,7 @@ var ControlPanel = () => {
|
|
|
1386
1710
|
const advancedConfig = config?.addAdvancedPaletteControl;
|
|
1387
1711
|
let advancedPaletteControlNode = null;
|
|
1388
1712
|
if (advancedConfig) {
|
|
1389
|
-
const advancedNode = /* @__PURE__ */
|
|
1713
|
+
const advancedNode = /* @__PURE__ */ jsx11(
|
|
1390
1714
|
AdvancedPaletteControl_default,
|
|
1391
1715
|
{
|
|
1392
1716
|
config: advancedConfig
|
|
@@ -1412,12 +1736,52 @@ var ControlPanel = () => {
|
|
|
1412
1736
|
advancedPaletteControlNode = advancedNode;
|
|
1413
1737
|
}
|
|
1414
1738
|
}
|
|
1415
|
-
const
|
|
1416
|
-
|
|
1417
|
-
)
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1739
|
+
const mediaUploadConfig = config?.addMediaUploadControl;
|
|
1740
|
+
let mediaUploadControlNode = null;
|
|
1741
|
+
if (mediaUploadConfig) {
|
|
1742
|
+
const mediaUploadNode = /* @__PURE__ */ jsx11(
|
|
1743
|
+
MediaUploadControl,
|
|
1744
|
+
{
|
|
1745
|
+
onSelectMedia: (media) => {
|
|
1746
|
+
mediaUploadConfig.onSelectMedia?.(media);
|
|
1747
|
+
},
|
|
1748
|
+
onClear: () => {
|
|
1749
|
+
mediaUploadConfig.onClear?.();
|
|
1750
|
+
},
|
|
1751
|
+
presetMedia: mediaUploadConfig.presetMedia,
|
|
1752
|
+
maxPresetCount: mediaUploadConfig.maxPresetCount
|
|
1753
|
+
},
|
|
1754
|
+
"mediaUploadControl"
|
|
1755
|
+
);
|
|
1756
|
+
const mediaFolder = mediaUploadConfig.folder?.trim();
|
|
1757
|
+
if (mediaFolder) {
|
|
1758
|
+
const placement = mediaUploadConfig.folderPlacement ?? "bottom";
|
|
1759
|
+
ensureFolder(mediaFolder);
|
|
1760
|
+
if (!folderControls.has(mediaFolder)) {
|
|
1761
|
+
folderControls.set(mediaFolder, []);
|
|
1762
|
+
}
|
|
1763
|
+
const existingPlacement = folderPlacement.get(mediaFolder);
|
|
1764
|
+
if (!existingPlacement || placement === "top") {
|
|
1765
|
+
folderPlacement.set(mediaFolder, placement);
|
|
1766
|
+
}
|
|
1767
|
+
if (!folderExtras.has(mediaFolder)) {
|
|
1768
|
+
folderExtras.set(mediaFolder, []);
|
|
1769
|
+
}
|
|
1770
|
+
folderExtras.get(mediaFolder).push(mediaUploadNode);
|
|
1771
|
+
} else {
|
|
1772
|
+
mediaUploadControlNode = mediaUploadNode;
|
|
1773
|
+
}
|
|
1774
|
+
}
|
|
1775
|
+
const rootButtonControls = [];
|
|
1776
|
+
const rootNormalControls = [];
|
|
1777
|
+
rootControls.forEach((entry) => {
|
|
1778
|
+
const [key, control] = entry;
|
|
1779
|
+
if (control.type === "button") {
|
|
1780
|
+
rootButtonControls.push([key, control]);
|
|
1781
|
+
} else {
|
|
1782
|
+
rootNormalControls.push(entry);
|
|
1783
|
+
}
|
|
1784
|
+
});
|
|
1421
1785
|
const folderGroups = folderOrder.map((folder) => ({
|
|
1422
1786
|
folder,
|
|
1423
1787
|
entries: folderControls.get(folder) ?? [],
|
|
@@ -1426,7 +1790,7 @@ var ControlPanel = () => {
|
|
|
1426
1790
|
})).filter((group) => group.entries.length > 0 || group.extras.length > 0);
|
|
1427
1791
|
const hasRootButtonControls = rootButtonControls.length > 0;
|
|
1428
1792
|
const hasAnyFolders = folderGroups.length > 0;
|
|
1429
|
-
const jsonToComponentString =
|
|
1793
|
+
const jsonToComponentString = useCallback4(
|
|
1430
1794
|
({
|
|
1431
1795
|
componentName: componentNameOverride,
|
|
1432
1796
|
props
|
|
@@ -1457,40 +1821,40 @@ var ControlPanel = () => {
|
|
|
1457
1821
|
componentName,
|
|
1458
1822
|
values,
|
|
1459
1823
|
schema,
|
|
1460
|
-
jsx:
|
|
1824
|
+
jsx: jsx15,
|
|
1461
1825
|
jsonToComponentString
|
|
1462
|
-
}) ??
|
|
1826
|
+
}) ?? jsx15;
|
|
1463
1827
|
const shouldShowCopyButton = config?.showCopyButton !== false && Boolean(copyText);
|
|
1464
|
-
const baseSnippet = copyText ||
|
|
1465
|
-
const formattedCode =
|
|
1828
|
+
const baseSnippet = copyText || jsx15;
|
|
1829
|
+
const formattedCode = useMemo4(
|
|
1466
1830
|
() => formatJsxCodeSnippet(baseSnippet),
|
|
1467
1831
|
[baseSnippet]
|
|
1468
1832
|
);
|
|
1469
1833
|
const hasCodeSnippet = Boolean(config?.showCodeSnippet && formattedCode);
|
|
1470
|
-
const highlightedCode =
|
|
1834
|
+
const highlightedCode = useMemo4(
|
|
1471
1835
|
() => formattedCode ? highlightJsx(formattedCode) : null,
|
|
1472
1836
|
[formattedCode]
|
|
1473
1837
|
);
|
|
1474
|
-
|
|
1838
|
+
useEffect6(() => {
|
|
1475
1839
|
if (!hasCodeSnippet) {
|
|
1476
1840
|
setIsCodeVisible(false);
|
|
1477
1841
|
}
|
|
1478
1842
|
}, [hasCodeSnippet]);
|
|
1479
|
-
|
|
1843
|
+
useEffect6(() => {
|
|
1480
1844
|
setCodeCopied(false);
|
|
1481
1845
|
if (codeCopyTimeoutRef.current) {
|
|
1482
1846
|
clearTimeout(codeCopyTimeoutRef.current);
|
|
1483
1847
|
codeCopyTimeoutRef.current = null;
|
|
1484
1848
|
}
|
|
1485
1849
|
}, [formattedCode]);
|
|
1486
|
-
|
|
1850
|
+
useEffect6(() => {
|
|
1487
1851
|
return () => {
|
|
1488
1852
|
if (codeCopyTimeoutRef.current) {
|
|
1489
1853
|
clearTimeout(codeCopyTimeoutRef.current);
|
|
1490
1854
|
}
|
|
1491
1855
|
};
|
|
1492
1856
|
}, []);
|
|
1493
|
-
const handleToggleCodeVisibility =
|
|
1857
|
+
const handleToggleCodeVisibility = useCallback4(() => {
|
|
1494
1858
|
setIsCodeVisible((prev) => {
|
|
1495
1859
|
const next = !prev;
|
|
1496
1860
|
if (!next) {
|
|
@@ -1503,7 +1867,7 @@ var ControlPanel = () => {
|
|
|
1503
1867
|
return next;
|
|
1504
1868
|
});
|
|
1505
1869
|
}, []);
|
|
1506
|
-
const handleCodeCopy =
|
|
1870
|
+
const handleCodeCopy = useCallback4(() => {
|
|
1507
1871
|
if (!formattedCode) return;
|
|
1508
1872
|
if (typeof navigator === "undefined" || !navigator.clipboard || typeof navigator.clipboard.writeText !== "function") {
|
|
1509
1873
|
return;
|
|
@@ -1521,11 +1885,11 @@ var ControlPanel = () => {
|
|
|
1521
1885
|
});
|
|
1522
1886
|
}, [formattedCode]);
|
|
1523
1887
|
const labelize = (key) => key.replace(/([A-Z])/g, " $1").replace(/[\-_]/g, " ").replace(/\s+/g, " ").trim().replace(/(^|\s)\S/g, (s) => s.toUpperCase());
|
|
1524
|
-
const renderButtonControl = (key, control, variant) => /* @__PURE__ */
|
|
1888
|
+
const renderButtonControl = (key, control, variant) => /* @__PURE__ */ jsx11(
|
|
1525
1889
|
"div",
|
|
1526
1890
|
{
|
|
1527
1891
|
className: variant === "root" ? "flex-1 [&_[data-slot=button]]:w-full" : "[&_[data-slot=button]]:w-full",
|
|
1528
|
-
children: control.render ? control.render() : /* @__PURE__ */
|
|
1892
|
+
children: control.render ? control.render() : /* @__PURE__ */ jsx11(
|
|
1529
1893
|
"button",
|
|
1530
1894
|
{
|
|
1531
1895
|
onClick: control.onClick,
|
|
@@ -1543,9 +1907,9 @@ var ControlPanel = () => {
|
|
|
1543
1907
|
const value = values[key];
|
|
1544
1908
|
switch (control.type) {
|
|
1545
1909
|
case "boolean":
|
|
1546
|
-
return /* @__PURE__ */
|
|
1547
|
-
/* @__PURE__ */
|
|
1548
|
-
/* @__PURE__ */
|
|
1910
|
+
return /* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between", children: [
|
|
1911
|
+
/* @__PURE__ */ jsx11(Label, { htmlFor: key, className: "cursor-pointer", children: labelize(key) }),
|
|
1912
|
+
/* @__PURE__ */ jsx11(
|
|
1549
1913
|
Switch,
|
|
1550
1914
|
{
|
|
1551
1915
|
id: key,
|
|
@@ -1556,10 +1920,10 @@ var ControlPanel = () => {
|
|
|
1556
1920
|
)
|
|
1557
1921
|
] }, key);
|
|
1558
1922
|
case "number":
|
|
1559
|
-
return /* @__PURE__ */
|
|
1560
|
-
/* @__PURE__ */
|
|
1561
|
-
/* @__PURE__ */
|
|
1562
|
-
/* @__PURE__ */
|
|
1923
|
+
return /* @__PURE__ */ jsxs6("div", { className: "space-y-3 w-full", children: [
|
|
1924
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between", children: [
|
|
1925
|
+
/* @__PURE__ */ jsx11(Label, { className: "text-stone-300", htmlFor: key, children: labelize(key) }),
|
|
1926
|
+
/* @__PURE__ */ jsx11(
|
|
1563
1927
|
Input,
|
|
1564
1928
|
{
|
|
1565
1929
|
type: "number",
|
|
@@ -1576,7 +1940,7 @@ var ControlPanel = () => {
|
|
|
1576
1940
|
}
|
|
1577
1941
|
)
|
|
1578
1942
|
] }),
|
|
1579
|
-
/* @__PURE__ */
|
|
1943
|
+
/* @__PURE__ */ jsx11(
|
|
1580
1944
|
Slider,
|
|
1581
1945
|
{
|
|
1582
1946
|
id: key,
|
|
@@ -1590,9 +1954,9 @@ var ControlPanel = () => {
|
|
|
1590
1954
|
)
|
|
1591
1955
|
] }, key);
|
|
1592
1956
|
case "string":
|
|
1593
|
-
return /* @__PURE__ */
|
|
1594
|
-
/* @__PURE__ */
|
|
1595
|
-
/* @__PURE__ */
|
|
1957
|
+
return /* @__PURE__ */ jsxs6("div", { className: "space-y-2 w-full", children: [
|
|
1958
|
+
/* @__PURE__ */ jsx11(Label, { className: "text-stone-300", htmlFor: key, children: labelize(key) }),
|
|
1959
|
+
/* @__PURE__ */ jsx11(
|
|
1596
1960
|
Input,
|
|
1597
1961
|
{
|
|
1598
1962
|
id: key,
|
|
@@ -1604,9 +1968,9 @@ var ControlPanel = () => {
|
|
|
1604
1968
|
)
|
|
1605
1969
|
] }, key);
|
|
1606
1970
|
case "color":
|
|
1607
|
-
return /* @__PURE__ */
|
|
1608
|
-
/* @__PURE__ */
|
|
1609
|
-
/* @__PURE__ */
|
|
1971
|
+
return /* @__PURE__ */ jsxs6("div", { className: "space-y-2 w-full", children: [
|
|
1972
|
+
/* @__PURE__ */ jsx11(Label, { className: "text-stone-300", htmlFor: key, children: labelize(key) }),
|
|
1973
|
+
/* @__PURE__ */ jsx11(
|
|
1610
1974
|
"input",
|
|
1611
1975
|
{
|
|
1612
1976
|
type: "color",
|
|
@@ -1618,11 +1982,11 @@ var ControlPanel = () => {
|
|
|
1618
1982
|
)
|
|
1619
1983
|
] }, key);
|
|
1620
1984
|
case "select":
|
|
1621
|
-
return /* @__PURE__ */
|
|
1622
|
-
/* @__PURE__ */
|
|
1623
|
-
/* @__PURE__ */
|
|
1624
|
-
/* @__PURE__ */
|
|
1625
|
-
/* @__PURE__ */
|
|
1985
|
+
return /* @__PURE__ */ jsx11("div", { className: "space-y-2", children: /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-3", children: [
|
|
1986
|
+
/* @__PURE__ */ jsx11(Label, { className: "min-w-fit", htmlFor: key, children: labelize(key) }),
|
|
1987
|
+
/* @__PURE__ */ jsxs6(Select, { value, onValueChange: (val) => setValue(key, val), children: [
|
|
1988
|
+
/* @__PURE__ */ jsx11(SelectTrigger, { className: "flex-1 cursor-pointer", children: /* @__PURE__ */ jsx11(SelectValue, { placeholder: "Select option" }) }),
|
|
1989
|
+
/* @__PURE__ */ jsx11(SelectContent, { className: "cursor-pointer z-[9999]", children: Object.entries(control.options).map(([label]) => /* @__PURE__ */ jsx11(
|
|
1626
1990
|
SelectItem,
|
|
1627
1991
|
{
|
|
1628
1992
|
value: label,
|
|
@@ -1639,12 +2003,12 @@ var ControlPanel = () => {
|
|
|
1639
2003
|
};
|
|
1640
2004
|
const renderFolder = (folder, entries, extras = []) => {
|
|
1641
2005
|
const isOpen = folderStates[folder] ?? true;
|
|
1642
|
-
return /* @__PURE__ */
|
|
2006
|
+
return /* @__PURE__ */ jsxs6(
|
|
1643
2007
|
"div",
|
|
1644
2008
|
{
|
|
1645
2009
|
className: "border border-stone-700/60 rounded-lg bg-stone-900/70",
|
|
1646
2010
|
children: [
|
|
1647
|
-
/* @__PURE__ */
|
|
2011
|
+
/* @__PURE__ */ jsxs6(
|
|
1648
2012
|
"button",
|
|
1649
2013
|
{
|
|
1650
2014
|
type: "button",
|
|
@@ -1654,8 +2018,8 @@ var ControlPanel = () => {
|
|
|
1654
2018
|
})),
|
|
1655
2019
|
className: "w-full flex items-center justify-between px-4 py-3 text-left font-semibold text-stone-200 tracking-wide",
|
|
1656
2020
|
children: [
|
|
1657
|
-
/* @__PURE__ */
|
|
1658
|
-
/* @__PURE__ */
|
|
2021
|
+
/* @__PURE__ */ jsx11("span", { children: folder }),
|
|
2022
|
+
/* @__PURE__ */ jsx11(
|
|
1659
2023
|
ChevronDown2,
|
|
1660
2024
|
{
|
|
1661
2025
|
className: `w-4 h-4 transition-transform duration-200 ${isOpen ? "rotate-180" : ""}`
|
|
@@ -1664,7 +2028,7 @@ var ControlPanel = () => {
|
|
|
1664
2028
|
]
|
|
1665
2029
|
}
|
|
1666
2030
|
),
|
|
1667
|
-
isOpen && /* @__PURE__ */
|
|
2031
|
+
isOpen && /* @__PURE__ */ jsxs6("div", { className: "px-4 pb-4 pt-0 space-y-5", children: [
|
|
1668
2032
|
entries.map(
|
|
1669
2033
|
([key, control]) => renderControl(key, control, "folder")
|
|
1670
2034
|
),
|
|
@@ -1703,27 +2067,28 @@ var ControlPanel = () => {
|
|
|
1703
2067
|
});
|
|
1704
2068
|
}
|
|
1705
2069
|
}
|
|
1706
|
-
return /* @__PURE__ */
|
|
2070
|
+
return /* @__PURE__ */ jsx11(
|
|
1707
2071
|
"div",
|
|
1708
2072
|
{
|
|
1709
2073
|
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 z-max ${!isHydrated ? "opacity-0" : "opacity-100"}`,
|
|
1710
2074
|
onPointerDown: (e) => e.stopPropagation(),
|
|
1711
2075
|
onTouchStart: (e) => e.stopPropagation(),
|
|
1712
2076
|
style: panelStyle,
|
|
1713
|
-
children: /* @__PURE__ */
|
|
1714
|
-
/* @__PURE__ */
|
|
1715
|
-
/* @__PURE__ */
|
|
2077
|
+
children: /* @__PURE__ */ jsxs6("div", { className: "dark mb-10 space-y-6 p-4 md:p-6 bg-stone-900/95 backdrop-blur-md border-2 border-stone-700 rounded-xl shadow-lg", children: [
|
|
2078
|
+
/* @__PURE__ */ jsx11("div", { className: "space-y-1", children: /* @__PURE__ */ jsx11("h1", { className: "text-lg text-stone-100 font-semibold", children: config?.mainLabel ?? "Controls" }) }),
|
|
2079
|
+
/* @__PURE__ */ jsxs6("div", { className: "space-y-6", children: [
|
|
1716
2080
|
topFolderSections,
|
|
1717
|
-
hasRootButtonControls && /* @__PURE__ */
|
|
2081
|
+
hasRootButtonControls && /* @__PURE__ */ jsx11("div", { className: "flex flex-wrap gap-2", children: rootButtonControls.map(
|
|
1718
2082
|
([key, control]) => renderButtonControl(key, control, "root")
|
|
1719
2083
|
) }),
|
|
1720
2084
|
advancedPaletteControlNode,
|
|
2085
|
+
mediaUploadControlNode,
|
|
1721
2086
|
rootNormalControls.map(
|
|
1722
2087
|
([key, control]) => renderControl(key, control, "root")
|
|
1723
2088
|
),
|
|
1724
2089
|
bottomFolderSections,
|
|
1725
|
-
hasCodeSnippet && /* @__PURE__ */
|
|
1726
|
-
/* @__PURE__ */
|
|
2090
|
+
hasCodeSnippet && /* @__PURE__ */ jsxs6("div", { className: "border border-stone-700/60 rounded-lg bg-stone-900/70", children: [
|
|
2091
|
+
/* @__PURE__ */ jsxs6(
|
|
1727
2092
|
"button",
|
|
1728
2093
|
{
|
|
1729
2094
|
type: "button",
|
|
@@ -1731,8 +2096,8 @@ var ControlPanel = () => {
|
|
|
1731
2096
|
className: "w-full flex items-center justify-between px-4 py-3 text-left font-semibold text-stone-200 tracking-wide",
|
|
1732
2097
|
"aria-expanded": isCodeVisible,
|
|
1733
2098
|
children: [
|
|
1734
|
-
/* @__PURE__ */
|
|
1735
|
-
/* @__PURE__ */
|
|
2099
|
+
/* @__PURE__ */ jsx11("span", { children: isCodeVisible ? "Hide Code" : "Show Code" }),
|
|
2100
|
+
/* @__PURE__ */ jsx11(
|
|
1736
2101
|
ChevronDown2,
|
|
1737
2102
|
{
|
|
1738
2103
|
className: `w-4 h-4 transition-transform duration-200 ${isCodeVisible ? "rotate-180" : ""}`
|
|
@@ -1741,26 +2106,26 @@ var ControlPanel = () => {
|
|
|
1741
2106
|
]
|
|
1742
2107
|
}
|
|
1743
2108
|
),
|
|
1744
|
-
isCodeVisible && /* @__PURE__ */
|
|
1745
|
-
/* @__PURE__ */
|
|
2109
|
+
isCodeVisible && /* @__PURE__ */ jsxs6("div", { className: "relative border-t border-stone-700/60 bg-stone-950/60 px-4 py-4 rounded-b-lg", children: [
|
|
2110
|
+
/* @__PURE__ */ jsx11(
|
|
1746
2111
|
"button",
|
|
1747
2112
|
{
|
|
1748
2113
|
type: "button",
|
|
1749
2114
|
onClick: handleCodeCopy,
|
|
1750
2115
|
className: "absolute top-3 right-3 flex items-center gap-1 rounded-md border border-stone-700 bg-stone-800 px-2 py-1 text-xs font-medium text-white shadow hover:bg-stone-700",
|
|
1751
|
-
children: codeCopied ? /* @__PURE__ */
|
|
1752
|
-
/* @__PURE__ */
|
|
2116
|
+
children: codeCopied ? /* @__PURE__ */ jsxs6(Fragment, { children: [
|
|
2117
|
+
/* @__PURE__ */ jsx11(Check2, { className: "h-3.5 w-3.5" }),
|
|
1753
2118
|
"Copied"
|
|
1754
|
-
] }) : /* @__PURE__ */
|
|
1755
|
-
/* @__PURE__ */
|
|
2119
|
+
] }) : /* @__PURE__ */ jsxs6(Fragment, { children: [
|
|
2120
|
+
/* @__PURE__ */ jsx11(Copy, { className: "h-3.5 w-3.5" }),
|
|
1756
2121
|
"Copy"
|
|
1757
2122
|
] })
|
|
1758
2123
|
}
|
|
1759
2124
|
),
|
|
1760
|
-
/* @__PURE__ */
|
|
2125
|
+
/* @__PURE__ */ jsx11("pre", { className: "whitespace-pre overflow-x-auto text-xs md:text-sm text-stone-200 pr-14", children: /* @__PURE__ */ jsx11("code", { className: "block text-stone-200", children: highlightedCode ?? formattedCode }) })
|
|
1761
2126
|
] })
|
|
1762
2127
|
] }),
|
|
1763
|
-
shouldShowCopyButton && /* @__PURE__ */
|
|
2128
|
+
shouldShowCopyButton && /* @__PURE__ */ jsx11("div", { className: "flex-1 pt-4", children: /* @__PURE__ */ jsx11(
|
|
1764
2129
|
"button",
|
|
1765
2130
|
{
|
|
1766
2131
|
onClick: () => {
|
|
@@ -1771,18 +2136,18 @@ var ControlPanel = () => {
|
|
|
1771
2136
|
setTimeout(() => setCopied(false), 5e3);
|
|
1772
2137
|
},
|
|
1773
2138
|
className: "w-full px-4 py-2 text-sm bg-stone-800 hover:bg-stone-700 text-white rounded-md flex items-center justify-center gap-2 shadow",
|
|
1774
|
-
children: copied ? /* @__PURE__ */
|
|
1775
|
-
/* @__PURE__ */
|
|
2139
|
+
children: copied ? /* @__PURE__ */ jsxs6(Fragment, { children: [
|
|
2140
|
+
/* @__PURE__ */ jsx11(Check2, { className: "w-4 h-4" }),
|
|
1776
2141
|
"Copied"
|
|
1777
|
-
] }) : /* @__PURE__ */
|
|
1778
|
-
/* @__PURE__ */
|
|
2142
|
+
] }) : /* @__PURE__ */ jsxs6(Fragment, { children: [
|
|
2143
|
+
/* @__PURE__ */ jsx11(Copy, { className: "w-4 h-4" }),
|
|
1779
2144
|
"Copy to Clipboard"
|
|
1780
2145
|
] })
|
|
1781
2146
|
}
|
|
1782
2147
|
) }, "control-panel-jsx")
|
|
1783
2148
|
] }),
|
|
1784
|
-
previewUrl && /* @__PURE__ */
|
|
1785
|
-
/* @__PURE__ */
|
|
2149
|
+
previewUrl && /* @__PURE__ */ jsxs6("div", { className: "flex flex-col gap-2", children: [
|
|
2150
|
+
/* @__PURE__ */ jsx11(Button, { asChild: true, className: "w-full", children: /* @__PURE__ */ jsxs6(
|
|
1786
2151
|
"a",
|
|
1787
2152
|
{
|
|
1788
2153
|
href: previewUrl,
|
|
@@ -1790,12 +2155,12 @@ var ControlPanel = () => {
|
|
|
1790
2155
|
rel: "noopener noreferrer",
|
|
1791
2156
|
className: "w-full px-4 py-2 text-sm text-center bg-stone-900 hover:bg-stone-800 text-white rounded-md border border-stone-700",
|
|
1792
2157
|
children: [
|
|
1793
|
-
/* @__PURE__ */
|
|
2158
|
+
/* @__PURE__ */ jsx11(SquareArrowOutUpRight, {}),
|
|
1794
2159
|
" Open in a New Tab"
|
|
1795
2160
|
]
|
|
1796
2161
|
}
|
|
1797
2162
|
) }),
|
|
1798
|
-
config?.showPresentationButton && presentationUrl && /* @__PURE__ */
|
|
2163
|
+
config?.showPresentationButton && presentationUrl && /* @__PURE__ */ jsxs6(
|
|
1799
2164
|
Button,
|
|
1800
2165
|
{
|
|
1801
2166
|
type: "button",
|
|
@@ -1803,7 +2168,7 @@ var ControlPanel = () => {
|
|
|
1803
2168
|
variant: "secondary",
|
|
1804
2169
|
className: "w-full bg-stone-800 text-white hover:bg-stone-700 border border-stone-700",
|
|
1805
2170
|
children: [
|
|
1806
|
-
/* @__PURE__ */
|
|
2171
|
+
/* @__PURE__ */ jsx11(Presentation, {}),
|
|
1807
2172
|
" Presentation Mode"
|
|
1808
2173
|
]
|
|
1809
2174
|
}
|
|
@@ -1815,16 +2180,16 @@ var ControlPanel = () => {
|
|
|
1815
2180
|
};
|
|
1816
2181
|
var ControlPanel_default = ControlPanel;
|
|
1817
2182
|
|
|
1818
|
-
// src/components/PreviewContainer
|
|
1819
|
-
import { useRef as
|
|
2183
|
+
// src/components/PreviewContainer.tsx
|
|
2184
|
+
import { useRef as useRef6 } from "react";
|
|
1820
2185
|
|
|
1821
|
-
// src/components/Grid
|
|
1822
|
-
import { jsx as
|
|
2186
|
+
// src/components/Grid.tsx
|
|
2187
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
1823
2188
|
function Grid() {
|
|
1824
|
-
return /* @__PURE__ */
|
|
2189
|
+
return /* @__PURE__ */ jsx12(
|
|
1825
2190
|
"div",
|
|
1826
2191
|
{
|
|
1827
|
-
className: "absolute inset-0 w-
|
|
2192
|
+
className: "absolute inset-0 w-full h-full z-[0] blur-[1px]",
|
|
1828
2193
|
style: {
|
|
1829
2194
|
backgroundImage: `
|
|
1830
2195
|
linear-gradient(to right,rgb(13, 13, 13) 1px, transparent 1px),
|
|
@@ -1838,40 +2203,40 @@ function Grid() {
|
|
|
1838
2203
|
}
|
|
1839
2204
|
var Grid_default = Grid;
|
|
1840
2205
|
|
|
1841
|
-
// src/components/PreviewContainer
|
|
1842
|
-
import { jsx as
|
|
2206
|
+
// src/components/PreviewContainer.tsx
|
|
2207
|
+
import { jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1843
2208
|
var PreviewContainer = ({ children, hideControls }) => {
|
|
1844
2209
|
const { config } = useControlsContext();
|
|
1845
2210
|
const { leftPanelWidth, isDesktop, isHydrated, containerRef } = useResizableLayout();
|
|
1846
|
-
const previewRef =
|
|
1847
|
-
return /* @__PURE__ */
|
|
2211
|
+
const previewRef = useRef6(null);
|
|
2212
|
+
return /* @__PURE__ */ jsx13(
|
|
1848
2213
|
"div",
|
|
1849
2214
|
{
|
|
1850
2215
|
ref: previewRef,
|
|
1851
|
-
className: "order-1 md:order-2 flex-1 bg-black overflow-auto flex items-center justify-center relative",
|
|
2216
|
+
className: "order-1 md:order-2 flex-1 md:flex-none bg-black overflow-auto flex items-center justify-center relative",
|
|
1852
2217
|
style: isHydrated && isDesktop && !hideControls ? {
|
|
1853
2218
|
width: `${100 - leftPanelWidth}%`,
|
|
1854
2219
|
marginLeft: `${leftPanelWidth}%`
|
|
1855
2220
|
} : {},
|
|
1856
|
-
children: /* @__PURE__ */
|
|
1857
|
-
config?.showGrid && /* @__PURE__ */
|
|
1858
|
-
/* @__PURE__ */
|
|
2221
|
+
children: /* @__PURE__ */ jsxs7("div", { className: "w-full h-screen", children: [
|
|
2222
|
+
config?.showGrid && /* @__PURE__ */ jsx13(Grid_default, {}),
|
|
2223
|
+
/* @__PURE__ */ jsx13("div", { className: "w-full h-full flex items-center justify-center relative", children })
|
|
1859
2224
|
] })
|
|
1860
2225
|
}
|
|
1861
2226
|
);
|
|
1862
2227
|
};
|
|
1863
2228
|
var PreviewContainer_default = PreviewContainer;
|
|
1864
2229
|
|
|
1865
|
-
// src/components/Playground
|
|
1866
|
-
import { jsx as
|
|
1867
|
-
var HiddenPreview = ({ children }) => /* @__PURE__ */
|
|
2230
|
+
// src/components/Playground.tsx
|
|
2231
|
+
import { jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2232
|
+
var HiddenPreview = ({ children }) => /* @__PURE__ */ jsx14("div", { "aria-hidden": "true", className: "hidden", children });
|
|
1868
2233
|
function Playground({ children }) {
|
|
1869
2234
|
const [isHydrated, setIsHydrated] = useState5(false);
|
|
1870
2235
|
const [copied, setCopied] = useState5(false);
|
|
1871
|
-
|
|
2236
|
+
useEffect7(() => {
|
|
1872
2237
|
setIsHydrated(true);
|
|
1873
2238
|
}, []);
|
|
1874
|
-
const { showControls, isPresentationMode, isControlsOnly } =
|
|
2239
|
+
const { showControls, isPresentationMode, isControlsOnly } = useMemo5(() => {
|
|
1875
2240
|
if (typeof window === "undefined") {
|
|
1876
2241
|
return {
|
|
1877
2242
|
showControls: true,
|
|
@@ -1898,54 +2263,54 @@ function Playground({ children }) {
|
|
|
1898
2263
|
setTimeout(() => setCopied(false), 2e3);
|
|
1899
2264
|
};
|
|
1900
2265
|
if (!isHydrated) return null;
|
|
1901
|
-
return /* @__PURE__ */
|
|
1902
|
-
shouldShowShareButton && /* @__PURE__ */
|
|
2266
|
+
return /* @__PURE__ */ jsx14(ResizableLayout, { hideControls: layoutHideControls, children: /* @__PURE__ */ jsxs8(ControlsProvider, { children: [
|
|
2267
|
+
shouldShowShareButton && /* @__PURE__ */ jsxs8(
|
|
1903
2268
|
"button",
|
|
1904
2269
|
{
|
|
1905
2270
|
onClick: handleCopy,
|
|
1906
2271
|
className: "absolute top-4 right-4 z-50 flex items-center gap-1 rounded bg-black/70 px-3 py-1 text-white hover:bg-black",
|
|
1907
2272
|
children: [
|
|
1908
|
-
copied ? /* @__PURE__ */
|
|
2273
|
+
copied ? /* @__PURE__ */ jsx14(Check3, { size: 16 }) : /* @__PURE__ */ jsx14(Copy2, { size: 16 }),
|
|
1909
2274
|
copied ? "Copied!" : "Share"
|
|
1910
2275
|
]
|
|
1911
2276
|
}
|
|
1912
2277
|
),
|
|
1913
|
-
isControlsOnly ? /* @__PURE__ */
|
|
1914
|
-
showControls && /* @__PURE__ */
|
|
2278
|
+
isControlsOnly ? /* @__PURE__ */ jsx14(HiddenPreview, { children }) : /* @__PURE__ */ jsx14(PreviewContainer_default, { hideControls: layoutHideControls, children }),
|
|
2279
|
+
showControls && /* @__PURE__ */ jsx14(ControlPanel_default, {})
|
|
1915
2280
|
] }) });
|
|
1916
2281
|
}
|
|
1917
2282
|
|
|
1918
2283
|
// src/hooks/useAdvancedPaletteControls.ts
|
|
1919
|
-
import { useCallback as
|
|
2284
|
+
import { useCallback as useCallback5, useEffect as useEffect8, useMemo as useMemo6, useRef as useRef7, useState as useState6 } from "react";
|
|
1920
2285
|
var cloneForCallbacks = (palette) => clonePalette(palette);
|
|
1921
2286
|
var useAdvancedPaletteControls = (options = {}) => {
|
|
1922
|
-
const resolvedDefaultPalette =
|
|
2287
|
+
const resolvedDefaultPalette = useMemo6(
|
|
1923
2288
|
() => createAdvancedPalette(options.defaultPalette),
|
|
1924
2289
|
[options.defaultPalette]
|
|
1925
2290
|
);
|
|
1926
|
-
const resolvedFallbackPalette =
|
|
2291
|
+
const resolvedFallbackPalette = useMemo6(
|
|
1927
2292
|
() => options.fallbackPalette ? createAdvancedPalette(options.fallbackPalette) : resolvedDefaultPalette,
|
|
1928
2293
|
[options.fallbackPalette, resolvedDefaultPalette]
|
|
1929
2294
|
);
|
|
1930
2295
|
const [palette, setPaletteState] = useState6(
|
|
1931
2296
|
() => clonePalette(resolvedDefaultPalette)
|
|
1932
2297
|
);
|
|
1933
|
-
const defaultSignatureRef =
|
|
2298
|
+
const defaultSignatureRef = useRef7(
|
|
1934
2299
|
createPaletteSignature(resolvedDefaultPalette)
|
|
1935
2300
|
);
|
|
1936
|
-
|
|
2301
|
+
useEffect8(() => {
|
|
1937
2302
|
const nextSignature = createPaletteSignature(resolvedDefaultPalette);
|
|
1938
2303
|
if (defaultSignatureRef.current === nextSignature) return;
|
|
1939
2304
|
defaultSignatureRef.current = nextSignature;
|
|
1940
2305
|
setPaletteState(clonePalette(resolvedDefaultPalette));
|
|
1941
2306
|
}, [resolvedDefaultPalette]);
|
|
1942
|
-
const notifyChange =
|
|
2307
|
+
const notifyChange = useCallback5(
|
|
1943
2308
|
(nextPalette) => {
|
|
1944
2309
|
options.onChange?.(cloneForCallbacks(nextPalette));
|
|
1945
2310
|
},
|
|
1946
2311
|
[options.onChange]
|
|
1947
2312
|
);
|
|
1948
|
-
const setPalette =
|
|
2313
|
+
const setPalette = useCallback5(
|
|
1949
2314
|
(source) => {
|
|
1950
2315
|
const nextPalette = createAdvancedPalette(
|
|
1951
2316
|
source ?? resolvedDefaultPalette
|
|
@@ -1955,7 +2320,7 @@ var useAdvancedPaletteControls = (options = {}) => {
|
|
|
1955
2320
|
},
|
|
1956
2321
|
[notifyChange, resolvedDefaultPalette]
|
|
1957
2322
|
);
|
|
1958
|
-
const updatePalette =
|
|
2323
|
+
const updatePalette = useCallback5(
|
|
1959
2324
|
(updater) => {
|
|
1960
2325
|
setPaletteState((current) => {
|
|
1961
2326
|
const nextSource = updater(clonePalette(current));
|
|
@@ -1968,18 +2333,18 @@ var useAdvancedPaletteControls = (options = {}) => {
|
|
|
1968
2333
|
},
|
|
1969
2334
|
[notifyChange, resolvedDefaultPalette]
|
|
1970
2335
|
);
|
|
1971
|
-
const resetPalette =
|
|
2336
|
+
const resetPalette = useCallback5(() => {
|
|
1972
2337
|
setPaletteState(clonePalette(resolvedDefaultPalette));
|
|
1973
2338
|
notifyChange(resolvedDefaultPalette);
|
|
1974
2339
|
}, [notifyChange, resolvedDefaultPalette]);
|
|
1975
|
-
const handleControlPaletteChange =
|
|
2340
|
+
const handleControlPaletteChange = useCallback5(
|
|
1976
2341
|
(nextPalette) => {
|
|
1977
2342
|
setPaletteState(clonePalette(nextPalette));
|
|
1978
2343
|
notifyChange(nextPalette);
|
|
1979
2344
|
},
|
|
1980
2345
|
[notifyChange]
|
|
1981
2346
|
);
|
|
1982
|
-
const controlConfig =
|
|
2347
|
+
const controlConfig = useMemo6(
|
|
1983
2348
|
() => ({
|
|
1984
2349
|
...options.control ?? {},
|
|
1985
2350
|
defaultPalette: resolvedDefaultPalette,
|
|
@@ -1987,7 +2352,7 @@ var useAdvancedPaletteControls = (options = {}) => {
|
|
|
1987
2352
|
}),
|
|
1988
2353
|
[handleControlPaletteChange, options.control, resolvedDefaultPalette]
|
|
1989
2354
|
);
|
|
1990
|
-
const hexColors =
|
|
2355
|
+
const hexColors = useMemo6(
|
|
1991
2356
|
() => advancedPaletteToHexColors(palette, {
|
|
1992
2357
|
sectionOrder: options.sectionOrder,
|
|
1993
2358
|
fallbackPalette: resolvedFallbackPalette,
|
|
@@ -2000,11 +2365,11 @@ var useAdvancedPaletteControls = (options = {}) => {
|
|
|
2000
2365
|
resolvedFallbackPalette
|
|
2001
2366
|
]
|
|
2002
2367
|
);
|
|
2003
|
-
const paletteSignature =
|
|
2368
|
+
const paletteSignature = useMemo6(
|
|
2004
2369
|
() => createPaletteSignature(palette),
|
|
2005
2370
|
[palette]
|
|
2006
2371
|
);
|
|
2007
|
-
const paletteGradient =
|
|
2372
|
+
const paletteGradient = useMemo6(
|
|
2008
2373
|
() => computePaletteGradient(palette, options.gradientSteps),
|
|
2009
2374
|
[options.gradientSteps, palette]
|
|
2010
2375
|
);
|