@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.js
CHANGED
|
@@ -49,9 +49,9 @@ __export(src_exports, {
|
|
|
49
49
|
});
|
|
50
50
|
module.exports = __toCommonJS(src_exports);
|
|
51
51
|
|
|
52
|
-
// src/components/Playground
|
|
53
|
-
var
|
|
54
|
-
var
|
|
52
|
+
// src/components/Playground.tsx
|
|
53
|
+
var import_react8 = require("react");
|
|
54
|
+
var import_lucide_react5 = require("lucide-react");
|
|
55
55
|
|
|
56
56
|
// src/context/ResizableLayout.tsx
|
|
57
57
|
var import_react = require("react");
|
|
@@ -472,17 +472,30 @@ var ControlsProvider = ({ children }) => {
|
|
|
472
472
|
setComponentName(opts.componentName);
|
|
473
473
|
}
|
|
474
474
|
if (opts?.config) {
|
|
475
|
-
const {
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
...otherConfig
|
|
479
|
-
|
|
475
|
+
const {
|
|
476
|
+
addAdvancedPaletteControl,
|
|
477
|
+
addMediaUploadControl,
|
|
478
|
+
...otherConfig
|
|
479
|
+
} = opts.config;
|
|
480
|
+
setConfig((prev) => {
|
|
481
|
+
const nextConfig = {
|
|
482
|
+
...prev,
|
|
483
|
+
...otherConfig
|
|
484
|
+
};
|
|
485
|
+
if (Object.prototype.hasOwnProperty.call(
|
|
480
486
|
opts.config,
|
|
481
487
|
"addAdvancedPaletteControl"
|
|
482
|
-
)
|
|
483
|
-
addAdvancedPaletteControl
|
|
484
|
-
}
|
|
485
|
-
|
|
488
|
+
)) {
|
|
489
|
+
nextConfig.addAdvancedPaletteControl = addAdvancedPaletteControl ? resolveAdvancedPaletteConfig(addAdvancedPaletteControl) : void 0;
|
|
490
|
+
}
|
|
491
|
+
if (Object.prototype.hasOwnProperty.call(
|
|
492
|
+
opts.config,
|
|
493
|
+
"addMediaUploadControl"
|
|
494
|
+
)) {
|
|
495
|
+
nextConfig.addMediaUploadControl = addMediaUploadControl ? { ...addMediaUploadControl } : void 0;
|
|
496
|
+
}
|
|
497
|
+
return nextConfig;
|
|
498
|
+
});
|
|
486
499
|
}
|
|
487
500
|
setSchema((prevSchema) => ({ ...prevSchema, ...newSchema }));
|
|
488
501
|
setValues((prevValues) => {
|
|
@@ -647,7 +660,7 @@ var useControls = (schema, options) => {
|
|
|
647
660
|
resolvedAdvancedConfig.onPaletteChange(clonePalette(palette));
|
|
648
661
|
}, [ctx.values, resolvedAdvancedConfig]);
|
|
649
662
|
const typedValues = ctx.values;
|
|
650
|
-
const
|
|
663
|
+
const jsx15 = (0, import_react2.useCallback)(() => {
|
|
651
664
|
if (!options?.componentName) return "";
|
|
652
665
|
const props = Object.entries(typedValues).map(([key, val]) => {
|
|
653
666
|
if (typeof val === "string") return `${key}="${val}"`;
|
|
@@ -661,14 +674,14 @@ var useControls = (schema, options) => {
|
|
|
661
674
|
controls: ctx.values,
|
|
662
675
|
schema: ctx.schema,
|
|
663
676
|
setValue: ctx.setValue,
|
|
664
|
-
jsx:
|
|
677
|
+
jsx: jsx15
|
|
665
678
|
};
|
|
666
679
|
};
|
|
667
680
|
var useUrlSyncedControls = useControls;
|
|
668
681
|
|
|
669
|
-
// src/components/ControlPanel
|
|
670
|
-
var
|
|
671
|
-
var
|
|
682
|
+
// src/components/ControlPanel.tsx
|
|
683
|
+
var import_react6 = require("react");
|
|
684
|
+
var import_lucide_react4 = require("lucide-react");
|
|
672
685
|
|
|
673
686
|
// src/hooks/usePreviewUrl.ts
|
|
674
687
|
var import_react3 = require("react");
|
|
@@ -943,7 +956,7 @@ Button.displayName = "Button";
|
|
|
943
956
|
// src/constants/layout.ts
|
|
944
957
|
var MOBILE_CONTROL_PANEL_PEEK = 112;
|
|
945
958
|
|
|
946
|
-
// src/components/AdvancedPaletteControl
|
|
959
|
+
// src/components/AdvancedPaletteControl.tsx
|
|
947
960
|
var import_react4 = require("react");
|
|
948
961
|
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
949
962
|
var AdvancedPaletteControl = ({
|
|
@@ -1091,8 +1104,309 @@ var AdvancedPaletteControl = ({
|
|
|
1091
1104
|
};
|
|
1092
1105
|
var AdvancedPaletteControl_default = AdvancedPaletteControl;
|
|
1093
1106
|
|
|
1094
|
-
// src/components/
|
|
1107
|
+
// src/components/MediaUploadControl.tsx
|
|
1108
|
+
var import_react5 = require("react");
|
|
1109
|
+
var import_lucide_react3 = require("lucide-react");
|
|
1110
|
+
|
|
1111
|
+
// src/state/mediaSelectionStore.ts
|
|
1112
|
+
var snapshot = {
|
|
1113
|
+
media: null,
|
|
1114
|
+
error: null
|
|
1115
|
+
};
|
|
1116
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
1117
|
+
var emitChange = () => {
|
|
1118
|
+
for (const listener of listeners) {
|
|
1119
|
+
listener();
|
|
1120
|
+
}
|
|
1121
|
+
};
|
|
1122
|
+
var mediaSelectionStore = {
|
|
1123
|
+
subscribe: (listener) => {
|
|
1124
|
+
listeners.add(listener);
|
|
1125
|
+
return () => {
|
|
1126
|
+
listeners.delete(listener);
|
|
1127
|
+
};
|
|
1128
|
+
},
|
|
1129
|
+
getSnapshot: () => snapshot,
|
|
1130
|
+
setSnapshot: (next) => {
|
|
1131
|
+
snapshot = next;
|
|
1132
|
+
emitChange();
|
|
1133
|
+
}
|
|
1134
|
+
};
|
|
1135
|
+
|
|
1136
|
+
// src/components/MediaUploadControl.tsx
|
|
1095
1137
|
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1138
|
+
var DEFAULT_PRESET_MEDIA = [
|
|
1139
|
+
{
|
|
1140
|
+
src: "https://res.cloudinary.com/dz8kk1l4r/image/upload/v1763233793/astronaut_q84mbj.png",
|
|
1141
|
+
label: "Astronaut",
|
|
1142
|
+
type: "image"
|
|
1143
|
+
},
|
|
1144
|
+
{
|
|
1145
|
+
src: "https://res.cloudinary.com/dz8kk1l4r/image/upload/v1763233793/surreal-head_r0ozcd.png",
|
|
1146
|
+
label: "Futuristic",
|
|
1147
|
+
type: "image"
|
|
1148
|
+
},
|
|
1149
|
+
{
|
|
1150
|
+
src: "https://res.cloudinary.com/dz8kk1l4r/image/upload/v1763233797/futuristic_bpwdzt.png",
|
|
1151
|
+
label: "Surreal",
|
|
1152
|
+
type: "image"
|
|
1153
|
+
},
|
|
1154
|
+
{
|
|
1155
|
+
src: "https://res.cloudinary.com/dz8kk1l4r/image/upload/v1763233793/portrait_hd7dyc.png",
|
|
1156
|
+
label: "Portrait",
|
|
1157
|
+
type: "image"
|
|
1158
|
+
}
|
|
1159
|
+
];
|
|
1160
|
+
function MediaUploadControl({
|
|
1161
|
+
onSelectMedia,
|
|
1162
|
+
onClear,
|
|
1163
|
+
presetMedia,
|
|
1164
|
+
maxPresetCount
|
|
1165
|
+
}) {
|
|
1166
|
+
const inputId = (0, import_react5.useId)();
|
|
1167
|
+
const inputRef = (0, import_react5.useRef)(null);
|
|
1168
|
+
const uploadedUrlRef = (0, import_react5.useRef)(null);
|
|
1169
|
+
const { media, error } = (0, import_react5.useSyncExternalStore)(
|
|
1170
|
+
mediaSelectionStore.subscribe,
|
|
1171
|
+
mediaSelectionStore.getSnapshot,
|
|
1172
|
+
mediaSelectionStore.getSnapshot
|
|
1173
|
+
);
|
|
1174
|
+
const VIDEO_EXTENSIONS = (0, import_react5.useMemo)(
|
|
1175
|
+
() => [".mp4", ".webm", ".ogg", ".ogv", ".mov", ".m4v"],
|
|
1176
|
+
[]
|
|
1177
|
+
);
|
|
1178
|
+
const setSelection = (0, import_react5.useCallback)(
|
|
1179
|
+
(next) => {
|
|
1180
|
+
mediaSelectionStore.setSnapshot(next);
|
|
1181
|
+
},
|
|
1182
|
+
[]
|
|
1183
|
+
);
|
|
1184
|
+
const handleFileChange = (event) => {
|
|
1185
|
+
const file = event.target.files?.[0];
|
|
1186
|
+
if (!file) {
|
|
1187
|
+
return;
|
|
1188
|
+
}
|
|
1189
|
+
if (uploadedUrlRef.current) {
|
|
1190
|
+
URL.revokeObjectURL(uploadedUrlRef.current);
|
|
1191
|
+
uploadedUrlRef.current = null;
|
|
1192
|
+
}
|
|
1193
|
+
const objectUrl = URL.createObjectURL(file);
|
|
1194
|
+
uploadedUrlRef.current = objectUrl;
|
|
1195
|
+
const lowerName = file.name?.toLowerCase() ?? "";
|
|
1196
|
+
const hasVideoExtension = VIDEO_EXTENSIONS.some(
|
|
1197
|
+
(ext) => lowerName.endsWith(ext)
|
|
1198
|
+
);
|
|
1199
|
+
const isVideo = file.type.startsWith("video/") || hasVideoExtension;
|
|
1200
|
+
if (isVideo) {
|
|
1201
|
+
setSelection({
|
|
1202
|
+
media: null,
|
|
1203
|
+
error: "Videos are not supported in this effect yet."
|
|
1204
|
+
});
|
|
1205
|
+
return;
|
|
1206
|
+
}
|
|
1207
|
+
const nextMedia = { src: objectUrl, type: "image" };
|
|
1208
|
+
setSelection({ media: nextMedia, error: null });
|
|
1209
|
+
onSelectMedia(nextMedia);
|
|
1210
|
+
};
|
|
1211
|
+
const handleClearSelection = () => {
|
|
1212
|
+
if (uploadedUrlRef.current) {
|
|
1213
|
+
URL.revokeObjectURL(uploadedUrlRef.current);
|
|
1214
|
+
uploadedUrlRef.current = null;
|
|
1215
|
+
}
|
|
1216
|
+
setSelection({ media: null, error: null });
|
|
1217
|
+
onClear();
|
|
1218
|
+
};
|
|
1219
|
+
const handlePresetSelect = (entry) => {
|
|
1220
|
+
if (entry.type === "video") {
|
|
1221
|
+
setSelection({
|
|
1222
|
+
media: null,
|
|
1223
|
+
error: "Videos are not supported in this effect yet."
|
|
1224
|
+
});
|
|
1225
|
+
return;
|
|
1226
|
+
}
|
|
1227
|
+
const nextMedia = { src: entry.src, type: entry.type };
|
|
1228
|
+
setSelection({ media: nextMedia, error: null });
|
|
1229
|
+
onSelectMedia(nextMedia);
|
|
1230
|
+
};
|
|
1231
|
+
(0, import_react5.useEffect)(() => {
|
|
1232
|
+
return () => {
|
|
1233
|
+
if (uploadedUrlRef.current) {
|
|
1234
|
+
URL.revokeObjectURL(uploadedUrlRef.current);
|
|
1235
|
+
uploadedUrlRef.current = null;
|
|
1236
|
+
}
|
|
1237
|
+
};
|
|
1238
|
+
}, []);
|
|
1239
|
+
const presets = (0, import_react5.useMemo)(() => {
|
|
1240
|
+
const source = presetMedia ?? DEFAULT_PRESET_MEDIA;
|
|
1241
|
+
if (typeof maxPresetCount === "number" && Number.isFinite(maxPresetCount)) {
|
|
1242
|
+
const safeCount = Math.max(0, Math.floor(maxPresetCount));
|
|
1243
|
+
return source.slice(0, safeCount);
|
|
1244
|
+
}
|
|
1245
|
+
return source;
|
|
1246
|
+
}, [presetMedia, maxPresetCount]);
|
|
1247
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
1248
|
+
"div",
|
|
1249
|
+
{
|
|
1250
|
+
style: {
|
|
1251
|
+
display: "flex",
|
|
1252
|
+
flexDirection: "column",
|
|
1253
|
+
gap: "0.5rem"
|
|
1254
|
+
},
|
|
1255
|
+
children: [
|
|
1256
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("label", { htmlFor: inputId, style: { fontSize: "0.85rem", fontWeight: 500 }, children: "Upload media" }),
|
|
1257
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1258
|
+
"input",
|
|
1259
|
+
{
|
|
1260
|
+
id: inputId,
|
|
1261
|
+
type: "file",
|
|
1262
|
+
accept: "image/*",
|
|
1263
|
+
ref: inputRef,
|
|
1264
|
+
style: { display: "none" },
|
|
1265
|
+
onChange: handleFileChange
|
|
1266
|
+
}
|
|
1267
|
+
),
|
|
1268
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
1269
|
+
"div",
|
|
1270
|
+
{
|
|
1271
|
+
style: {
|
|
1272
|
+
display: "flex",
|
|
1273
|
+
alignItems: "center",
|
|
1274
|
+
gap: "0.75rem"
|
|
1275
|
+
},
|
|
1276
|
+
children: [
|
|
1277
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1278
|
+
"button",
|
|
1279
|
+
{
|
|
1280
|
+
type: "button",
|
|
1281
|
+
onClick: () => inputRef.current?.click(),
|
|
1282
|
+
style: {
|
|
1283
|
+
padding: "0.35rem 0.75rem",
|
|
1284
|
+
borderRadius: "0.4rem",
|
|
1285
|
+
border: "1px solid rgba(255, 255, 255, 0.25)",
|
|
1286
|
+
background: "rgba(255, 255, 255, 0.08)",
|
|
1287
|
+
color: "inherit",
|
|
1288
|
+
cursor: "pointer"
|
|
1289
|
+
},
|
|
1290
|
+
children: "Choose file"
|
|
1291
|
+
}
|
|
1292
|
+
),
|
|
1293
|
+
media ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1294
|
+
"div",
|
|
1295
|
+
{
|
|
1296
|
+
style: {
|
|
1297
|
+
width: 36,
|
|
1298
|
+
height: 36,
|
|
1299
|
+
borderRadius: "0.35rem",
|
|
1300
|
+
overflow: "hidden",
|
|
1301
|
+
border: "1px solid rgba(255, 255, 255, 0.15)"
|
|
1302
|
+
},
|
|
1303
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1304
|
+
"img",
|
|
1305
|
+
{
|
|
1306
|
+
src: media.src,
|
|
1307
|
+
alt: "Thumbnail",
|
|
1308
|
+
style: {
|
|
1309
|
+
width: "100%",
|
|
1310
|
+
height: "100%",
|
|
1311
|
+
objectFit: "cover",
|
|
1312
|
+
display: "block"
|
|
1313
|
+
}
|
|
1314
|
+
}
|
|
1315
|
+
)
|
|
1316
|
+
}
|
|
1317
|
+
) : null,
|
|
1318
|
+
media ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1319
|
+
"button",
|
|
1320
|
+
{
|
|
1321
|
+
type: "button",
|
|
1322
|
+
onClick: handleClearSelection,
|
|
1323
|
+
style: {
|
|
1324
|
+
display: "flex",
|
|
1325
|
+
alignItems: "center",
|
|
1326
|
+
justifyContent: "center",
|
|
1327
|
+
padding: "0.3rem",
|
|
1328
|
+
borderRadius: "0.4rem",
|
|
1329
|
+
border: "1px solid rgba(255,255,255,0.2)",
|
|
1330
|
+
background: "transparent",
|
|
1331
|
+
color: "inherit",
|
|
1332
|
+
cursor: "pointer"
|
|
1333
|
+
},
|
|
1334
|
+
"aria-label": "Clear selection",
|
|
1335
|
+
title: "Clear selection",
|
|
1336
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react3.X, { size: 16, strokeWidth: 2 })
|
|
1337
|
+
}
|
|
1338
|
+
) : null
|
|
1339
|
+
]
|
|
1340
|
+
}
|
|
1341
|
+
),
|
|
1342
|
+
presets.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1343
|
+
"div",
|
|
1344
|
+
{
|
|
1345
|
+
style: {
|
|
1346
|
+
display: "grid",
|
|
1347
|
+
gridTemplateColumns: "repeat(2, minmax(0, 1fr))",
|
|
1348
|
+
gap: "0.5rem"
|
|
1349
|
+
},
|
|
1350
|
+
children: presets.map((entry) => {
|
|
1351
|
+
const isSelected = media?.src === entry.src && media?.type === entry.type;
|
|
1352
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
1353
|
+
"button",
|
|
1354
|
+
{
|
|
1355
|
+
type: "button",
|
|
1356
|
+
onClick: () => handlePresetSelect(entry),
|
|
1357
|
+
style: {
|
|
1358
|
+
width: "100%",
|
|
1359
|
+
borderRadius: "0.4rem",
|
|
1360
|
+
border: "1px solid rgba(255,255,255,0.25)",
|
|
1361
|
+
outline: isSelected ? "2px solid #fff" : "none",
|
|
1362
|
+
outlineOffset: 2,
|
|
1363
|
+
padding: 0,
|
|
1364
|
+
overflow: "hidden",
|
|
1365
|
+
background: "transparent",
|
|
1366
|
+
cursor: "pointer"
|
|
1367
|
+
},
|
|
1368
|
+
children: [
|
|
1369
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1370
|
+
"img",
|
|
1371
|
+
{
|
|
1372
|
+
src: entry.src,
|
|
1373
|
+
alt: entry.label,
|
|
1374
|
+
style: {
|
|
1375
|
+
width: "100%",
|
|
1376
|
+
height: 100,
|
|
1377
|
+
objectFit: "cover",
|
|
1378
|
+
display: "block"
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
),
|
|
1382
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1383
|
+
"span",
|
|
1384
|
+
{
|
|
1385
|
+
style: {
|
|
1386
|
+
display: "block",
|
|
1387
|
+
padding: "0.35rem",
|
|
1388
|
+
fontSize: "0.75rem",
|
|
1389
|
+
textAlign: "left",
|
|
1390
|
+
background: "rgba(0,0,0,0.45)"
|
|
1391
|
+
},
|
|
1392
|
+
children: entry.label
|
|
1393
|
+
}
|
|
1394
|
+
)
|
|
1395
|
+
]
|
|
1396
|
+
},
|
|
1397
|
+
`${entry.src}-${entry.type}`
|
|
1398
|
+
);
|
|
1399
|
+
})
|
|
1400
|
+
}
|
|
1401
|
+
) : null,
|
|
1402
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { style: { color: "#ff9da4", fontSize: "0.8rem" }, children: error }) : null
|
|
1403
|
+
]
|
|
1404
|
+
}
|
|
1405
|
+
);
|
|
1406
|
+
}
|
|
1407
|
+
|
|
1408
|
+
// src/components/ControlPanel.tsx
|
|
1409
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
1096
1410
|
var splitPropsString = (input) => {
|
|
1097
1411
|
const props = [];
|
|
1098
1412
|
let current = "";
|
|
@@ -1299,23 +1613,23 @@ var highlightJsx = (input) => {
|
|
|
1299
1613
|
nodes.push(token.value);
|
|
1300
1614
|
} else {
|
|
1301
1615
|
nodes.push(
|
|
1302
|
-
/* @__PURE__ */ (0,
|
|
1616
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: TOKEN_CLASS_MAP[token.type], children: token.value }, `token-${index}`)
|
|
1303
1617
|
);
|
|
1304
1618
|
}
|
|
1305
1619
|
});
|
|
1306
1620
|
return nodes;
|
|
1307
1621
|
};
|
|
1308
1622
|
var ControlPanel = () => {
|
|
1309
|
-
const [copied, setCopied] = (0,
|
|
1310
|
-
const [codeCopied, setCodeCopied] = (0,
|
|
1311
|
-
const [isCodeVisible, setIsCodeVisible] = (0,
|
|
1312
|
-
const [folderStates, setFolderStates] = (0,
|
|
1313
|
-
const codeCopyTimeoutRef = (0,
|
|
1623
|
+
const [copied, setCopied] = (0, import_react6.useState)(false);
|
|
1624
|
+
const [codeCopied, setCodeCopied] = (0, import_react6.useState)(false);
|
|
1625
|
+
const [isCodeVisible, setIsCodeVisible] = (0, import_react6.useState)(false);
|
|
1626
|
+
const [folderStates, setFolderStates] = (0, import_react6.useState)({});
|
|
1627
|
+
const codeCopyTimeoutRef = (0, import_react6.useRef)(null);
|
|
1314
1628
|
const { leftPanelWidth, isDesktop, isHydrated } = useResizableLayout();
|
|
1315
1629
|
const { schema, setValue, values, componentName, config } = useControlsContext();
|
|
1316
1630
|
const isControlsOnlyView = typeof window !== "undefined" && new URLSearchParams(window.location.search).get(CONTROLS_ONLY_PARAM) === "true";
|
|
1317
1631
|
const previewUrl = usePreviewUrl(values);
|
|
1318
|
-
const buildUrl = (0,
|
|
1632
|
+
const buildUrl = (0, import_react6.useCallback)(
|
|
1319
1633
|
(modifier) => {
|
|
1320
1634
|
if (!previewUrl) return "";
|
|
1321
1635
|
const [path, search = ""] = previewUrl.split("?");
|
|
@@ -1326,13 +1640,13 @@ var ControlPanel = () => {
|
|
|
1326
1640
|
},
|
|
1327
1641
|
[previewUrl]
|
|
1328
1642
|
);
|
|
1329
|
-
const presentationUrl = (0,
|
|
1643
|
+
const presentationUrl = (0, import_react6.useMemo)(() => {
|
|
1330
1644
|
if (!previewUrl) return "";
|
|
1331
1645
|
return buildUrl((params) => {
|
|
1332
1646
|
params.set(PRESENTATION_PARAM, "true");
|
|
1333
1647
|
});
|
|
1334
1648
|
}, [buildUrl, previewUrl]);
|
|
1335
|
-
const controlsOnlyUrl = (0,
|
|
1649
|
+
const controlsOnlyUrl = (0, import_react6.useMemo)(() => {
|
|
1336
1650
|
if (!previewUrl) return "";
|
|
1337
1651
|
return buildUrl((params) => {
|
|
1338
1652
|
params.delete(NO_CONTROLS_PARAM);
|
|
@@ -1340,7 +1654,7 @@ var ControlPanel = () => {
|
|
|
1340
1654
|
params.set(CONTROLS_ONLY_PARAM, "true");
|
|
1341
1655
|
});
|
|
1342
1656
|
}, [buildUrl, previewUrl]);
|
|
1343
|
-
const handlePresentationClick = (0,
|
|
1657
|
+
const handlePresentationClick = (0, import_react6.useCallback)(() => {
|
|
1344
1658
|
if (typeof window === "undefined" || !presentationUrl) return;
|
|
1345
1659
|
window.open(presentationUrl, "_blank", "noopener,noreferrer");
|
|
1346
1660
|
if (controlsOnlyUrl) {
|
|
@@ -1348,10 +1662,7 @@ var ControlPanel = () => {
|
|
|
1348
1662
|
const viewportHeight = window.innerHeight || 900;
|
|
1349
1663
|
const controlsWidth = Math.max(
|
|
1350
1664
|
320,
|
|
1351
|
-
Math.min(
|
|
1352
|
-
600,
|
|
1353
|
-
Math.round(viewportWidth * leftPanelWidth / 100)
|
|
1354
|
-
)
|
|
1665
|
+
Math.min(600, Math.round(viewportWidth * leftPanelWidth / 100))
|
|
1355
1666
|
);
|
|
1356
1667
|
const controlsHeight = Math.max(600, viewportHeight);
|
|
1357
1668
|
const controlsFeatures = [
|
|
@@ -1367,7 +1678,7 @@ var ControlPanel = () => {
|
|
|
1367
1678
|
window.open(controlsOnlyUrl, "v0-controls", controlsFeatures);
|
|
1368
1679
|
}
|
|
1369
1680
|
}, [controlsOnlyUrl, leftPanelWidth, presentationUrl]);
|
|
1370
|
-
const
|
|
1681
|
+
const jsx15 = (0, import_react6.useMemo)(() => {
|
|
1371
1682
|
if (!componentName) return "";
|
|
1372
1683
|
const props = Object.entries(values).map(([key, val]) => {
|
|
1373
1684
|
if (typeof val === "string") return `${key}="${val}"`;
|
|
@@ -1412,7 +1723,7 @@ var ControlPanel = () => {
|
|
|
1412
1723
|
const advancedConfig = config?.addAdvancedPaletteControl;
|
|
1413
1724
|
let advancedPaletteControlNode = null;
|
|
1414
1725
|
if (advancedConfig) {
|
|
1415
|
-
const advancedNode = /* @__PURE__ */ (0,
|
|
1726
|
+
const advancedNode = /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1416
1727
|
AdvancedPaletteControl_default,
|
|
1417
1728
|
{
|
|
1418
1729
|
config: advancedConfig
|
|
@@ -1438,12 +1749,52 @@ var ControlPanel = () => {
|
|
|
1438
1749
|
advancedPaletteControlNode = advancedNode;
|
|
1439
1750
|
}
|
|
1440
1751
|
}
|
|
1441
|
-
const
|
|
1442
|
-
|
|
1443
|
-
)
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1752
|
+
const mediaUploadConfig = config?.addMediaUploadControl;
|
|
1753
|
+
let mediaUploadControlNode = null;
|
|
1754
|
+
if (mediaUploadConfig) {
|
|
1755
|
+
const mediaUploadNode = /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1756
|
+
MediaUploadControl,
|
|
1757
|
+
{
|
|
1758
|
+
onSelectMedia: (media) => {
|
|
1759
|
+
mediaUploadConfig.onSelectMedia?.(media);
|
|
1760
|
+
},
|
|
1761
|
+
onClear: () => {
|
|
1762
|
+
mediaUploadConfig.onClear?.();
|
|
1763
|
+
},
|
|
1764
|
+
presetMedia: mediaUploadConfig.presetMedia,
|
|
1765
|
+
maxPresetCount: mediaUploadConfig.maxPresetCount
|
|
1766
|
+
},
|
|
1767
|
+
"mediaUploadControl"
|
|
1768
|
+
);
|
|
1769
|
+
const mediaFolder = mediaUploadConfig.folder?.trim();
|
|
1770
|
+
if (mediaFolder) {
|
|
1771
|
+
const placement = mediaUploadConfig.folderPlacement ?? "bottom";
|
|
1772
|
+
ensureFolder(mediaFolder);
|
|
1773
|
+
if (!folderControls.has(mediaFolder)) {
|
|
1774
|
+
folderControls.set(mediaFolder, []);
|
|
1775
|
+
}
|
|
1776
|
+
const existingPlacement = folderPlacement.get(mediaFolder);
|
|
1777
|
+
if (!existingPlacement || placement === "top") {
|
|
1778
|
+
folderPlacement.set(mediaFolder, placement);
|
|
1779
|
+
}
|
|
1780
|
+
if (!folderExtras.has(mediaFolder)) {
|
|
1781
|
+
folderExtras.set(mediaFolder, []);
|
|
1782
|
+
}
|
|
1783
|
+
folderExtras.get(mediaFolder).push(mediaUploadNode);
|
|
1784
|
+
} else {
|
|
1785
|
+
mediaUploadControlNode = mediaUploadNode;
|
|
1786
|
+
}
|
|
1787
|
+
}
|
|
1788
|
+
const rootButtonControls = [];
|
|
1789
|
+
const rootNormalControls = [];
|
|
1790
|
+
rootControls.forEach((entry) => {
|
|
1791
|
+
const [key, control] = entry;
|
|
1792
|
+
if (control.type === "button") {
|
|
1793
|
+
rootButtonControls.push([key, control]);
|
|
1794
|
+
} else {
|
|
1795
|
+
rootNormalControls.push(entry);
|
|
1796
|
+
}
|
|
1797
|
+
});
|
|
1447
1798
|
const folderGroups = folderOrder.map((folder) => ({
|
|
1448
1799
|
folder,
|
|
1449
1800
|
entries: folderControls.get(folder) ?? [],
|
|
@@ -1452,7 +1803,7 @@ var ControlPanel = () => {
|
|
|
1452
1803
|
})).filter((group) => group.entries.length > 0 || group.extras.length > 0);
|
|
1453
1804
|
const hasRootButtonControls = rootButtonControls.length > 0;
|
|
1454
1805
|
const hasAnyFolders = folderGroups.length > 0;
|
|
1455
|
-
const jsonToComponentString = (0,
|
|
1806
|
+
const jsonToComponentString = (0, import_react6.useCallback)(
|
|
1456
1807
|
({
|
|
1457
1808
|
componentName: componentNameOverride,
|
|
1458
1809
|
props
|
|
@@ -1483,40 +1834,40 @@ var ControlPanel = () => {
|
|
|
1483
1834
|
componentName,
|
|
1484
1835
|
values,
|
|
1485
1836
|
schema,
|
|
1486
|
-
jsx:
|
|
1837
|
+
jsx: jsx15,
|
|
1487
1838
|
jsonToComponentString
|
|
1488
|
-
}) ??
|
|
1839
|
+
}) ?? jsx15;
|
|
1489
1840
|
const shouldShowCopyButton = config?.showCopyButton !== false && Boolean(copyText);
|
|
1490
|
-
const baseSnippet = copyText ||
|
|
1491
|
-
const formattedCode = (0,
|
|
1841
|
+
const baseSnippet = copyText || jsx15;
|
|
1842
|
+
const formattedCode = (0, import_react6.useMemo)(
|
|
1492
1843
|
() => formatJsxCodeSnippet(baseSnippet),
|
|
1493
1844
|
[baseSnippet]
|
|
1494
1845
|
);
|
|
1495
1846
|
const hasCodeSnippet = Boolean(config?.showCodeSnippet && formattedCode);
|
|
1496
|
-
const highlightedCode = (0,
|
|
1847
|
+
const highlightedCode = (0, import_react6.useMemo)(
|
|
1497
1848
|
() => formattedCode ? highlightJsx(formattedCode) : null,
|
|
1498
1849
|
[formattedCode]
|
|
1499
1850
|
);
|
|
1500
|
-
(0,
|
|
1851
|
+
(0, import_react6.useEffect)(() => {
|
|
1501
1852
|
if (!hasCodeSnippet) {
|
|
1502
1853
|
setIsCodeVisible(false);
|
|
1503
1854
|
}
|
|
1504
1855
|
}, [hasCodeSnippet]);
|
|
1505
|
-
(0,
|
|
1856
|
+
(0, import_react6.useEffect)(() => {
|
|
1506
1857
|
setCodeCopied(false);
|
|
1507
1858
|
if (codeCopyTimeoutRef.current) {
|
|
1508
1859
|
clearTimeout(codeCopyTimeoutRef.current);
|
|
1509
1860
|
codeCopyTimeoutRef.current = null;
|
|
1510
1861
|
}
|
|
1511
1862
|
}, [formattedCode]);
|
|
1512
|
-
(0,
|
|
1863
|
+
(0, import_react6.useEffect)(() => {
|
|
1513
1864
|
return () => {
|
|
1514
1865
|
if (codeCopyTimeoutRef.current) {
|
|
1515
1866
|
clearTimeout(codeCopyTimeoutRef.current);
|
|
1516
1867
|
}
|
|
1517
1868
|
};
|
|
1518
1869
|
}, []);
|
|
1519
|
-
const handleToggleCodeVisibility = (0,
|
|
1870
|
+
const handleToggleCodeVisibility = (0, import_react6.useCallback)(() => {
|
|
1520
1871
|
setIsCodeVisible((prev) => {
|
|
1521
1872
|
const next = !prev;
|
|
1522
1873
|
if (!next) {
|
|
@@ -1529,7 +1880,7 @@ var ControlPanel = () => {
|
|
|
1529
1880
|
return next;
|
|
1530
1881
|
});
|
|
1531
1882
|
}, []);
|
|
1532
|
-
const handleCodeCopy = (0,
|
|
1883
|
+
const handleCodeCopy = (0, import_react6.useCallback)(() => {
|
|
1533
1884
|
if (!formattedCode) return;
|
|
1534
1885
|
if (typeof navigator === "undefined" || !navigator.clipboard || typeof navigator.clipboard.writeText !== "function") {
|
|
1535
1886
|
return;
|
|
@@ -1547,11 +1898,11 @@ var ControlPanel = () => {
|
|
|
1547
1898
|
});
|
|
1548
1899
|
}, [formattedCode]);
|
|
1549
1900
|
const labelize = (key) => key.replace(/([A-Z])/g, " $1").replace(/[\-_]/g, " ").replace(/\s+/g, " ").trim().replace(/(^|\s)\S/g, (s) => s.toUpperCase());
|
|
1550
|
-
const renderButtonControl = (key, control, variant) => /* @__PURE__ */ (0,
|
|
1901
|
+
const renderButtonControl = (key, control, variant) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1551
1902
|
"div",
|
|
1552
1903
|
{
|
|
1553
1904
|
className: variant === "root" ? "flex-1 [&_[data-slot=button]]:w-full" : "[&_[data-slot=button]]:w-full",
|
|
1554
|
-
children: control.render ? control.render() : /* @__PURE__ */ (0,
|
|
1905
|
+
children: control.render ? control.render() : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1555
1906
|
"button",
|
|
1556
1907
|
{
|
|
1557
1908
|
onClick: control.onClick,
|
|
@@ -1569,9 +1920,9 @@ var ControlPanel = () => {
|
|
|
1569
1920
|
const value = values[key];
|
|
1570
1921
|
switch (control.type) {
|
|
1571
1922
|
case "boolean":
|
|
1572
|
-
return /* @__PURE__ */ (0,
|
|
1573
|
-
/* @__PURE__ */ (0,
|
|
1574
|
-
/* @__PURE__ */ (0,
|
|
1923
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
1924
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Label, { htmlFor: key, className: "cursor-pointer", children: labelize(key) }),
|
|
1925
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1575
1926
|
Switch,
|
|
1576
1927
|
{
|
|
1577
1928
|
id: key,
|
|
@@ -1582,10 +1933,10 @@ var ControlPanel = () => {
|
|
|
1582
1933
|
)
|
|
1583
1934
|
] }, key);
|
|
1584
1935
|
case "number":
|
|
1585
|
-
return /* @__PURE__ */ (0,
|
|
1586
|
-
/* @__PURE__ */ (0,
|
|
1587
|
-
/* @__PURE__ */ (0,
|
|
1588
|
-
/* @__PURE__ */ (0,
|
|
1936
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "space-y-3 w-full", children: [
|
|
1937
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
1938
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Label, { className: "text-stone-300", htmlFor: key, children: labelize(key) }),
|
|
1939
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1589
1940
|
Input,
|
|
1590
1941
|
{
|
|
1591
1942
|
type: "number",
|
|
@@ -1602,7 +1953,7 @@ var ControlPanel = () => {
|
|
|
1602
1953
|
}
|
|
1603
1954
|
)
|
|
1604
1955
|
] }),
|
|
1605
|
-
/* @__PURE__ */ (0,
|
|
1956
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1606
1957
|
Slider,
|
|
1607
1958
|
{
|
|
1608
1959
|
id: key,
|
|
@@ -1616,9 +1967,9 @@ var ControlPanel = () => {
|
|
|
1616
1967
|
)
|
|
1617
1968
|
] }, key);
|
|
1618
1969
|
case "string":
|
|
1619
|
-
return /* @__PURE__ */ (0,
|
|
1620
|
-
/* @__PURE__ */ (0,
|
|
1621
|
-
/* @__PURE__ */ (0,
|
|
1970
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "space-y-2 w-full", children: [
|
|
1971
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Label, { className: "text-stone-300", htmlFor: key, children: labelize(key) }),
|
|
1972
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1622
1973
|
Input,
|
|
1623
1974
|
{
|
|
1624
1975
|
id: key,
|
|
@@ -1630,9 +1981,9 @@ var ControlPanel = () => {
|
|
|
1630
1981
|
)
|
|
1631
1982
|
] }, key);
|
|
1632
1983
|
case "color":
|
|
1633
|
-
return /* @__PURE__ */ (0,
|
|
1634
|
-
/* @__PURE__ */ (0,
|
|
1635
|
-
/* @__PURE__ */ (0,
|
|
1984
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "space-y-2 w-full", children: [
|
|
1985
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Label, { className: "text-stone-300", htmlFor: key, children: labelize(key) }),
|
|
1986
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1636
1987
|
"input",
|
|
1637
1988
|
{
|
|
1638
1989
|
type: "color",
|
|
@@ -1644,11 +1995,11 @@ var ControlPanel = () => {
|
|
|
1644
1995
|
)
|
|
1645
1996
|
] }, key);
|
|
1646
1997
|
case "select":
|
|
1647
|
-
return /* @__PURE__ */ (0,
|
|
1648
|
-
/* @__PURE__ */ (0,
|
|
1649
|
-
/* @__PURE__ */ (0,
|
|
1650
|
-
/* @__PURE__ */ (0,
|
|
1651
|
-
/* @__PURE__ */ (0,
|
|
1998
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "space-y-2", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-3", children: [
|
|
1999
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Label, { className: "min-w-fit", htmlFor: key, children: labelize(key) }),
|
|
2000
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Select, { value, onValueChange: (val) => setValue(key, val), children: [
|
|
2001
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SelectTrigger, { className: "flex-1 cursor-pointer", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SelectValue, { placeholder: "Select option" }) }),
|
|
2002
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SelectContent, { className: "cursor-pointer z-[9999]", children: Object.entries(control.options).map(([label]) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1652
2003
|
SelectItem,
|
|
1653
2004
|
{
|
|
1654
2005
|
value: label,
|
|
@@ -1665,12 +2016,12 @@ var ControlPanel = () => {
|
|
|
1665
2016
|
};
|
|
1666
2017
|
const renderFolder = (folder, entries, extras = []) => {
|
|
1667
2018
|
const isOpen = folderStates[folder] ?? true;
|
|
1668
|
-
return /* @__PURE__ */ (0,
|
|
2019
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
1669
2020
|
"div",
|
|
1670
2021
|
{
|
|
1671
2022
|
className: "border border-stone-700/60 rounded-lg bg-stone-900/70",
|
|
1672
2023
|
children: [
|
|
1673
|
-
/* @__PURE__ */ (0,
|
|
2024
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
1674
2025
|
"button",
|
|
1675
2026
|
{
|
|
1676
2027
|
type: "button",
|
|
@@ -1680,9 +2031,9 @@ var ControlPanel = () => {
|
|
|
1680
2031
|
})),
|
|
1681
2032
|
className: "w-full flex items-center justify-between px-4 py-3 text-left font-semibold text-stone-200 tracking-wide",
|
|
1682
2033
|
children: [
|
|
1683
|
-
/* @__PURE__ */ (0,
|
|
1684
|
-
/* @__PURE__ */ (0,
|
|
1685
|
-
|
|
2034
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: folder }),
|
|
2035
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2036
|
+
import_lucide_react4.ChevronDown,
|
|
1686
2037
|
{
|
|
1687
2038
|
className: `w-4 h-4 transition-transform duration-200 ${isOpen ? "rotate-180" : ""}`
|
|
1688
2039
|
}
|
|
@@ -1690,7 +2041,7 @@ var ControlPanel = () => {
|
|
|
1690
2041
|
]
|
|
1691
2042
|
}
|
|
1692
2043
|
),
|
|
1693
|
-
isOpen && /* @__PURE__ */ (0,
|
|
2044
|
+
isOpen && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "px-4 pb-4 pt-0 space-y-5", children: [
|
|
1694
2045
|
entries.map(
|
|
1695
2046
|
([key, control]) => renderControl(key, control, "folder")
|
|
1696
2047
|
),
|
|
@@ -1729,27 +2080,28 @@ var ControlPanel = () => {
|
|
|
1729
2080
|
});
|
|
1730
2081
|
}
|
|
1731
2082
|
}
|
|
1732
|
-
return /* @__PURE__ */ (0,
|
|
2083
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1733
2084
|
"div",
|
|
1734
2085
|
{
|
|
1735
2086
|
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"}`,
|
|
1736
2087
|
onPointerDown: (e) => e.stopPropagation(),
|
|
1737
2088
|
onTouchStart: (e) => e.stopPropagation(),
|
|
1738
2089
|
style: panelStyle,
|
|
1739
|
-
children: /* @__PURE__ */ (0,
|
|
1740
|
-
/* @__PURE__ */ (0,
|
|
1741
|
-
/* @__PURE__ */ (0,
|
|
2090
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("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: [
|
|
2091
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "space-y-1", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h1", { className: "text-lg text-stone-100 font-semibold", children: config?.mainLabel ?? "Controls" }) }),
|
|
2092
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "space-y-6", children: [
|
|
1742
2093
|
topFolderSections,
|
|
1743
|
-
hasRootButtonControls && /* @__PURE__ */ (0,
|
|
2094
|
+
hasRootButtonControls && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "flex flex-wrap gap-2", children: rootButtonControls.map(
|
|
1744
2095
|
([key, control]) => renderButtonControl(key, control, "root")
|
|
1745
2096
|
) }),
|
|
1746
2097
|
advancedPaletteControlNode,
|
|
2098
|
+
mediaUploadControlNode,
|
|
1747
2099
|
rootNormalControls.map(
|
|
1748
2100
|
([key, control]) => renderControl(key, control, "root")
|
|
1749
2101
|
),
|
|
1750
2102
|
bottomFolderSections,
|
|
1751
|
-
hasCodeSnippet && /* @__PURE__ */ (0,
|
|
1752
|
-
/* @__PURE__ */ (0,
|
|
2103
|
+
hasCodeSnippet && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "border border-stone-700/60 rounded-lg bg-stone-900/70", children: [
|
|
2104
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
1753
2105
|
"button",
|
|
1754
2106
|
{
|
|
1755
2107
|
type: "button",
|
|
@@ -1757,9 +2109,9 @@ var ControlPanel = () => {
|
|
|
1757
2109
|
className: "w-full flex items-center justify-between px-4 py-3 text-left font-semibold text-stone-200 tracking-wide",
|
|
1758
2110
|
"aria-expanded": isCodeVisible,
|
|
1759
2111
|
children: [
|
|
1760
|
-
/* @__PURE__ */ (0,
|
|
1761
|
-
/* @__PURE__ */ (0,
|
|
1762
|
-
|
|
2112
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: isCodeVisible ? "Hide Code" : "Show Code" }),
|
|
2113
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2114
|
+
import_lucide_react4.ChevronDown,
|
|
1763
2115
|
{
|
|
1764
2116
|
className: `w-4 h-4 transition-transform duration-200 ${isCodeVisible ? "rotate-180" : ""}`
|
|
1765
2117
|
}
|
|
@@ -1767,26 +2119,26 @@ var ControlPanel = () => {
|
|
|
1767
2119
|
]
|
|
1768
2120
|
}
|
|
1769
2121
|
),
|
|
1770
|
-
isCodeVisible && /* @__PURE__ */ (0,
|
|
1771
|
-
/* @__PURE__ */ (0,
|
|
2122
|
+
isCodeVisible && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "relative border-t border-stone-700/60 bg-stone-950/60 px-4 py-4 rounded-b-lg", children: [
|
|
2123
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1772
2124
|
"button",
|
|
1773
2125
|
{
|
|
1774
2126
|
type: "button",
|
|
1775
2127
|
onClick: handleCodeCopy,
|
|
1776
2128
|
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",
|
|
1777
|
-
children: codeCopied ? /* @__PURE__ */ (0,
|
|
1778
|
-
/* @__PURE__ */ (0,
|
|
2129
|
+
children: codeCopied ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
2130
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react4.Check, { className: "h-3.5 w-3.5" }),
|
|
1779
2131
|
"Copied"
|
|
1780
|
-
] }) : /* @__PURE__ */ (0,
|
|
1781
|
-
/* @__PURE__ */ (0,
|
|
2132
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
2133
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react4.Copy, { className: "h-3.5 w-3.5" }),
|
|
1782
2134
|
"Copy"
|
|
1783
2135
|
] })
|
|
1784
2136
|
}
|
|
1785
2137
|
),
|
|
1786
|
-
/* @__PURE__ */ (0,
|
|
2138
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("pre", { className: "whitespace-pre overflow-x-auto text-xs md:text-sm text-stone-200 pr-14", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("code", { className: "block text-stone-200", children: highlightedCode ?? formattedCode }) })
|
|
1787
2139
|
] })
|
|
1788
2140
|
] }),
|
|
1789
|
-
shouldShowCopyButton && /* @__PURE__ */ (0,
|
|
2141
|
+
shouldShowCopyButton && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "flex-1 pt-4", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1790
2142
|
"button",
|
|
1791
2143
|
{
|
|
1792
2144
|
onClick: () => {
|
|
@@ -1797,18 +2149,18 @@ var ControlPanel = () => {
|
|
|
1797
2149
|
setTimeout(() => setCopied(false), 5e3);
|
|
1798
2150
|
},
|
|
1799
2151
|
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",
|
|
1800
|
-
children: copied ? /* @__PURE__ */ (0,
|
|
1801
|
-
/* @__PURE__ */ (0,
|
|
2152
|
+
children: copied ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
2153
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react4.Check, { className: "w-4 h-4" }),
|
|
1802
2154
|
"Copied"
|
|
1803
|
-
] }) : /* @__PURE__ */ (0,
|
|
1804
|
-
/* @__PURE__ */ (0,
|
|
2155
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
2156
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react4.Copy, { className: "w-4 h-4" }),
|
|
1805
2157
|
"Copy to Clipboard"
|
|
1806
2158
|
] })
|
|
1807
2159
|
}
|
|
1808
2160
|
) }, "control-panel-jsx")
|
|
1809
2161
|
] }),
|
|
1810
|
-
previewUrl && /* @__PURE__ */ (0,
|
|
1811
|
-
/* @__PURE__ */ (0,
|
|
2162
|
+
previewUrl && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col gap-2", children: [
|
|
2163
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Button, { asChild: true, className: "w-full", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
1812
2164
|
"a",
|
|
1813
2165
|
{
|
|
1814
2166
|
href: previewUrl,
|
|
@@ -1816,12 +2168,12 @@ var ControlPanel = () => {
|
|
|
1816
2168
|
rel: "noopener noreferrer",
|
|
1817
2169
|
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",
|
|
1818
2170
|
children: [
|
|
1819
|
-
/* @__PURE__ */ (0,
|
|
2171
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react4.SquareArrowOutUpRight, {}),
|
|
1820
2172
|
" Open in a New Tab"
|
|
1821
2173
|
]
|
|
1822
2174
|
}
|
|
1823
2175
|
) }),
|
|
1824
|
-
config?.showPresentationButton && presentationUrl && /* @__PURE__ */ (0,
|
|
2176
|
+
config?.showPresentationButton && presentationUrl && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
1825
2177
|
Button,
|
|
1826
2178
|
{
|
|
1827
2179
|
type: "button",
|
|
@@ -1829,7 +2181,7 @@ var ControlPanel = () => {
|
|
|
1829
2181
|
variant: "secondary",
|
|
1830
2182
|
className: "w-full bg-stone-800 text-white hover:bg-stone-700 border border-stone-700",
|
|
1831
2183
|
children: [
|
|
1832
|
-
/* @__PURE__ */ (0,
|
|
2184
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react4.Presentation, {}),
|
|
1833
2185
|
" Presentation Mode"
|
|
1834
2186
|
]
|
|
1835
2187
|
}
|
|
@@ -1841,16 +2193,16 @@ var ControlPanel = () => {
|
|
|
1841
2193
|
};
|
|
1842
2194
|
var ControlPanel_default = ControlPanel;
|
|
1843
2195
|
|
|
1844
|
-
// src/components/PreviewContainer
|
|
1845
|
-
var
|
|
2196
|
+
// src/components/PreviewContainer.tsx
|
|
2197
|
+
var import_react7 = require("react");
|
|
1846
2198
|
|
|
1847
|
-
// src/components/Grid
|
|
1848
|
-
var
|
|
2199
|
+
// src/components/Grid.tsx
|
|
2200
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
1849
2201
|
function Grid() {
|
|
1850
|
-
return /* @__PURE__ */ (0,
|
|
2202
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1851
2203
|
"div",
|
|
1852
2204
|
{
|
|
1853
|
-
className: "absolute inset-0 w-
|
|
2205
|
+
className: "absolute inset-0 w-full h-full z-[0] blur-[1px]",
|
|
1854
2206
|
style: {
|
|
1855
2207
|
backgroundImage: `
|
|
1856
2208
|
linear-gradient(to right,rgb(13, 13, 13) 1px, transparent 1px),
|
|
@@ -1864,40 +2216,40 @@ function Grid() {
|
|
|
1864
2216
|
}
|
|
1865
2217
|
var Grid_default = Grid;
|
|
1866
2218
|
|
|
1867
|
-
// src/components/PreviewContainer
|
|
1868
|
-
var
|
|
2219
|
+
// src/components/PreviewContainer.tsx
|
|
2220
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
1869
2221
|
var PreviewContainer = ({ children, hideControls }) => {
|
|
1870
2222
|
const { config } = useControlsContext();
|
|
1871
2223
|
const { leftPanelWidth, isDesktop, isHydrated, containerRef } = useResizableLayout();
|
|
1872
|
-
const previewRef = (0,
|
|
1873
|
-
return /* @__PURE__ */ (0,
|
|
2224
|
+
const previewRef = (0, import_react7.useRef)(null);
|
|
2225
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1874
2226
|
"div",
|
|
1875
2227
|
{
|
|
1876
2228
|
ref: previewRef,
|
|
1877
|
-
className: "order-1 md:order-2 flex-1 bg-black overflow-auto flex items-center justify-center relative",
|
|
2229
|
+
className: "order-1 md:order-2 flex-1 md:flex-none bg-black overflow-auto flex items-center justify-center relative",
|
|
1878
2230
|
style: isHydrated && isDesktop && !hideControls ? {
|
|
1879
2231
|
width: `${100 - leftPanelWidth}%`,
|
|
1880
2232
|
marginLeft: `${leftPanelWidth}%`
|
|
1881
2233
|
} : {},
|
|
1882
|
-
children: /* @__PURE__ */ (0,
|
|
1883
|
-
config?.showGrid && /* @__PURE__ */ (0,
|
|
1884
|
-
/* @__PURE__ */ (0,
|
|
2234
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "w-full h-screen", children: [
|
|
2235
|
+
config?.showGrid && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Grid_default, {}),
|
|
2236
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "w-full h-full flex items-center justify-center relative", children })
|
|
1885
2237
|
] })
|
|
1886
2238
|
}
|
|
1887
2239
|
);
|
|
1888
2240
|
};
|
|
1889
2241
|
var PreviewContainer_default = PreviewContainer;
|
|
1890
2242
|
|
|
1891
|
-
// src/components/Playground
|
|
1892
|
-
var
|
|
1893
|
-
var HiddenPreview = ({ children }) => /* @__PURE__ */ (0,
|
|
2243
|
+
// src/components/Playground.tsx
|
|
2244
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
2245
|
+
var HiddenPreview = ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { "aria-hidden": "true", className: "hidden", children });
|
|
1894
2246
|
function Playground({ children }) {
|
|
1895
|
-
const [isHydrated, setIsHydrated] = (0,
|
|
1896
|
-
const [copied, setCopied] = (0,
|
|
1897
|
-
(0,
|
|
2247
|
+
const [isHydrated, setIsHydrated] = (0, import_react8.useState)(false);
|
|
2248
|
+
const [copied, setCopied] = (0, import_react8.useState)(false);
|
|
2249
|
+
(0, import_react8.useEffect)(() => {
|
|
1898
2250
|
setIsHydrated(true);
|
|
1899
2251
|
}, []);
|
|
1900
|
-
const { showControls, isPresentationMode, isControlsOnly } = (0,
|
|
2252
|
+
const { showControls, isPresentationMode, isControlsOnly } = (0, import_react8.useMemo)(() => {
|
|
1901
2253
|
if (typeof window === "undefined") {
|
|
1902
2254
|
return {
|
|
1903
2255
|
showControls: true,
|
|
@@ -1924,54 +2276,54 @@ function Playground({ children }) {
|
|
|
1924
2276
|
setTimeout(() => setCopied(false), 2e3);
|
|
1925
2277
|
};
|
|
1926
2278
|
if (!isHydrated) return null;
|
|
1927
|
-
return /* @__PURE__ */ (0,
|
|
1928
|
-
shouldShowShareButton && /* @__PURE__ */ (0,
|
|
2279
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ResizableLayout, { hideControls: layoutHideControls, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(ControlsProvider, { children: [
|
|
2280
|
+
shouldShowShareButton && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
1929
2281
|
"button",
|
|
1930
2282
|
{
|
|
1931
2283
|
onClick: handleCopy,
|
|
1932
2284
|
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",
|
|
1933
2285
|
children: [
|
|
1934
|
-
copied ? /* @__PURE__ */ (0,
|
|
2286
|
+
copied ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react5.Check, { size: 16 }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react5.Copy, { size: 16 }),
|
|
1935
2287
|
copied ? "Copied!" : "Share"
|
|
1936
2288
|
]
|
|
1937
2289
|
}
|
|
1938
2290
|
),
|
|
1939
|
-
isControlsOnly ? /* @__PURE__ */ (0,
|
|
1940
|
-
showControls && /* @__PURE__ */ (0,
|
|
2291
|
+
isControlsOnly ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(HiddenPreview, { children }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(PreviewContainer_default, { hideControls: layoutHideControls, children }),
|
|
2292
|
+
showControls && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ControlPanel_default, {})
|
|
1941
2293
|
] }) });
|
|
1942
2294
|
}
|
|
1943
2295
|
|
|
1944
2296
|
// src/hooks/useAdvancedPaletteControls.ts
|
|
1945
|
-
var
|
|
2297
|
+
var import_react9 = require("react");
|
|
1946
2298
|
var cloneForCallbacks = (palette) => clonePalette(palette);
|
|
1947
2299
|
var useAdvancedPaletteControls = (options = {}) => {
|
|
1948
|
-
const resolvedDefaultPalette = (0,
|
|
2300
|
+
const resolvedDefaultPalette = (0, import_react9.useMemo)(
|
|
1949
2301
|
() => createAdvancedPalette(options.defaultPalette),
|
|
1950
2302
|
[options.defaultPalette]
|
|
1951
2303
|
);
|
|
1952
|
-
const resolvedFallbackPalette = (0,
|
|
2304
|
+
const resolvedFallbackPalette = (0, import_react9.useMemo)(
|
|
1953
2305
|
() => options.fallbackPalette ? createAdvancedPalette(options.fallbackPalette) : resolvedDefaultPalette,
|
|
1954
2306
|
[options.fallbackPalette, resolvedDefaultPalette]
|
|
1955
2307
|
);
|
|
1956
|
-
const [palette, setPaletteState] = (0,
|
|
2308
|
+
const [palette, setPaletteState] = (0, import_react9.useState)(
|
|
1957
2309
|
() => clonePalette(resolvedDefaultPalette)
|
|
1958
2310
|
);
|
|
1959
|
-
const defaultSignatureRef = (0,
|
|
2311
|
+
const defaultSignatureRef = (0, import_react9.useRef)(
|
|
1960
2312
|
createPaletteSignature(resolvedDefaultPalette)
|
|
1961
2313
|
);
|
|
1962
|
-
(0,
|
|
2314
|
+
(0, import_react9.useEffect)(() => {
|
|
1963
2315
|
const nextSignature = createPaletteSignature(resolvedDefaultPalette);
|
|
1964
2316
|
if (defaultSignatureRef.current === nextSignature) return;
|
|
1965
2317
|
defaultSignatureRef.current = nextSignature;
|
|
1966
2318
|
setPaletteState(clonePalette(resolvedDefaultPalette));
|
|
1967
2319
|
}, [resolvedDefaultPalette]);
|
|
1968
|
-
const notifyChange = (0,
|
|
2320
|
+
const notifyChange = (0, import_react9.useCallback)(
|
|
1969
2321
|
(nextPalette) => {
|
|
1970
2322
|
options.onChange?.(cloneForCallbacks(nextPalette));
|
|
1971
2323
|
},
|
|
1972
2324
|
[options.onChange]
|
|
1973
2325
|
);
|
|
1974
|
-
const setPalette = (0,
|
|
2326
|
+
const setPalette = (0, import_react9.useCallback)(
|
|
1975
2327
|
(source) => {
|
|
1976
2328
|
const nextPalette = createAdvancedPalette(
|
|
1977
2329
|
source ?? resolvedDefaultPalette
|
|
@@ -1981,7 +2333,7 @@ var useAdvancedPaletteControls = (options = {}) => {
|
|
|
1981
2333
|
},
|
|
1982
2334
|
[notifyChange, resolvedDefaultPalette]
|
|
1983
2335
|
);
|
|
1984
|
-
const updatePalette = (0,
|
|
2336
|
+
const updatePalette = (0, import_react9.useCallback)(
|
|
1985
2337
|
(updater) => {
|
|
1986
2338
|
setPaletteState((current) => {
|
|
1987
2339
|
const nextSource = updater(clonePalette(current));
|
|
@@ -1994,18 +2346,18 @@ var useAdvancedPaletteControls = (options = {}) => {
|
|
|
1994
2346
|
},
|
|
1995
2347
|
[notifyChange, resolvedDefaultPalette]
|
|
1996
2348
|
);
|
|
1997
|
-
const resetPalette = (0,
|
|
2349
|
+
const resetPalette = (0, import_react9.useCallback)(() => {
|
|
1998
2350
|
setPaletteState(clonePalette(resolvedDefaultPalette));
|
|
1999
2351
|
notifyChange(resolvedDefaultPalette);
|
|
2000
2352
|
}, [notifyChange, resolvedDefaultPalette]);
|
|
2001
|
-
const handleControlPaletteChange = (0,
|
|
2353
|
+
const handleControlPaletteChange = (0, import_react9.useCallback)(
|
|
2002
2354
|
(nextPalette) => {
|
|
2003
2355
|
setPaletteState(clonePalette(nextPalette));
|
|
2004
2356
|
notifyChange(nextPalette);
|
|
2005
2357
|
},
|
|
2006
2358
|
[notifyChange]
|
|
2007
2359
|
);
|
|
2008
|
-
const controlConfig = (0,
|
|
2360
|
+
const controlConfig = (0, import_react9.useMemo)(
|
|
2009
2361
|
() => ({
|
|
2010
2362
|
...options.control ?? {},
|
|
2011
2363
|
defaultPalette: resolvedDefaultPalette,
|
|
@@ -2013,7 +2365,7 @@ var useAdvancedPaletteControls = (options = {}) => {
|
|
|
2013
2365
|
}),
|
|
2014
2366
|
[handleControlPaletteChange, options.control, resolvedDefaultPalette]
|
|
2015
2367
|
);
|
|
2016
|
-
const hexColors = (0,
|
|
2368
|
+
const hexColors = (0, import_react9.useMemo)(
|
|
2017
2369
|
() => advancedPaletteToHexColors(palette, {
|
|
2018
2370
|
sectionOrder: options.sectionOrder,
|
|
2019
2371
|
fallbackPalette: resolvedFallbackPalette,
|
|
@@ -2026,11 +2378,11 @@ var useAdvancedPaletteControls = (options = {}) => {
|
|
|
2026
2378
|
resolvedFallbackPalette
|
|
2027
2379
|
]
|
|
2028
2380
|
);
|
|
2029
|
-
const paletteSignature = (0,
|
|
2381
|
+
const paletteSignature = (0, import_react9.useMemo)(
|
|
2030
2382
|
() => createPaletteSignature(palette),
|
|
2031
2383
|
[palette]
|
|
2032
2384
|
);
|
|
2033
|
-
const paletteGradient = (0,
|
|
2385
|
+
const paletteGradient = (0, import_react9.useMemo)(
|
|
2034
2386
|
() => computePaletteGradient(palette, options.gradientSteps),
|
|
2035
2387
|
[options.gradientSteps, palette]
|
|
2036
2388
|
);
|