@jbpark/live-editor 2.1.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.ko.md +101 -17
- package/README.md +101 -17
- package/dist/dnd/index.d.ts +2 -2
- package/dist/dnd/index.js +2 -2
- package/dist/{dnd-C1YGcp4k.js → dnd-DRivgZdt.js} +370 -324
- package/dist/dnd-DRivgZdt.js.map +1 -0
- package/dist/{index-9bvWkK07.d.ts → index-DYm4nsej.d.ts} +62 -8
- package/dist/index.d.ts +3 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/dnd-C1YGcp4k.js.map +0 -1
|
@@ -166,37 +166,141 @@ const Overlay = ({ sections, renderProps }) => {
|
|
|
166
166
|
return null;
|
|
167
167
|
};
|
|
168
168
|
//#endregion
|
|
169
|
-
//#region src/components/dnd/panel/
|
|
169
|
+
//#region src/components/dnd/panel/use-items-editor.ts
|
|
170
170
|
var import_lib = /* @__PURE__ */ __toESM(require_lib(), 1);
|
|
171
|
-
const
|
|
172
|
-
const
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
const
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
171
|
+
const resolveLeaf = (render, key) => {
|
|
172
|
+
const leaf = render?.[key];
|
|
173
|
+
return leaf && "type" in leaf ? leaf : null;
|
|
174
|
+
};
|
|
175
|
+
const resolveMap = (render, key) => {
|
|
176
|
+
const leaf = render?.[key];
|
|
177
|
+
return leaf && !("type" in leaf) ? leaf : void 0;
|
|
178
|
+
};
|
|
179
|
+
const bindingsInJSX = (node) => {
|
|
180
|
+
const nodes = extract(generateCode(node));
|
|
181
|
+
const container = nodes.find((n) => n.bindings?.some((b) => b.property === "children"));
|
|
182
|
+
if (container) return [container];
|
|
183
|
+
const bindings = [];
|
|
184
|
+
nodes.forEach((n) => {
|
|
185
|
+
if (n.bindings && n.bindings.length > 0 && n.dataAttributes.some((a) => a.name === "data-id")) bindings.push(n);
|
|
186
|
+
bindings.push(...findEditableChildren(n));
|
|
187
|
+
});
|
|
188
|
+
return bindings;
|
|
189
|
+
};
|
|
190
|
+
const parseSource = (value) => {
|
|
191
|
+
const ast = parseArrayExpression(value);
|
|
192
|
+
if (!ast) return {
|
|
193
|
+
objectItems: [],
|
|
194
|
+
primitiveItems: [],
|
|
195
|
+
parseError: true
|
|
196
|
+
};
|
|
197
|
+
const objectItems = [];
|
|
198
|
+
const primitiveItems = [];
|
|
199
|
+
ast.elements.filter((element) => Boolean(element)).forEach((element, elementIndex) => {
|
|
200
|
+
if (!import_lib.isObjectExpression(element)) {
|
|
201
|
+
const extracted = extractNodeValue(element);
|
|
202
|
+
primitiveItems.push({
|
|
203
|
+
id: nanoid(6),
|
|
204
|
+
index: primitiveItems.length,
|
|
205
|
+
elementIndex,
|
|
206
|
+
value: extracted.value,
|
|
207
|
+
type: extracted.type
|
|
208
|
+
});
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
const jsxBindings = {};
|
|
212
|
+
const jsxFallbacks = {};
|
|
213
|
+
element.properties.forEach((prop) => {
|
|
214
|
+
if (!import_lib.isObjectProperty(prop) || !import_lib.isIdentifier(prop.key) || !(import_lib.isJSXElement(prop.value) || import_lib.isJSXFragment(prop.value))) return;
|
|
215
|
+
const propertyName = prop.key.name;
|
|
216
|
+
try {
|
|
217
|
+
const found = bindingsInJSX(prop.value);
|
|
218
|
+
if (found.length > 0) jsxBindings[propertyName] = found;
|
|
219
|
+
else jsxFallbacks[propertyName] = generateCode(prop.value);
|
|
220
|
+
} catch (error) {
|
|
221
|
+
console.error(`Failed to parse JSX in property '${propertyName}':`, error);
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
objectItems.push({
|
|
225
|
+
id: nanoid(6),
|
|
226
|
+
index: objectItems.length,
|
|
227
|
+
elementIndex,
|
|
228
|
+
editableProperties: extractObjectProperties(element),
|
|
229
|
+
jsxBindings,
|
|
230
|
+
jsxFallbacks
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
return {
|
|
234
|
+
objectItems,
|
|
235
|
+
primitiveItems,
|
|
236
|
+
parseError: false
|
|
237
|
+
};
|
|
238
|
+
};
|
|
239
|
+
const useItemsEditor = (value, { render, onChange, onNodeChange } = {}) => {
|
|
240
|
+
const { objectItems, primitiveItems, parseError } = useMemo(() => parseSource(value), [value]);
|
|
241
|
+
useEffect(() => {
|
|
242
|
+
if (parseError) Toast.error("Failed to parse items", { description: "Check the console for details." });
|
|
243
|
+
}, [parseError]);
|
|
244
|
+
const kind = primitiveItems.length > 0 && objectItems.length === 0 ? "primitive" : "object";
|
|
245
|
+
const isPrimitive = kind === "primitive";
|
|
246
|
+
const selection = useMultiSelect(isPrimitive ? primitiveItems.length : objectItems.length);
|
|
247
|
+
const commit = (next) => {
|
|
248
|
+
if (next === null) {
|
|
249
|
+
Toast.error("Failed to update this item", { description: "Check the console for details." });
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
onChange?.(next);
|
|
253
|
+
};
|
|
254
|
+
const elementIndicesOf = (indices) => {
|
|
255
|
+
return new Set((isPrimitive ? primitiveItems : objectItems).filter((item) => indices.has(item.index)).map((item) => item.elementIndex));
|
|
256
|
+
};
|
|
257
|
+
const updateProperty = (elementIndex, propertyKey, next) => {
|
|
258
|
+
commit(updateArrayItemProperty(value, elementIndex, propertyKey, next, render));
|
|
259
|
+
};
|
|
260
|
+
return {
|
|
261
|
+
kind,
|
|
262
|
+
items: isPrimitive ? primitiveItems.map((item) => ({
|
|
263
|
+
id: item.id,
|
|
264
|
+
index: item.index,
|
|
265
|
+
elementIndex: item.elementIndex,
|
|
266
|
+
properties: [],
|
|
267
|
+
nested: [],
|
|
268
|
+
value: {
|
|
269
|
+
id: `primitive-${item.id}`,
|
|
270
|
+
label: `item-${item.index}`,
|
|
271
|
+
property: item.type,
|
|
272
|
+
value: item.value ?? "",
|
|
273
|
+
rawValue: String(item.value ?? ""),
|
|
274
|
+
onChange: (next) => commit(updateArrayItemValue(value, item.elementIndex, next))
|
|
275
|
+
}
|
|
276
|
+
})) : objectItems.map((item) => {
|
|
277
|
+
const properties = Object.entries(item.editableProperties).map(([key, prop]) => {
|
|
278
|
+
const leaf = resolveLeaf(render, key);
|
|
279
|
+
return {
|
|
280
|
+
id: `item-${item.id}-${key}`,
|
|
281
|
+
label: key,
|
|
282
|
+
property: leaf ? leaf.property ?? leaf.type : key,
|
|
283
|
+
type: leaf?.type,
|
|
284
|
+
render: leaf ? leaf.render : resolveMap(render, key),
|
|
285
|
+
value: parseValue(String(prop.value)),
|
|
286
|
+
rawValue: String(prop.value),
|
|
287
|
+
meta: { valueType: prop.type },
|
|
288
|
+
onChange: (next) => updateProperty(item.elementIndex, key, next)
|
|
289
|
+
};
|
|
290
|
+
});
|
|
291
|
+
const nested = [...Object.entries(item.jsxBindings).map(([property, nodes]) => ({
|
|
292
|
+
property,
|
|
293
|
+
elements: nodes.flatMap((node) => {
|
|
294
|
+
const id = node.dataAttributes.find((a) => a.name === "data-id")?.value;
|
|
295
|
+
const attr = node.dataAttributes.find((a) => a.name === "data-binding")?.value;
|
|
296
|
+
if (!id || !attr) return [];
|
|
297
|
+
const parsed = node.bindings ?? parseBinding(attr);
|
|
298
|
+
if (!parsed.length) return [];
|
|
299
|
+
return [{
|
|
300
|
+
id,
|
|
301
|
+
tagName: node.tagName || "element",
|
|
302
|
+
bindings: parsed.map((binding) => ({
|
|
303
|
+
id,
|
|
200
304
|
label: binding.label,
|
|
201
305
|
property: binding.property,
|
|
202
306
|
type: binding.type,
|
|
@@ -208,21 +312,68 @@ const Node = ({ data, onChange }) => {
|
|
|
208
312
|
pattern: binding.pattern,
|
|
209
313
|
required: binding.required,
|
|
210
314
|
meta: binding.meta,
|
|
211
|
-
value:
|
|
212
|
-
rawValue:
|
|
213
|
-
onChange: (next) =>
|
|
214
|
-
id
|
|
315
|
+
value: getStructuredValue(node, binding.property, binding.type),
|
|
316
|
+
rawValue: getCurrentValue(node, binding.property),
|
|
317
|
+
onChange: (next) => onNodeChange?.({
|
|
318
|
+
id,
|
|
215
319
|
label: binding.label,
|
|
216
320
|
property: binding.property,
|
|
217
321
|
value: next
|
|
218
322
|
})
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
323
|
+
}))
|
|
324
|
+
}];
|
|
325
|
+
})
|
|
326
|
+
})), ...Object.entries(item.jsxFallbacks).map(([property, code]) => ({
|
|
327
|
+
property,
|
|
328
|
+
elements: [],
|
|
329
|
+
fallback: {
|
|
330
|
+
id: `item-${item.id}-${property}-jsx`,
|
|
331
|
+
label: property,
|
|
332
|
+
property,
|
|
333
|
+
type: "jsx",
|
|
334
|
+
value: code,
|
|
335
|
+
rawValue: code,
|
|
336
|
+
onChange: (next) => updateProperty(item.elementIndex, property, next)
|
|
337
|
+
}
|
|
338
|
+
}))];
|
|
339
|
+
return {
|
|
340
|
+
id: item.id,
|
|
341
|
+
index: item.index,
|
|
342
|
+
elementIndex: item.elementIndex,
|
|
343
|
+
properties,
|
|
344
|
+
nested
|
|
345
|
+
};
|
|
346
|
+
}),
|
|
347
|
+
selection,
|
|
348
|
+
actions: {
|
|
349
|
+
add: () => commit(appendArrayItem(value, kind)),
|
|
350
|
+
move: (elementIndex, toIndex) => {
|
|
351
|
+
const target = (isPrimitive ? primitiveItems : objectItems).find((item) => item.index === toIndex);
|
|
352
|
+
if (!target) return;
|
|
353
|
+
commit(moveArrayItem(value, elementIndex, target.elementIndex));
|
|
354
|
+
selection.clear();
|
|
355
|
+
},
|
|
356
|
+
remove: (elementIndex) => {
|
|
357
|
+
commit(removeArrayItems(value, /* @__PURE__ */ new Set([elementIndex]), kind));
|
|
358
|
+
selection.clear();
|
|
359
|
+
},
|
|
360
|
+
duplicateSelected: () => commit(duplicateArrayItems(value, elementIndicesOf(selection.selected))),
|
|
361
|
+
moveSelected: (direction) => {
|
|
362
|
+
const result = moveArrayItems(value, elementIndicesOf(selection.selected), direction);
|
|
363
|
+
if (!result) {
|
|
364
|
+
commit(null);
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
selection.replace(result.indices);
|
|
368
|
+
commit(result.code);
|
|
369
|
+
},
|
|
370
|
+
removeSelected: () => {
|
|
371
|
+
commit(removeArrayItems(value, elementIndicesOf(selection.selected), kind));
|
|
372
|
+
selection.clear();
|
|
373
|
+
}
|
|
374
|
+
},
|
|
375
|
+
parseError
|
|
376
|
+
};
|
|
226
377
|
};
|
|
227
378
|
//#endregion
|
|
228
379
|
//#region src/components/dnd/panel/items.tsx
|
|
@@ -270,143 +421,101 @@ const BulkActionsBar = ({ count, onDuplicate, onMoveUp, onMoveDown, onDelete, on
|
|
|
270
421
|
})]
|
|
271
422
|
});
|
|
272
423
|
};
|
|
424
|
+
const NestedGroup = ({ group, onNodeChange }) => {
|
|
425
|
+
if (group.fallback) return /* @__PURE__ */ jsxs("div", {
|
|
426
|
+
className: "space-y-2",
|
|
427
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
428
|
+
className: "text-xs font-medium text-blue-700",
|
|
429
|
+
children: group.property
|
|
430
|
+
}), /* @__PURE__ */ jsx(Field, {
|
|
431
|
+
binding: group.fallback,
|
|
432
|
+
onNodeChange
|
|
433
|
+
})]
|
|
434
|
+
});
|
|
435
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
436
|
+
className: "space-y-2",
|
|
437
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
438
|
+
className: "text-xs font-medium text-blue-700",
|
|
439
|
+
children: [
|
|
440
|
+
group.property,
|
|
441
|
+
" Bindings (",
|
|
442
|
+
group.elements.length,
|
|
443
|
+
"):"
|
|
444
|
+
]
|
|
445
|
+
}), group.elements.map((element) => /* @__PURE__ */ jsxs("div", {
|
|
446
|
+
className: "rounded border border-blue-100 bg-blue-50 p-2",
|
|
447
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
448
|
+
className: "mb-1 text-xs text-blue-600",
|
|
449
|
+
children: [
|
|
450
|
+
"<",
|
|
451
|
+
element.tagName,
|
|
452
|
+
">"
|
|
453
|
+
]
|
|
454
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
455
|
+
className: "space-y-2 rounded",
|
|
456
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
457
|
+
className: "space-y-1",
|
|
458
|
+
children: element.bindings.map((binding) => /* @__PURE__ */ jsxs("div", {
|
|
459
|
+
className: "space-y-1",
|
|
460
|
+
children: [/* @__PURE__ */ jsxs("label", {
|
|
461
|
+
className: "block text-xs font-semibold text-gray-700",
|
|
462
|
+
children: [binding.label, /* @__PURE__ */ jsxs("span", {
|
|
463
|
+
className: "ml-1 text-gray-400",
|
|
464
|
+
children: [
|
|
465
|
+
"(",
|
|
466
|
+
binding.property,
|
|
467
|
+
")"
|
|
468
|
+
]
|
|
469
|
+
})]
|
|
470
|
+
}), /* @__PURE__ */ jsx(Field, {
|
|
471
|
+
binding,
|
|
472
|
+
onNodeChange
|
|
473
|
+
})]
|
|
474
|
+
}, binding.label))
|
|
475
|
+
})
|
|
476
|
+
})]
|
|
477
|
+
}, `${group.property}-${element.id}`))]
|
|
478
|
+
});
|
|
479
|
+
};
|
|
273
480
|
const Items = ({ value, render, onChange, onChildChange }) => {
|
|
274
|
-
const {
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
})
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
else jsxFallbacks[propertyName] = jsxCode;
|
|
313
|
-
} catch (error) {
|
|
314
|
-
console.error(`Failed to parse JSX in property '${propertyName}':`, error);
|
|
315
|
-
}
|
|
316
|
-
});
|
|
317
|
-
objectItems.push({
|
|
318
|
-
id: nanoid(6),
|
|
319
|
-
index: objectItems.length,
|
|
320
|
-
elementIndex,
|
|
321
|
-
editableProperties: extractObjectProperties(element),
|
|
322
|
-
jsxBindings,
|
|
323
|
-
jsxFallbacks
|
|
324
|
-
});
|
|
325
|
-
});
|
|
326
|
-
return {
|
|
327
|
-
objectItems,
|
|
328
|
-
primitiveItems,
|
|
329
|
-
parseError: false
|
|
330
|
-
};
|
|
331
|
-
}, [value]);
|
|
332
|
-
useEffect(() => {
|
|
333
|
-
if (parseError) Toast.error("Failed to parse items", { description: "Check the console for details." });
|
|
334
|
-
}, [parseError]);
|
|
335
|
-
const isPrimitive = primitiveItems.length > 0 && objectItems.length === 0;
|
|
336
|
-
const selection = useMultiSelect(isPrimitive ? primitiveItems.length : objectItems.length);
|
|
337
|
-
const commit = (next) => {
|
|
338
|
-
if (next === null) {
|
|
339
|
-
Toast.error("Failed to update this item", { description: "Check the console for details." });
|
|
340
|
-
return;
|
|
341
|
-
}
|
|
342
|
-
onChange?.(next);
|
|
343
|
-
};
|
|
344
|
-
const elementIndicesOf = (items, indices) => {
|
|
345
|
-
return new Set(items.filter((item) => indices.has(item.index)).map((item) => item.elementIndex));
|
|
346
|
-
};
|
|
347
|
-
const updatePrimitive = (elementIndex, next) => {
|
|
348
|
-
commit(updateArrayItemValue(value, elementIndex, next));
|
|
349
|
-
};
|
|
350
|
-
const movePrimitive = (from, to) => {
|
|
351
|
-
const target = primitiveItems.find((item) => item.index === to);
|
|
352
|
-
if (!target) return;
|
|
353
|
-
commit(moveArrayItem(value, from, target.elementIndex));
|
|
354
|
-
selection.clear();
|
|
355
|
-
};
|
|
356
|
-
const deleteSelectedPrimitives = (indices) => {
|
|
357
|
-
commit(removeArrayItems(value, elementIndicesOf(primitiveItems, indices), "primitive"));
|
|
358
|
-
};
|
|
359
|
-
const deletePrimitive = (elementIndex) => {
|
|
360
|
-
commit(removeArrayItems(value, /* @__PURE__ */ new Set([elementIndex]), "primitive"));
|
|
361
|
-
selection.clear();
|
|
362
|
-
};
|
|
363
|
-
const addPrimitive = () => {
|
|
364
|
-
commit(appendArrayItem(value, "primitive"));
|
|
365
|
-
};
|
|
366
|
-
const duplicateSelectedPrimitives = (indices) => {
|
|
367
|
-
commit(duplicateArrayItems(value, elementIndicesOf(primitiveItems, indices)));
|
|
368
|
-
};
|
|
369
|
-
const moveSelectedPrimitives = (indices, direction) => {
|
|
370
|
-
const result = moveArrayItems(value, elementIndicesOf(primitiveItems, indices), direction);
|
|
371
|
-
if (!result) {
|
|
372
|
-
commit(null);
|
|
373
|
-
return;
|
|
374
|
-
}
|
|
375
|
-
selection.replace(result.indices);
|
|
376
|
-
commit(result.code);
|
|
377
|
-
};
|
|
378
|
-
const moveItem = (from, to) => {
|
|
379
|
-
const target = objectItems.find((item) => item.index === to);
|
|
380
|
-
if (!target) return;
|
|
381
|
-
commit(moveArrayItem(value, from, target.elementIndex));
|
|
382
|
-
selection.clear();
|
|
383
|
-
};
|
|
384
|
-
const updateProperty = (elementIndex, propertyKey, next) => {
|
|
385
|
-
commit(updateArrayItemProperty(value, elementIndex, propertyKey, next, render));
|
|
386
|
-
};
|
|
387
|
-
const deleteSelectedItems = (indices) => {
|
|
388
|
-
commit(removeArrayItems(value, elementIndicesOf(objectItems, indices), "object"));
|
|
389
|
-
};
|
|
390
|
-
const deleteItem = (elementIndex) => {
|
|
391
|
-
commit(removeArrayItems(value, /* @__PURE__ */ new Set([elementIndex]), "object"));
|
|
392
|
-
selection.clear();
|
|
393
|
-
};
|
|
394
|
-
const addItem = () => {
|
|
395
|
-
commit(appendArrayItem(value, "object"));
|
|
396
|
-
};
|
|
397
|
-
const duplicateSelectedItems = (indices) => {
|
|
398
|
-
commit(duplicateArrayItems(value, elementIndicesOf(objectItems, indices)));
|
|
399
|
-
};
|
|
400
|
-
const moveSelectedItems = (indices, direction) => {
|
|
401
|
-
const result = moveArrayItems(value, elementIndicesOf(objectItems, indices), direction);
|
|
402
|
-
if (!result) {
|
|
403
|
-
commit(null);
|
|
404
|
-
return;
|
|
405
|
-
}
|
|
406
|
-
selection.replace(result.indices);
|
|
407
|
-
commit(result.code);
|
|
408
|
-
};
|
|
409
|
-
if (isPrimitive) return /* @__PURE__ */ jsxs("div", {
|
|
481
|
+
const { kind, items, selection, actions } = useItemsEditor(value, {
|
|
482
|
+
render,
|
|
483
|
+
onChange,
|
|
484
|
+
onNodeChange: onChildChange
|
|
485
|
+
});
|
|
486
|
+
const bulkBar = /* @__PURE__ */ jsx(BulkActionsBar, {
|
|
487
|
+
count: selection.selected.size,
|
|
488
|
+
onDuplicate: actions.duplicateSelected,
|
|
489
|
+
onMoveUp: () => actions.moveSelected("up"),
|
|
490
|
+
onMoveDown: () => actions.moveSelected("down"),
|
|
491
|
+
onDelete: actions.removeSelected,
|
|
492
|
+
onClear: selection.clear
|
|
493
|
+
});
|
|
494
|
+
const itemControls = (item) => /* @__PURE__ */ jsxs("div", {
|
|
495
|
+
className: "flex space-x-1",
|
|
496
|
+
children: [
|
|
497
|
+
/* @__PURE__ */ jsx(Button, {
|
|
498
|
+
size: "small",
|
|
499
|
+
icon: /* @__PURE__ */ jsx(ArrowUp, {}),
|
|
500
|
+
disabled: item.index === 0,
|
|
501
|
+
onClick: () => actions.move(item.elementIndex, item.index - 1)
|
|
502
|
+
}),
|
|
503
|
+
/* @__PURE__ */ jsx(Button, {
|
|
504
|
+
size: "small",
|
|
505
|
+
icon: /* @__PURE__ */ jsx(ArrowDown, {}),
|
|
506
|
+
disabled: item.index === items.length - 1,
|
|
507
|
+
onClick: () => actions.move(item.elementIndex, item.index + 1)
|
|
508
|
+
}),
|
|
509
|
+
/* @__PURE__ */ jsx(Button, {
|
|
510
|
+
danger: true,
|
|
511
|
+
size: "small",
|
|
512
|
+
icon: /* @__PURE__ */ jsx(X, {}),
|
|
513
|
+
disabled: items.length <= 1,
|
|
514
|
+
onClick: () => actions.remove(item.elementIndex)
|
|
515
|
+
})
|
|
516
|
+
]
|
|
517
|
+
});
|
|
518
|
+
if (kind === "primitive") return /* @__PURE__ */ jsxs("div", {
|
|
410
519
|
className: "space-y-4",
|
|
411
520
|
children: [
|
|
412
521
|
/* @__PURE__ */ jsxs("div", {
|
|
@@ -415,7 +524,7 @@ const Items = ({ value, render, onChange, onChildChange }) => {
|
|
|
415
524
|
className: "text-sm font-semibold",
|
|
416
525
|
children: [
|
|
417
526
|
"Items (",
|
|
418
|
-
|
|
527
|
+
items.length,
|
|
419
528
|
")"
|
|
420
529
|
]
|
|
421
530
|
}), /* @__PURE__ */ jsx(Button, {
|
|
@@ -423,22 +532,12 @@ const Items = ({ value, render, onChange, onChildChange }) => {
|
|
|
423
532
|
icon: /* @__PURE__ */ jsx(Plus, {}),
|
|
424
533
|
variant: "solid",
|
|
425
534
|
color: "green",
|
|
426
|
-
onClick:
|
|
535
|
+
onClick: actions.add,
|
|
427
536
|
children: "Add Item"
|
|
428
537
|
})]
|
|
429
538
|
}),
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
onDuplicate: () => duplicateSelectedPrimitives(selection.selected),
|
|
433
|
-
onMoveUp: () => moveSelectedPrimitives(selection.selected, "up"),
|
|
434
|
-
onMoveDown: () => moveSelectedPrimitives(selection.selected, "down"),
|
|
435
|
-
onDelete: () => {
|
|
436
|
-
deleteSelectedPrimitives(selection.selected);
|
|
437
|
-
selection.clear();
|
|
438
|
-
},
|
|
439
|
-
onClear: selection.clear
|
|
440
|
-
}),
|
|
441
|
-
primitiveItems.map((item, i) => /* @__PURE__ */ jsxs("div", {
|
|
539
|
+
bulkBar,
|
|
540
|
+
items.map((item) => /* @__PURE__ */ jsxs("div", {
|
|
442
541
|
className: "space-y-2 rounded border border-gray-100 bg-gray-50 p-2",
|
|
443
542
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
444
543
|
className: "flex items-center justify-between space-x-1",
|
|
@@ -449,39 +548,9 @@ const Items = ({ value, render, onChange, onChildChange }) => {
|
|
|
449
548
|
checked: selection.isSelected(item.index),
|
|
450
549
|
onChange: () => {}
|
|
451
550
|
})
|
|
452
|
-
}),
|
|
453
|
-
className: "flex space-x-1",
|
|
454
|
-
children: [
|
|
455
|
-
/* @__PURE__ */ jsx(Button, {
|
|
456
|
-
size: "small",
|
|
457
|
-
icon: /* @__PURE__ */ jsx(ArrowUp, {}),
|
|
458
|
-
disabled: i === 0,
|
|
459
|
-
onClick: () => movePrimitive(item.elementIndex, item.index - 1)
|
|
460
|
-
}),
|
|
461
|
-
/* @__PURE__ */ jsx(Button, {
|
|
462
|
-
size: "small",
|
|
463
|
-
icon: /* @__PURE__ */ jsx(ArrowDown, {}),
|
|
464
|
-
disabled: i === primitiveItems.length - 1,
|
|
465
|
-
onClick: () => movePrimitive(item.elementIndex, item.index + 1)
|
|
466
|
-
}),
|
|
467
|
-
/* @__PURE__ */ jsx(Button, {
|
|
468
|
-
danger: true,
|
|
469
|
-
size: "small",
|
|
470
|
-
icon: /* @__PURE__ */ jsx(X, {}),
|
|
471
|
-
disabled: primitiveItems.length <= 1,
|
|
472
|
-
onClick: () => deletePrimitive(item.elementIndex)
|
|
473
|
-
})
|
|
474
|
-
]
|
|
475
|
-
})]
|
|
551
|
+
}), itemControls(item)]
|
|
476
552
|
}), /* @__PURE__ */ jsx(Field, {
|
|
477
|
-
binding:
|
|
478
|
-
id: `primitive-${item.id}`,
|
|
479
|
-
label: `item-${i}`,
|
|
480
|
-
property: item.type,
|
|
481
|
-
value: item.value ?? "",
|
|
482
|
-
rawValue: String(item.value ?? ""),
|
|
483
|
-
onChange: (next) => updatePrimitive(item.elementIndex, next)
|
|
484
|
-
},
|
|
553
|
+
binding: item.value,
|
|
485
554
|
onNodeChange: onChildChange
|
|
486
555
|
})]
|
|
487
556
|
}, item.id))
|
|
@@ -496,7 +565,7 @@ const Items = ({ value, render, onChange, onChildChange }) => {
|
|
|
496
565
|
className: "text-sm font-semibold",
|
|
497
566
|
children: [
|
|
498
567
|
"Items (",
|
|
499
|
-
|
|
568
|
+
items.length,
|
|
500
569
|
")"
|
|
501
570
|
]
|
|
502
571
|
}), /* @__PURE__ */ jsx(Button, {
|
|
@@ -504,23 +573,13 @@ const Items = ({ value, render, onChange, onChildChange }) => {
|
|
|
504
573
|
icon: /* @__PURE__ */ jsx(Plus, {}),
|
|
505
574
|
variant: "solid",
|
|
506
575
|
color: "green",
|
|
507
|
-
disabled:
|
|
508
|
-
onClick:
|
|
576
|
+
disabled: items.length === 0,
|
|
577
|
+
onClick: actions.add,
|
|
509
578
|
children: "Add Item"
|
|
510
579
|
})]
|
|
511
580
|
}),
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
onDuplicate: () => duplicateSelectedItems(selection.selected),
|
|
515
|
-
onMoveUp: () => moveSelectedItems(selection.selected, "up"),
|
|
516
|
-
onMoveDown: () => moveSelectedItems(selection.selected, "down"),
|
|
517
|
-
onDelete: () => {
|
|
518
|
-
deleteSelectedItems(selection.selected);
|
|
519
|
-
selection.clear();
|
|
520
|
-
},
|
|
521
|
-
onClear: selection.clear
|
|
522
|
-
}),
|
|
523
|
-
objectItems.map((item) => /* @__PURE__ */ jsxs("div", {
|
|
581
|
+
bulkBar,
|
|
582
|
+
items.map((item) => /* @__PURE__ */ jsxs("div", {
|
|
524
583
|
className: "space-y-3 rounded border bg-gray-50 p-3",
|
|
525
584
|
children: [
|
|
526
585
|
/* @__PURE__ */ jsxs("div", {
|
|
@@ -538,107 +597,34 @@ const Items = ({ value, render, onChange, onChildChange }) => {
|
|
|
538
597
|
className: "text-xs font-medium",
|
|
539
598
|
children: ["Item ", item.index + 1]
|
|
540
599
|
})]
|
|
541
|
-
}),
|
|
542
|
-
className: "flex space-x-1",
|
|
543
|
-
children: [
|
|
544
|
-
/* @__PURE__ */ jsx(Button, {
|
|
545
|
-
size: "small",
|
|
546
|
-
icon: /* @__PURE__ */ jsx(ArrowUp, {}),
|
|
547
|
-
disabled: item.index === 0,
|
|
548
|
-
onClick: () => moveItem(item.elementIndex, item.index - 1)
|
|
549
|
-
}),
|
|
550
|
-
/* @__PURE__ */ jsx(Button, {
|
|
551
|
-
size: "small",
|
|
552
|
-
icon: /* @__PURE__ */ jsx(ArrowDown, {}),
|
|
553
|
-
disabled: item.index === objectItems.length - 1,
|
|
554
|
-
onClick: () => moveItem(item.elementIndex, item.index + 1)
|
|
555
|
-
}),
|
|
556
|
-
/* @__PURE__ */ jsx(Button, {
|
|
557
|
-
danger: true,
|
|
558
|
-
size: "small",
|
|
559
|
-
icon: /* @__PURE__ */ jsx(X, {}),
|
|
560
|
-
disabled: objectItems.length <= 1,
|
|
561
|
-
onClick: () => deleteItem(item.elementIndex)
|
|
562
|
-
})
|
|
563
|
-
]
|
|
564
|
-
})]
|
|
600
|
+
}), itemControls(item)]
|
|
565
601
|
}),
|
|
566
602
|
/* @__PURE__ */ jsx("div", {
|
|
567
603
|
className: "space-y-2",
|
|
568
|
-
children:
|
|
604
|
+
children: item.properties.map((binding) => /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsxs("div", {
|
|
569
605
|
className: "flex flex-col space-y-2",
|
|
570
606
|
children: [/* @__PURE__ */ jsx("label", {
|
|
571
607
|
className: "w-20 shrink-0 text-xs font-medium",
|
|
572
|
-
children:
|
|
608
|
+
children: binding.label
|
|
573
609
|
}), /* @__PURE__ */ jsx(Field, {
|
|
574
|
-
binding
|
|
575
|
-
id: `item-${item.id}-${key}`,
|
|
576
|
-
label: key,
|
|
577
|
-
property: render?.[key] && "type" in render[key] ? render[key].property ?? render[key].type : key,
|
|
578
|
-
type: render?.[key] && "type" in render[key] ? render[key].type : void 0,
|
|
579
|
-
render: render?.[key] && "type" in render[key] ? render[key].render : render?.[key] && !("type" in render[key]) ? render[key] : void 0,
|
|
580
|
-
value: parseValue(String(prop.value)),
|
|
581
|
-
rawValue: String(prop.value),
|
|
582
|
-
onChange: (next) => updateProperty(item.elementIndex, key, next)
|
|
583
|
-
},
|
|
610
|
+
binding,
|
|
584
611
|
onNodeChange: onChildChange
|
|
585
612
|
})]
|
|
586
613
|
}), /* @__PURE__ */ jsxs("span", {
|
|
587
614
|
className: "text-right text-xs text-gray-500",
|
|
588
615
|
children: [
|
|
589
616
|
"(",
|
|
590
|
-
|
|
617
|
+
String(binding.meta?.valueType),
|
|
591
618
|
")"
|
|
592
619
|
]
|
|
593
|
-
})] }, `${item.id}-${
|
|
620
|
+
})] }, `${item.id}-${binding.label}`))
|
|
594
621
|
}),
|
|
595
622
|
/* @__PURE__ */ jsx("div", {
|
|
596
623
|
className: "space-y-3 border-t pt-2",
|
|
597
|
-
children:
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
children: [
|
|
602
|
-
propertyName,
|
|
603
|
-
" Bindings (",
|
|
604
|
-
bindings.length,
|
|
605
|
-
"):"
|
|
606
|
-
]
|
|
607
|
-
}), bindings.map((bindingNode, idx) => {
|
|
608
|
-
const nodeId = bindingNode.dataAttributes.find((a) => a.name === "data-id")?.value;
|
|
609
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
610
|
-
className: "rounded border border-blue-100 bg-blue-50\n p-2",
|
|
611
|
-
children: [/* @__PURE__ */ jsxs("div", {
|
|
612
|
-
className: "mb-1 text-xs text-blue-600",
|
|
613
|
-
children: [
|
|
614
|
-
"<",
|
|
615
|
-
bindingNode.tagName || "element",
|
|
616
|
-
">"
|
|
617
|
-
]
|
|
618
|
-
}), /* @__PURE__ */ jsx(Node, {
|
|
619
|
-
data: bindingNode,
|
|
620
|
-
onChange: onChildChange
|
|
621
|
-
})]
|
|
622
|
-
}, `binding-${item.id}-${propertyName}-${nodeId || idx}`);
|
|
623
|
-
})]
|
|
624
|
-
}, propertyName)), Object.entries(item.jsxFallbacks).map(([propertyName, code]) => /* @__PURE__ */ jsxs("div", {
|
|
625
|
-
className: "space-y-2",
|
|
626
|
-
children: [/* @__PURE__ */ jsx("div", {
|
|
627
|
-
className: "text-xs font-medium text-blue-700",
|
|
628
|
-
children: propertyName
|
|
629
|
-
}), /* @__PURE__ */ jsx(Field, {
|
|
630
|
-
binding: {
|
|
631
|
-
id: `item-${item.id}-${propertyName}-jsx`,
|
|
632
|
-
label: propertyName,
|
|
633
|
-
property: propertyName,
|
|
634
|
-
type: "jsx",
|
|
635
|
-
value: code,
|
|
636
|
-
rawValue: code,
|
|
637
|
-
onChange: (next) => updateProperty(item.elementIndex, propertyName, next)
|
|
638
|
-
},
|
|
639
|
-
onNodeChange: onChildChange
|
|
640
|
-
})]
|
|
641
|
-
}, propertyName))] }) : /* @__PURE__ */ jsx("div", {
|
|
624
|
+
children: item.nested.length ? item.nested.map((group) => /* @__PURE__ */ jsx(NestedGroup, {
|
|
625
|
+
group,
|
|
626
|
+
onNodeChange: onChildChange
|
|
627
|
+
}, group.property)) : /* @__PURE__ */ jsx("div", {
|
|
642
628
|
className: "text-xs text-gray-500",
|
|
643
629
|
children: "✓ No JSX bindings found"
|
|
644
630
|
})
|
|
@@ -649,6 +635,64 @@ const Items = ({ value, render, onChange, onChildChange }) => {
|
|
|
649
635
|
});
|
|
650
636
|
};
|
|
651
637
|
//#endregion
|
|
638
|
+
//#region src/components/dnd/panel/node.tsx
|
|
639
|
+
const Node = ({ data, onChange }) => {
|
|
640
|
+
const idAttr = data.dataAttributes.find((a) => a.name === "data-id");
|
|
641
|
+
const bindingAttr = data.dataAttributes.find((a) => a.name === "data-binding");
|
|
642
|
+
if (!idAttr?.value || !bindingAttr?.value) return null;
|
|
643
|
+
const dataId = idAttr.value;
|
|
644
|
+
const bindings = data.bindings || parseBinding(bindingAttr.value);
|
|
645
|
+
if (!bindings.length) return null;
|
|
646
|
+
return /* @__PURE__ */ jsx("div", {
|
|
647
|
+
className: "space-y-2 rounded",
|
|
648
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
649
|
+
className: "space-y-1",
|
|
650
|
+
children: bindings.map((binding) => {
|
|
651
|
+
const currentValue = getCurrentValue(data, binding.property);
|
|
652
|
+
const structuredValue = getStructuredValue(data, binding.property, binding.type);
|
|
653
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
654
|
+
className: "space-y-1",
|
|
655
|
+
children: [/* @__PURE__ */ jsxs("label", {
|
|
656
|
+
className: "block text-xs font-semibold text-gray-700",
|
|
657
|
+
children: [binding.label, /* @__PURE__ */ jsxs("span", {
|
|
658
|
+
className: "ml-1 text-gray-400",
|
|
659
|
+
children: [
|
|
660
|
+
"(",
|
|
661
|
+
binding.property,
|
|
662
|
+
")"
|
|
663
|
+
]
|
|
664
|
+
})]
|
|
665
|
+
}), /* @__PURE__ */ jsx(Field, {
|
|
666
|
+
binding: {
|
|
667
|
+
id: dataId,
|
|
668
|
+
label: binding.label,
|
|
669
|
+
property: binding.property,
|
|
670
|
+
type: binding.type,
|
|
671
|
+
widget: binding.widget,
|
|
672
|
+
options: binding.options,
|
|
673
|
+
render: binding.render,
|
|
674
|
+
min: binding.min,
|
|
675
|
+
max: binding.max,
|
|
676
|
+
pattern: binding.pattern,
|
|
677
|
+
required: binding.required,
|
|
678
|
+
meta: binding.meta,
|
|
679
|
+
value: structuredValue,
|
|
680
|
+
rawValue: currentValue,
|
|
681
|
+
onChange: (next) => onChange?.({
|
|
682
|
+
id: dataId,
|
|
683
|
+
label: binding.label,
|
|
684
|
+
property: binding.property,
|
|
685
|
+
value: next
|
|
686
|
+
})
|
|
687
|
+
},
|
|
688
|
+
onNodeChange: onChange
|
|
689
|
+
})]
|
|
690
|
+
}, binding.label);
|
|
691
|
+
})
|
|
692
|
+
})
|
|
693
|
+
});
|
|
694
|
+
};
|
|
695
|
+
//#endregion
|
|
652
696
|
//#region src/components/dnd/panel/children.tsx
|
|
653
697
|
const Children = ({ value, onChange, onNodeChange }) => {
|
|
654
698
|
const items = useMemo(() => Array.isArray(value) ? value : [], [value]);
|
|
@@ -1499,7 +1543,8 @@ const Dnd$1 = ({ value: _value, props, modules = {}, onChange: _onChange, classN
|
|
|
1499
1543
|
onMoveDown: () => moveSection(selectedId, "down"),
|
|
1500
1544
|
canMoveUp,
|
|
1501
1545
|
canMoveDown,
|
|
1502
|
-
bindings
|
|
1546
|
+
bindings,
|
|
1547
|
+
onNodeChange: onFieldChange
|
|
1503
1548
|
});
|
|
1504
1549
|
return /* @__PURE__ */ jsx(Panel, {
|
|
1505
1550
|
item: selectedItem,
|
|
@@ -1634,7 +1679,8 @@ const Dnd$1 = ({ value: _value, props, modules = {}, onChange: _onChange, classN
|
|
|
1634
1679
|
const Dnd = Dnd$1;
|
|
1635
1680
|
Dnd.DraggableItem = DraggableItem;
|
|
1636
1681
|
Dnd.DefaultPanel = Panel;
|
|
1682
|
+
Dnd.Field = Field;
|
|
1637
1683
|
//#endregion
|
|
1638
|
-
export {
|
|
1684
|
+
export { ICON_OPTIONS as a, ICON_MAP as i, Panel as n, useItemsEditor as o, Field as r, DraggableItem as s, Dnd as t };
|
|
1639
1685
|
|
|
1640
|
-
//# sourceMappingURL=dnd-
|
|
1686
|
+
//# sourceMappingURL=dnd-DRivgZdt.js.map
|