@haklex/rich-ext-gallery 0.0.65 → 0.0.66
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 +9 -4
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,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@haklex/rich-ext-gallery",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.66",
|
|
5
5
|
"description": "Image gallery extension with drag-and-drop",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"exports": {
|
|
@@ -31,9 +31,9 @@
|
|
|
31
31
|
"@dnd-kit/utilities": "^3.2.2",
|
|
32
32
|
"react-intersection-observer": "^10.0.3",
|
|
33
33
|
"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.
|
|
34
|
+
"@haklex/rich-editor": "0.0.66",
|
|
35
|
+
"@haklex/rich-editor-ui": "0.0.66",
|
|
36
|
+
"@haklex/rich-style-token": "0.0.66"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@types/react": "^19.2.14",
|
|
@@ -51,6 +51,11 @@
|
|
|
51
51
|
"publishConfig": {
|
|
52
52
|
"access": "public"
|
|
53
53
|
},
|
|
54
|
+
"repository": {
|
|
55
|
+
"type": "git",
|
|
56
|
+
"url": "https://github.com/Innei/haklex.git",
|
|
57
|
+
"directory": "packages/rich-ext-gallery"
|
|
58
|
+
},
|
|
54
59
|
"scripts": {
|
|
55
60
|
"build": "vite build",
|
|
56
61
|
"dev:build": "vite build --watch"
|