@haklex/rich-ext-gallery 0.0.80 → 0.0.81

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,336 +1,407 @@
1
- var __defProp = Object.defineProperty;
2
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
- import { G as GalleryNode, a as GalleryRenderer, g as galleryDialogPopup, b as galleryEditContainer, c as galleryEmptyState, d as galleryEditOverlay, e as galleryEditLabel, f as galleryDialogHeader, h as galleryDialogTitle, i as galleryHeaderActions, j as galleryHeaderClose, k as galleryDialogBody, l as galleryDialogEmpty, m as galleryAddBtn, n as galleryImageList, o as galleryDialogFooter, p as galleryFooterInfo, q as galleryFooterActions, r as galleryFooterBtnCancel, s as galleryFooterBtnSave, t as galleryImageCard, u as galleryImageDragHandle, v as galleryImageThumb, w as galleryImageThumbPlaceholder, x as galleryImageFields, y as galleryImageInput, z as galleryImageActions, A as galleryImageDeleteBtn } from "./GalleryNode-CV8DRu_G.js";
5
- import { $, B, C } from "./GalleryNode-CV8DRu_G.js";
1
+ import { A as galleryImageList, C as galleryHeaderClose, D as galleryImageDragHandle, E as galleryImageDeleteBtn, M as galleryImageThumbPlaceholder, O as galleryImageFields, S as galleryHeaderActions, T as galleryImageCard, _ as galleryEmptyState, a as GalleryRenderer, b as galleryFooterBtnSave, c as galleryDialogBody, d as galleryDialogHeader, f as galleryDialogPopup, g as galleryEditOverlay, h as galleryEditLabel, i as _defineProperty, j as galleryImageThumb, k as galleryImageInput, l as galleryDialogEmpty, m as galleryEditContainer, n as $isGalleryNode, o as GalleryRenderer_default, p as galleryDialogTitle, r as GalleryNode, s as galleryAddBtn, t as $createGalleryNode, u as galleryDialogFooter, v as galleryFooterActions, w as galleryImageActions, x as galleryFooterInfo, y as galleryFooterBtnCancel } from "./GalleryNode-CXLSG7vE.js";
6
2
  import { createRendererDecoration } from "@haklex/rich-editor/renderers";
7
- import { $insertNodes, $getNodeByKey } from "lexical";
8
- import { Images, ImageIcon, Pencil, X, Plus, GripVertical, Trash2 } from "lucide-react";
9
- import { createElement, useCallback, useState, useRef } from "react";
10
- import { jsx, jsxs, Fragment } from "react/jsx-runtime";
11
- import { useSensors, useSensor, PointerSensor, DndContext, closestCenter, DragOverlay } from "@dnd-kit/core";
12
- import { arrayMove, SortableContext, verticalListSortingStrategy, useSortable } from "@dnd-kit/sortable";
3
+ import { $getNodeByKey, $insertNodes } from "lexical";
4
+ import { GripVertical, ImageIcon, Images, Pencil, Plus, Trash2, X } from "lucide-react";
5
+ import { createElement, useCallback, useRef, useState } from "react";
6
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
7
+ import { DndContext, DragOverlay, PointerSensor, closestCenter, useSensor, useSensors } from "@dnd-kit/core";
8
+ import { SortableContext, arrayMove, useSortable, verticalListSortingStrategy } from "@dnd-kit/sortable";
13
9
  import { CSS } from "@dnd-kit/utilities";
14
10
  import { useColorScheme } from "@haklex/rich-editor";
15
- import { presentDialog, SegmentedControl } from "@haklex/rich-editor-ui";
11
+ import { SegmentedControl, presentDialog } from "@haklex/rich-editor-ui";
16
12
  import { usePortalTheme, vars } from "@haklex/rich-style-token";
17
13
  import { createPortal } from "react-dom";
18
- const _GalleryEditNode = class _GalleryEditNode extends GalleryNode {
19
- static clone(node) {
20
- return new _GalleryEditNode(
21
- {
22
- images: node.__images.map((img) => ({ ...img })),
23
- layout: node.__layout
24
- },
25
- node.__key
26
- );
27
- }
28
- constructor(payload, key) {
29
- super(payload, key);
30
- }
31
- static importJSON(serializedNode) {
32
- return new _GalleryEditNode({
33
- images: serializedNode.images,
34
- layout: serializedNode.layout
35
- });
36
- }
37
- decorate(editor, _config) {
38
- const nodeKey = this.__key;
39
- const props = {
40
- images: this.__images,
41
- layout: this.__layout,
42
- onImagesChange: (images) => {
43
- editor.update(() => {
44
- const node = $getNodeByKey(nodeKey);
45
- if (node) node.setImages(images);
46
- });
47
- },
48
- onLayoutChange: (layout) => {
49
- editor.update(() => {
50
- const node = $getNodeByKey(nodeKey);
51
- if (node) node.setLayout(layout);
52
- });
53
- }
54
- };
55
- return createRendererDecoration("Gallery", GalleryRenderer, props);
56
- }
14
+ //#region src/GalleryEditNode.ts
15
+ var GalleryEditNode = class GalleryEditNode extends GalleryNode {
16
+ static clone(node) {
17
+ return new GalleryEditNode({
18
+ images: node.__images.map((img) => ({ ...img })),
19
+ layout: node.__layout
20
+ }, node.__key);
21
+ }
22
+ constructor(payload, key) {
23
+ super(payload, key);
24
+ }
25
+ static importJSON(serializedNode) {
26
+ return new GalleryEditNode({
27
+ images: serializedNode.images,
28
+ layout: serializedNode.layout
29
+ });
30
+ }
31
+ decorate(editor, _config) {
32
+ const nodeKey = this.__key;
33
+ return createRendererDecoration("Gallery", GalleryRenderer, {
34
+ images: this.__images,
35
+ layout: this.__layout,
36
+ onImagesChange: (images) => {
37
+ editor.update(() => {
38
+ const node = $getNodeByKey(nodeKey);
39
+ if (node) node.setImages(images);
40
+ });
41
+ },
42
+ onLayoutChange: (layout) => {
43
+ editor.update(() => {
44
+ const node = $getNodeByKey(nodeKey);
45
+ if (node) node.setLayout(layout);
46
+ });
47
+ }
48
+ });
49
+ }
57
50
  };
58
- __publicField(_GalleryEditNode, "commandItems", [
59
- {
60
- title: "Gallery",
61
- icon: createElement(Images, { size: 20 }),
62
- description: "Image gallery grid",
63
- keywords: ["gallery", "images", "grid"],
64
- section: "MEDIA",
65
- placement: ["slash", "toolbar"],
66
- group: "insert",
67
- onSelect: (editor) => {
68
- editor.update(() => {
69
- $insertNodes([$createGalleryEditNode({ images: [] })]);
70
- });
71
- }
72
- }
73
- ]);
74
- let GalleryEditNode = _GalleryEditNode;
51
+ _defineProperty(GalleryEditNode, "commandItems", [{
52
+ title: "Gallery",
53
+ icon: createElement(Images, { size: 20 }),
54
+ description: "Image gallery grid",
55
+ keywords: [
56
+ "gallery",
57
+ "images",
58
+ "grid"
59
+ ],
60
+ section: "MEDIA",
61
+ placement: ["slash", "toolbar"],
62
+ group: "insert",
63
+ onSelect: (editor) => {
64
+ editor.update(() => {
65
+ $insertNodes([$createGalleryEditNode({ images: [] })]);
66
+ });
67
+ }
68
+ }]);
75
69
  function $createGalleryEditNode(payload) {
76
- return new GalleryEditNode(payload);
70
+ return new GalleryEditNode(payload);
77
71
  }
78
72
  function $isGalleryEditNode(node) {
79
- return node instanceof GalleryEditNode;
73
+ return node instanceof GalleryEditNode;
80
74
  }
81
- const layoutItems = [
82
- { value: "grid", label: "Grid" },
83
- { value: "masonry", label: "Masonry" },
84
- { value: "carousel", label: "Carousel" }
75
+ //#endregion
76
+ //#region src/GalleryEditRenderer.tsx
77
+ var layoutItems = [
78
+ {
79
+ value: "grid",
80
+ label: "Grid"
81
+ },
82
+ {
83
+ value: "masonry",
84
+ label: "Masonry"
85
+ },
86
+ {
87
+ value: "carousel",
88
+ label: "Carousel"
89
+ }
85
90
  ];
86
- let nextId = 0;
91
+ var nextId = 0;
87
92
  function genId() {
88
- return `img-${++nextId}`;
93
+ return `img-${++nextId}`;
89
94
  }
90
- const SortableImageCard = ({ id, image, index, isLast, lastInputRef, onUpdate, onRemove }) => {
91
- const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({
92
- id
93
- });
94
- const style = {
95
- transform: CSS.Transform.toString(transform),
96
- transition: isDragging ? void 0 : transition,
97
- opacity: isDragging ? 0.4 : 1
98
- };
99
- return /* @__PURE__ */ jsxs("div", { className: galleryImageCard, ref: setNodeRef, style, children: [
100
- /* @__PURE__ */ jsx("div", { className: galleryImageDragHandle, ...attributes, ...listeners, children: /* @__PURE__ */ jsx(GripVertical, { size: 14 }) }),
101
- /* @__PURE__ */ jsx("div", { className: galleryImageThumb, children: image.src ? /* @__PURE__ */ jsx("img", { alt: image.alt || "", src: image.src }) : /* @__PURE__ */ jsx("span", { className: galleryImageThumbPlaceholder, children: /* @__PURE__ */ jsx(ImageIcon, { size: 20 }) }) }),
102
- /* @__PURE__ */ jsxs("div", { className: galleryImageFields, children: [
103
- /* @__PURE__ */ jsx(
104
- "input",
105
- {
106
- className: galleryImageInput,
107
- placeholder: "Image URL",
108
- ref: isLast ? lastInputRef : void 0,
109
- type: "text",
110
- value: image.src,
111
- onChange: (e) => onUpdate(index, "src", e.target.value)
112
- }
113
- ),
114
- /* @__PURE__ */ jsx(
115
- "input",
116
- {
117
- className: galleryImageInput,
118
- placeholder: "Alt text (optional)",
119
- type: "text",
120
- value: image.alt || "",
121
- onChange: (e) => onUpdate(index, "alt", e.target.value)
122
- }
123
- )
124
- ] }),
125
- /* @__PURE__ */ jsx("div", { className: galleryImageActions, children: /* @__PURE__ */ jsx(
126
- "button",
127
- {
128
- className: galleryImageDeleteBtn,
129
- title: "Remove",
130
- type: "button",
131
- onClick: () => onRemove(index),
132
- children: /* @__PURE__ */ jsx(Trash2, { size: 14 })
133
- }
134
- ) })
135
- ] });
95
+ var SortableImageCard = ({ id, image, index, isLast, lastInputRef, onUpdate, onRemove }) => {
96
+ const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id });
97
+ return /* @__PURE__ */ jsxs("div", {
98
+ className: galleryImageCard,
99
+ ref: setNodeRef,
100
+ style: {
101
+ transform: CSS.Transform.toString(transform),
102
+ transition: isDragging ? void 0 : transition,
103
+ opacity: isDragging ? .4 : 1
104
+ },
105
+ children: [
106
+ /* @__PURE__ */ jsx("div", {
107
+ className: galleryImageDragHandle,
108
+ ...attributes,
109
+ ...listeners,
110
+ children: /* @__PURE__ */ jsx(GripVertical, { size: 14 })
111
+ }),
112
+ /* @__PURE__ */ jsx("div", {
113
+ className: galleryImageThumb,
114
+ children: image.src ? /* @__PURE__ */ jsx("img", {
115
+ alt: image.alt || "",
116
+ src: image.src
117
+ }) : /* @__PURE__ */ jsx("span", {
118
+ className: galleryImageThumbPlaceholder,
119
+ children: /* @__PURE__ */ jsx(ImageIcon, { size: 20 })
120
+ })
121
+ }),
122
+ /* @__PURE__ */ jsxs("div", {
123
+ className: galleryImageFields,
124
+ children: [/* @__PURE__ */ jsx("input", {
125
+ className: galleryImageInput,
126
+ placeholder: "Image URL",
127
+ ref: isLast ? lastInputRef : void 0,
128
+ type: "text",
129
+ value: image.src,
130
+ onChange: (e) => onUpdate(index, "src", e.target.value)
131
+ }), /* @__PURE__ */ jsx("input", {
132
+ className: galleryImageInput,
133
+ placeholder: "Alt text (optional)",
134
+ type: "text",
135
+ value: image.alt || "",
136
+ onChange: (e) => onUpdate(index, "alt", e.target.value)
137
+ })]
138
+ }),
139
+ /* @__PURE__ */ jsx("div", {
140
+ className: galleryImageActions,
141
+ children: /* @__PURE__ */ jsx("button", {
142
+ className: galleryImageDeleteBtn,
143
+ title: "Remove",
144
+ type: "button",
145
+ onClick: () => onRemove(index),
146
+ children: /* @__PURE__ */ jsx(Trash2, { size: 14 })
147
+ })
148
+ })
149
+ ]
150
+ });
136
151
  };
137
- const DragOverlayCard = ({ image }) => /* @__PURE__ */ jsxs("div", { className: galleryImageCard, style: { opacity: 0.9 }, children: [
138
- /* @__PURE__ */ jsx("div", { className: galleryImageDragHandle, children: /* @__PURE__ */ jsx(GripVertical, { size: 14 }) }),
139
- /* @__PURE__ */ jsx("div", { className: galleryImageThumb, children: image.src ? /* @__PURE__ */ jsx("img", { alt: image.alt || "", src: image.src }) : /* @__PURE__ */ jsx("span", { className: galleryImageThumbPlaceholder, children: /* @__PURE__ */ jsx(ImageIcon, { size: 20 }) }) }),
140
- /* @__PURE__ */ jsx("div", { className: galleryImageFields, children: /* @__PURE__ */ jsx(
141
- "span",
142
- {
143
- style: {
144
- fontSize: vars.typography.fontSizeSm,
145
- overflow: "hidden",
146
- textOverflow: "ellipsis",
147
- whiteSpace: "nowrap"
148
- },
149
- children: image.src || "No URL"
150
- }
151
- ) })
152
- ] });
153
- const GalleryEditorDialogContent = ({ dismiss, initialImages, initialLayout, onImagesChange, onLayoutChange }) => {
154
- const { className: portalClassName } = usePortalTheme();
155
- const [entries, setEntries] = useState(
156
- () => initialImages.map((img) => ({ id: genId(), image: { ...img } }))
157
- );
158
- const [layout, setLayout] = useState(initialLayout);
159
- const newInputRef = useRef(null);
160
- const [dragActiveId, setDragActiveId] = useState(null);
161
- const itemIds = entries.map((e) => e.id);
162
- const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 5 } }));
163
- const handleAddImage = useCallback(() => {
164
- setEntries((prev) => [...prev, { id: genId(), image: { src: "", alt: "" } }]);
165
- requestAnimationFrame(() => {
166
- newInputRef.current?.focus();
167
- });
168
- }, []);
169
- const handleRemoveImage = useCallback((index) => {
170
- setEntries((prev) => prev.filter((_, i) => i !== index));
171
- }, []);
172
- const handleUpdateImage = useCallback(
173
- (index, field, value) => {
174
- setEntries(
175
- (prev) => prev.map(
176
- (entry, i) => i === index ? { ...entry, image: { ...entry.image, [field]: value } } : entry
177
- )
178
- );
179
- },
180
- []
181
- );
182
- const handleDragEnd = useCallback((event) => {
183
- const { active, over } = event;
184
- setDragActiveId(null);
185
- if (!over || active.id === over.id) return;
186
- setEntries((prev) => {
187
- const oldIndex = prev.findIndex((e) => e.id === String(active.id));
188
- const newIndex = prev.findIndex((e) => e.id === String(over.id));
189
- if (oldIndex === -1 || newIndex === -1) return prev;
190
- return arrayMove(prev, oldIndex, newIndex);
191
- });
192
- }, []);
193
- const handleSave = useCallback(() => {
194
- const filtered = entries.map((e) => e.image).filter((img) => img.src.trim());
195
- onImagesChange(filtered);
196
- onLayoutChange(layout);
197
- dismiss();
198
- }, [entries, layout, onImagesChange, onLayoutChange, dismiss]);
199
- const dragActiveEntry = dragActiveId ? entries.find((e) => e.id === dragActiveId) : null;
200
- return /* @__PURE__ */ jsxs(Fragment, { children: [
201
- /* @__PURE__ */ jsxs("div", { className: galleryDialogHeader, children: [
202
- /* @__PURE__ */ jsxs("div", { className: galleryDialogTitle, children: [
203
- /* @__PURE__ */ jsx(Images, { size: 18 }),
204
- /* @__PURE__ */ jsx("span", { children: "Gallery Editor" })
205
- ] }),
206
- /* @__PURE__ */ jsx("div", { className: galleryHeaderActions, children: /* @__PURE__ */ jsx(SegmentedControl, { items: layoutItems, value: layout, onChange: setLayout }) }),
207
- /* @__PURE__ */ jsx("button", { className: galleryHeaderClose, type: "button", onClick: dismiss, children: /* @__PURE__ */ jsx(X, { size: 18 }) })
208
- ] }),
209
- /* @__PURE__ */ jsx("div", { className: galleryDialogBody, children: entries.length === 0 ? /* @__PURE__ */ jsxs("div", { className: galleryDialogEmpty, children: [
210
- /* @__PURE__ */ jsx(ImageIcon, { size: 32 }),
211
- /* @__PURE__ */ jsx("span", { children: "Add your first image" }),
212
- /* @__PURE__ */ jsxs(
213
- "button",
214
- {
215
- className: galleryAddBtn,
216
- style: { maxWidth: 200 },
217
- type: "button",
218
- onClick: handleAddImage,
219
- children: [
220
- /* @__PURE__ */ jsx(Plus, { size: 14 }),
221
- "Add Image"
222
- ]
223
- }
224
- )
225
- ] }) : /* @__PURE__ */ jsxs("div", { className: galleryImageList, children: [
226
- /* @__PURE__ */ jsxs(
227
- DndContext,
228
- {
229
- collisionDetection: closestCenter,
230
- sensors,
231
- onDragCancel: () => setDragActiveId(null),
232
- onDragEnd: handleDragEnd,
233
- onDragStart: (event) => {
234
- setDragActiveId(String(event.active.id));
235
- },
236
- children: [
237
- /* @__PURE__ */ jsx(SortableContext, { items: itemIds, strategy: verticalListSortingStrategy, children: entries.map((entry, index) => /* @__PURE__ */ jsx(
238
- SortableImageCard,
239
- {
240
- id: entry.id,
241
- image: entry.image,
242
- index,
243
- isLast: index === entries.length - 1,
244
- lastInputRef: newInputRef,
245
- onRemove: handleRemoveImage,
246
- onUpdate: handleUpdateImage
247
- },
248
- entry.id
249
- )) }),
250
- typeof document !== "undefined" ? createPortal(
251
- /* @__PURE__ */ jsx("div", { className: portalClassName, children: /* @__PURE__ */ jsx(DragOverlay, { dropAnimation: null, children: dragActiveEntry ? /* @__PURE__ */ jsx(DragOverlayCard, { image: dragActiveEntry.image }) : null }) }),
252
- document.body
253
- ) : null
254
- ]
255
- }
256
- ),
257
- /* @__PURE__ */ jsxs("button", { className: galleryAddBtn, type: "button", onClick: handleAddImage, children: [
258
- /* @__PURE__ */ jsx(Plus, { size: 14 }),
259
- "Add Image"
260
- ] })
261
- ] }) }),
262
- /* @__PURE__ */ jsxs("div", { className: galleryDialogFooter, children: [
263
- /* @__PURE__ */ jsx("span", { className: galleryFooterInfo, children: `${entries.filter((e) => e.image.src.trim()).length} ${entries.filter((e) => e.image.src.trim()).length !== 1 ? "images" : "image"}` }),
264
- /* @__PURE__ */ jsxs("div", { className: galleryFooterActions, children: [
265
- /* @__PURE__ */ jsx("button", { className: galleryFooterBtnCancel, type: "button", onClick: dismiss, children: "Cancel" }),
266
- /* @__PURE__ */ jsx("button", { className: galleryFooterBtnSave, type: "button", onClick: handleSave, children: "Save" })
267
- ] })
268
- ] })
269
- ] });
152
+ var DragOverlayCard = ({ image }) => /* @__PURE__ */ jsxs("div", {
153
+ className: galleryImageCard,
154
+ style: { opacity: .9 },
155
+ children: [
156
+ /* @__PURE__ */ jsx("div", {
157
+ className: galleryImageDragHandle,
158
+ children: /* @__PURE__ */ jsx(GripVertical, { size: 14 })
159
+ }),
160
+ /* @__PURE__ */ jsx("div", {
161
+ className: galleryImageThumb,
162
+ children: image.src ? /* @__PURE__ */ jsx("img", {
163
+ alt: image.alt || "",
164
+ src: image.src
165
+ }) : /* @__PURE__ */ jsx("span", {
166
+ className: galleryImageThumbPlaceholder,
167
+ children: /* @__PURE__ */ jsx(ImageIcon, { size: 20 })
168
+ })
169
+ }),
170
+ /* @__PURE__ */ jsx("div", {
171
+ className: galleryImageFields,
172
+ children: /* @__PURE__ */ jsx("span", {
173
+ style: {
174
+ fontSize: vars.typography.fontSizeSm,
175
+ overflow: "hidden",
176
+ textOverflow: "ellipsis",
177
+ whiteSpace: "nowrap"
178
+ },
179
+ children: image.src || "No URL"
180
+ })
181
+ })
182
+ ]
183
+ });
184
+ var GalleryEditorDialogContent = ({ dismiss, initialImages, initialLayout, onImagesChange, onLayoutChange }) => {
185
+ const { className: portalClassName } = usePortalTheme();
186
+ const [entries, setEntries] = useState(() => initialImages.map((img) => ({
187
+ id: genId(),
188
+ image: { ...img }
189
+ })));
190
+ const [layout, setLayout] = useState(initialLayout);
191
+ const newInputRef = useRef(null);
192
+ const [dragActiveId, setDragActiveId] = useState(null);
193
+ const itemIds = entries.map((e) => e.id);
194
+ const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 5 } }));
195
+ const handleAddImage = useCallback(() => {
196
+ setEntries((prev) => [...prev, {
197
+ id: genId(),
198
+ image: {
199
+ src: "",
200
+ alt: ""
201
+ }
202
+ }]);
203
+ requestAnimationFrame(() => {
204
+ newInputRef.current?.focus();
205
+ });
206
+ }, []);
207
+ const handleRemoveImage = useCallback((index) => {
208
+ setEntries((prev) => prev.filter((_, i) => i !== index));
209
+ }, []);
210
+ const handleUpdateImage = useCallback((index, field, value) => {
211
+ setEntries((prev) => prev.map((entry, i) => i === index ? {
212
+ ...entry,
213
+ image: {
214
+ ...entry.image,
215
+ [field]: value
216
+ }
217
+ } : entry));
218
+ }, []);
219
+ const handleDragEnd = useCallback((event) => {
220
+ const { active, over } = event;
221
+ setDragActiveId(null);
222
+ if (!over || active.id === over.id) return;
223
+ setEntries((prev) => {
224
+ const oldIndex = prev.findIndex((e) => e.id === String(active.id));
225
+ const newIndex = prev.findIndex((e) => e.id === String(over.id));
226
+ if (oldIndex === -1 || newIndex === -1) return prev;
227
+ return arrayMove(prev, oldIndex, newIndex);
228
+ });
229
+ }, []);
230
+ const handleSave = useCallback(() => {
231
+ onImagesChange(entries.map((e) => e.image).filter((img) => img.src.trim()));
232
+ onLayoutChange(layout);
233
+ dismiss();
234
+ }, [
235
+ entries,
236
+ layout,
237
+ onImagesChange,
238
+ onLayoutChange,
239
+ dismiss
240
+ ]);
241
+ const dragActiveEntry = dragActiveId ? entries.find((e) => e.id === dragActiveId) : null;
242
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
243
+ /* @__PURE__ */ jsxs("div", {
244
+ className: galleryDialogHeader,
245
+ children: [
246
+ /* @__PURE__ */ jsxs("div", {
247
+ className: galleryDialogTitle,
248
+ children: [/* @__PURE__ */ jsx(Images, { size: 18 }), /* @__PURE__ */ jsx("span", { children: "Gallery Editor" })]
249
+ }),
250
+ /* @__PURE__ */ jsx("div", {
251
+ className: galleryHeaderActions,
252
+ children: /* @__PURE__ */ jsx(SegmentedControl, {
253
+ items: layoutItems,
254
+ value: layout,
255
+ onChange: setLayout
256
+ })
257
+ }),
258
+ /* @__PURE__ */ jsx("button", {
259
+ className: galleryHeaderClose,
260
+ type: "button",
261
+ onClick: dismiss,
262
+ children: /* @__PURE__ */ jsx(X, { size: 18 })
263
+ })
264
+ ]
265
+ }),
266
+ /* @__PURE__ */ jsx("div", {
267
+ className: galleryDialogBody,
268
+ children: entries.length === 0 ? /* @__PURE__ */ jsxs("div", {
269
+ className: galleryDialogEmpty,
270
+ children: [
271
+ /* @__PURE__ */ jsx(ImageIcon, { size: 32 }),
272
+ /* @__PURE__ */ jsx("span", { children: "Add your first image" }),
273
+ /* @__PURE__ */ jsxs("button", {
274
+ className: galleryAddBtn,
275
+ style: { maxWidth: 200 },
276
+ type: "button",
277
+ onClick: handleAddImage,
278
+ children: [/* @__PURE__ */ jsx(Plus, { size: 14 }), "Add Image"]
279
+ })
280
+ ]
281
+ }) : /* @__PURE__ */ jsxs("div", {
282
+ className: galleryImageList,
283
+ children: [/* @__PURE__ */ jsxs(DndContext, {
284
+ collisionDetection: closestCenter,
285
+ sensors,
286
+ onDragCancel: () => setDragActiveId(null),
287
+ onDragEnd: handleDragEnd,
288
+ onDragStart: (event) => {
289
+ setDragActiveId(String(event.active.id));
290
+ },
291
+ children: [/* @__PURE__ */ jsx(SortableContext, {
292
+ items: itemIds,
293
+ strategy: verticalListSortingStrategy,
294
+ children: entries.map((entry, index) => /* @__PURE__ */ jsx(SortableImageCard, {
295
+ id: entry.id,
296
+ image: entry.image,
297
+ index,
298
+ isLast: index === entries.length - 1,
299
+ lastInputRef: newInputRef,
300
+ onRemove: handleRemoveImage,
301
+ onUpdate: handleUpdateImage
302
+ }, entry.id))
303
+ }), typeof document !== "undefined" ? createPortal(/* @__PURE__ */ jsx("div", {
304
+ className: portalClassName,
305
+ children: /* @__PURE__ */ jsx(DragOverlay, {
306
+ dropAnimation: null,
307
+ children: dragActiveEntry ? /* @__PURE__ */ jsx(DragOverlayCard, { image: dragActiveEntry.image }) : null
308
+ })
309
+ }), document.body) : null]
310
+ }), /* @__PURE__ */ jsxs("button", {
311
+ className: galleryAddBtn,
312
+ type: "button",
313
+ onClick: handleAddImage,
314
+ children: [/* @__PURE__ */ jsx(Plus, { size: 14 }), "Add Image"]
315
+ })]
316
+ })
317
+ }),
318
+ /* @__PURE__ */ jsxs("div", {
319
+ className: galleryDialogFooter,
320
+ children: [/* @__PURE__ */ jsx("span", {
321
+ className: galleryFooterInfo,
322
+ children: `${entries.filter((e) => e.image.src.trim()).length} ${entries.filter((e) => e.image.src.trim()).length !== 1 ? "images" : "image"}`
323
+ }), /* @__PURE__ */ jsxs("div", {
324
+ className: galleryFooterActions,
325
+ children: [/* @__PURE__ */ jsx("button", {
326
+ className: galleryFooterBtnCancel,
327
+ type: "button",
328
+ onClick: dismiss,
329
+ children: "Cancel"
330
+ }), /* @__PURE__ */ jsx("button", {
331
+ className: galleryFooterBtnSave,
332
+ type: "button",
333
+ onClick: handleSave,
334
+ children: "Save"
335
+ })]
336
+ })]
337
+ })
338
+ ] });
270
339
  };
271
- const GalleryEditRenderer = ({
272
- images,
273
- layout,
274
- onImagesChange,
275
- onLayoutChange
276
- }) => {
277
- const { className: portalClassName } = usePortalTheme();
278
- const theme = useColorScheme();
279
- const handleOpenEditor = useCallback(() => {
280
- if (!onImagesChange || !onLayoutChange) return;
281
- presentDialog({
282
- content: ({ dismiss }) => /* @__PURE__ */ jsx(
283
- GalleryEditorDialogContent,
284
- {
285
- dismiss,
286
- initialImages: images,
287
- initialLayout: layout,
288
- onImagesChange,
289
- onLayoutChange
290
- }
291
- ),
292
- className: galleryDialogPopup,
293
- portalClassName,
294
- theme,
295
- showCloseButton: false,
296
- clickOutsideToDismiss: false
297
- });
298
- }, [images, layout, onImagesChange, onLayoutChange, portalClassName, theme]);
299
- if (!onImagesChange) {
300
- return /* @__PURE__ */ jsx(GalleryRenderer, { images, layout });
301
- }
302
- if (images.length === 0) {
303
- return /* @__PURE__ */ jsxs("div", { className: galleryEditContainer, children: [
304
- /* @__PURE__ */ jsxs("div", { className: galleryEmptyState, children: [
305
- /* @__PURE__ */ jsx(ImageIcon, { size: 32 }),
306
- /* @__PURE__ */ jsx("span", { children: "Empty gallery" })
307
- ] }),
308
- /* @__PURE__ */ jsx("button", { className: galleryEditOverlay, type: "button", onClick: handleOpenEditor, children: /* @__PURE__ */ jsxs("span", { className: galleryEditLabel, children: [
309
- /* @__PURE__ */ jsx(Pencil, { size: 16 }),
310
- "Edit Gallery"
311
- ] }) })
312
- ] });
313
- }
314
- return /* @__PURE__ */ jsxs("div", { className: galleryEditContainer, children: [
315
- /* @__PURE__ */ jsx(GalleryRenderer, { images, layout }),
316
- /* @__PURE__ */ jsx("button", { className: galleryEditOverlay, type: "button", onClick: handleOpenEditor, children: /* @__PURE__ */ jsxs("span", { className: galleryEditLabel, children: [
317
- /* @__PURE__ */ jsx(Pencil, { size: 16 }),
318
- "Edit Gallery"
319
- ] }) })
320
- ] });
321
- };
322
- const galleryNodes = [GalleryNode];
323
- const galleryEditNodes = [GalleryEditNode];
324
- export {
325
- $createGalleryEditNode,
326
- $ as $createGalleryNode,
327
- $isGalleryEditNode,
328
- B as $isGalleryNode,
329
- GalleryEditNode,
330
- GalleryEditRenderer,
331
- GalleryNode,
332
- GalleryRenderer,
333
- C as default,
334
- galleryEditNodes,
335
- galleryNodes
340
+ var GalleryEditRenderer = ({ images, layout, onImagesChange, onLayoutChange }) => {
341
+ const { className: portalClassName } = usePortalTheme();
342
+ const theme = useColorScheme();
343
+ const handleOpenEditor = useCallback(() => {
344
+ if (!onImagesChange || !onLayoutChange) return;
345
+ presentDialog({
346
+ content: ({ dismiss }) => /* @__PURE__ */ jsx(GalleryEditorDialogContent, {
347
+ dismiss,
348
+ initialImages: images,
349
+ initialLayout: layout,
350
+ onImagesChange,
351
+ onLayoutChange
352
+ }),
353
+ className: galleryDialogPopup,
354
+ portalClassName,
355
+ theme,
356
+ showCloseButton: false,
357
+ clickOutsideToDismiss: false
358
+ });
359
+ }, [
360
+ images,
361
+ layout,
362
+ onImagesChange,
363
+ onLayoutChange,
364
+ portalClassName,
365
+ theme
366
+ ]);
367
+ if (!onImagesChange) return /* @__PURE__ */ jsx(GalleryRenderer, {
368
+ images,
369
+ layout
370
+ });
371
+ if (images.length === 0) return /* @__PURE__ */ jsxs("div", {
372
+ className: galleryEditContainer,
373
+ children: [/* @__PURE__ */ jsxs("div", {
374
+ className: galleryEmptyState,
375
+ children: [/* @__PURE__ */ jsx(ImageIcon, { size: 32 }), /* @__PURE__ */ jsx("span", { children: "Empty gallery" })]
376
+ }), /* @__PURE__ */ jsx("button", {
377
+ className: galleryEditOverlay,
378
+ type: "button",
379
+ onClick: handleOpenEditor,
380
+ children: /* @__PURE__ */ jsxs("span", {
381
+ className: galleryEditLabel,
382
+ children: [/* @__PURE__ */ jsx(Pencil, { size: 16 }), "Edit Gallery"]
383
+ })
384
+ })]
385
+ });
386
+ return /* @__PURE__ */ jsxs("div", {
387
+ className: galleryEditContainer,
388
+ children: [/* @__PURE__ */ jsx(GalleryRenderer, {
389
+ images,
390
+ layout
391
+ }), /* @__PURE__ */ jsx("button", {
392
+ className: galleryEditOverlay,
393
+ type: "button",
394
+ onClick: handleOpenEditor,
395
+ children: /* @__PURE__ */ jsxs("span", {
396
+ className: galleryEditLabel,
397
+ children: [/* @__PURE__ */ jsx(Pencil, { size: 16 }), "Edit Gallery"]
398
+ })
399
+ })]
400
+ });
336
401
  };
402
+ //#endregion
403
+ //#region src/index.ts
404
+ var galleryNodes = [GalleryNode];
405
+ var galleryEditNodes = [GalleryEditNode];
406
+ //#endregion
407
+ export { $createGalleryEditNode, $createGalleryNode, $isGalleryEditNode, $isGalleryNode, GalleryEditNode, GalleryEditRenderer, GalleryNode, GalleryRenderer, GalleryRenderer_default as default, galleryEditNodes, galleryNodes };