@haklex/rich-ext-gallery 0.0.64 → 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 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 @haklex/rich-editor
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
- export { GalleryNode } from './GalleryNode'
16
- export { $createGalleryNode, $isGalleryNode } from './GalleryNode'
17
- export type { GalleryNodePayload, SerializedGalleryNode } from './GalleryNode'
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
- export const galleryNodes: Array<Klass<LexicalNode>>
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 { GalleryRenderer, galleryNodes } from '@haklex/rich-ext-gallery'
31
- import { RichRenderer } from '@haklex/rich-editor/renderer'
32
- import type { RendererConfig } from '@haklex/rich-editor'
45
+ import { GalleryEditRenderer } from '@haklex/rich-ext-gallery'
46
+ import { GalleryRenderer } from '@haklex/rich-ext-gallery/static'
47
+ ```
33
48
 
34
- const config: RendererConfig = {
35
- Gallery: GalleryRenderer,
36
- }
49
+ ### Import styles
37
50
 
38
- <RichRenderer
39
- value={content}
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,EACV,iBAAiB,EAGlB,MAAM,qBAAqB,CAAA;AAE5B,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAGhF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAA;AAGzC,OAAO,EACL,WAAW,EACX,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAC3B,MAAM,eAAe,CAAA;AAGtB,qBAAa,eAAgB,SAAQ,WAAW;IAC9C,MAAM,CAAC,YAAY,EAAE,iBAAiB,EAAE,CAevC;IAED,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,CACpC,OAAO,EAAE,kBAAkB,GAC1B,eAAe,CAEjB;AAED,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,GACnC,IAAI,IAAI,eAAe,CAEzB"}
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":"AAgBA,OAAO,KAAK,EAAgB,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAa7E,OAAO,KAAK,EAAiB,EAAE,EAAE,MAAM,OAAO,CAAA;AAmV9C,eAAO,MAAM,mBAAmB,EAAE,EAAE,CAAC,oBAAoB,CAqExD,CAAA"}
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
- style: { maxWidth: "100%", height: "auto" }
235
+ src: image.src,
236
+ style: { maxWidth: "100%", height: "auto" },
237
+ width: image.width
241
238
  }
242
239
  ) }) });
243
240
  }
@@ -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,qBAAqB,CAAA;AAE7E,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,WAAW,EACX,OAAO,EACP,qBAAqB,EACrB,MAAM,EACP,MAAM,SAAS,CAAA;AAChB,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AACvC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAA;AAIzC,MAAM,MAAM,qBAAqB,GAAG,MAAM,CACxC;IACE,MAAM,EAAE,YAAY,EAAE,CAAA;IACtB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,CAAA;CACzC,EACD,qBAAqB,CACtB,CAAA;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,YAAY,EAAE,CAAA;IACtB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,CAAA;CACzC;AAED,qBAAa,WAAY,SAAQ,aAAa,CAAC,YAAY,CAAC;IAC1D,QAAQ,EAAE,YAAY,EAAE,CAAA;IACxB,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,CAAA;IAEzC,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,CAC5B,IAAI,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,GACnC,IAAI,IAAI,WAAW,CAErB"}
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,CAAA;AAEnD,OAAO,EAGL,KAAK,oBAAoB,EAC1B,MAAM,qBAAqB,CAAA;AAE5B,OAAO,KAAK,EAAE,aAAa,EAAkB,MAAM,OAAO,CAAA;AAyC1D,eAAO,MAAM,eAAe,EAAE,aAAa,CAAC,oBAAoB,CA2L/D,CAAA;;AAuBD,wBAAoC"}
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-DUfg2dIP.js";
5
- import { $, B, C } from "./GalleryNode-DUfg2dIP.js";
6
- import { createRendererDecoration, useColorScheme } from "@haklex/rich-editor";
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
- attributes,
92
- listeners,
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, className: galleryImageCard, children: [
104
- /* @__PURE__ */ jsx(
105
- "div",
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", { src: image.src, alt: image.alt || "" }) : /* @__PURE__ */ jsx("span", { className: galleryImageThumbPlaceholder, children: /* @__PURE__ */ jsx(ImageIcon, { size: 20 }) }) }),
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
- SegmentedControl,
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
- SortableContext,
237
+ /* @__PURE__ */ jsx(SortableContext, { items: itemIds, strategy: verticalListSortingStrategy, children: entries.map((entry, index) => /* @__PURE__ */ jsx(
238
+ SortableImageCard,
277
239
  {
278
- items: itemIds,
279
- strategy: verticalListSortingStrategy,
280
- children: entries.map((entry, index) => /* @__PURE__ */ jsx(
281
- SortableImageCard,
282
- {
283
- id: entry.id,
284
- image: entry.image,
285
- index,
286
- isLast: index === entries.length - 1,
287
- lastInputRef: newInputRef,
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
- "button",
304
- {
305
- type: "button",
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
- "button",
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
- "button",
379
- {
380
- type: "button",
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
- "button",
395
- {
396
- type: "button",
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-DUfg2dIP.js";
2
- import { $, B, a, C } from "./GalleryNode-DUfg2dIP.js";
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.64",
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.64",
35
- "@haklex/rich-style-token": "0.0.64",
36
- "@haklex/rich-editor-ui": "0.0.64"
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"
package/LICENSE DELETED
@@ -1,28 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2024 Innei
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
22
-
23
-
24
- Additional Terms and Conditions
25
-
26
- ----------------
27
-
28
- Use of this software is governed by the terms of MIT and, in addition, by the terms and conditions described in the additional file (ADDITIONAL_TERMS.md). By using this software, you agree to abide by these additional terms and conditions.