@haklex/rich-ext-gallery 0.0.65 → 0.0.67
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/README.md +67 -25
- package/dist/GalleryEditNode.d.ts +1 -1
- package/dist/GalleryEditNode.d.ts.map +1 -1
- package/dist/GalleryEditRenderer.d.ts +1 -1
- package/dist/GalleryEditRenderer.d.ts.map +1 -1
- package/dist/{GalleryNode-DUfg2dIP.js → GalleryNode-CV8DRu_G.js} +7 -10
- package/dist/GalleryNode.d.ts +1 -1
- package/dist/GalleryNode.d.ts.map +1 -1
- package/dist/GalleryRenderer.d.ts +1 -1
- package/dist/GalleryRenderer.d.ts.map +1 -1
- package/dist/index.mjs +52 -137
- package/dist/static.mjs +2 -2
- package/package.json +16 -11
package/README.md
CHANGED
|
@@ -1,47 +1,89 @@
|
|
|
1
1
|
# @haklex/rich-ext-gallery
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Image gallery extension with grid and carousel layouts, drag-and-drop reordering.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
pnpm add @haklex/rich-ext-gallery
|
|
8
|
+
pnpm add @haklex/rich-ext-gallery
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Peer Dependencies
|
|
12
|
+
|
|
13
|
+
| Package | Version |
|
|
14
|
+
| --- | --- |
|
|
15
|
+
| `lexical` | `^0.41.0` |
|
|
16
|
+
| `lucide-react` | `^0.574.0` |
|
|
17
|
+
| `react` | `>= 19` |
|
|
18
|
+
| `react-dom` | `>= 19` |
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
### Register nodes in your editor config
|
|
12
23
|
|
|
13
24
|
```ts
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
25
|
+
import { galleryEditNodes } from '@haklex/rich-ext-gallery'
|
|
26
|
+
|
|
27
|
+
const editorConfig = {
|
|
28
|
+
nodes: [...galleryEditNodes],
|
|
29
|
+
}
|
|
30
|
+
```
|
|
18
31
|
|
|
19
|
-
|
|
20
|
-
export { GalleryRenderer } from './GalleryRenderer'
|
|
21
|
-
export { GalleryEditRenderer } from './GalleryEditRenderer'
|
|
32
|
+
For static/read-only rendering:
|
|
22
33
|
|
|
23
|
-
|
|
24
|
-
|
|
34
|
+
```ts
|
|
35
|
+
import { galleryNodes } from '@haklex/rich-ext-gallery/static'
|
|
36
|
+
|
|
37
|
+
const staticConfig = {
|
|
38
|
+
nodes: [...galleryNodes],
|
|
39
|
+
}
|
|
25
40
|
```
|
|
26
41
|
|
|
27
|
-
|
|
42
|
+
### Use renderers
|
|
28
43
|
|
|
29
44
|
```tsx
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
32
|
-
|
|
45
|
+
import { GalleryEditRenderer } from '@haklex/rich-ext-gallery'
|
|
46
|
+
import { GalleryRenderer } from '@haklex/rich-ext-gallery/static'
|
|
47
|
+
```
|
|
33
48
|
|
|
34
|
-
|
|
35
|
-
Gallery: GalleryRenderer,
|
|
36
|
-
}
|
|
49
|
+
### Import styles
|
|
37
50
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
rendererConfig={config}
|
|
41
|
-
extraNodes={[...galleryNodes]}
|
|
42
|
-
/>
|
|
51
|
+
```ts
|
|
52
|
+
import '@haklex/rich-ext-gallery/style.css'
|
|
43
53
|
```
|
|
44
54
|
|
|
55
|
+
## Exports
|
|
56
|
+
|
|
57
|
+
### Nodes
|
|
58
|
+
|
|
59
|
+
- `GalleryNode` -- static (read-only) node
|
|
60
|
+
- `GalleryEditNode` -- edit node with drag-and-drop image reordering
|
|
61
|
+
- `$createGalleryNode()` / `$isGalleryNode()` -- Lexical helpers
|
|
62
|
+
- `galleryNodes` -- array of static nodes for config registration
|
|
63
|
+
- `galleryEditNodes` -- array of edit nodes for config registration
|
|
64
|
+
|
|
65
|
+
### Renderers
|
|
66
|
+
|
|
67
|
+
- `GalleryRenderer` -- static renderer (grid/carousel display)
|
|
68
|
+
- `GalleryEditRenderer` -- edit renderer with drag-and-drop support
|
|
69
|
+
|
|
70
|
+
### Types
|
|
71
|
+
|
|
72
|
+
- `GalleryNodePayload` -- payload type for creating gallery nodes
|
|
73
|
+
- `SerializedGalleryNode` -- serialized gallery node type
|
|
74
|
+
|
|
75
|
+
### Sub-path Exports
|
|
76
|
+
|
|
77
|
+
| Path | Description |
|
|
78
|
+
| --- | --- |
|
|
79
|
+
| `@haklex/rich-ext-gallery` | Full exports (edit + static) |
|
|
80
|
+
| `@haklex/rich-ext-gallery/static` | Static-only (no drag-and-drop deps) |
|
|
81
|
+
| `@haklex/rich-ext-gallery/style.css` | Stylesheet |
|
|
82
|
+
|
|
83
|
+
## Part of Haklex
|
|
84
|
+
|
|
85
|
+
This package is part of the [Haklex](../../README.md) rich editor ecosystem.
|
|
86
|
+
|
|
45
87
|
## License
|
|
46
88
|
|
|
47
89
|
MIT
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CommandItemConfig } from '@haklex/rich-editor';
|
|
1
|
+
import { CommandItemConfig } from '@haklex/rich-editor/commands';
|
|
2
2
|
import { EditorConfig, LexicalEditor, LexicalNode, NodeKey } from 'lexical';
|
|
3
3
|
import { ReactElement } from 'react';
|
|
4
4
|
import { GalleryNode, GalleryNodePayload, SerializedGalleryNode } from './GalleryNode';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GalleryEditNode.d.ts","sourceRoot":"","sources":["../src/GalleryEditNode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"GalleryEditNode.d.ts","sourceRoot":"","sources":["../src/GalleryEditNode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAGtE,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAGjF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAG1C,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,KAAK,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAGjG,qBAAa,eAAgB,SAAQ,WAAW;IAC9C,MAAM,CAAC,YAAY,EAAE,iBAAiB,EAAE,CAetC;IAEF,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,eAAe,GAAG,eAAe;gBAUxC,OAAO,EAAE,kBAAkB,EAAE,GAAG,CAAC,EAAE,OAAO;IAItD,MAAM,CAAC,UAAU,CAAC,cAAc,EAAE,qBAAqB,GAAG,eAAe;IAOzE,QAAQ,CAAC,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,YAAY,GAAG,YAAY;CAoBrE;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,kBAAkB,GAAG,eAAe,CAEnF;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,IAAI,eAAe,CAEhG"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { GalleryRendererProps } from '@haklex/rich-editor';
|
|
1
|
+
import { GalleryRendererProps } from '@haklex/rich-editor/renderers';
|
|
2
2
|
import { FC } from 'react';
|
|
3
3
|
export declare const GalleryEditRenderer: FC<GalleryRendererProps>;
|
|
4
4
|
//# sourceMappingURL=GalleryEditRenderer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GalleryEditRenderer.d.ts","sourceRoot":"","sources":["../src/GalleryEditRenderer.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"GalleryEditRenderer.d.ts","sourceRoot":"","sources":["../src/GalleryEditRenderer.tsx"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAgB,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAIxF,OAAO,KAAK,EAAiB,EAAE,EAAE,MAAM,OAAO,CAAC;AAkS/C,eAAO,MAAM,mBAAmB,EAAE,EAAE,CAAC,oBAAoB,CA6DxD,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
3
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
|
-
import { decodeThumbHash, createRendererDecoration } from "@haklex/rich-editor";
|
|
4
|
+
import { decodeThumbHash, createRendererDecoration } from "@haklex/rich-editor/renderers";
|
|
5
5
|
import { DecoratorNode } from "lexical";
|
|
6
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
7
|
import "react-photo-view/dist/react-photo-view.css";
|
|
@@ -72,10 +72,7 @@ function useThumbhashStyle(image) {
|
|
|
72
72
|
return { backgroundImage: `url(${url})`, backgroundSize: "cover" };
|
|
73
73
|
}, [image.thumbhash]);
|
|
74
74
|
}
|
|
75
|
-
const GalleryRenderer = ({
|
|
76
|
-
images,
|
|
77
|
-
layout
|
|
78
|
-
}) => {
|
|
75
|
+
const GalleryRenderer = ({ images, layout }) => {
|
|
79
76
|
const [containerRef, setContainerRef] = useState(null);
|
|
80
77
|
const [, setUpdated] = useState({});
|
|
81
78
|
const memoedChildContainerWidthRef = useRef(0);
|
|
@@ -179,9 +176,9 @@ const GalleryRenderer = ({
|
|
|
179
176
|
"div",
|
|
180
177
|
{
|
|
181
178
|
className: galleryContainer,
|
|
182
|
-
onTouchStart: handleCancelAutoplay,
|
|
183
|
-
onScroll: handleOnScroll,
|
|
184
179
|
ref: setContainerRef,
|
|
180
|
+
onScroll: handleOnScroll,
|
|
181
|
+
onTouchStart: handleCancelAutoplay,
|
|
185
182
|
children: images.map((image, index) => /* @__PURE__ */ jsx(
|
|
186
183
|
GalleryFigure,
|
|
187
184
|
{
|
|
@@ -232,12 +229,12 @@ const GalleryFigure = memo(
|
|
|
232
229
|
return /* @__PURE__ */ jsx(PhotoView, { src: image.src, children: /* @__PURE__ */ jsx("figure", { className: galleryItem, style: { ...thumbStyle, ...style }, children: /* @__PURE__ */ jsx(
|
|
233
230
|
"img",
|
|
234
231
|
{
|
|
235
|
-
src: image.src,
|
|
236
232
|
alt: image.alt || "",
|
|
237
|
-
width: image.width,
|
|
238
233
|
height: image.height,
|
|
239
234
|
loading: "lazy",
|
|
240
|
-
|
|
235
|
+
src: image.src,
|
|
236
|
+
style: { maxWidth: "100%", height: "auto" },
|
|
237
|
+
width: image.width
|
|
241
238
|
}
|
|
242
239
|
) }) });
|
|
243
240
|
}
|
package/dist/GalleryNode.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { GalleryImage } from '@haklex/rich-editor';
|
|
1
|
+
import { GalleryImage } from '@haklex/rich-editor/renderers';
|
|
2
2
|
import { EditorConfig, LexicalEditor, LexicalNode, NodeKey, SerializedLexicalNode, Spread, DecoratorNode } from 'lexical';
|
|
3
3
|
import { ReactElement } from 'react';
|
|
4
4
|
export type SerializedGalleryNode = Spread<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GalleryNode.d.ts","sourceRoot":"","sources":["../src/GalleryNode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAwB,MAAM,
|
|
1
|
+
{"version":3,"file":"GalleryNode.d.ts","sourceRoot":"","sources":["../src/GalleryNode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAwB,MAAM,+BAA+B,CAAC;AAExF,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,WAAW,EACX,OAAO,EACP,qBAAqB,EACrB,MAAM,EACP,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAI1C,MAAM,MAAM,qBAAqB,GAAG,MAAM,CACxC;IACE,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,CAAC;CAC1C,EACD,qBAAqB,CACtB,CAAC;AAEF,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,CAAC;CAC1C;AAED,qBAAa,WAAY,SAAQ,aAAa,CAAC,YAAY,CAAC;IAC1D,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,CAAC;IAE1C,MAAM,CAAC,OAAO,IAAI,MAAM;IAIxB,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,WAAW,GAAG,WAAW;gBAUhC,OAAO,EAAE,kBAAkB,EAAE,GAAG,CAAC,EAAE,OAAO;IAMtD,SAAS,CAAC,OAAO,EAAE,YAAY,GAAG,WAAW;IAM7C,SAAS,IAAI,OAAO;IAIpB,QAAQ,IAAI,OAAO;IAInB,MAAM,CAAC,UAAU,CAAC,cAAc,EAAE,qBAAqB,GAAG,WAAW;IAOrE,UAAU,IAAI,qBAAqB;IAUnC,SAAS,IAAI,YAAY,EAAE;IAI3B,SAAS,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,IAAI;IAKvC,SAAS,IAAI,MAAM,GAAG,SAAS,GAAG,UAAU;IAI5C,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,GAAG,IAAI;IAKxD,QAAQ,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,YAAY,GAAG,YAAY;CAOtE;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,kBAAkB,GAAG,WAAW,CAE3E;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,IAAI,WAAW,CAExF"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { GalleryRendererProps } from '@haklex/rich-editor';
|
|
1
|
+
import { GalleryRendererProps } from '@haklex/rich-editor/renderers';
|
|
2
2
|
import { ComponentType } from 'react';
|
|
3
3
|
export declare const GalleryRenderer: ComponentType<GalleryRendererProps>;
|
|
4
4
|
declare const _default: import('react').NamedExoticComponent<GalleryRendererProps>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GalleryRenderer.d.ts","sourceRoot":"","sources":["../src/GalleryRenderer.tsx"],"names":[],"mappings":"AAAA,OAAO,4CAA4C,
|
|
1
|
+
{"version":3,"file":"GalleryRenderer.d.ts","sourceRoot":"","sources":["../src/GalleryRenderer.tsx"],"names":[],"mappings":"AAAA,OAAO,4CAA4C,CAAC;AAEpD,OAAO,EAGL,KAAK,oBAAoB,EAC1B,MAAM,+BAA+B,CAAC;AAEvC,OAAO,KAAK,EAAE,aAAa,EAAkB,MAAM,OAAO,CAAC;AAoC3D,eAAO,MAAM,eAAe,EAAE,aAAa,CAAC,oBAAoB,CAuL/D,CAAC;;AAuBF,wBAAqC"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
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-
|
|
5
|
-
import { $, B, C } from "./GalleryNode-
|
|
6
|
-
import { createRendererDecoration
|
|
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";
|
|
6
|
+
import { createRendererDecoration } from "@haklex/rich-editor/renderers";
|
|
7
7
|
import { $insertNodes, $getNodeByKey } from "lexical";
|
|
8
8
|
import { Images, ImageIcon, Pencil, X, Plus, GripVertical, Trash2 } from "lucide-react";
|
|
9
9
|
import { createElement, useCallback, useState, useRef } from "react";
|
|
@@ -11,6 +11,7 @@ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
|
11
11
|
import { useSensors, useSensor, PointerSensor, DndContext, closestCenter, DragOverlay } from "@dnd-kit/core";
|
|
12
12
|
import { arrayMove, SortableContext, verticalListSortingStrategy, useSortable } from "@dnd-kit/sortable";
|
|
13
13
|
import { CSS } from "@dnd-kit/utilities";
|
|
14
|
+
import { useColorScheme } from "@haklex/rich-editor";
|
|
14
15
|
import { presentDialog, SegmentedControl } from "@haklex/rich-editor-ui";
|
|
15
16
|
import { usePortalTheme, vars } from "@haklex/rich-style-token";
|
|
16
17
|
import { createPortal } from "react-dom";
|
|
@@ -87,38 +88,25 @@ function genId() {
|
|
|
87
88
|
return `img-${++nextId}`;
|
|
88
89
|
}
|
|
89
90
|
const SortableImageCard = ({ id, image, index, isLast, lastInputRef, onUpdate, onRemove }) => {
|
|
90
|
-
const {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
setNodeRef,
|
|
94
|
-
transform,
|
|
95
|
-
transition,
|
|
96
|
-
isDragging
|
|
97
|
-
} = useSortable({ id });
|
|
91
|
+
const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({
|
|
92
|
+
id
|
|
93
|
+
});
|
|
98
94
|
const style = {
|
|
99
95
|
transform: CSS.Transform.toString(transform),
|
|
100
96
|
transition: isDragging ? void 0 : transition,
|
|
101
97
|
opacity: isDragging ? 0.4 : 1
|
|
102
98
|
};
|
|
103
|
-
return /* @__PURE__ */ jsxs("div", { ref: setNodeRef, style,
|
|
104
|
-
/* @__PURE__ */ jsx(
|
|
105
|
-
|
|
106
|
-
{
|
|
107
|
-
className: galleryImageDragHandle,
|
|
108
|
-
...attributes,
|
|
109
|
-
...listeners,
|
|
110
|
-
children: /* @__PURE__ */ jsx(GripVertical, { size: 14 })
|
|
111
|
-
}
|
|
112
|
-
),
|
|
113
|
-
/* @__PURE__ */ jsx("div", { className: galleryImageThumb, children: image.src ? /* @__PURE__ */ jsx("img", { src: image.src, alt: image.alt || "" }) : /* @__PURE__ */ jsx("span", { className: galleryImageThumbPlaceholder, children: /* @__PURE__ */ jsx(ImageIcon, { size: 20 }) }) }),
|
|
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 }) }) }),
|
|
114
102
|
/* @__PURE__ */ jsxs("div", { className: galleryImageFields, children: [
|
|
115
103
|
/* @__PURE__ */ jsx(
|
|
116
104
|
"input",
|
|
117
105
|
{
|
|
118
|
-
ref: isLast ? lastInputRef : void 0,
|
|
119
106
|
className: galleryImageInput,
|
|
120
|
-
type: "text",
|
|
121
107
|
placeholder: "Image URL",
|
|
108
|
+
ref: isLast ? lastInputRef : void 0,
|
|
109
|
+
type: "text",
|
|
122
110
|
value: image.src,
|
|
123
111
|
onChange: (e) => onUpdate(index, "src", e.target.value)
|
|
124
112
|
}
|
|
@@ -127,8 +115,8 @@ const SortableImageCard = ({ id, image, index, isLast, lastInputRef, onUpdate, o
|
|
|
127
115
|
"input",
|
|
128
116
|
{
|
|
129
117
|
className: galleryImageInput,
|
|
130
|
-
type: "text",
|
|
131
118
|
placeholder: "Alt text (optional)",
|
|
119
|
+
type: "text",
|
|
132
120
|
value: image.alt || "",
|
|
133
121
|
onChange: (e) => onUpdate(index, "alt", e.target.value)
|
|
134
122
|
}
|
|
@@ -137,10 +125,10 @@ const SortableImageCard = ({ id, image, index, isLast, lastInputRef, onUpdate, o
|
|
|
137
125
|
/* @__PURE__ */ jsx("div", { className: galleryImageActions, children: /* @__PURE__ */ jsx(
|
|
138
126
|
"button",
|
|
139
127
|
{
|
|
140
|
-
type: "button",
|
|
141
128
|
className: galleryImageDeleteBtn,
|
|
142
|
-
onClick: () => onRemove(index),
|
|
143
129
|
title: "Remove",
|
|
130
|
+
type: "button",
|
|
131
|
+
onClick: () => onRemove(index),
|
|
144
132
|
children: /* @__PURE__ */ jsx(Trash2, { size: 14 })
|
|
145
133
|
}
|
|
146
134
|
) })
|
|
@@ -148,7 +136,7 @@ const SortableImageCard = ({ id, image, index, isLast, lastInputRef, onUpdate, o
|
|
|
148
136
|
};
|
|
149
137
|
const DragOverlayCard = ({ image }) => /* @__PURE__ */ jsxs("div", { className: galleryImageCard, style: { opacity: 0.9 }, children: [
|
|
150
138
|
/* @__PURE__ */ jsx("div", { className: galleryImageDragHandle, children: /* @__PURE__ */ jsx(GripVertical, { size: 14 }) }),
|
|
151
|
-
/* @__PURE__ */ jsx("div", { className: galleryImageThumb, children: image.src ? /* @__PURE__ */ jsx("img", {
|
|
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 }) }) }),
|
|
152
140
|
/* @__PURE__ */ jsx("div", { className: galleryImageFields, children: /* @__PURE__ */ jsx(
|
|
153
141
|
"span",
|
|
154
142
|
{
|
|
@@ -162,13 +150,7 @@ const DragOverlayCard = ({ image }) => /* @__PURE__ */ jsxs("div", { className:
|
|
|
162
150
|
}
|
|
163
151
|
) })
|
|
164
152
|
] });
|
|
165
|
-
const GalleryEditorDialogContent = ({
|
|
166
|
-
dismiss,
|
|
167
|
-
initialImages,
|
|
168
|
-
initialLayout,
|
|
169
|
-
onImagesChange,
|
|
170
|
-
onLayoutChange
|
|
171
|
-
}) => {
|
|
153
|
+
const GalleryEditorDialogContent = ({ dismiss, initialImages, initialLayout, onImagesChange, onLayoutChange }) => {
|
|
172
154
|
const { className: portalClassName } = usePortalTheme();
|
|
173
155
|
const [entries, setEntries] = useState(
|
|
174
156
|
() => initialImages.map((img) => ({ id: genId(), image: { ...img } }))
|
|
@@ -177,14 +159,9 @@ const GalleryEditorDialogContent = ({
|
|
|
177
159
|
const newInputRef = useRef(null);
|
|
178
160
|
const [dragActiveId, setDragActiveId] = useState(null);
|
|
179
161
|
const itemIds = entries.map((e) => e.id);
|
|
180
|
-
const sensors = useSensors(
|
|
181
|
-
useSensor(PointerSensor, { activationConstraint: { distance: 5 } })
|
|
182
|
-
);
|
|
162
|
+
const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 5 } }));
|
|
183
163
|
const handleAddImage = useCallback(() => {
|
|
184
|
-
setEntries((prev) => [
|
|
185
|
-
...prev,
|
|
186
|
-
{ id: genId(), image: { src: "", alt: "" } }
|
|
187
|
-
]);
|
|
164
|
+
setEntries((prev) => [...prev, { id: genId(), image: { src: "", alt: "" } }]);
|
|
188
165
|
requestAnimationFrame(() => {
|
|
189
166
|
newInputRef.current?.focus();
|
|
190
167
|
});
|
|
@@ -226,23 +203,8 @@ const GalleryEditorDialogContent = ({
|
|
|
226
203
|
/* @__PURE__ */ jsx(Images, { size: 18 }),
|
|
227
204
|
/* @__PURE__ */ jsx("span", { children: "Gallery Editor" })
|
|
228
205
|
] }),
|
|
229
|
-
/* @__PURE__ */ jsx("div", { className: galleryHeaderActions, children: /* @__PURE__ */ jsx(
|
|
230
|
-
|
|
231
|
-
{
|
|
232
|
-
items: layoutItems,
|
|
233
|
-
value: layout,
|
|
234
|
-
onChange: setLayout
|
|
235
|
-
}
|
|
236
|
-
) }),
|
|
237
|
-
/* @__PURE__ */ jsx(
|
|
238
|
-
"button",
|
|
239
|
-
{
|
|
240
|
-
type: "button",
|
|
241
|
-
className: galleryHeaderClose,
|
|
242
|
-
onClick: dismiss,
|
|
243
|
-
children: /* @__PURE__ */ jsx(X, { size: 18 })
|
|
244
|
-
}
|
|
245
|
-
)
|
|
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 }) })
|
|
246
208
|
] }),
|
|
247
209
|
/* @__PURE__ */ jsx("div", { className: galleryDialogBody, children: entries.length === 0 ? /* @__PURE__ */ jsxs("div", { className: galleryDialogEmpty, children: [
|
|
248
210
|
/* @__PURE__ */ jsx(ImageIcon, { size: 32 }),
|
|
@@ -250,10 +212,10 @@ const GalleryEditorDialogContent = ({
|
|
|
250
212
|
/* @__PURE__ */ jsxs(
|
|
251
213
|
"button",
|
|
252
214
|
{
|
|
253
|
-
type: "button",
|
|
254
215
|
className: galleryAddBtn,
|
|
255
|
-
onClick: handleAddImage,
|
|
256
216
|
style: { maxWidth: 200 },
|
|
217
|
+
type: "button",
|
|
218
|
+
onClick: handleAddImage,
|
|
257
219
|
children: [
|
|
258
220
|
/* @__PURE__ */ jsx(Plus, { size: 14 }),
|
|
259
221
|
"Add Image"
|
|
@@ -264,34 +226,27 @@ const GalleryEditorDialogContent = ({
|
|
|
264
226
|
/* @__PURE__ */ jsxs(
|
|
265
227
|
DndContext,
|
|
266
228
|
{
|
|
267
|
-
sensors,
|
|
268
229
|
collisionDetection: closestCenter,
|
|
230
|
+
sensors,
|
|
231
|
+
onDragCancel: () => setDragActiveId(null),
|
|
232
|
+
onDragEnd: handleDragEnd,
|
|
269
233
|
onDragStart: (event) => {
|
|
270
234
|
setDragActiveId(String(event.active.id));
|
|
271
235
|
},
|
|
272
|
-
onDragEnd: handleDragEnd,
|
|
273
|
-
onDragCancel: () => setDragActiveId(null),
|
|
274
236
|
children: [
|
|
275
|
-
/* @__PURE__ */ jsx(
|
|
276
|
-
|
|
237
|
+
/* @__PURE__ */ jsx(SortableContext, { items: itemIds, strategy: verticalListSortingStrategy, children: entries.map((entry, index) => /* @__PURE__ */ jsx(
|
|
238
|
+
SortableImageCard,
|
|
277
239
|
{
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
onUpdate: handleUpdateImage,
|
|
289
|
-
onRemove: handleRemoveImage
|
|
290
|
-
},
|
|
291
|
-
entry.id
|
|
292
|
-
))
|
|
293
|
-
}
|
|
294
|
-
),
|
|
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
|
+
)) }),
|
|
295
250
|
typeof document !== "undefined" ? createPortal(
|
|
296
251
|
/* @__PURE__ */ jsx("div", { className: portalClassName, children: /* @__PURE__ */ jsx(DragOverlay, { dropAnimation: null, children: dragActiveEntry ? /* @__PURE__ */ jsx(DragOverlayCard, { image: dragActiveEntry.image }) : null }) }),
|
|
297
252
|
document.body
|
|
@@ -299,40 +254,16 @@ const GalleryEditorDialogContent = ({
|
|
|
299
254
|
]
|
|
300
255
|
}
|
|
301
256
|
),
|
|
302
|
-
/* @__PURE__ */ jsxs(
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
className: galleryAddBtn,
|
|
307
|
-
onClick: handleAddImage,
|
|
308
|
-
children: [
|
|
309
|
-
/* @__PURE__ */ jsx(Plus, { size: 14 }),
|
|
310
|
-
"Add Image"
|
|
311
|
-
]
|
|
312
|
-
}
|
|
313
|
-
)
|
|
257
|
+
/* @__PURE__ */ jsxs("button", { className: galleryAddBtn, type: "button", onClick: handleAddImage, children: [
|
|
258
|
+
/* @__PURE__ */ jsx(Plus, { size: 14 }),
|
|
259
|
+
"Add Image"
|
|
260
|
+
] })
|
|
314
261
|
] }) }),
|
|
315
262
|
/* @__PURE__ */ jsxs("div", { className: galleryDialogFooter, children: [
|
|
316
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"}` }),
|
|
317
264
|
/* @__PURE__ */ jsxs("div", { className: galleryFooterActions, children: [
|
|
318
|
-
/* @__PURE__ */ jsx(
|
|
319
|
-
|
|
320
|
-
{
|
|
321
|
-
type: "button",
|
|
322
|
-
className: galleryFooterBtnCancel,
|
|
323
|
-
onClick: dismiss,
|
|
324
|
-
children: "Cancel"
|
|
325
|
-
}
|
|
326
|
-
),
|
|
327
|
-
/* @__PURE__ */ jsx(
|
|
328
|
-
"button",
|
|
329
|
-
{
|
|
330
|
-
type: "button",
|
|
331
|
-
className: galleryFooterBtnSave,
|
|
332
|
-
onClick: handleSave,
|
|
333
|
-
children: "Save"
|
|
334
|
-
}
|
|
335
|
-
)
|
|
265
|
+
/* @__PURE__ */ jsx("button", { className: galleryFooterBtnCancel, type: "button", onClick: dismiss, children: "Cancel" }),
|
|
266
|
+
/* @__PURE__ */ jsx("button", { className: galleryFooterBtnSave, type: "button", onClick: handleSave, children: "Save" })
|
|
336
267
|
] })
|
|
337
268
|
] })
|
|
338
269
|
] });
|
|
@@ -374,34 +305,18 @@ const GalleryEditRenderer = ({
|
|
|
374
305
|
/* @__PURE__ */ jsx(ImageIcon, { size: 32 }),
|
|
375
306
|
/* @__PURE__ */ jsx("span", { children: "Empty gallery" })
|
|
376
307
|
] }),
|
|
377
|
-
/* @__PURE__ */ jsx(
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
className: galleryEditOverlay,
|
|
382
|
-
onClick: handleOpenEditor,
|
|
383
|
-
children: /* @__PURE__ */ jsxs("span", { className: galleryEditLabel, children: [
|
|
384
|
-
/* @__PURE__ */ jsx(Pencil, { size: 16 }),
|
|
385
|
-
"Edit Gallery"
|
|
386
|
-
] })
|
|
387
|
-
}
|
|
388
|
-
)
|
|
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
|
+
] }) })
|
|
389
312
|
] });
|
|
390
313
|
}
|
|
391
314
|
return /* @__PURE__ */ jsxs("div", { className: galleryEditContainer, children: [
|
|
392
315
|
/* @__PURE__ */ jsx(GalleryRenderer, { images, layout }),
|
|
393
|
-
/* @__PURE__ */ jsx(
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
className: galleryEditOverlay,
|
|
398
|
-
onClick: handleOpenEditor,
|
|
399
|
-
children: /* @__PURE__ */ jsxs("span", { className: galleryEditLabel, children: [
|
|
400
|
-
/* @__PURE__ */ jsx(Pencil, { size: 16 }),
|
|
401
|
-
"Edit Gallery"
|
|
402
|
-
] })
|
|
403
|
-
}
|
|
404
|
-
)
|
|
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
|
+
] }) })
|
|
405
320
|
] });
|
|
406
321
|
};
|
|
407
322
|
const galleryNodes = [GalleryNode];
|
package/dist/static.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { G as GalleryNode } from "./GalleryNode-
|
|
2
|
-
import { $, B, a, C } from "./GalleryNode-
|
|
1
|
+
import { G as GalleryNode } from "./GalleryNode-CV8DRu_G.js";
|
|
2
|
+
import { $, B, a, C } from "./GalleryNode-CV8DRu_G.js";
|
|
3
3
|
const galleryNodes = [GalleryNode];
|
|
4
4
|
export {
|
|
5
5
|
$ as $createGalleryNode,
|
package/package.json
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@haklex/rich-ext-gallery",
|
|
3
|
-
"
|
|
4
|
-
"version": "0.0.65",
|
|
3
|
+
"version": "0.0.67",
|
|
5
4
|
"description": "Image gallery extension with drag-and-drop",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/Innei/haklex.git",
|
|
8
|
+
"directory": "packages/rich-ext-gallery"
|
|
9
|
+
},
|
|
6
10
|
"license": "MIT",
|
|
11
|
+
"type": "module",
|
|
7
12
|
"exports": {
|
|
8
13
|
".": {
|
|
9
14
|
"import": "./dist/index.mjs",
|
|
@@ -19,21 +24,15 @@
|
|
|
19
24
|
"files": [
|
|
20
25
|
"dist"
|
|
21
26
|
],
|
|
22
|
-
"peerDependencies": {
|
|
23
|
-
"lexical": "^0.41.0",
|
|
24
|
-
"lucide-react": "^0.574.0",
|
|
25
|
-
"react": ">=19",
|
|
26
|
-
"react-dom": ">=19"
|
|
27
|
-
},
|
|
28
27
|
"dependencies": {
|
|
29
28
|
"@dnd-kit/core": "^6.3.1",
|
|
30
29
|
"@dnd-kit/sortable": "^10.0.0",
|
|
31
30
|
"@dnd-kit/utilities": "^3.2.2",
|
|
32
31
|
"react-intersection-observer": "^10.0.3",
|
|
33
32
|
"react-photo-view": "^1.2.7",
|
|
34
|
-
"@haklex/rich-editor": "0.0.
|
|
35
|
-
"@haklex/rich-editor-ui": "0.0.
|
|
36
|
-
"@haklex/rich-style-token": "0.0.
|
|
33
|
+
"@haklex/rich-editor": "0.0.67",
|
|
34
|
+
"@haklex/rich-editor-ui": "0.0.67",
|
|
35
|
+
"@haklex/rich-style-token": "0.0.67"
|
|
37
36
|
},
|
|
38
37
|
"devDependencies": {
|
|
39
38
|
"@types/react": "^19.2.14",
|
|
@@ -48,6 +47,12 @@
|
|
|
48
47
|
"vite": "^7.3.1",
|
|
49
48
|
"vite-plugin-dts": "^4.5.4"
|
|
50
49
|
},
|
|
50
|
+
"peerDependencies": {
|
|
51
|
+
"lexical": "^0.41.0",
|
|
52
|
+
"lucide-react": "^0.574.0",
|
|
53
|
+
"react": ">=19",
|
|
54
|
+
"react-dom": ">=19"
|
|
55
|
+
},
|
|
51
56
|
"publishConfig": {
|
|
52
57
|
"access": "public"
|
|
53
58
|
},
|