@drawnagency/primitives 0.1.79 → 0.1.80
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/{chunk-FRTJNS5F.js → chunk-4TVODHD2.js} +3 -3
- package/dist/{chunk-4XXLH5CL.js → chunk-7XWER6YR.js} +17 -10
- package/dist/{chunk-RWMSDDQM.js → chunk-KVQFMVXE.js} +77 -24
- package/dist/{chunk-DR22HM44.js → chunk-VI26O4E3.js} +1 -1
- package/dist/components/brandguide/Colors.d.ts +2 -1
- package/dist/components/brandguide/Colors.d.ts.map +1 -1
- package/dist/components/primitives/EditableGrid.d.ts +11 -1
- package/dist/components/primitives/EditableGrid.d.ts.map +1 -1
- package/dist/components/primitives/gridDrop.d.ts +18 -0
- package/dist/components/primitives/gridDrop.d.ts.map +1 -0
- package/dist/components/primitives/index.js +2 -2
- package/dist/components/primitives/useEditableCollection.d.ts +1 -0
- package/dist/components/primitives/useEditableCollection.d.ts.map +1 -1
- package/dist/components/sections/Colors/index.d.ts.map +1 -1
- package/dist/components/sections/brand-guide.js +2 -2
- package/dist/components/sections/register-schemas.js +4 -4
- package/dist/components/sections/register.js +4 -4
- package/dist/components/shell/EditorContext.d.ts +2 -0
- package/dist/components/shell/EditorContext.d.ts.map +1 -1
- package/dist/components/shell/EditorShell.d.ts +13 -0
- package/dist/components/shell/EditorShell.d.ts.map +1 -1
- package/dist/components/shell/HistoryToolbar.d.ts +8 -1
- package/dist/components/shell/HistoryToolbar.d.ts.map +1 -1
- package/dist/lib/registry.d.ts +3 -0
- package/dist/lib/registry.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/brandguide/Colors.tsx +15 -5
- package/src/components/primitives/EditableGrid.tsx +86 -24
- package/src/components/primitives/gridDrop.ts +26 -0
- package/src/components/primitives/useEditableCollection.ts +16 -1
- package/src/components/sections/Colors/index.tsx +2 -1
- package/src/components/shell/EditorContext.tsx +6 -1
- package/src/components/shell/EditorShell.tsx +43 -5
- package/src/components/shell/HistoryToolbar.tsx +24 -2
- package/src/lib/registry.ts +3 -0
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
pluralize,
|
|
4
4
|
stripHtmlToPlainText,
|
|
5
5
|
truncate
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-7XWER6YR.js";
|
|
7
7
|
import {
|
|
8
8
|
DeleteButton,
|
|
9
9
|
DragHandle,
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
import {
|
|
20
20
|
EditableRichText,
|
|
21
21
|
defineHeadingSection
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-VI26O4E3.js";
|
|
23
23
|
import {
|
|
24
24
|
EditablePlainText,
|
|
25
25
|
ImageDropZone,
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
colSpanClass,
|
|
29
29
|
containerGridClass,
|
|
30
30
|
spacerHiddenClass
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-KVQFMVXE.js";
|
|
32
32
|
import {
|
|
33
33
|
useMediaLibrary,
|
|
34
34
|
useResolvedMedia
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
MediaBlock,
|
|
10
10
|
containerGridClass,
|
|
11
11
|
useEditableCollection
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-KVQFMVXE.js";
|
|
13
13
|
import {
|
|
14
14
|
AddIcon,
|
|
15
15
|
DeleteIcon,
|
|
@@ -124,7 +124,7 @@ function buildContent(colors, options) {
|
|
|
124
124
|
...label || columns || collapsing !== void 0 || showLabel !== void 0 ? { options: { label, columns, collapsing, showLabel } } : {}
|
|
125
125
|
};
|
|
126
126
|
}
|
|
127
|
-
function Colors({ colors, columns = 3, label, collapsing, showLabel = true, onChange, openModal }) {
|
|
127
|
+
function Colors({ colors, columns = 3, label, collapsing, showLabel = true, onChange, openModal, onDelete }) {
|
|
128
128
|
if (onChange && openModal) {
|
|
129
129
|
return /* @__PURE__ */ jsx2(
|
|
130
130
|
ColorsEditable,
|
|
@@ -135,7 +135,8 @@ function Colors({ colors, columns = 3, label, collapsing, showLabel = true, onCh
|
|
|
135
135
|
collapsing,
|
|
136
136
|
showLabel,
|
|
137
137
|
onChange,
|
|
138
|
-
openModal
|
|
138
|
+
openModal,
|
|
139
|
+
onDelete
|
|
139
140
|
}
|
|
140
141
|
);
|
|
141
142
|
}
|
|
@@ -184,7 +185,7 @@ function ColorsView({
|
|
|
184
185
|
/* @__PURE__ */ jsx2("div", { className: "@container", children: /* @__PURE__ */ jsx2("div", { className: cn("grid gap-4", containerGridClass[columns] || containerGridClass[3]), children: colors.map((color, i) => {
|
|
185
186
|
const hex = color.spaces[0]?.hex;
|
|
186
187
|
const contrast = getContrastClass(hex);
|
|
187
|
-
return /* @__PURE__ */ jsxs2("div", { className: "overflow-hidden rounded-outer border border-base-200", children: [
|
|
188
|
+
return /* @__PURE__ */ jsxs2("div", { className: "flex h-full flex-col overflow-hidden rounded-outer border border-base-200", children: [
|
|
188
189
|
/* @__PURE__ */ jsxs2("div", { className: cn("relative flex min-h-[80px] items-end p-3", contrast), style: { backgroundColor: hex || "#ccc" }, children: [
|
|
189
190
|
color.name && /* @__PURE__ */ jsx2("span", { className: "text-sm font-bold", children: color.name }),
|
|
190
191
|
copiedIndex === i && /* @__PURE__ */ jsx2("span", { className: cn(
|
|
@@ -192,7 +193,8 @@ function ColorsView({
|
|
|
192
193
|
getContrastClass(hex) === "text-black" ? "bg-black/15 text-black" : "bg-white/25 text-white"
|
|
193
194
|
), children: "Copied!" })
|
|
194
195
|
] }),
|
|
195
|
-
expanded &&
|
|
196
|
+
expanded && // flex-1 so every swatch's label block grows to the tallest in its row.
|
|
197
|
+
/* @__PURE__ */ jsx2("div", { className: "flex-1 space-y-1 bg-base-accent p-3 text-sm", children: color.spaces.map(
|
|
196
198
|
(space, j) => Object.entries(space).map(
|
|
197
199
|
([key, value]) => value ? /* @__PURE__ */ jsxs2("button", { onClick: () => handleCopy(value, i), className: "cursor-pointer flex w-full justify-between hover:text-primary", children: [
|
|
198
200
|
/* @__PURE__ */ jsx2("span", { className: "font-medium uppercase", children: key }),
|
|
@@ -211,7 +213,8 @@ function ColorsEditable({
|
|
|
211
213
|
collapsing,
|
|
212
214
|
showLabel,
|
|
213
215
|
onChange,
|
|
214
|
-
openModal
|
|
216
|
+
openModal,
|
|
217
|
+
onDelete
|
|
215
218
|
}) {
|
|
216
219
|
const [expanded, setExpanded] = useState2(!collapsing);
|
|
217
220
|
const options = { label, columns, collapsing, showLabel };
|
|
@@ -257,6 +260,8 @@ function ColorsEditable({
|
|
|
257
260
|
{
|
|
258
261
|
items: colors,
|
|
259
262
|
columns,
|
|
263
|
+
group: "colors",
|
|
264
|
+
onEmptied: onDelete,
|
|
260
265
|
onChange: (newColors) => onChange(buildContent(newColors, options)),
|
|
261
266
|
createItem: createColorItem,
|
|
262
267
|
isEditMode: true,
|
|
@@ -290,7 +295,7 @@ function ColorSwatchEditable({
|
|
|
290
295
|
const newColors = colors.map((c, i) => i === index ? updated : c);
|
|
291
296
|
onChange(buildContent(newColors, options));
|
|
292
297
|
};
|
|
293
|
-
return /* @__PURE__ */ jsxs2("div", { className: "overflow-hidden rounded-outer border border-base-200", children: [
|
|
298
|
+
return /* @__PURE__ */ jsxs2("div", { className: "flex h-full flex-col overflow-hidden rounded-outer border border-base-200", children: [
|
|
294
299
|
/* @__PURE__ */ jsx2("div", { className: cn("flex min-h-[80px] items-end p-3", contrast), style: { backgroundColor: hex || "#ccc" }, children: /* @__PURE__ */ jsx2(
|
|
295
300
|
EditablePlainText,
|
|
296
301
|
{
|
|
@@ -302,7 +307,8 @@ function ColorSwatchEditable({
|
|
|
302
307
|
className: "text-sm font-bold"
|
|
303
308
|
}
|
|
304
309
|
) }),
|
|
305
|
-
expanded &&
|
|
310
|
+
expanded && // flex-1 so every swatch's label block grows to the tallest in its row.
|
|
311
|
+
/* @__PURE__ */ jsx2("div", { className: "flex-1 space-y-1 bg-base-accent p-3 text-sm", children: color.spaces.map(
|
|
306
312
|
(space, j) => Object.entries(space).map(
|
|
307
313
|
([key, value]) => value ? /* @__PURE__ */ jsxs2("div", { className: "flex w-full justify-between", children: [
|
|
308
314
|
/* @__PURE__ */ jsx2("span", { className: "font-medium uppercase", children: key }),
|
|
@@ -346,7 +352,7 @@ var Colors_default = defineSection({
|
|
|
346
352
|
icon: /* @__PURE__ */ jsx3(Palette, { size: 18 }),
|
|
347
353
|
schema,
|
|
348
354
|
authoringNote: "A brand color palette. Each color may carry hex/rgb/cmyk/pantone values. Use to document brand colors with swatches.",
|
|
349
|
-
component: ({ content, options, onChange, openModal }) => /* @__PURE__ */ jsx3(
|
|
355
|
+
component: ({ content, options, onChange, openModal, onDelete }) => /* @__PURE__ */ jsx3(
|
|
350
356
|
Colors,
|
|
351
357
|
{
|
|
352
358
|
colors: content.content.colors,
|
|
@@ -355,7 +361,8 @@ var Colors_default = defineSection({
|
|
|
355
361
|
collapsing: options?.collapsing,
|
|
356
362
|
showLabel: options?.showLabel,
|
|
357
363
|
onChange: onChange ? (c) => onChange(c) : void 0,
|
|
358
|
-
openModal
|
|
364
|
+
openModal,
|
|
365
|
+
onDelete
|
|
359
366
|
}
|
|
360
367
|
),
|
|
361
368
|
defaults: () => ({
|
|
@@ -319,7 +319,7 @@ function MediaBlock({ refValue, options, link, isEditMode, onRefChange }) {
|
|
|
319
319
|
}
|
|
320
320
|
|
|
321
321
|
// src/components/primitives/EditableGrid.tsx
|
|
322
|
-
import { useRef as useRef4, useEffect as useEffect4, useState as useState5 } from "react";
|
|
322
|
+
import { useRef as useRef4, useEffect as useEffect4, useState as useState5, useId } from "react";
|
|
323
323
|
import { ImageIcon as ImageIcon2 } from "lucide-react";
|
|
324
324
|
|
|
325
325
|
// src/lib/container-grid.ts
|
|
@@ -411,6 +411,17 @@ function useEditableCollection({
|
|
|
411
411
|
},
|
|
412
412
|
[createItem, onChange]
|
|
413
413
|
);
|
|
414
|
+
const onInsertItem = useCallback3(
|
|
415
|
+
(index, data) => {
|
|
416
|
+
setWrappedItems((prev) => {
|
|
417
|
+
const next = [...prev];
|
|
418
|
+
next.splice(index, 0, { id: uid(), data });
|
|
419
|
+
onChange(next.map((w) => w.data));
|
|
420
|
+
return next;
|
|
421
|
+
});
|
|
422
|
+
},
|
|
423
|
+
[onChange]
|
|
424
|
+
);
|
|
414
425
|
const onRemove = useCallback3(
|
|
415
426
|
(id) => {
|
|
416
427
|
setWrappedItems((prev) => {
|
|
@@ -421,7 +432,19 @@ function useEditableCollection({
|
|
|
421
432
|
},
|
|
422
433
|
[onChange]
|
|
423
434
|
);
|
|
424
|
-
return { wrappedItems, onReorder, onAdd, onInsert, onRemove };
|
|
435
|
+
return { wrappedItems, onReorder, onAdd, onInsert, onInsertItem, onRemove };
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
// src/components/primitives/gridDrop.ts
|
|
439
|
+
function resolveDropIndex({
|
|
440
|
+
fromIndex,
|
|
441
|
+
targetIndex,
|
|
442
|
+
edge,
|
|
443
|
+
sameCollection
|
|
444
|
+
}) {
|
|
445
|
+
let toIndex = targetIndex + (edge === "right" ? 1 : 0);
|
|
446
|
+
if (sameCollection && fromIndex < toIndex) toIndex--;
|
|
447
|
+
return toIndex;
|
|
425
448
|
}
|
|
426
449
|
|
|
427
450
|
// src/components/primitives/EditableGrid.tsx
|
|
@@ -436,26 +459,57 @@ function EditableGrid({
|
|
|
436
459
|
onItemSettings,
|
|
437
460
|
onItemImageClick,
|
|
438
461
|
chromeTopClass,
|
|
439
|
-
className
|
|
462
|
+
className,
|
|
463
|
+
group,
|
|
464
|
+
onEmptied
|
|
440
465
|
}) {
|
|
441
|
-
const
|
|
466
|
+
const gridId = useId();
|
|
467
|
+
const { wrappedItems, onReorder, onAdd, onInsert, onInsertItem, onRemove } = useEditableCollection({
|
|
442
468
|
items,
|
|
443
469
|
onChange,
|
|
444
470
|
createItem
|
|
445
471
|
});
|
|
446
472
|
const [dragState, setDragState] = useState5({ sourceId: null, closestEdge: null });
|
|
447
473
|
const [isDragging, setIsDragging] = useState5(false);
|
|
474
|
+
const cfgRef = useRef4({ gridId, group, itemCount: wrappedItems.length, onReorder, onRemove, onInsertItem, onEmptied });
|
|
475
|
+
cfgRef.current = { gridId, group, itemCount: wrappedItems.length, onReorder, onRemove, onInsertItem, onEmptied };
|
|
448
476
|
useEffect4(() => {
|
|
449
477
|
let cleanup;
|
|
450
478
|
let cancelled = false;
|
|
451
|
-
|
|
479
|
+
Promise.all([
|
|
480
|
+
import("./adapter-HH47ZPGM.js"),
|
|
481
|
+
import("./closest-edge-EBOXL3YW.js")
|
|
482
|
+
]).then(([{ monitorForElements }, { extractClosestEdge }]) => {
|
|
452
483
|
if (cancelled) return;
|
|
453
484
|
cleanup = monitorForElements({
|
|
454
485
|
onDragStart: ({ source }) => {
|
|
455
486
|
if (source.data.dragType === "grid-cell") setIsDragging(true);
|
|
456
487
|
},
|
|
457
|
-
onDrop: ({ source }) => {
|
|
458
|
-
if (source.data.dragType
|
|
488
|
+
onDrop: ({ source, location }) => {
|
|
489
|
+
if (source.data.dragType !== "grid-cell") return;
|
|
490
|
+
setIsDragging(false);
|
|
491
|
+
setDragState({ sourceId: null, closestEdge: null });
|
|
492
|
+
const { gridId: my, group: myGroup, itemCount, onReorder: onReorder2, onRemove: onRemove2, onInsertItem: onInsertItem2, onEmptied: onEmptied2 } = cfgRef.current;
|
|
493
|
+
const srcGridId = source.data.gridId;
|
|
494
|
+
const target = location.current.dropTargets[0];
|
|
495
|
+
const dstGridId = target?.data.gridId;
|
|
496
|
+
if (srcGridId === my && dstGridId === my && target) {
|
|
497
|
+
const fromIndex = source.data.index;
|
|
498
|
+
const edge = extractClosestEdge(target.data);
|
|
499
|
+
const toIndex = resolveDropIndex({ fromIndex, targetIndex: target.data.index, edge, sameCollection: true });
|
|
500
|
+
if (fromIndex !== toIndex) onReorder2(fromIndex, toIndex);
|
|
501
|
+
return;
|
|
502
|
+
}
|
|
503
|
+
const crossAllowed = myGroup != null && source.data.group === myGroup;
|
|
504
|
+
if (!crossAllowed) return;
|
|
505
|
+
if (srcGridId === my && dstGridId && dstGridId !== my) {
|
|
506
|
+
if (itemCount <= 1 && onEmptied2) onEmptied2();
|
|
507
|
+
else onRemove2(source.data.id);
|
|
508
|
+
} else if (dstGridId === my && srcGridId !== my && target) {
|
|
509
|
+
const edge = extractClosestEdge(target.data);
|
|
510
|
+
const toIndex = resolveDropIndex({ fromIndex: source.data.index, targetIndex: target.data.index, edge, sameCollection: false });
|
|
511
|
+
onInsertItem2(toIndex, source.data.item);
|
|
512
|
+
}
|
|
459
513
|
}
|
|
460
514
|
});
|
|
461
515
|
});
|
|
@@ -473,9 +527,11 @@ function EditableGrid({
|
|
|
473
527
|
{
|
|
474
528
|
id: wrapped.id,
|
|
475
529
|
index,
|
|
530
|
+
gridId,
|
|
531
|
+
group,
|
|
532
|
+
item: wrapped.data,
|
|
476
533
|
isLast: index === wrappedItems.length - 1,
|
|
477
534
|
isDragging,
|
|
478
|
-
onReorder,
|
|
479
535
|
onRemove,
|
|
480
536
|
onInsert,
|
|
481
537
|
onSettings: onItemSettings ? () => onItemSettings(index) : void 0,
|
|
@@ -503,9 +559,11 @@ function EditableGrid({
|
|
|
503
559
|
function GridCell({
|
|
504
560
|
id,
|
|
505
561
|
index,
|
|
562
|
+
gridId,
|
|
563
|
+
group,
|
|
564
|
+
item,
|
|
506
565
|
isLast,
|
|
507
566
|
isDragging,
|
|
508
|
-
onReorder,
|
|
509
567
|
onRemove,
|
|
510
568
|
onInsert,
|
|
511
569
|
onSettings,
|
|
@@ -530,15 +588,18 @@ function GridCell({
|
|
|
530
588
|
if (cancelled) return;
|
|
531
589
|
const cleanupDraggable = draggable({
|
|
532
590
|
element: handle,
|
|
533
|
-
|
|
591
|
+
// `item` rides along so a cross-grid destination can insert it verbatim.
|
|
592
|
+
getInitialData: () => ({ dragType: "grid-cell", gridId, group, id, index, item }),
|
|
534
593
|
onDragStart: () => setDragState({ sourceId: id, closestEdge: null }),
|
|
535
594
|
onDrop: () => setDragState({ sourceId: null, closestEdge: null })
|
|
536
595
|
});
|
|
537
596
|
const cleanupDropTarget = dropTargetForElements({
|
|
538
597
|
element: cell,
|
|
539
|
-
|
|
598
|
+
// Accept a reorder within this grid, or a transfer from another grid in
|
|
599
|
+
// the same group. The actual move is performed by the grid-level monitor.
|
|
600
|
+
canDrop: ({ source }) => source.data.dragType === "grid-cell" && (source.data.gridId === gridId || group != null && source.data.group === group),
|
|
540
601
|
getData: ({ input, element }) => attachClosestEdge(
|
|
541
|
-
{ id, index },
|
|
602
|
+
{ gridId, id, index },
|
|
542
603
|
{ input, element, allowedEdges: ["left", "right"] }
|
|
543
604
|
),
|
|
544
605
|
onDragEnter: ({ self }) => {
|
|
@@ -551,16 +612,6 @@ function GridCell({
|
|
|
551
612
|
},
|
|
552
613
|
onDragLeave: () => {
|
|
553
614
|
setDragState((prev) => prev.closestEdge?.id === id ? { ...prev, closestEdge: null } : prev);
|
|
554
|
-
},
|
|
555
|
-
onDrop: ({ source, self }) => {
|
|
556
|
-
const fromIndex = source.data.index;
|
|
557
|
-
const edge = extractClosestEdge(self.data);
|
|
558
|
-
let toIndex = index;
|
|
559
|
-
if (edge === "right") toIndex = index + 1;
|
|
560
|
-
if (fromIndex < toIndex) toIndex--;
|
|
561
|
-
if (fromIndex !== toIndex) {
|
|
562
|
-
onReorder(fromIndex, toIndex);
|
|
563
|
-
}
|
|
564
615
|
}
|
|
565
616
|
});
|
|
566
617
|
cleanup = () => {
|
|
@@ -572,7 +623,7 @@ function GridCell({
|
|
|
572
623
|
cancelled = true;
|
|
573
624
|
cleanup?.();
|
|
574
625
|
};
|
|
575
|
-
}, [id, index,
|
|
626
|
+
}, [id, index, gridId, group, item, setDragState]);
|
|
576
627
|
const isCellDragging = dragState.sourceId === id;
|
|
577
628
|
const showLeftEdge = dragState.closestEdge?.id === id && dragState.closestEdge.edge === "left" && dragState.sourceId !== id;
|
|
578
629
|
const showRightEdge = dragState.closestEdge?.id === id && dragState.closestEdge.edge === "right" && dragState.sourceId !== id;
|
|
@@ -581,7 +632,9 @@ function GridCell({
|
|
|
581
632
|
{
|
|
582
633
|
ref: cellRef,
|
|
583
634
|
className: cn(
|
|
584
|
-
|
|
635
|
+
// h-full so a full-height renderItem (e.g. a colors swatch) fills the
|
|
636
|
+
// stretched grid track and can equalize height across the row.
|
|
637
|
+
"group/cell relative h-full",
|
|
585
638
|
isCellDragging && "opacity-50"
|
|
586
639
|
),
|
|
587
640
|
children: [
|
|
@@ -9,7 +9,8 @@ interface Props {
|
|
|
9
9
|
showLabel?: boolean;
|
|
10
10
|
onChange?: (content: SectionContent) => void;
|
|
11
11
|
openModal?: (title: string, content: ReactNode) => void;
|
|
12
|
+
onDelete?: () => void;
|
|
12
13
|
}
|
|
13
|
-
export default function Colors({ colors, columns, label, collapsing, showLabel, onChange, openModal }: Props): import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
export default function Colors({ colors, columns, label, collapsing, showLabel, onChange, openModal, onDelete }: Props): import("react/jsx-runtime").JSX.Element;
|
|
14
15
|
export {};
|
|
15
16
|
//# sourceMappingURL=Colors.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Colors.d.ts","sourceRoot":"","sources":["../../../src/components/brandguide/Colors.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE7D,UAAU,KAAK;IACb,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC;IAC7C,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,KAAK,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"Colors.d.ts","sourceRoot":"","sources":["../../../src/components/brandguide/Colors.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE7D,UAAU,KAAK;IACb,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC;IAC7C,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,KAAK,IAAI,CAAC;IACxD,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;CACvB;AAgCD,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,EAAE,MAAM,EAAE,OAAW,EAAE,KAAK,EAAE,UAAU,EAAE,SAAgB,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,KAAK,2CAiBhI"}
|
|
@@ -13,7 +13,17 @@ interface EditableGridProps<T> {
|
|
|
13
13
|
onItemImageClick?: (index: number) => void;
|
|
14
14
|
chromeTopClass?: string;
|
|
15
15
|
className?: string;
|
|
16
|
+
/**
|
|
17
|
+
* Items can be dragged BETWEEN two EditableGrids that share the same non-null
|
|
18
|
+
* `group` (e.g. two colors sections). Without a group, a grid only reorders
|
|
19
|
+
* its own items. Only pass the same group to grids whose item shape matches —
|
|
20
|
+
* a cross-grid drop inserts the source item verbatim into the destination.
|
|
21
|
+
*/
|
|
22
|
+
group?: string;
|
|
23
|
+
/** Called instead of removing the last item when it is dragged out to another
|
|
24
|
+
* grid — lets the owner tear down a now-empty container (e.g. delete the section). */
|
|
25
|
+
onEmptied?: () => void;
|
|
16
26
|
}
|
|
17
|
-
export declare function EditableGrid<T>({ items, columns, onChange, createItem, isEditMode, renderItem, onItemSettings, onItemImageClick, chromeTopClass, className, }: EditableGridProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
27
|
+
export declare function EditableGrid<T>({ items, columns, onChange, createItem, isEditMode, renderItem, onItemSettings, onItemImageClick, chromeTopClass, className, group, onEmptied, }: EditableGridProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
18
28
|
export {};
|
|
19
29
|
//# sourceMappingURL=EditableGrid.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EditableGrid.d.ts","sourceRoot":"","sources":["../../../src/components/primitives/EditableGrid.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"EditableGrid.d.ts","sourceRoot":"","sources":["../../../src/components/primitives/EditableGrid.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAsC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAS3E,UAAU,iBAAiB,CAAC,CAAC;IAC3B,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,IAAI,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE;QAAE,UAAU,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,KAAK,SAAS,CAAC;IAClF,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;2FACuF;IACvF,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB;AAED,wBAAgB,YAAY,CAAC,CAAC,EAAE,EAC9B,KAAK,EACL,OAAO,EACP,QAAQ,EACR,UAAU,EACV,UAAU,EACV,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,SAAS,EACT,KAAK,EACL,SAAS,GACV,EAAE,iBAAiB,CAAC,CAAC,CAAC,2CAqItB"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convert a drop target (the cell being dropped onto + the closest edge) into
|
|
3
|
+
* the destination index for the moved item.
|
|
4
|
+
*
|
|
5
|
+
* Same-collection reorder: the dragged item is spliced OUT of the array before
|
|
6
|
+
* being re-inserted, so a destination past its original position shifts down by
|
|
7
|
+
* one — hence the `fromIndex < toIndex` decrement.
|
|
8
|
+
*
|
|
9
|
+
* Cross-collection insert: nothing is removed from the destination array, so no
|
|
10
|
+
* shift adjustment applies.
|
|
11
|
+
*/
|
|
12
|
+
export declare function resolveDropIndex({ fromIndex, targetIndex, edge, sameCollection, }: {
|
|
13
|
+
fromIndex: number;
|
|
14
|
+
targetIndex: number;
|
|
15
|
+
edge: "left" | "right" | null;
|
|
16
|
+
sameCollection: boolean;
|
|
17
|
+
}): number;
|
|
18
|
+
//# sourceMappingURL=gridDrop.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gridDrop.d.ts","sourceRoot":"","sources":["../../../src/components/primitives/gridDrop.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,SAAS,EACT,WAAW,EACX,IAAI,EACJ,cAAc,GACf,EAAE;IACD,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;IAC9B,cAAc,EAAE,OAAO,CAAC;CACzB,GAAG,MAAM,CAIT"}
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
EditableRichText,
|
|
3
3
|
LinkPopover,
|
|
4
4
|
defineHeadingSection
|
|
5
|
-
} from "../../chunk-
|
|
5
|
+
} from "../../chunk-VI26O4E3.js";
|
|
6
6
|
import {
|
|
7
7
|
EditableGrid,
|
|
8
8
|
EditablePlainText,
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
MediaBlock,
|
|
11
11
|
ResolvedMedia,
|
|
12
12
|
useEditableCollection
|
|
13
|
-
} from "../../chunk-
|
|
13
|
+
} from "../../chunk-KVQFMVXE.js";
|
|
14
14
|
import "../../chunk-ZSPCE6MZ.js";
|
|
15
15
|
import {
|
|
16
16
|
DeleteIcon,
|
|
@@ -12,6 +12,7 @@ interface UseEditableCollectionReturn<T> {
|
|
|
12
12
|
onReorder: (fromIndex: number, toIndex: number) => void;
|
|
13
13
|
onAdd: () => void;
|
|
14
14
|
onInsert: (index: number) => void;
|
|
15
|
+
onInsertItem: (index: number, data: T) => void;
|
|
15
16
|
onRemove: (id: string) => void;
|
|
16
17
|
}
|
|
17
18
|
export declare function useEditableCollection<T>({ items, onChange, createItem, }: UseEditableCollectionOptions<T>): UseEditableCollectionReturn<T>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useEditableCollection.d.ts","sourceRoot":"","sources":["../../../src/components/primitives/useEditableCollection.ts"],"names":[],"mappings":"AAEA,UAAU,WAAW,CAAC,CAAC;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,CAAC,CAAC;CACT;AAED,UAAU,4BAA4B,CAAC,CAAC;IACtC,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,IAAI,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC,CAAC;CACrB;AAED,UAAU,2BAA2B,CAAC,CAAC;IACrC,YAAY,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/B,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACxD,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;AAaD,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,EACvC,KAAK,EACL,QAAQ,EACR,UAAU,GACX,EAAE,4BAA4B,CAAC,CAAC,CAAC,GAAG,2BAA2B,CAAC,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"useEditableCollection.d.ts","sourceRoot":"","sources":["../../../src/components/primitives/useEditableCollection.ts"],"names":[],"mappings":"AAEA,UAAU,WAAW,CAAC,CAAC;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,CAAC,CAAC;CACT;AAED,UAAU,4BAA4B,CAAC,CAAC;IACtC,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,IAAI,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC,CAAC;CACrB;AAED,UAAU,2BAA2B,CAAC,CAAC;IACrC,YAAY,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/B,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACxD,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;IAC/C,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;AAaD,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,EACvC,KAAK,EACL,QAAQ,EACR,UAAU,GACX,EAAE,4BAA4B,CAAC,CAAC,CAAC,GAAG,2BAA2B,CAAC,CAAC,CAAC,CAiFlE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/sections/Colors/index.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AAwBA,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/sections/Colors/index.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AAwBA,wBAsCG"}
|
|
@@ -2,9 +2,9 @@ import {
|
|
|
2
2
|
ColorItemSchema,
|
|
3
3
|
ColorSpaceSchema,
|
|
4
4
|
brandGuideSectionDefs
|
|
5
|
-
} from "../../chunk-
|
|
5
|
+
} from "../../chunk-7XWER6YR.js";
|
|
6
6
|
import "../../chunk-5THS4K5D.js";
|
|
7
|
-
import "../../chunk-
|
|
7
|
+
import "../../chunk-KVQFMVXE.js";
|
|
8
8
|
import "../../chunk-EMGLZQCM.js";
|
|
9
9
|
import "../../chunk-3LNKOLZP.js";
|
|
10
10
|
import "../../chunk-PZJL2S3Z.js";
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
allSectionDefs
|
|
3
|
-
} from "../../chunk-
|
|
4
|
-
import "../../chunk-
|
|
3
|
+
} from "../../chunk-4TVODHD2.js";
|
|
4
|
+
import "../../chunk-7XWER6YR.js";
|
|
5
5
|
import "../../chunk-2DDWWTRX.js";
|
|
6
6
|
import "../../chunk-5THS4K5D.js";
|
|
7
|
-
import "../../chunk-
|
|
8
|
-
import "../../chunk-
|
|
7
|
+
import "../../chunk-VI26O4E3.js";
|
|
8
|
+
import "../../chunk-KVQFMVXE.js";
|
|
9
9
|
import "../../chunk-ZSPCE6MZ.js";
|
|
10
10
|
import "../../chunk-EMGLZQCM.js";
|
|
11
11
|
import "../../chunk-Y4JQGO6G.js";
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
allSectionDefs
|
|
3
|
-
} from "../../chunk-
|
|
4
|
-
import "../../chunk-
|
|
3
|
+
} from "../../chunk-4TVODHD2.js";
|
|
4
|
+
import "../../chunk-7XWER6YR.js";
|
|
5
5
|
import "../../chunk-2DDWWTRX.js";
|
|
6
6
|
import "../../chunk-5THS4K5D.js";
|
|
7
|
-
import "../../chunk-
|
|
8
|
-
import "../../chunk-
|
|
7
|
+
import "../../chunk-VI26O4E3.js";
|
|
8
|
+
import "../../chunk-KVQFMVXE.js";
|
|
9
9
|
import "../../chunk-ZSPCE6MZ.js";
|
|
10
10
|
import "../../chunk-EMGLZQCM.js";
|
|
11
11
|
import "../../chunk-Y4JQGO6G.js";
|
|
@@ -13,10 +13,12 @@ interface EditorContextValue {
|
|
|
13
13
|
showAllChrome: boolean;
|
|
14
14
|
viewBranch: "saved" | "live";
|
|
15
15
|
historyState: HistoryState;
|
|
16
|
+
historyPageId: string | null;
|
|
16
17
|
toggleEditMode: () => void;
|
|
17
18
|
toggleShowAllChrome: () => void;
|
|
18
19
|
setViewBranch: (branch: "saved" | "live") => void;
|
|
19
20
|
setHistoryState: (state: HistoryState) => void;
|
|
21
|
+
setHistoryPageId: (pageId: string | null) => void;
|
|
20
22
|
}
|
|
21
23
|
interface EditorProviderProps {
|
|
22
24
|
children: ReactNode;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EditorContext.d.ts","sourceRoot":"","sources":["../../../src/components/shell/EditorContext.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAoD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAEzF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAEvE,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,KAAK,EAAE,SAAS,CAAC;IACjB,UAAU,EAAE,UAAU,CAAC;CACxB,GAAG,IAAI,CAAC;AAET,UAAU,kBAAkB;IAC1B,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,OAAO,CAAC;IACvB,UAAU,EAAE,OAAO,GAAG,MAAM,CAAC;IAC7B,YAAY,EAAE,YAAY,CAAC;IAC3B,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,mBAAmB,EAAE,MAAM,IAAI,CAAC;IAChC,aAAa,EAAE,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,KAAK,IAAI,CAAC;IAClD,eAAe,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"EditorContext.d.ts","sourceRoot":"","sources":["../../../src/components/shell/EditorContext.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAoD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAEzF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAEvE,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,KAAK,EAAE,SAAS,CAAC;IACjB,UAAU,EAAE,UAAU,CAAC;CACxB,GAAG,IAAI,CAAC;AAET,UAAU,kBAAkB;IAC1B,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,OAAO,CAAC;IACvB,UAAU,EAAE,OAAO,GAAG,MAAM,CAAC;IAC7B,YAAY,EAAE,YAAY,CAAC;IAC3B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,mBAAmB,EAAE,MAAM,IAAI,CAAC;IAChC,aAAa,EAAE,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,KAAK,IAAI,CAAC;IAClD,eAAe,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IAC/C,gBAAgB,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;CACnD;AAID,UAAU,mBAAmB;IAC3B,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,wBAAgB,cAAc,CAAC,EAAE,QAAQ,EAAE,EAAE,mBAAmB,2CA4B/D;AAED,wBAAgB,gBAAgB,IAAI,kBAAkB,CAMrD"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Audience } from "../../auth/types";
|
|
2
|
+
import { type HistoryState } from "./EditorContext";
|
|
2
3
|
import type { CollabBootstrap } from "../../collab/types";
|
|
3
4
|
export { useMediaLibrary } from "./MediaLibraryContext";
|
|
4
5
|
interface Props {
|
|
@@ -22,4 +23,16 @@ interface Props {
|
|
|
22
23
|
collabBootstrap?: CollabBootstrap | null;
|
|
23
24
|
}
|
|
24
25
|
export default function EditorShell({ headSha, draftHeadSha, siteId, audiences: initialAudiences, capabilities, currentUser, chatbotPlatformEnabled, collabBootstrap, }: Props): import("react/jsx-runtime").JSX.Element;
|
|
26
|
+
/** Resolve which historical page to show: explicit selection → the page the
|
|
27
|
+
* editor is currently on (if it existed at that version) → home → first. */
|
|
28
|
+
export declare function resolveHistoryPage(historyState: NonNullable<HistoryState>, historyPageId: string | null, preferredPageId: string | null): {
|
|
29
|
+
id: string;
|
|
30
|
+
title: string;
|
|
31
|
+
slug: string;
|
|
32
|
+
isHome: boolean;
|
|
33
|
+
showInNav: boolean;
|
|
34
|
+
status: "live" | "archived";
|
|
35
|
+
access: string[];
|
|
36
|
+
order: string[];
|
|
37
|
+
};
|
|
25
38
|
//# sourceMappingURL=EditorShell.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EditorShell.d.ts","sourceRoot":"","sources":["../../../src/components/shell/EditorShell.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"EditorShell.d.ts","sourceRoot":"","sources":["../../../src/components/shell/EditorShell.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAKjD,OAAO,EAAoC,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AA6CtF,OAAO,KAAK,EAAE,eAAe,EAA2D,MAAM,oBAAoB,CAAC;AAmCnH,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAoBxD,UAAU,KAAK;IACb,OAAO,EAAE,MAAM,CAAC;IAIhB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,YAAY,EAAE;QACZ,KAAK,EAAE,OAAO,CAAC;QACf,aAAa,EAAE,OAAO,CAAC;QACvB,YAAY,EAAE,OAAO,CAAC;QACtB,cAAc,EAAE,OAAO,CAAC;QACxB,kBAAkB,EAAE,OAAO,CAAC;QAC5B,cAAc,EAAE,OAAO,CAAC;KACzB,CAAC;IACF,WAAW,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAA;KAAE,GAAG,IAAI,CAAC;IAIhE,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAKjC,eAAe,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;CAC1C;AAED,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,EAClC,OAAO,EACP,YAAY,EACZ,MAAM,EACN,SAAS,EAAE,gBAAgB,EAC3B,YAAY,EACZ,WAAW,EACX,sBAA8B,EAC9B,eAAe,GAChB,EAAE,KAAK,2CA88CP;AA2DD;6EAC6E;AAC7E,wBAAgB,kBAAkB,CAChC,YAAY,EAAE,WAAW,CAAC,YAAY,CAAC,EACvC,aAAa,EAAE,MAAM,GAAG,IAAI,EAC5B,eAAe,EAAE,MAAM,GAAG,IAAI;;;;;;;;;EAK/B"}
|
|
@@ -1,8 +1,15 @@
|
|
|
1
|
+
interface HistoryPageOption {
|
|
2
|
+
id: string;
|
|
3
|
+
title: string;
|
|
4
|
+
}
|
|
1
5
|
interface HistoryToolbarProps {
|
|
2
6
|
date: string;
|
|
7
|
+
pages: HistoryPageOption[];
|
|
8
|
+
activePageId: string;
|
|
9
|
+
onPageChange: (pageId: string) => void;
|
|
3
10
|
onBackToCurrent: () => void;
|
|
4
11
|
onRestore: () => void;
|
|
5
12
|
}
|
|
6
|
-
export declare function HistoryToolbar({ date, onBackToCurrent, onRestore }: HistoryToolbarProps): import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
export declare function HistoryToolbar({ date, pages, activePageId, onPageChange, onBackToCurrent, onRestore }: HistoryToolbarProps): import("react/jsx-runtime").JSX.Element;
|
|
7
14
|
export {};
|
|
8
15
|
//# sourceMappingURL=HistoryToolbar.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HistoryToolbar.d.ts","sourceRoot":"","sources":["../../../src/components/shell/HistoryToolbar.tsx"],"names":[],"mappings":"AAGA,UAAU,mBAAmB;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,SAAS,EAAE,MAAM,IAAI,CAAC;CACvB;AAED,wBAAgB,cAAc,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,SAAS,EAAE,EAAE,mBAAmB,
|
|
1
|
+
{"version":3,"file":"HistoryToolbar.d.ts","sourceRoot":"","sources":["../../../src/components/shell/HistoryToolbar.tsx"],"names":[],"mappings":"AAGA,UAAU,iBAAiB;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;CACf;AAED,UAAU,mBAAmB;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,iBAAiB,EAAE,CAAC;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,SAAS,EAAE,MAAM,IAAI,CAAC;CACvB;AAED,wBAAgB,cAAc,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,SAAS,EAAE,EAAE,mBAAmB,2CAoC1H"}
|
package/dist/lib/registry.d.ts
CHANGED
|
@@ -72,6 +72,9 @@ export interface SectionProps<T = unknown> {
|
|
|
72
72
|
onChange?: (content: T) => void;
|
|
73
73
|
isEditMode: boolean;
|
|
74
74
|
openModal?: (title: string, content: ReactNode) => void;
|
|
75
|
+
/** Delete this whole section. Used e.g. when a colors section's last swatch
|
|
76
|
+
* is dragged into another section, leaving it empty. */
|
|
77
|
+
onDelete?: () => void;
|
|
75
78
|
}
|
|
76
79
|
export interface WrapperProps {
|
|
77
80
|
sectionId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/lib/registry.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/lib/registry.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -17,6 +17,7 @@ interface Props {
|
|
|
17
17
|
showLabel?: boolean;
|
|
18
18
|
onChange?: (content: SectionContent) => void;
|
|
19
19
|
openModal?: (title: string, content: ReactNode) => void;
|
|
20
|
+
onDelete?: () => void;
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
function getContrastClass(hex: string | undefined): string {
|
|
@@ -49,7 +50,7 @@ function buildContent(
|
|
|
49
50
|
};
|
|
50
51
|
}
|
|
51
52
|
|
|
52
|
-
export default function Colors({ colors, columns = 3, label, collapsing, showLabel = true, onChange, openModal }: Props) {
|
|
53
|
+
export default function Colors({ colors, columns = 3, label, collapsing, showLabel = true, onChange, openModal, onDelete }: Props) {
|
|
53
54
|
if (onChange && openModal) {
|
|
54
55
|
return (
|
|
55
56
|
<ColorsEditable
|
|
@@ -60,6 +61,7 @@ export default function Colors({ colors, columns = 3, label, collapsing, showLab
|
|
|
60
61
|
showLabel={showLabel}
|
|
61
62
|
onChange={onChange}
|
|
62
63
|
openModal={openModal}
|
|
64
|
+
onDelete={onDelete}
|
|
63
65
|
/>
|
|
64
66
|
);
|
|
65
67
|
}
|
|
@@ -125,7 +127,7 @@ function ColorsView({
|
|
|
125
127
|
const hex = color.spaces[0]?.hex;
|
|
126
128
|
const contrast = getContrastClass(hex);
|
|
127
129
|
return (
|
|
128
|
-
<div key={i} className="overflow-hidden rounded-outer border border-base-200">
|
|
130
|
+
<div key={i} className="flex h-full flex-col overflow-hidden rounded-outer border border-base-200">
|
|
129
131
|
<div className={cn("relative flex min-h-[80px] items-end p-3", contrast)} style={{ backgroundColor: hex || "#ccc" }}>
|
|
130
132
|
{color.name && <span className="text-sm font-bold">{color.name}</span>}
|
|
131
133
|
{copiedIndex === i && (
|
|
@@ -138,7 +140,8 @@ function ColorsView({
|
|
|
138
140
|
)}
|
|
139
141
|
</div>
|
|
140
142
|
{expanded && (
|
|
141
|
-
|
|
143
|
+
// flex-1 so every swatch's label block grows to the tallest in its row.
|
|
144
|
+
<div className="flex-1 space-y-1 bg-base-accent p-3 text-sm">
|
|
142
145
|
{color.spaces.map((space, j) =>
|
|
143
146
|
Object.entries(space).map(([key, value]) =>
|
|
144
147
|
value ? (
|
|
@@ -168,6 +171,7 @@ function ColorsEditable({
|
|
|
168
171
|
showLabel,
|
|
169
172
|
onChange,
|
|
170
173
|
openModal,
|
|
174
|
+
onDelete,
|
|
171
175
|
}: {
|
|
172
176
|
colors: ColorItem[];
|
|
173
177
|
columns: number;
|
|
@@ -176,6 +180,7 @@ function ColorsEditable({
|
|
|
176
180
|
showLabel?: boolean;
|
|
177
181
|
onChange: (content: SectionContent) => void;
|
|
178
182
|
openModal: (title: string, content: ReactNode) => void;
|
|
183
|
+
onDelete?: () => void;
|
|
179
184
|
}) {
|
|
180
185
|
const [expanded, setExpanded] = useState(!collapsing);
|
|
181
186
|
const options = { label, columns, collapsing, showLabel };
|
|
@@ -224,6 +229,10 @@ function ColorsEditable({
|
|
|
224
229
|
<EditableGrid
|
|
225
230
|
items={colors}
|
|
226
231
|
columns={columns}
|
|
232
|
+
// Shared group lets a swatch be dragged from one colors section into another.
|
|
233
|
+
group="colors"
|
|
234
|
+
// When the last swatch is dragged out to another section, delete this now-empty one.
|
|
235
|
+
onEmptied={onDelete}
|
|
227
236
|
onChange={(newColors) => onChange(buildContent(newColors, options))}
|
|
228
237
|
createItem={createColorItem}
|
|
229
238
|
isEditMode={true}
|
|
@@ -267,7 +276,7 @@ function ColorSwatchEditable({
|
|
|
267
276
|
};
|
|
268
277
|
|
|
269
278
|
return (
|
|
270
|
-
<div className="overflow-hidden rounded-outer border border-base-200">
|
|
279
|
+
<div className="flex h-full flex-col overflow-hidden rounded-outer border border-base-200">
|
|
271
280
|
<div className={cn("flex min-h-[80px] items-end p-3", contrast)} style={{ backgroundColor: hex || "#ccc" }}>
|
|
272
281
|
<EditablePlainText
|
|
273
282
|
tag="span"
|
|
@@ -279,7 +288,8 @@ function ColorSwatchEditable({
|
|
|
279
288
|
/>
|
|
280
289
|
</div>
|
|
281
290
|
{expanded && (
|
|
282
|
-
|
|
291
|
+
// flex-1 so every swatch's label block grows to the tallest in its row.
|
|
292
|
+
<div className="flex-1 space-y-1 bg-base-accent p-3 text-sm">
|
|
283
293
|
{color.spaces.map((space, j) =>
|
|
284
294
|
Object.entries(space).map(([key, value]) =>
|
|
285
295
|
value ? (
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { useRef, useEffect, useState, type ReactNode } from "react";
|
|
1
|
+
import { useRef, useEffect, useState, useId, type ReactNode } from "react";
|
|
2
2
|
import { ImageIcon } from "lucide-react";
|
|
3
3
|
import { AddIcon, DragHandle, DeleteIcon, SettingsIcon } from "../shared/icons";
|
|
4
4
|
import { IconButton } from "../shared/IconButton";
|
|
5
5
|
import { cn } from "../../lib/cn";
|
|
6
6
|
import { containerGridClass } from "../../lib/container-grid";
|
|
7
7
|
import { useEditableCollection } from "./useEditableCollection";
|
|
8
|
+
import { resolveDropIndex } from "./gridDrop";
|
|
8
9
|
|
|
9
10
|
interface EditableGridProps<T> {
|
|
10
11
|
items: T[];
|
|
@@ -17,6 +18,16 @@ interface EditableGridProps<T> {
|
|
|
17
18
|
onItemImageClick?: (index: number) => void;
|
|
18
19
|
chromeTopClass?: string;
|
|
19
20
|
className?: string;
|
|
21
|
+
/**
|
|
22
|
+
* Items can be dragged BETWEEN two EditableGrids that share the same non-null
|
|
23
|
+
* `group` (e.g. two colors sections). Without a group, a grid only reorders
|
|
24
|
+
* its own items. Only pass the same group to grids whose item shape matches —
|
|
25
|
+
* a cross-grid drop inserts the source item verbatim into the destination.
|
|
26
|
+
*/
|
|
27
|
+
group?: string;
|
|
28
|
+
/** Called instead of removing the last item when it is dragged out to another
|
|
29
|
+
* grid — lets the owner tear down a now-empty container (e.g. delete the section). */
|
|
30
|
+
onEmptied?: () => void;
|
|
20
31
|
}
|
|
21
32
|
|
|
22
33
|
export function EditableGrid<T>({
|
|
@@ -30,8 +41,11 @@ export function EditableGrid<T>({
|
|
|
30
41
|
onItemImageClick,
|
|
31
42
|
chromeTopClass,
|
|
32
43
|
className,
|
|
44
|
+
group,
|
|
45
|
+
onEmptied,
|
|
33
46
|
}: EditableGridProps<T>) {
|
|
34
|
-
const
|
|
47
|
+
const gridId = useId();
|
|
48
|
+
const { wrappedItems, onReorder, onAdd, onInsert, onInsertItem, onRemove } = useEditableCollection({
|
|
35
49
|
items,
|
|
36
50
|
onChange,
|
|
37
51
|
createItem,
|
|
@@ -44,18 +58,63 @@ export function EditableGrid<T>({
|
|
|
44
58
|
|
|
45
59
|
const [isDragging, setIsDragging] = useState(false);
|
|
46
60
|
|
|
61
|
+
// The drop transaction is centralized here (not in each GridCell) because this
|
|
62
|
+
// monitor is GLOBAL: it fires for every grid-cell drop on the page, so the
|
|
63
|
+
// source grid and destination grid each see the same drop and act on their own
|
|
64
|
+
// collection — source removes, destination inserts, same-grid reorders. Keep
|
|
65
|
+
// the latest handlers/config in a ref so the monitor can be set up once.
|
|
66
|
+
const cfgRef = useRef({ gridId, group, itemCount: wrappedItems.length, onReorder, onRemove, onInsertItem, onEmptied });
|
|
67
|
+
cfgRef.current = { gridId, group, itemCount: wrappedItems.length, onReorder, onRemove, onInsertItem, onEmptied };
|
|
68
|
+
|
|
47
69
|
useEffect(() => {
|
|
48
70
|
let cleanup: (() => void) | undefined;
|
|
49
71
|
let cancelled = false;
|
|
50
72
|
|
|
51
|
-
|
|
73
|
+
Promise.all([
|
|
74
|
+
import("@atlaskit/pragmatic-drag-and-drop/element/adapter"),
|
|
75
|
+
import("@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge"),
|
|
76
|
+
]).then(([{ monitorForElements }, { extractClosestEdge }]) => {
|
|
52
77
|
if (cancelled) return;
|
|
53
78
|
cleanup = monitorForElements({
|
|
54
79
|
onDragStart: ({ source }) => {
|
|
55
80
|
if (source.data.dragType === "grid-cell") setIsDragging(true);
|
|
56
81
|
},
|
|
57
|
-
onDrop: ({ source }) => {
|
|
58
|
-
if (source.data.dragType
|
|
82
|
+
onDrop: ({ source, location }) => {
|
|
83
|
+
if (source.data.dragType !== "grid-cell") return;
|
|
84
|
+
setIsDragging(false);
|
|
85
|
+
// Every grid clears its own indicator on any drop — this is what stops
|
|
86
|
+
// the destination grid's drop line from sticking after a cross-grid drop.
|
|
87
|
+
setDragState({ sourceId: null, closestEdge: null });
|
|
88
|
+
|
|
89
|
+
const { gridId: my, group: myGroup, itemCount, onReorder, onRemove, onInsertItem, onEmptied } = cfgRef.current;
|
|
90
|
+
const srcGridId = source.data.gridId as string;
|
|
91
|
+
const target = location.current.dropTargets[0];
|
|
92
|
+
const dstGridId = target?.data.gridId as string | undefined;
|
|
93
|
+
|
|
94
|
+
// Same-grid reorder — only the owning grid acts on it.
|
|
95
|
+
if (srcGridId === my && dstGridId === my && target) {
|
|
96
|
+
const fromIndex = source.data.index as number;
|
|
97
|
+
const edge = extractClosestEdge(target.data) as "left" | "right" | null;
|
|
98
|
+
const toIndex = resolveDropIndex({ fromIndex, targetIndex: target.data.index as number, edge, sameCollection: true });
|
|
99
|
+
if (fromIndex !== toIndex) onReorder(fromIndex, toIndex);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Cross-grid transfer requires a shared group. The source grid removes
|
|
104
|
+
// its item; the destination grid inserts it. Two grids, two updates.
|
|
105
|
+
const crossAllowed = myGroup != null && source.data.group === myGroup;
|
|
106
|
+
if (!crossAllowed) return;
|
|
107
|
+
|
|
108
|
+
if (srcGridId === my && dstGridId && dstGridId !== my) {
|
|
109
|
+
// Dragging the last item out empties this grid — let the owner tear
|
|
110
|
+
// down the now-empty container instead of leaving it behind.
|
|
111
|
+
if (itemCount <= 1 && onEmptied) onEmptied();
|
|
112
|
+
else onRemove(source.data.id as string);
|
|
113
|
+
} else if (dstGridId === my && srcGridId !== my && target) {
|
|
114
|
+
const edge = extractClosestEdge(target.data) as "left" | "right" | null;
|
|
115
|
+
const toIndex = resolveDropIndex({ fromIndex: source.data.index as number, targetIndex: target.data.index as number, edge, sameCollection: false });
|
|
116
|
+
onInsertItem(toIndex, source.data.item as T);
|
|
117
|
+
}
|
|
59
118
|
},
|
|
60
119
|
});
|
|
61
120
|
});
|
|
@@ -88,9 +147,11 @@ export function EditableGrid<T>({
|
|
|
88
147
|
key={wrapped.id}
|
|
89
148
|
id={wrapped.id}
|
|
90
149
|
index={index}
|
|
150
|
+
gridId={gridId}
|
|
151
|
+
group={group}
|
|
152
|
+
item={wrapped.data}
|
|
91
153
|
isLast={index === wrappedItems.length - 1}
|
|
92
154
|
isDragging={isDragging}
|
|
93
|
-
onReorder={onReorder}
|
|
94
155
|
onRemove={onRemove}
|
|
95
156
|
onInsert={onInsert}
|
|
96
157
|
onSettings={onItemSettings ? () => onItemSettings(index) : undefined}
|
|
@@ -117,12 +178,14 @@ export function EditableGrid<T>({
|
|
|
117
178
|
);
|
|
118
179
|
}
|
|
119
180
|
|
|
120
|
-
function GridCell({
|
|
181
|
+
function GridCell<T>({
|
|
121
182
|
id,
|
|
122
183
|
index,
|
|
184
|
+
gridId,
|
|
185
|
+
group,
|
|
186
|
+
item,
|
|
123
187
|
isLast,
|
|
124
188
|
isDragging,
|
|
125
|
-
onReorder,
|
|
126
189
|
onRemove,
|
|
127
190
|
onInsert,
|
|
128
191
|
onSettings,
|
|
@@ -134,9 +197,11 @@ function GridCell({
|
|
|
134
197
|
}: {
|
|
135
198
|
id: string;
|
|
136
199
|
index: number;
|
|
200
|
+
gridId: string;
|
|
201
|
+
group?: string;
|
|
202
|
+
item: T;
|
|
137
203
|
isLast: boolean;
|
|
138
204
|
isDragging: boolean;
|
|
139
|
-
onReorder: (from: number, to: number) => void;
|
|
140
205
|
onRemove: (id: string) => void;
|
|
141
206
|
onInsert: (index: number) => void;
|
|
142
207
|
onSettings?: () => void;
|
|
@@ -165,17 +230,22 @@ function GridCell({
|
|
|
165
230
|
|
|
166
231
|
const cleanupDraggable = draggable({
|
|
167
232
|
element: handle,
|
|
168
|
-
|
|
233
|
+
// `item` rides along so a cross-grid destination can insert it verbatim.
|
|
234
|
+
getInitialData: () => ({ dragType: "grid-cell", gridId, group, id, index, item }),
|
|
169
235
|
onDragStart: () => setDragState({ sourceId: id, closestEdge: null }),
|
|
170
236
|
onDrop: () => setDragState({ sourceId: null, closestEdge: null }),
|
|
171
237
|
});
|
|
172
238
|
|
|
173
239
|
const cleanupDropTarget = dropTargetForElements({
|
|
174
240
|
element: cell,
|
|
175
|
-
|
|
241
|
+
// Accept a reorder within this grid, or a transfer from another grid in
|
|
242
|
+
// the same group. The actual move is performed by the grid-level monitor.
|
|
243
|
+
canDrop: ({ source }) =>
|
|
244
|
+
source.data.dragType === "grid-cell" &&
|
|
245
|
+
(source.data.gridId === gridId || (group != null && source.data.group === group)),
|
|
176
246
|
getData: ({ input, element }) =>
|
|
177
247
|
attachClosestEdge(
|
|
178
|
-
{ id, index },
|
|
248
|
+
{ gridId, id, index },
|
|
179
249
|
{ input, element, allowedEdges: ["left", "right"] },
|
|
180
250
|
),
|
|
181
251
|
onDragEnter: ({ self }) => {
|
|
@@ -189,16 +259,6 @@ function GridCell({
|
|
|
189
259
|
onDragLeave: () => {
|
|
190
260
|
setDragState((prev) => prev.closestEdge?.id === id ? { ...prev, closestEdge: null } : prev);
|
|
191
261
|
},
|
|
192
|
-
onDrop: ({ source, self }) => {
|
|
193
|
-
const fromIndex = source.data.index as number;
|
|
194
|
-
const edge = extractClosestEdge(self.data);
|
|
195
|
-
let toIndex = index;
|
|
196
|
-
if (edge === "right") toIndex = index + 1;
|
|
197
|
-
if (fromIndex < toIndex) toIndex--;
|
|
198
|
-
if (fromIndex !== toIndex) {
|
|
199
|
-
onReorder(fromIndex, toIndex);
|
|
200
|
-
}
|
|
201
|
-
},
|
|
202
262
|
});
|
|
203
263
|
|
|
204
264
|
cleanup = () => {
|
|
@@ -211,7 +271,7 @@ function GridCell({
|
|
|
211
271
|
cancelled = true;
|
|
212
272
|
cleanup?.();
|
|
213
273
|
};
|
|
214
|
-
}, [id, index,
|
|
274
|
+
}, [id, index, gridId, group, item, setDragState]);
|
|
215
275
|
|
|
216
276
|
const isCellDragging = dragState.sourceId === id;
|
|
217
277
|
const showLeftEdge = dragState.closestEdge?.id === id && dragState.closestEdge.edge === "left" && dragState.sourceId !== id;
|
|
@@ -221,7 +281,9 @@ function GridCell({
|
|
|
221
281
|
<div
|
|
222
282
|
ref={cellRef}
|
|
223
283
|
className={cn(
|
|
224
|
-
|
|
284
|
+
// h-full so a full-height renderItem (e.g. a colors swatch) fills the
|
|
285
|
+
// stretched grid track and can equalize height across the row.
|
|
286
|
+
"group/cell relative h-full",
|
|
225
287
|
isCellDragging && "opacity-50",
|
|
226
288
|
)}
|
|
227
289
|
>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convert a drop target (the cell being dropped onto + the closest edge) into
|
|
3
|
+
* the destination index for the moved item.
|
|
4
|
+
*
|
|
5
|
+
* Same-collection reorder: the dragged item is spliced OUT of the array before
|
|
6
|
+
* being re-inserted, so a destination past its original position shifts down by
|
|
7
|
+
* one — hence the `fromIndex < toIndex` decrement.
|
|
8
|
+
*
|
|
9
|
+
* Cross-collection insert: nothing is removed from the destination array, so no
|
|
10
|
+
* shift adjustment applies.
|
|
11
|
+
*/
|
|
12
|
+
export function resolveDropIndex({
|
|
13
|
+
fromIndex,
|
|
14
|
+
targetIndex,
|
|
15
|
+
edge,
|
|
16
|
+
sameCollection,
|
|
17
|
+
}: {
|
|
18
|
+
fromIndex: number;
|
|
19
|
+
targetIndex: number;
|
|
20
|
+
edge: "left" | "right" | null;
|
|
21
|
+
sameCollection: boolean;
|
|
22
|
+
}): number {
|
|
23
|
+
let toIndex = targetIndex + (edge === "right" ? 1 : 0);
|
|
24
|
+
if (sameCollection && fromIndex < toIndex) toIndex--;
|
|
25
|
+
return toIndex;
|
|
26
|
+
}
|
|
@@ -16,6 +16,7 @@ interface UseEditableCollectionReturn<T> {
|
|
|
16
16
|
onReorder: (fromIndex: number, toIndex: number) => void;
|
|
17
17
|
onAdd: () => void;
|
|
18
18
|
onInsert: (index: number) => void;
|
|
19
|
+
onInsertItem: (index: number, data: T) => void;
|
|
19
20
|
onRemove: (id: string) => void;
|
|
20
21
|
}
|
|
21
22
|
|
|
@@ -89,6 +90,20 @@ export function useEditableCollection<T>({
|
|
|
89
90
|
[createItem, onChange],
|
|
90
91
|
);
|
|
91
92
|
|
|
93
|
+
// Insert an externally-provided item (e.g. one dragged in from another grid)
|
|
94
|
+
// at a specific index. Distinct from onInsert, which creates a blank item.
|
|
95
|
+
const onInsertItem = useCallback(
|
|
96
|
+
(index: number, data: T) => {
|
|
97
|
+
setWrappedItems((prev) => {
|
|
98
|
+
const next = [...prev];
|
|
99
|
+
next.splice(index, 0, { id: uid(), data });
|
|
100
|
+
onChange(next.map((w) => w.data));
|
|
101
|
+
return next;
|
|
102
|
+
});
|
|
103
|
+
},
|
|
104
|
+
[onChange]
|
|
105
|
+
);
|
|
106
|
+
|
|
92
107
|
const onRemove = useCallback(
|
|
93
108
|
(id: string) => {
|
|
94
109
|
setWrappedItems((prev) => {
|
|
@@ -100,5 +115,5 @@ export function useEditableCollection<T>({
|
|
|
100
115
|
[onChange]
|
|
101
116
|
);
|
|
102
117
|
|
|
103
|
-
return { wrappedItems, onReorder, onAdd, onInsert, onRemove };
|
|
118
|
+
return { wrappedItems, onReorder, onAdd, onInsert, onInsertItem, onRemove };
|
|
104
119
|
}
|
|
@@ -30,7 +30,7 @@ export default defineSection({
|
|
|
30
30
|
schema,
|
|
31
31
|
authoringNote:
|
|
32
32
|
"A brand color palette. Each color may carry hex/rgb/cmyk/pantone values. Use to document brand colors with swatches.",
|
|
33
|
-
component: ({ content, options, onChange, openModal }) => (
|
|
33
|
+
component: ({ content, options, onChange, openModal, onDelete }) => (
|
|
34
34
|
<Colors
|
|
35
35
|
colors={content.content.colors}
|
|
36
36
|
columns={options?.columns as number}
|
|
@@ -39,6 +39,7 @@ export default defineSection({
|
|
|
39
39
|
showLabel={options?.showLabel as boolean}
|
|
40
40
|
onChange={onChange ? (c) => onChange(c as typeof content) : undefined}
|
|
41
41
|
openModal={openModal}
|
|
42
|
+
onDelete={onDelete}
|
|
42
43
|
/>
|
|
43
44
|
),
|
|
44
45
|
defaults: () => ({
|
|
@@ -16,10 +16,12 @@ interface EditorContextValue {
|
|
|
16
16
|
showAllChrome: boolean;
|
|
17
17
|
viewBranch: "saved" | "live";
|
|
18
18
|
historyState: HistoryState;
|
|
19
|
+
historyPageId: string | null;
|
|
19
20
|
toggleEditMode: () => void;
|
|
20
21
|
toggleShowAllChrome: () => void;
|
|
21
22
|
setViewBranch: (branch: "saved" | "live") => void;
|
|
22
23
|
setHistoryState: (state: HistoryState) => void;
|
|
24
|
+
setHistoryPageId: (pageId: string | null) => void;
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
const EditorContext = createContext<EditorContextValue | null>(null);
|
|
@@ -33,7 +35,10 @@ export function EditorProvider({ children }: EditorProviderProps) {
|
|
|
33
35
|
const [showAllChrome, setShowAllChrome] = useState(false);
|
|
34
36
|
const [viewBranch, setViewBranchState] = useState<"saved" | "live">("saved");
|
|
35
37
|
const [historyState, setHistoryStateRaw] = useState<HistoryState>(null);
|
|
38
|
+
const [historyPageId, setHistoryPageId] = useState<string | null>(null);
|
|
36
39
|
const setHistoryState = useCallback((state: HistoryState) => {
|
|
40
|
+
// null = "auto": resolved to the current page (or home) at render time
|
|
41
|
+
setHistoryPageId(null);
|
|
37
42
|
setHistoryStateRaw(state);
|
|
38
43
|
}, []);
|
|
39
44
|
|
|
@@ -49,7 +54,7 @@ export function EditorProvider({ children }: EditorProviderProps) {
|
|
|
49
54
|
const setViewBranch = useCallback((b: "saved" | "live") => setViewBranchState(b), []);
|
|
50
55
|
|
|
51
56
|
return (
|
|
52
|
-
<EditorContext.Provider value={{ isEditMode, showAllChrome, viewBranch, historyState, toggleEditMode, toggleShowAllChrome, setViewBranch, setHistoryState }}>
|
|
57
|
+
<EditorContext.Provider value={{ isEditMode, showAllChrome, viewBranch, historyState, historyPageId, toggleEditMode, toggleShowAllChrome, setViewBranch, setHistoryState, setHistoryPageId }}>
|
|
53
58
|
{children}
|
|
54
59
|
</EditorContext.Provider>
|
|
55
60
|
);
|
|
@@ -12,7 +12,7 @@ import type { MediaManifest } from "../../media/types";
|
|
|
12
12
|
import type { QueueItem } from "../../media/queue";
|
|
13
13
|
import { SiteConfigSchema, IndexSchema } from "../../schemas/site-config";
|
|
14
14
|
import { ensureSanitizer } from "../../lib/sanitize";
|
|
15
|
-
import { EditorProvider, useEditorContext } from "./EditorContext";
|
|
15
|
+
import { EditorProvider, useEditorContext, type HistoryState } from "./EditorContext";
|
|
16
16
|
import { makeBlockMoveDispatch } from "./blockMoveDispatch";
|
|
17
17
|
import { ROOT_CONTAINER_ID, resolveDropIndex } from "../../lib/block-dnd";
|
|
18
18
|
import type { BlockMove } from "../../lib/block-move";
|
|
@@ -1454,6 +1454,7 @@ export default function EditorShell({
|
|
|
1454
1454
|
onSectionChange={onSectionChange}
|
|
1455
1455
|
onAddSection={onAddSection}
|
|
1456
1456
|
onDeleteSection={setPendingDeleteSectionId}
|
|
1457
|
+
onDeleteSectionImmediate={performDeleteSection}
|
|
1457
1458
|
onReorderSections={onReorderSections}
|
|
1458
1459
|
onBlockMove={onBlockMove}
|
|
1459
1460
|
onMoveSection={siteIndex.pages.length > 1 ? setMovingSectionId : undefined}
|
|
@@ -1693,6 +1694,18 @@ function HistoryWatcher() {
|
|
|
1693
1694
|
return null;
|
|
1694
1695
|
}
|
|
1695
1696
|
|
|
1697
|
+
/** Resolve which historical page to show: explicit selection → the page the
|
|
1698
|
+
* editor is currently on (if it existed at that version) → home → first. */
|
|
1699
|
+
export function resolveHistoryPage(
|
|
1700
|
+
historyState: NonNullable<HistoryState>,
|
|
1701
|
+
historyPageId: string | null,
|
|
1702
|
+
preferredPageId: string | null,
|
|
1703
|
+
) {
|
|
1704
|
+
const pages = historyState.index.pages;
|
|
1705
|
+
const byId = (id: string | null) => (id ? pages.find((p) => p.id === id) : undefined);
|
|
1706
|
+
return byId(historyPageId) ?? byId(preferredPageId) ?? pages.find((p) => p.isHome) ?? pages[0];
|
|
1707
|
+
}
|
|
1708
|
+
|
|
1696
1709
|
function HistoryOrEditorContent({
|
|
1697
1710
|
children,
|
|
1698
1711
|
index,
|
|
@@ -1704,9 +1717,11 @@ function HistoryOrEditorContent({
|
|
|
1704
1717
|
activeSections: LoadedSection[];
|
|
1705
1718
|
activePageId: string | null;
|
|
1706
1719
|
}) {
|
|
1707
|
-
const { historyState } = useEditorContext();
|
|
1720
|
+
const { historyState, historyPageId, setHistoryPageId } = useEditorContext();
|
|
1708
1721
|
const wasInHistory = useRef(false);
|
|
1709
1722
|
|
|
1723
|
+
const historyPage = historyState ? resolveHistoryPage(historyState, historyPageId, activePageId) : null;
|
|
1724
|
+
|
|
1710
1725
|
useEffect(() => {
|
|
1711
1726
|
if (historyState) {
|
|
1712
1727
|
wasInHistory.current = true;
|
|
@@ -1720,8 +1735,22 @@ function HistoryOrEditorContent({
|
|
|
1720
1735
|
}
|
|
1721
1736
|
}, [historyState, index, activeSections, activePageId]);
|
|
1722
1737
|
|
|
1723
|
-
|
|
1724
|
-
|
|
1738
|
+
// Pin the auto-resolved page into context so the toolbar selector agrees,
|
|
1739
|
+
// and keep the nav highlighting in sync with the page being viewed.
|
|
1740
|
+
useEffect(() => {
|
|
1741
|
+
if (!historyState || !historyPage) return;
|
|
1742
|
+
if (!historyPageId) setHistoryPageId(historyPage.id);
|
|
1743
|
+
siteNavChangeEvent.dispatch(
|
|
1744
|
+
generateSiteNav({ index: historyState.index, activeSections: [], activePageId: historyPage.id, mode: "editor", audience: null }),
|
|
1745
|
+
);
|
|
1746
|
+
}, [historyState, historyPage?.id]);
|
|
1747
|
+
|
|
1748
|
+
if (historyState && historyPage) {
|
|
1749
|
+
const position = new Map(historyPage.order.map((id, i) => [id, i]));
|
|
1750
|
+
const pageSections = historyState.sections
|
|
1751
|
+
.filter((s) => position.has(s.section.id))
|
|
1752
|
+
.sort((a, b) => (position.get(a.section.id) ?? 0) - (position.get(b.section.id) ?? 0));
|
|
1753
|
+
return <ViewRenderer sections={pageSections} />;
|
|
1725
1754
|
}
|
|
1726
1755
|
return <>{children}</>;
|
|
1727
1756
|
}
|
|
@@ -1764,6 +1793,7 @@ function EditorContent({
|
|
|
1764
1793
|
onSectionChange,
|
|
1765
1794
|
onAddSection,
|
|
1766
1795
|
onDeleteSection,
|
|
1796
|
+
onDeleteSectionImmediate,
|
|
1767
1797
|
onReorderSections,
|
|
1768
1798
|
onBlockMove,
|
|
1769
1799
|
onMoveSection,
|
|
@@ -1784,6 +1814,7 @@ function EditorContent({
|
|
|
1784
1814
|
onSectionChange: (sectionId: string, content: SectionContent) => void;
|
|
1785
1815
|
onAddSection: (insertIndex: number, selection: string) => void;
|
|
1786
1816
|
onDeleteSection: (sectionId: string) => void;
|
|
1817
|
+
onDeleteSectionImmediate: (sectionId: string) => void;
|
|
1787
1818
|
onReorderSections: (fromIndex: number, toIndex: number) => void;
|
|
1788
1819
|
onBlockMove: (move: BlockMove) => void;
|
|
1789
1820
|
onMoveSection?: (sectionId: string) => void;
|
|
@@ -1978,6 +2009,9 @@ function EditorContent({
|
|
|
1978
2009
|
onChange={editingEnabled ? (newContent) => onSectionChange(section.id, newContent as SectionContent) : undefined}
|
|
1979
2010
|
isEditMode={isEditMode}
|
|
1980
2011
|
openModal={editingEnabled ? openModal : undefined}
|
|
2012
|
+
// Immediate (no confirm modal): used when a colors section's
|
|
2013
|
+
// last swatch is dragged out, auto-removing the empty section.
|
|
2014
|
+
onDelete={editingEnabled ? () => onDeleteSectionImmediate(section.id) : undefined}
|
|
1981
2015
|
/>
|
|
1982
2016
|
</SectionWrapper>
|
|
1983
2017
|
</SectionLayout>
|
|
@@ -2150,12 +2184,16 @@ function EditorToolbar({
|
|
|
2150
2184
|
collabSelfId: string | null;
|
|
2151
2185
|
collabStatus: CollabStatus;
|
|
2152
2186
|
}) {
|
|
2153
|
-
const { isEditMode, viewBranch, setViewBranch, toggleEditMode, historyState, setHistoryState } = useEditorContext();
|
|
2187
|
+
const { isEditMode, viewBranch, setViewBranch, toggleEditMode, historyState, setHistoryState, historyPageId, setHistoryPageId } = useEditorContext();
|
|
2154
2188
|
|
|
2155
2189
|
if (historyState) {
|
|
2190
|
+
const page = resolveHistoryPage(historyState, historyPageId, null);
|
|
2156
2191
|
return (
|
|
2157
2192
|
<HistoryToolbar
|
|
2158
2193
|
date={historyState.date}
|
|
2194
|
+
pages={historyState.index.pages.map((p) => ({ id: p.id, title: p.title }))}
|
|
2195
|
+
activePageId={page?.id ?? ""}
|
|
2196
|
+
onPageChange={setHistoryPageId}
|
|
2159
2197
|
onBackToCurrent={() => setHistoryState(null)}
|
|
2160
2198
|
onRestore={onRestoreClick}
|
|
2161
2199
|
/>
|
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
import { formatDateTime } from "../../lib/timestamp";
|
|
2
2
|
import { Button } from "../shared/Button";
|
|
3
3
|
|
|
4
|
+
interface HistoryPageOption {
|
|
5
|
+
id: string;
|
|
6
|
+
title: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
4
9
|
interface HistoryToolbarProps {
|
|
5
10
|
date: string;
|
|
11
|
+
pages: HistoryPageOption[];
|
|
12
|
+
activePageId: string;
|
|
13
|
+
onPageChange: (pageId: string) => void;
|
|
6
14
|
onBackToCurrent: () => void;
|
|
7
15
|
onRestore: () => void;
|
|
8
16
|
}
|
|
9
17
|
|
|
10
|
-
export function HistoryToolbar({ date, onBackToCurrent, onRestore }: HistoryToolbarProps) {
|
|
18
|
+
export function HistoryToolbar({ date, pages, activePageId, onPageChange, onBackToCurrent, onRestore }: HistoryToolbarProps) {
|
|
11
19
|
return (
|
|
12
20
|
<div className="fixed top-0 right-0 left-0 z-50 border-b border-base-200 bg-base">
|
|
13
21
|
<div className="mx-auto max-w-screen-xl grid grid-cols-3 items-center px-4 py-2">
|
|
@@ -16,10 +24,24 @@ export function HistoryToolbar({ date, onBackToCurrent, onRestore }: HistoryTool
|
|
|
16
24
|
Back to current
|
|
17
25
|
</Button>
|
|
18
26
|
</div>
|
|
19
|
-
<div className="flex items-center justify-center">
|
|
27
|
+
<div className="flex items-center justify-center gap-2">
|
|
20
28
|
<span className="text-xs font-medium text-base-contrast-light">
|
|
21
29
|
Viewing {formatDateTime(date)}
|
|
22
30
|
</span>
|
|
31
|
+
{pages.length > 1 && (
|
|
32
|
+
<select
|
|
33
|
+
value={activePageId}
|
|
34
|
+
onChange={(e) => onPageChange(e.target.value)}
|
|
35
|
+
className="rounded border border-base-200 bg-base px-1.5 py-0.5 text-xs font-medium text-base-contrast"
|
|
36
|
+
aria-label="Page at this version"
|
|
37
|
+
>
|
|
38
|
+
{pages.map((p) => (
|
|
39
|
+
<option key={p.id} value={p.id}>
|
|
40
|
+
{p.title}
|
|
41
|
+
</option>
|
|
42
|
+
))}
|
|
43
|
+
</select>
|
|
44
|
+
)}
|
|
23
45
|
</div>
|
|
24
46
|
<div className="flex items-center justify-end">
|
|
25
47
|
<Button variant="primary" size="sm" onClick={onRestore}>
|
package/src/lib/registry.ts
CHANGED
|
@@ -83,6 +83,9 @@ export interface SectionProps<T = unknown> {
|
|
|
83
83
|
onChange?: (content: T) => void;
|
|
84
84
|
isEditMode: boolean;
|
|
85
85
|
openModal?: (title: string, content: ReactNode) => void;
|
|
86
|
+
/** Delete this whole section. Used e.g. when a colors section's last swatch
|
|
87
|
+
* is dragged into another section, leaving it empty. */
|
|
88
|
+
onDelete?: () => void;
|
|
86
89
|
}
|
|
87
90
|
|
|
88
91
|
export interface WrapperProps {
|