@haklex/rich-renderer-image 0.35.0 → 0.37.0
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/ImageEditContext.d.ts.map +1 -1
- package/dist/ImageEditRenderer.d.ts.map +1 -1
- package/dist/ImageLayoutControls.d.ts +1 -1
- package/dist/ImageLayoutControls.d.ts.map +1 -1
- package/dist/{ImageRenderer-BUWdit_Y.js → ImageRenderer-B3TgOJEU.js} +31 -12
- package/dist/ImageRenderer.d.ts +1 -1
- package/dist/ImageRenderer.d.ts.map +1 -1
- package/dist/ImageSizeControl.d.ts +2 -0
- package/dist/ImageSizeControl.d.ts.map +1 -0
- package/dist/atoms.d.ts +6 -0
- package/dist/atoms.d.ts.map +1 -1
- package/dist/image-metrics.d.ts +5 -0
- package/dist/image-metrics.d.ts.map +1 -0
- package/dist/index.mjs +311 -85
- package/dist/rich-renderer-image.css +1 -1
- package/dist/static.mjs +1 -1
- package/dist/styles.css.d.ts +6 -1
- package/dist/styles.css.d.ts.map +1 -1
- package/dist/useImageActions.d.ts +2 -2
- package/dist/useImageActions.d.ts.map +1 -1
- package/dist/useImageResize.d.ts.map +1 -1
- package/package.json +5 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ImageEditContext.d.ts","sourceRoot":"","sources":["../src/ImageEditContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAExE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"ImageEditContext.d.ts","sourceRoot":"","sources":["../src/ImageEditContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAExE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAwBvC,wBAAgB,iBAAiB,CAAC,EAChC,KAAK,EACL,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,kBAAkB,CAAC;IAC1B,QAAQ,EAAE,SAAS,CAAC;CACrB,+BAkEA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ImageEditRenderer.d.ts","sourceRoot":"","sources":["../src/ImageEditRenderer.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ImageEditRenderer.d.ts","sourceRoot":"","sources":["../src/ImageEditRenderer.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAuCxE,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,kBAAkB,+BAQ1D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ImageLayoutControls.d.ts","sourceRoot":"","sources":["../src/ImageLayoutControls.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ImageLayoutControls.d.ts","sourceRoot":"","sources":["../src/ImageLayoutControls.tsx"],"names":[],"mappings":"AAgBA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAiBtD,wBAAgB,kBAAkB,gCAmCjC"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { imageDisplayCssVars, imageDisplayDataAttr, resolveImageDisplaySize } from "@haklex/rich-editor/nodes";
|
|
1
2
|
import { vars } from "@haklex/rich-editor/static";
|
|
2
3
|
import { useMemo, useRef, useState } from "react";
|
|
3
4
|
import { decodeThumbHash } from "@haklex/rich-editor/renderers";
|
|
@@ -61,12 +62,17 @@ var resizeHandleLeft = "_1n94osf10";
|
|
|
61
62
|
var resizeHandleRight = "_1n94osf11";
|
|
62
63
|
var resizeHandleVisible = "_1n94osf12";
|
|
63
64
|
var controlPanel = "_1n94osf13";
|
|
64
|
-
var
|
|
65
|
-
var
|
|
66
|
-
var
|
|
67
|
-
var
|
|
68
|
-
var
|
|
69
|
-
var
|
|
65
|
+
var sizePanel = "_1n94osf14";
|
|
66
|
+
var sizePanelRow = "_1n94osf15";
|
|
67
|
+
var sizeReadout = "_1n94osf16";
|
|
68
|
+
var sizeSliderWrap = "_1n94osf17";
|
|
69
|
+
var sizeSlider = "_1n94osf18";
|
|
70
|
+
var sizeSliderTick = "_1n94osf19";
|
|
71
|
+
var sizeValueField = "_1n94osf1a";
|
|
72
|
+
var sizePxInput = "_1n94osf1b";
|
|
73
|
+
var sizeEquiv = "_1n94osf1c";
|
|
74
|
+
var sizeOption = "_1n94osf1d";
|
|
75
|
+
var editToolbarButtonActive = "_1n94osf1e";
|
|
70
76
|
//#endregion
|
|
71
77
|
//#region src/ImageRenderer.tsx
|
|
72
78
|
var frameStateSemanticClass = {
|
|
@@ -79,19 +85,26 @@ function getCaptionText(altText, caption) {
|
|
|
79
85
|
if (!altText) return void 0;
|
|
80
86
|
if (altText.startsWith("!") || altText.startsWith("¡")) return altText.slice(1);
|
|
81
87
|
}
|
|
82
|
-
function ImageRenderer({ src, altText, width, height, caption: caption$1, thumbhash, accent, displayWidth, layout, onActivate, ref }) {
|
|
88
|
+
function ImageRenderer({ src, altText, width, height, caption: caption$1, thumbhash, accent, displayWidth, fixedWidth, fixedHeight, layout, onActivate, ref }) {
|
|
83
89
|
const [state, setState] = useState("loading");
|
|
84
90
|
const imgRef = useRef(null);
|
|
85
91
|
const captionText = useMemo(() => getCaptionText(altText, caption$1), [altText, caption$1]);
|
|
86
92
|
const placeholderUrl = useMemo(() => thumbhash ? decodeThumbHash(thumbhash) : void 0, [thumbhash]);
|
|
87
93
|
if (!src) return null;
|
|
88
94
|
const interactive = Boolean(onActivate);
|
|
95
|
+
const displaySize = resolveImageDisplaySize({
|
|
96
|
+
displayWidth,
|
|
97
|
+
fixedWidth,
|
|
98
|
+
fixedHeight
|
|
99
|
+
});
|
|
100
|
+
const fillsFigure = displaySize.mode === "percent" || displaySize.mode === "fixed-width";
|
|
89
101
|
const frameStyle = {
|
|
90
102
|
backgroundColor: state !== "loaded" && !placeholderUrl ? accent || vars.color.bgTertiary : "transparent",
|
|
91
103
|
backgroundImage: placeholderUrl && state !== "loaded" ? `url(${placeholderUrl})` : void 0,
|
|
92
104
|
backgroundSize: "cover",
|
|
93
|
-
width:
|
|
105
|
+
width: fillsFigure ? "100%" : width ? Math.min(width, 1200) : void 0,
|
|
94
106
|
maxWidth: "100%",
|
|
107
|
+
maxHeight: displaySize.mode === "fixed-height" ? `${displaySize.px}px` : void 0,
|
|
95
108
|
...width && height ? { aspectRatio: `${width} / ${height}` } : {}
|
|
96
109
|
};
|
|
97
110
|
const activate = () => {
|
|
@@ -102,9 +115,10 @@ function ImageRenderer({ src, altText, width, height, caption: caption$1, thumbh
|
|
|
102
115
|
e.preventDefault();
|
|
103
116
|
activate();
|
|
104
117
|
};
|
|
105
|
-
const figureStyle =
|
|
118
|
+
const figureStyle = imageDisplayCssVars(displaySize);
|
|
106
119
|
return /* @__PURE__ */ jsxs("figure", {
|
|
107
120
|
className: `${root} ${semanticClassNames.root}`,
|
|
121
|
+
"data-display": imageDisplayDataAttr(displaySize),
|
|
108
122
|
"data-layout": layout,
|
|
109
123
|
ref,
|
|
110
124
|
style: figureStyle,
|
|
@@ -125,11 +139,16 @@ function ImageRenderer({ src, altText, width, height, caption: caption$1, thumbh
|
|
|
125
139
|
loading: "lazy",
|
|
126
140
|
ref: imgRef,
|
|
127
141
|
src,
|
|
128
|
-
|
|
142
|
+
width,
|
|
143
|
+
style: displaySize.mode === "fixed-height" ? {
|
|
144
|
+
width: "auto",
|
|
145
|
+
height: "auto",
|
|
146
|
+
maxWidth: "100%",
|
|
147
|
+
maxHeight: "100%"
|
|
148
|
+
} : width && height ? {
|
|
129
149
|
height: "100%",
|
|
130
150
|
objectFit: "cover"
|
|
131
151
|
} : void 0,
|
|
132
|
-
width,
|
|
133
152
|
onError: () => setState("error"),
|
|
134
153
|
onLoad: () => setState("loaded")
|
|
135
154
|
}),
|
|
@@ -146,4 +165,4 @@ function ImageRenderer({ src, altText, width, height, caption: caption$1, thumbh
|
|
|
146
165
|
});
|
|
147
166
|
}
|
|
148
167
|
//#endregion
|
|
149
|
-
export { root as A, panelHint as C, resizeHandleLeft as D, resizeHandle as E,
|
|
168
|
+
export { root as A, sizeSliderWrap as B, panelHint as C, resizeHandleLeft as D, resizeHandle as E, sizePanelRow as F, sizePxInput as I, sizeReadout as L, sizeEquiv as M, sizeOption as N, resizeHandleRight as O, sizePanel as P, sizeSlider as R, loader as S, replaceUploadArea as T, sizeValueField as V, frameEditMode as _, editFieldIcon as a, imageState as b, editPlaceholder as c, editToolbarButtonActive as d, editToolbarButtonDanger as f, frame as g, errorBadge as h, editField as i, semanticClassNames as j, resizeHandleVisible as k, editToolbar as l, editTrigger as m, caption as n, editInput as o, editToolbarVisible as p, controlPanel as r, editPanel as s, ImageRenderer as t, editToolbarButton as u, image as v, replacePreview as w, imageVisible as x, imageDragging as y, sizeSliderTick as z };
|
package/dist/ImageRenderer.d.ts
CHANGED
|
@@ -4,5 +4,5 @@ export interface ImageRendererInteractiveProps extends ImageRendererProps {
|
|
|
4
4
|
onActivate?: (target: HTMLElement) => void;
|
|
5
5
|
ref?: Ref<HTMLElement>;
|
|
6
6
|
}
|
|
7
|
-
export declare function ImageRenderer({ src, altText, width, height, caption, thumbhash, accent, displayWidth, layout, onActivate, ref, }: ImageRendererInteractiveProps): import("react").JSX.Element | null;
|
|
7
|
+
export declare function ImageRenderer({ src, altText, width, height, caption, thumbhash, accent, displayWidth, fixedWidth, fixedHeight, layout, onActivate, ref, }: ImageRendererInteractiveProps): import("react").JSX.Element | null;
|
|
8
8
|
//# sourceMappingURL=ImageRenderer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ImageRenderer.d.ts","sourceRoot":"","sources":["../src/ImageRenderer.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ImageRenderer.d.ts","sourceRoot":"","sources":["../src/ImageRenderer.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAmB,KAAK,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAEzF,OAAO,KAAK,EAAgC,GAAG,EAAE,MAAM,OAAO,CAAC;AAsB/D,MAAM,WAAW,6BAA8B,SAAQ,kBAAkB;IACvE,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,CAAC;IAC3C,GAAG,CAAC,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC;CACxB;AAED,wBAAgB,aAAa,CAAC,EAC5B,GAAG,EACH,OAAO,EACP,KAAK,EACL,MAAM,EACN,OAAO,EACP,SAAS,EACT,MAAM,EACN,YAAY,EACZ,UAAU,EACV,WAAW,EACX,MAAM,EACN,UAAU,EACV,GAAG,GACJ,EAAE,6BAA6B,sCA+F/B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ImageSizeControl.d.ts","sourceRoot":"","sources":["../src/ImageSizeControl.tsx"],"names":[],"mappings":"AAwDA,wBAAgB,gBAAgB,gCA8M/B"}
|
package/dist/atoms.d.ts
CHANGED
|
@@ -26,6 +26,12 @@ export declare const accentAtom: import('jotai').PrimitiveAtom<string | undefine
|
|
|
26
26
|
export declare const displayWidthAtom: import('jotai').PrimitiveAtom<number | undefined> & {
|
|
27
27
|
init: number | undefined;
|
|
28
28
|
};
|
|
29
|
+
export declare const fixedWidthAtom: import('jotai').PrimitiveAtom<number | undefined> & {
|
|
30
|
+
init: number | undefined;
|
|
31
|
+
};
|
|
32
|
+
export declare const fixedHeightAtom: import('jotai').PrimitiveAtom<number | undefined> & {
|
|
33
|
+
init: number | undefined;
|
|
34
|
+
};
|
|
29
35
|
export declare const layoutAtom: import('jotai').PrimitiveAtom<ImageLayout | undefined> & {
|
|
30
36
|
init: ImageLayout | undefined;
|
|
31
37
|
};
|
package/dist/atoms.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"atoms.d.ts","sourceRoot":"","sources":["../src/atoms.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAG7D,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEtD,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;AAC5D,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,KAAK,CAAC;AAY3C,eAAO,MAAM,OAAO;;CAAW,CAAC;AAChC,eAAO,MAAM,WAAW;;CAAW,CAAC;AACpC,eAAO,MAAM,SAAS;;CAA6B,CAAC;AACpD,eAAO,MAAM,UAAU;;CAA6B,CAAC;AACrD,eAAO,MAAM,WAAW;;CAA6B,CAAC;AACtD,eAAO,MAAM,aAAa;;CAA6B,CAAC;AACxD,eAAO,MAAM,UAAU;;CAA6B,CAAC;AACrD,eAAO,MAAM,gBAAgB;;CAA6B,CAAC;AAC3D,eAAO,MAAM,UAAU;;CAAkC,CAAC;AAG1D,eAAO,MAAM,aAAa;;CAAkC,CAAC;AAC7D,eAAO,MAAM,YAAY;;CAAc,CAAC;AACxC,eAAO,MAAM,YAAY;;CAAc,CAAC;AACxC,eAAO,MAAM,eAAe;;CAAc,CAAC;AAC3C,eAAO,MAAM,YAAY;;CAAc,CAAC;AACxC,eAAO,MAAM,cAAc;;CAAc,CAAC;AAC1C,eAAO,MAAM,YAAY;;CAAc,CAAC;AACxC,eAAO,MAAM,kBAAkB,+BAQ9B,CAAC;AAEF,eAAO,MAAM,sBAAsB;;CAAc,CAAC;AAGlD,eAAO,MAAM,WAAW;;CAAW,CAAC;AACpC,eAAO,MAAM,eAAe;;CAAW,CAAC;AACxC,eAAO,MAAM,eAAe;;CAAW,CAAC;AAGxC,eAAO,MAAM,eAAe;;CAA8B,CAAC;AAC3D,eAAO,MAAM,cAAc;;CAAW,CAAC;AACvC,eAAO,MAAM,kBAAkB;;CAA4B,CAAC;AAC5D,eAAO,MAAM,eAAe;WACnB,MAAM;YACL,MAAM;;;eADP,MAAM;gBACL,MAAM;;CACD,CAAC;AAChB,eAAO,MAAM,kBAAkB;;CAAc,CAAC;AAC9C,eAAO,MAAM,gBAAgB;;CAA4B,CAAC;AAG1D,eAAO,MAAM,cAAc;;CAEzB,CAAC;AACH,eAAO,MAAM,gBAAgB;;CAE3B,CAAC;AAGH,eAAO,MAAM,kBAAkB,0CAG7B,CAAC;AAEH,eAAO,MAAM,eAAe,0CAAoE,CAAC;AAEjG,eAAO,MAAM,cAAc,
|
|
1
|
+
{"version":3,"file":"atoms.d.ts","sourceRoot":"","sources":["../src/atoms.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAG7D,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEtD,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;AAC5D,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,KAAK,CAAC;AAY3C,eAAO,MAAM,OAAO;;CAAW,CAAC;AAChC,eAAO,MAAM,WAAW;;CAAW,CAAC;AACpC,eAAO,MAAM,SAAS;;CAA6B,CAAC;AACpD,eAAO,MAAM,UAAU;;CAA6B,CAAC;AACrD,eAAO,MAAM,WAAW;;CAA6B,CAAC;AACtD,eAAO,MAAM,aAAa;;CAA6B,CAAC;AACxD,eAAO,MAAM,UAAU;;CAA6B,CAAC;AACrD,eAAO,MAAM,gBAAgB;;CAA6B,CAAC;AAC3D,eAAO,MAAM,cAAc;;CAA6B,CAAC;AACzD,eAAO,MAAM,eAAe;;CAA6B,CAAC;AAC1D,eAAO,MAAM,UAAU;;CAAkC,CAAC;AAG1D,eAAO,MAAM,aAAa;;CAAkC,CAAC;AAC7D,eAAO,MAAM,YAAY;;CAAc,CAAC;AACxC,eAAO,MAAM,YAAY;;CAAc,CAAC;AACxC,eAAO,MAAM,eAAe;;CAAc,CAAC;AAC3C,eAAO,MAAM,YAAY;;CAAc,CAAC;AACxC,eAAO,MAAM,cAAc;;CAAc,CAAC;AAC1C,eAAO,MAAM,YAAY;;CAAc,CAAC;AACxC,eAAO,MAAM,kBAAkB,+BAQ9B,CAAC;AAEF,eAAO,MAAM,sBAAsB;;CAAc,CAAC;AAGlD,eAAO,MAAM,WAAW;;CAAW,CAAC;AACpC,eAAO,MAAM,eAAe;;CAAW,CAAC;AACxC,eAAO,MAAM,eAAe;;CAAW,CAAC;AAGxC,eAAO,MAAM,eAAe;;CAA8B,CAAC;AAC3D,eAAO,MAAM,cAAc;;CAAW,CAAC;AACvC,eAAO,MAAM,kBAAkB;;CAA4B,CAAC;AAC5D,eAAO,MAAM,eAAe;WACnB,MAAM;YACL,MAAM;;;eADP,MAAM;gBACL,MAAM;;CACD,CAAC;AAChB,eAAO,MAAM,kBAAkB;;CAAc,CAAC;AAC9C,eAAO,MAAM,gBAAgB;;CAA4B,CAAC;AAG1D,eAAO,MAAM,cAAc;;CAEzB,CAAC;AACH,eAAO,MAAM,gBAAgB;;CAE3B,CAAC;AAGH,eAAO,MAAM,kBAAkB,0CAG7B,CAAC;AAEH,eAAO,MAAM,eAAe,0CAAoE,CAAC;AAEjG,eAAO,MAAM,cAAc,qCAqBzB,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { ImageDisplayConvertContext, ImageDisplaySize } from '@haklex/rich-editor/nodes';
|
|
2
|
+
export declare function measureImageContainerWidth(trigger: HTMLElement): number | undefined;
|
|
3
|
+
export declare function readImageDisplayContext(trigger: HTMLElement | null, intrinsicWidth?: number, intrinsicHeight?: number): ImageDisplayConvertContext | undefined;
|
|
4
|
+
export declare function applyImageSizePreview(trigger: HTMLElement, layout: string | undefined, next: ImageDisplaySize): void;
|
|
5
|
+
//# sourceMappingURL=image-metrics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image-metrics.d.ts","sourceRoot":"","sources":["../src/image-metrics.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,0BAA0B,EAE/B,KAAK,gBAAgB,EACtB,MAAM,2BAA2B,CAAC;AAInC,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,CAUnF;AAED,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,WAAW,GAAG,IAAI,EAC3B,cAAc,CAAC,EAAE,MAAM,EACvB,eAAe,CAAC,EAAE,MAAM,GACvB,0BAA0B,GAAG,SAAS,CAaxC;AAED,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,IAAI,EAAE,gBAAgB,QA+BvB"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { A as root, D as resizeHandleLeft, E as resizeHandle, F as
|
|
1
|
+
import { A as root, B as sizeSliderWrap, D as resizeHandleLeft, E as resizeHandle, F as sizePanelRow, I as sizePxInput, L as sizeReadout, M as sizeEquiv, N as sizeOption, O as resizeHandleRight, P as sizePanel, R as sizeSlider, T as replaceUploadArea, V as sizeValueField, _ as frameEditMode, a as editFieldIcon, b as imageState, c as editPlaceholder, d as editToolbarButtonActive, f as editToolbarButtonDanger, g as frame, i as editField, j as semanticClassNames, k as resizeHandleVisible, l as editToolbar, m as editTrigger, o as editInput, p as editToolbarVisible, r as controlPanel, s as editPanel, t as ImageRenderer, u as editToolbarButton, v as image, x as imageVisible, y as imageDragging, z as sizeSliderTick } from "./ImageRenderer-B3TgOJEU.js";
|
|
2
|
+
import { $createImageNode, $isImageNode, computeImageDisplayPixels, convertImageDisplaySize, imageDisplayCssVars, imageDisplayDataAttr, imageDisplaySizeAfterResize, resolveImageDisplaySize, sanitizeImageDisplayWidth, sanitizeImageFixedPx } from "@haklex/rich-editor/nodes";
|
|
2
3
|
import { useRendererMode } from "@haklex/rich-editor/static";
|
|
3
4
|
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
|
|
4
5
|
import { Provider, atom, createStore, useAtom, useAtomValue, useSetAtom, useStore } from "jotai";
|
|
@@ -8,7 +9,6 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
|
8
9
|
import { ActionBar, ActionButton, Popover, PopoverPanel, PopoverTrigger, SegmentedControl } from "@haklex/rich-editor-ui";
|
|
9
10
|
import { $getNearestNodeFromDOMNode, $getNodeByKey, COMMAND_PRIORITY_HIGH, DRAGOVER_COMMAND, DRAGSTART_COMMAND, DROP_COMMAND, REDO_COMMAND, UNDO_COMMAND } from "lexical";
|
|
10
11
|
import { AlignCenterVertical, AlignEndVertical, AlignStartVertical, ArrowLeftToLine, ArrowRightToLine, Captions, CopyPlus, Download, ExternalLink, ImageIcon, Loader2, Replace, Scaling, Trash2, Type, Upload } from "lucide-react";
|
|
11
|
-
import { $createImageNode, $isImageNode, sanitizeImageDisplayWidth } from "@haklex/rich-editor/nodes";
|
|
12
12
|
import { useImageUpload } from "@haklex/rich-editor/plugins";
|
|
13
13
|
//#region src/atoms.ts
|
|
14
14
|
function getCaptionText(altText, caption) {
|
|
@@ -24,6 +24,8 @@ var captionAtom = atom();
|
|
|
24
24
|
var thumbhashAtom = atom();
|
|
25
25
|
var accentAtom = atom();
|
|
26
26
|
var displayWidthAtom = atom();
|
|
27
|
+
var fixedWidthAtom = atom();
|
|
28
|
+
var fixedHeightAtom = atom();
|
|
27
29
|
var layoutAtom = atom();
|
|
28
30
|
var loadStateAtom = atom("loading");
|
|
29
31
|
var hoveringAtom = atom(false);
|
|
@@ -57,12 +59,16 @@ var frameStyleAtom = atom((get) => {
|
|
|
57
59
|
const width = get(widthAtom);
|
|
58
60
|
const height = get(heightAtom);
|
|
59
61
|
const displayWidth = get(displayWidthAtom);
|
|
62
|
+
const fixedWidth = get(fixedWidthAtom);
|
|
63
|
+
const fixedHeight = get(fixedHeightAtom);
|
|
64
|
+
const fillsFigure = displayWidth !== void 0 || fixedWidth !== void 0;
|
|
60
65
|
return {
|
|
61
66
|
backgroundColor: loadState !== "loaded" && !placeholderUrl ? accent || "#f5f5f5" : "transparent",
|
|
62
67
|
backgroundImage: placeholderUrl && loadState !== "loaded" ? `url(${placeholderUrl})` : void 0,
|
|
63
68
|
backgroundSize: "cover",
|
|
64
|
-
width:
|
|
69
|
+
width: fillsFigure ? "100%" : width ? Math.min(width, 1200) : void 0,
|
|
65
70
|
maxWidth: "100%",
|
|
71
|
+
maxHeight: fixedHeight !== void 0 ? `${fixedHeight}px` : void 0,
|
|
66
72
|
...width && height ? { aspectRatio: `${width} / ${height}` } : {}
|
|
67
73
|
};
|
|
68
74
|
});
|
|
@@ -81,6 +87,8 @@ function ImageEditProvider({ props, children }) {
|
|
|
81
87
|
s.set(thumbhashAtom, props.thumbhash);
|
|
82
88
|
s.set(accentAtom, props.accent);
|
|
83
89
|
s.set(displayWidthAtom, props.displayWidth);
|
|
90
|
+
s.set(fixedWidthAtom, props.fixedWidth);
|
|
91
|
+
s.set(fixedHeightAtom, props.fixedHeight);
|
|
84
92
|
s.set(layoutAtom, props.layout);
|
|
85
93
|
s.set(editSrcAtom, props.src);
|
|
86
94
|
s.set(editAltTextAtom, props.altText);
|
|
@@ -100,6 +108,8 @@ function ImageEditProvider({ props, children }) {
|
|
|
100
108
|
store.set(thumbhashAtom, props.thumbhash);
|
|
101
109
|
store.set(accentAtom, props.accent);
|
|
102
110
|
store.set(displayWidthAtom, props.displayWidth);
|
|
111
|
+
store.set(fixedWidthAtom, props.fixedWidth);
|
|
112
|
+
store.set(fixedHeightAtom, props.fixedHeight);
|
|
103
113
|
store.set(layoutAtom, props.layout);
|
|
104
114
|
}, [
|
|
105
115
|
store,
|
|
@@ -111,6 +121,8 @@ function ImageEditProvider({ props, children }) {
|
|
|
111
121
|
props.thumbhash,
|
|
112
122
|
props.accent,
|
|
113
123
|
props.displayWidth,
|
|
124
|
+
props.fixedWidth,
|
|
125
|
+
props.fixedHeight,
|
|
114
126
|
props.layout
|
|
115
127
|
]);
|
|
116
128
|
useEffect(() => {
|
|
@@ -226,14 +238,16 @@ function useImageActions() {
|
|
|
226
238
|
thumbhash: node.getThumbhash(),
|
|
227
239
|
accent: node.getAccent(),
|
|
228
240
|
displayWidth: node.getDisplayWidth(),
|
|
241
|
+
fixedWidth: node.getFixedWidth(),
|
|
242
|
+
fixedHeight: node.getFixedHeight(),
|
|
229
243
|
layout: node.getLayout()
|
|
230
244
|
});
|
|
231
245
|
node.insertAfter(copy);
|
|
232
246
|
});
|
|
233
247
|
}, [withImageNode]);
|
|
234
|
-
const
|
|
248
|
+
const handleSetDisplaySize = useCallback((size) => {
|
|
235
249
|
withImageNode((node) => {
|
|
236
|
-
node.
|
|
250
|
+
node.applyDisplaySize(size);
|
|
237
251
|
});
|
|
238
252
|
}, [withImageNode]);
|
|
239
253
|
const handleSetLayout = useCallback((layout) => {
|
|
@@ -316,7 +330,7 @@ function useImageActions() {
|
|
|
316
330
|
handleDuplicate,
|
|
317
331
|
handleDownload,
|
|
318
332
|
handleDelete,
|
|
319
|
-
|
|
333
|
+
handleSetDisplaySize,
|
|
320
334
|
handleSetLayout
|
|
321
335
|
};
|
|
322
336
|
}
|
|
@@ -404,7 +418,56 @@ function getEditorHistoryShortcut(event, options = {}) {
|
|
|
404
418
|
return null;
|
|
405
419
|
}
|
|
406
420
|
//#endregion
|
|
407
|
-
//#region src/
|
|
421
|
+
//#region src/image-metrics.ts
|
|
422
|
+
function measureImageContainerWidth(trigger) {
|
|
423
|
+
const container = trigger.closest(".rich-image-wrapper")?.parentElement ?? trigger.parentElement;
|
|
424
|
+
if (!container) return void 0;
|
|
425
|
+
const style = getComputedStyle(container);
|
|
426
|
+
const width = container.clientWidth - Number.parseFloat(style.paddingLeft) - Number.parseFloat(style.paddingRight);
|
|
427
|
+
return width > 0 ? width : void 0;
|
|
428
|
+
}
|
|
429
|
+
function readImageDisplayContext(trigger, intrinsicWidth, intrinsicHeight) {
|
|
430
|
+
if (!trigger) return void 0;
|
|
431
|
+
const containerWidth = measureImageContainerWidth(trigger);
|
|
432
|
+
if (!containerWidth) return void 0;
|
|
433
|
+
const rect = trigger.querySelector(`.${semanticClassNames.frame}`)?.getBoundingClientRect();
|
|
434
|
+
return {
|
|
435
|
+
containerWidth,
|
|
436
|
+
intrinsicWidth,
|
|
437
|
+
intrinsicHeight,
|
|
438
|
+
renderedWidth: rect?.width,
|
|
439
|
+
renderedHeight: rect?.height
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
function applyImageSizePreview(trigger, layout, next) {
|
|
443
|
+
const figure = trigger.querySelector("figure");
|
|
444
|
+
const isFloat = layout === "float-left" || layout === "float-right";
|
|
445
|
+
const blockWrapper = trigger.closest(".rich-image-wrapper");
|
|
446
|
+
figure?.style.removeProperty("--rich-image-display-width");
|
|
447
|
+
figure?.style.removeProperty("--rich-image-display-height");
|
|
448
|
+
const vars = imageDisplayCssVars(next);
|
|
449
|
+
if (figure && vars) for (const [key, value] of Object.entries(vars)) figure.style.setProperty(key, value);
|
|
450
|
+
if (!isFloat || !blockWrapper) return;
|
|
451
|
+
if (next.mode === "percent") {
|
|
452
|
+
blockWrapper.style.width = `${next.value}%`;
|
|
453
|
+
blockWrapper.style.maxWidth = "";
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
if (next.mode === "fixed-width") {
|
|
457
|
+
blockWrapper.style.width = `${next.px}px`;
|
|
458
|
+
blockWrapper.style.maxWidth = "100%";
|
|
459
|
+
return;
|
|
460
|
+
}
|
|
461
|
+
if (next.mode === "fixed-height") {
|
|
462
|
+
blockWrapper.style.width = "auto";
|
|
463
|
+
blockWrapper.style.maxWidth = "100%";
|
|
464
|
+
return;
|
|
465
|
+
}
|
|
466
|
+
blockWrapper.style.width = "";
|
|
467
|
+
blockWrapper.style.maxWidth = "";
|
|
468
|
+
}
|
|
469
|
+
//#endregion
|
|
470
|
+
//#region src/ImageSizeControl.tsx
|
|
408
471
|
var SIZE_PRESETS = [
|
|
409
472
|
25,
|
|
410
473
|
50,
|
|
@@ -414,6 +477,23 @@ var SIZE_PRESETS = [
|
|
|
414
477
|
var SIZE_MIN = 10;
|
|
415
478
|
var SIZE_MAX = 100;
|
|
416
479
|
var SNAP_THRESHOLD = 3;
|
|
480
|
+
var MODE_BUTTONS = [
|
|
481
|
+
[
|
|
482
|
+
"percent",
|
|
483
|
+
"%",
|
|
484
|
+
"Percent of content width"
|
|
485
|
+
],
|
|
486
|
+
[
|
|
487
|
+
"fixed-width",
|
|
488
|
+
"W",
|
|
489
|
+
"Fixed width"
|
|
490
|
+
],
|
|
491
|
+
[
|
|
492
|
+
"fixed-height",
|
|
493
|
+
"H",
|
|
494
|
+
"Fixed height"
|
|
495
|
+
]
|
|
496
|
+
];
|
|
417
497
|
function snapToPreset(value) {
|
|
418
498
|
for (const preset of SIZE_PRESETS) if (Math.abs(value - preset) <= SNAP_THRESHOLD) return preset;
|
|
419
499
|
return value;
|
|
@@ -421,35 +501,8 @@ function snapToPreset(value) {
|
|
|
421
501
|
function tickLeft(preset) {
|
|
422
502
|
return `calc(6px + ${(preset - SIZE_MIN) / 90} * (100% - 12px))`;
|
|
423
503
|
}
|
|
424
|
-
var
|
|
425
|
-
|
|
426
|
-
value: void 0,
|
|
427
|
-
label: "Center",
|
|
428
|
-
Icon: AlignCenterVertical
|
|
429
|
-
},
|
|
430
|
-
{
|
|
431
|
-
value: "align-left",
|
|
432
|
-
label: "Align left",
|
|
433
|
-
Icon: AlignStartVertical
|
|
434
|
-
},
|
|
435
|
-
{
|
|
436
|
-
value: "align-right",
|
|
437
|
-
label: "Align right",
|
|
438
|
-
Icon: AlignEndVertical
|
|
439
|
-
},
|
|
440
|
-
{
|
|
441
|
-
value: "float-left",
|
|
442
|
-
label: "Wrap left",
|
|
443
|
-
Icon: ArrowLeftToLine
|
|
444
|
-
},
|
|
445
|
-
{
|
|
446
|
-
value: "float-right",
|
|
447
|
-
label: "Wrap right",
|
|
448
|
-
Icon: ArrowRightToLine
|
|
449
|
-
}
|
|
450
|
-
];
|
|
451
|
-
var toolbarButtonClass = `${editToolbarButton} ${semanticClassNames.editToolbarButton}`;
|
|
452
|
-
var stopMouseDown = (e) => {
|
|
504
|
+
var toolbarButtonClass$1 = `${editToolbarButton} ${semanticClassNames.editToolbarButton}`;
|
|
505
|
+
var stopMouseDown$1 = (e) => {
|
|
453
506
|
e.preventDefault();
|
|
454
507
|
e.stopPropagation();
|
|
455
508
|
};
|
|
@@ -457,56 +510,162 @@ function ImageSizeControl() {
|
|
|
457
510
|
const store = useStore();
|
|
458
511
|
const [sizeOpen, setSizeOpen] = useAtom(sizeOpenAtom);
|
|
459
512
|
const displayWidth = useAtomValue(displayWidthAtom);
|
|
460
|
-
const
|
|
513
|
+
const fixedWidth = useAtomValue(fixedWidthAtom);
|
|
514
|
+
const fixedHeight = useAtomValue(fixedHeightAtom);
|
|
515
|
+
const intrinsicWidth = useAtomValue(widthAtom);
|
|
516
|
+
const intrinsicHeight = useAtomValue(heightAtom);
|
|
517
|
+
const { handleSetDisplaySize } = useImageActions();
|
|
461
518
|
const [dragValue, setDragValue] = useState(null);
|
|
519
|
+
const [fixedDraft, setFixedDraft] = useState(null);
|
|
520
|
+
const size = resolveImageDisplaySize({
|
|
521
|
+
displayWidth,
|
|
522
|
+
fixedWidth,
|
|
523
|
+
fixedHeight
|
|
524
|
+
});
|
|
462
525
|
useEffect(() => {
|
|
463
526
|
setDragValue(null);
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
527
|
+
setFixedDraft(null);
|
|
528
|
+
}, [
|
|
529
|
+
displayWidth,
|
|
530
|
+
fixedWidth,
|
|
531
|
+
fixedHeight
|
|
532
|
+
]);
|
|
533
|
+
const ctx = readImageDisplayContext(store.get(wrapperRefAtom).current, intrinsicWidth, intrinsicHeight);
|
|
534
|
+
const committedPixels = ctx ? computeImageDisplayPixels(size, ctx) : {};
|
|
535
|
+
const committedPercent = size.mode === "percent" ? size.value : ctx && committedPixels.widthPx ? sanitizeImageDisplayWidth(committedPixels.widthPx / ctx.containerWidth * 100) : void 0;
|
|
536
|
+
const previewSize = dragValue === null ? size : size.mode === "fixed-width" || size.mode === "fixed-height" ? ctx ? convertImageDisplaySize({
|
|
537
|
+
mode: "percent",
|
|
538
|
+
value: dragValue
|
|
539
|
+
}, size.mode, ctx) : size : {
|
|
540
|
+
mode: "percent",
|
|
541
|
+
value: dragValue
|
|
542
|
+
};
|
|
543
|
+
const previewPixels = ctx ? computeImageDisplayPixels(previewSize, {
|
|
544
|
+
...ctx,
|
|
545
|
+
renderedWidth: dragValue !== null ? void 0 : ctx.renderedWidth,
|
|
546
|
+
renderedHeight: dragValue !== null ? void 0 : ctx.renderedHeight
|
|
547
|
+
}) : {};
|
|
548
|
+
const previewPercent = dragValue ?? (ctx && previewPixels.widthPx ? sanitizeImageDisplayWidth(previewPixels.widthPx / ctx.containerWidth * 100) : committedPercent);
|
|
549
|
+
const applyPreview = (next) => {
|
|
467
550
|
const trigger = store.get(wrapperRefAtom).current;
|
|
468
|
-
if (
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
551
|
+
if (trigger) applyImageSizePreview(trigger, store.get(layoutAtom), next);
|
|
552
|
+
};
|
|
553
|
+
const switchMode = (to) => {
|
|
554
|
+
if (to === size.mode) return;
|
|
555
|
+
if (to === "auto") {
|
|
556
|
+
handleSetDisplaySize({ mode: "auto" });
|
|
557
|
+
return;
|
|
558
|
+
}
|
|
559
|
+
if (!ctx) return;
|
|
560
|
+
handleSetDisplaySize(convertImageDisplaySize(size, to, ctx));
|
|
561
|
+
};
|
|
562
|
+
const commitSlider = () => {
|
|
563
|
+
if (dragValue === null) return;
|
|
564
|
+
if (size.mode === "fixed-width" || size.mode === "fixed-height") {
|
|
565
|
+
if (dragValue === committedPercent || !ctx) return;
|
|
566
|
+
handleSetDisplaySize(convertImageDisplaySize({
|
|
567
|
+
mode: "percent",
|
|
568
|
+
value: dragValue
|
|
569
|
+
}, size.mode, ctx));
|
|
570
|
+
return;
|
|
571
|
+
}
|
|
572
|
+
if (dragValue === (displayWidth ?? SIZE_MAX)) return;
|
|
573
|
+
handleSetDisplaySize({
|
|
574
|
+
mode: "percent",
|
|
575
|
+
value: dragValue
|
|
576
|
+
});
|
|
474
577
|
};
|
|
475
578
|
const handleSliderChange = (event) => {
|
|
476
579
|
const next = snapToPreset(Number(event.target.value));
|
|
477
580
|
setDragValue(next);
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
581
|
+
if (size.mode === "fixed-width" || size.mode === "fixed-height") {
|
|
582
|
+
if (!ctx) return;
|
|
583
|
+
applyPreview(convertImageDisplaySize({
|
|
584
|
+
mode: "percent",
|
|
585
|
+
value: next
|
|
586
|
+
}, size.mode, ctx));
|
|
587
|
+
return;
|
|
588
|
+
}
|
|
589
|
+
applyPreview({
|
|
590
|
+
mode: "percent",
|
|
591
|
+
value: next
|
|
592
|
+
});
|
|
483
593
|
};
|
|
594
|
+
const value = dragValue ?? committedPercent ?? SIZE_MAX;
|
|
484
595
|
const fill = `${(value - SIZE_MIN) / 90 * 100}%`;
|
|
596
|
+
const fixedPx = size.mode === "fixed-width" || size.mode === "fixed-height" ? size.px : void 0;
|
|
485
597
|
return /* @__PURE__ */ jsxs(Popover, {
|
|
486
598
|
open: sizeOpen,
|
|
487
599
|
onOpenChange: setSizeOpen,
|
|
488
600
|
children: [/* @__PURE__ */ jsx(PopoverTrigger, {
|
|
489
|
-
className: toolbarButtonClass,
|
|
601
|
+
className: toolbarButtonClass$1,
|
|
490
602
|
title: "Image size",
|
|
491
|
-
onMouseDown: stopMouseDown,
|
|
603
|
+
onMouseDown: stopMouseDown$1,
|
|
492
604
|
children: /* @__PURE__ */ jsx(Scaling, { size: 14 })
|
|
493
605
|
}), /* @__PURE__ */ jsxs(PopoverPanel, {
|
|
494
|
-
className:
|
|
606
|
+
className: sizePanel,
|
|
495
607
|
side: "bottom",
|
|
496
608
|
sideOffset: 8,
|
|
497
|
-
children: [
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
609
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
610
|
+
className: sizePanelRow,
|
|
611
|
+
children: [
|
|
612
|
+
/* @__PURE__ */ jsx("button", {
|
|
613
|
+
className: `${sizeOption} ${size.mode === "auto" ? editToolbarButtonActive : ""}`.trim(),
|
|
614
|
+
title: "Natural size",
|
|
615
|
+
type: "button",
|
|
616
|
+
onMouseDown: stopMouseDown$1,
|
|
617
|
+
onClick: () => {
|
|
618
|
+
handleSetDisplaySize({ mode: "auto" });
|
|
619
|
+
setSizeOpen(false);
|
|
620
|
+
},
|
|
621
|
+
children: "Auto"
|
|
622
|
+
}),
|
|
623
|
+
MODE_BUTTONS.map(([mode, label, title]) => /* @__PURE__ */ jsx("button", {
|
|
624
|
+
className: `${sizeOption} ${size.mode === mode ? editToolbarButtonActive : ""}`.trim(),
|
|
625
|
+
title,
|
|
626
|
+
type: "button",
|
|
627
|
+
onClick: () => switchMode(mode),
|
|
628
|
+
onMouseDown: stopMouseDown$1,
|
|
629
|
+
children: label
|
|
630
|
+
}, mode)),
|
|
631
|
+
/* @__PURE__ */ jsxs("span", {
|
|
632
|
+
className: sizeReadout,
|
|
633
|
+
children: [size.mode === "fixed-width" || size.mode === "fixed-height" ? /* @__PURE__ */ jsx("input", {
|
|
634
|
+
autoComplete: "off",
|
|
635
|
+
className: `${sizeValueField} ${sizePxInput}`,
|
|
636
|
+
inputMode: "numeric",
|
|
637
|
+
spellCheck: false,
|
|
638
|
+
"aria-label": size.mode === "fixed-width" ? "Image width in pixels" : "Image height in pixels",
|
|
639
|
+
value: fixedDraft ?? (previewSize.mode === "fixed-width" || previewSize.mode === "fixed-height" ? String(previewSize.px) : String(fixedPx ?? "")),
|
|
640
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
641
|
+
onBlur: () => {
|
|
642
|
+
const px = sanitizeImageFixedPx(Number(fixedDraft ?? fixedPx));
|
|
643
|
+
if (px && (size.mode === "fixed-width" || size.mode === "fixed-height")) handleSetDisplaySize({
|
|
644
|
+
mode: size.mode,
|
|
645
|
+
px
|
|
646
|
+
});
|
|
647
|
+
setFixedDraft(null);
|
|
648
|
+
},
|
|
649
|
+
onChange: (event) => {
|
|
650
|
+
setFixedDraft(event.target.value);
|
|
651
|
+
const px = sanitizeImageFixedPx(Number(event.target.value));
|
|
652
|
+
if (px && (size.mode === "fixed-width" || size.mode === "fixed-height")) applyPreview({
|
|
653
|
+
mode: size.mode,
|
|
654
|
+
px
|
|
655
|
+
});
|
|
656
|
+
}
|
|
657
|
+
}) : /* @__PURE__ */ jsx("span", {
|
|
658
|
+
className: sizeValueField,
|
|
659
|
+
children: previewSize.mode === "percent" ? `${previewSize.value}%` : "Auto"
|
|
660
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
661
|
+
className: sizeEquiv,
|
|
662
|
+
children: previewSize.mode === "percent" ? previewPixels.widthPx ? `${previewPixels.widthPx}px` : "\xA0" : previewSize.mode === "auto" ? "\xA0" : previewPercent ? `${previewPercent}%` : "\xA0"
|
|
663
|
+
})]
|
|
664
|
+
})
|
|
665
|
+
]
|
|
666
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
667
|
+
className: sizePanelRow,
|
|
668
|
+
children: /* @__PURE__ */ jsxs("span", {
|
|
510
669
|
className: sizeSliderWrap,
|
|
511
670
|
children: [/* @__PURE__ */ jsx("input", {
|
|
512
671
|
"aria-label": "Image width, percent of content width",
|
|
@@ -517,24 +676,54 @@ function ImageSizeControl() {
|
|
|
517
676
|
style: { "--fill": fill },
|
|
518
677
|
type: "range",
|
|
519
678
|
value,
|
|
520
|
-
onBlur:
|
|
679
|
+
onBlur: commitSlider,
|
|
521
680
|
onChange: handleSliderChange,
|
|
522
|
-
onKeyUp:
|
|
681
|
+
onKeyUp: commitSlider,
|
|
523
682
|
onMouseDown: (e) => e.stopPropagation(),
|
|
524
|
-
onPointerUp:
|
|
683
|
+
onPointerUp: commitSlider
|
|
525
684
|
}), SIZE_PRESETS.map((preset) => /* @__PURE__ */ jsx("span", {
|
|
526
685
|
className: sizeSliderTick,
|
|
527
686
|
style: { left: tickLeft(preset) }
|
|
528
687
|
}, preset))]
|
|
529
|
-
}),
|
|
530
|
-
/* @__PURE__ */ jsx("span", {
|
|
531
|
-
className: sizeValue,
|
|
532
|
-
children: displayWidth === void 0 && dragValue === null ? "Auto" : `${value}%`
|
|
533
688
|
})
|
|
534
|
-
]
|
|
689
|
+
})]
|
|
535
690
|
})]
|
|
536
691
|
});
|
|
537
692
|
}
|
|
693
|
+
//#endregion
|
|
694
|
+
//#region src/ImageLayoutControls.tsx
|
|
695
|
+
var LAYOUT_OPTIONS = [
|
|
696
|
+
{
|
|
697
|
+
value: void 0,
|
|
698
|
+
label: "Center",
|
|
699
|
+
Icon: AlignCenterVertical
|
|
700
|
+
},
|
|
701
|
+
{
|
|
702
|
+
value: "align-left",
|
|
703
|
+
label: "Align left",
|
|
704
|
+
Icon: AlignStartVertical
|
|
705
|
+
},
|
|
706
|
+
{
|
|
707
|
+
value: "align-right",
|
|
708
|
+
label: "Align right",
|
|
709
|
+
Icon: AlignEndVertical
|
|
710
|
+
},
|
|
711
|
+
{
|
|
712
|
+
value: "float-left",
|
|
713
|
+
label: "Wrap left",
|
|
714
|
+
Icon: ArrowLeftToLine
|
|
715
|
+
},
|
|
716
|
+
{
|
|
717
|
+
value: "float-right",
|
|
718
|
+
label: "Wrap right",
|
|
719
|
+
Icon: ArrowRightToLine
|
|
720
|
+
}
|
|
721
|
+
];
|
|
722
|
+
var toolbarButtonClass = `${editToolbarButton} ${semanticClassNames.editToolbarButton}`;
|
|
723
|
+
var stopMouseDown = (e) => {
|
|
724
|
+
e.preventDefault();
|
|
725
|
+
e.stopPropagation();
|
|
726
|
+
};
|
|
538
727
|
function ImageLayoutControl() {
|
|
539
728
|
const [layoutOpen, setLayoutOpen] = useAtom(layoutOpenAtom);
|
|
540
729
|
const layout = useAtomValue(layoutAtom);
|
|
@@ -826,10 +1015,8 @@ function useImageResize() {
|
|
|
826
1015
|
const frame = trigger.querySelector(`.${semanticClassNames.frame}`);
|
|
827
1016
|
const figure = trigger.querySelector("figure");
|
|
828
1017
|
const blockWrapper = trigger.closest(".rich-image-wrapper");
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
const containerStyle = getComputedStyle(container);
|
|
832
|
-
const containerWidth = container.clientWidth - Number.parseFloat(containerStyle.paddingLeft) - Number.parseFloat(containerStyle.paddingRight);
|
|
1018
|
+
if (!frame || !figure) return;
|
|
1019
|
+
const containerWidth = measureImageContainerWidth(trigger);
|
|
833
1020
|
const startWidth = frame.getBoundingClientRect().width;
|
|
834
1021
|
if (!containerWidth || containerWidth <= 0 || !startWidth) return;
|
|
835
1022
|
event.preventDefault();
|
|
@@ -845,17 +1032,42 @@ function useImageResize() {
|
|
|
845
1032
|
store.set(resizingAtom, true);
|
|
846
1033
|
const prevUserSelect = document.body.style.userSelect;
|
|
847
1034
|
document.body.style.userSelect = "none";
|
|
848
|
-
|
|
1035
|
+
const startHeight = frame.getBoundingClientRect().height;
|
|
1036
|
+
const aspect = startWidth > 0 && startHeight > 0 ? startHeight / startWidth : void 0;
|
|
1037
|
+
const currentMode = resolveImageDisplaySize({
|
|
1038
|
+
displayWidth: store.get(displayWidthAtom),
|
|
1039
|
+
fixedWidth: store.get(fixedWidthAtom),
|
|
1040
|
+
fixedHeight: store.get(fixedHeightAtom)
|
|
1041
|
+
}).mode;
|
|
1042
|
+
let nextSize = imageDisplaySizeAfterResize(currentMode, startWidth, startHeight, containerWidth);
|
|
849
1043
|
let moved = false;
|
|
1044
|
+
const applyPreview = (size) => {
|
|
1045
|
+
const vars = imageDisplayCssVars(size);
|
|
1046
|
+
figure.style.removeProperty("--rich-image-display-width");
|
|
1047
|
+
figure.style.removeProperty("--rich-image-display-height");
|
|
1048
|
+
if (vars) for (const [key, value] of Object.entries(vars)) figure.style.setProperty(key, value);
|
|
1049
|
+
if (isFloat && blockWrapper) {
|
|
1050
|
+
if (size.mode === "percent") {
|
|
1051
|
+
blockWrapper.style.width = `${size.value}%`;
|
|
1052
|
+
blockWrapper.style.maxWidth = "";
|
|
1053
|
+
} else if (size.mode === "fixed-width") {
|
|
1054
|
+
blockWrapper.style.width = `${size.px}px`;
|
|
1055
|
+
blockWrapper.style.maxWidth = "100%";
|
|
1056
|
+
} else if (size.mode === "fixed-height") {
|
|
1057
|
+
blockWrapper.style.width = "auto";
|
|
1058
|
+
blockWrapper.style.maxWidth = "100%";
|
|
1059
|
+
}
|
|
1060
|
+
}
|
|
1061
|
+
};
|
|
850
1062
|
const handleMove = (moveEvent) => {
|
|
851
1063
|
const rawDelta = moveEvent.clientX - startX;
|
|
852
1064
|
if (!moved && Math.abs(rawDelta) < MOVE_THRESHOLD_PX) return;
|
|
853
1065
|
moved = true;
|
|
854
1066
|
const outward = side === "left" ? -rawDelta : rawDelta;
|
|
855
1067
|
const nextWidth = startWidth + outward * factor;
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
1068
|
+
const nextHeight = aspect ? nextWidth * aspect : startHeight;
|
|
1069
|
+
nextSize = imageDisplaySizeAfterResize(currentMode, nextWidth, nextHeight, containerWidth);
|
|
1070
|
+
applyPreview(nextSize);
|
|
859
1071
|
};
|
|
860
1072
|
const finish = (commit) => {
|
|
861
1073
|
if (finishRef.current !== finish) return;
|
|
@@ -868,7 +1080,7 @@ function useImageResize() {
|
|
|
868
1080
|
if (!commit || !moved) return;
|
|
869
1081
|
editor.update(() => {
|
|
870
1082
|
const node = $getNearestNodeFromDOMNode(trigger);
|
|
871
|
-
if ($isImageNode(node)) node.
|
|
1083
|
+
if ($isImageNode(node)) node.applyDisplaySize(nextSize);
|
|
872
1084
|
}, { tag: "skip-scroll-into-view" });
|
|
873
1085
|
};
|
|
874
1086
|
const handleEnd = () => finish(true);
|
|
@@ -1105,7 +1317,14 @@ function ImageEditContent() {
|
|
|
1105
1317
|
const setReplaceOpen = useSetAtom(replaceOpenAtom);
|
|
1106
1318
|
const setFocusCaptionOnOpen = useSetAtom(focusCaptionOnOpenAtom);
|
|
1107
1319
|
const displayWidth = useAtomValue(displayWidthAtom);
|
|
1320
|
+
const fixedWidth = useAtomValue(fixedWidthAtom);
|
|
1321
|
+
const fixedHeight = useAtomValue(fixedHeightAtom);
|
|
1108
1322
|
const layout = useAtomValue(layoutAtom);
|
|
1323
|
+
const displaySize = resolveImageDisplaySize({
|
|
1324
|
+
displayWidth,
|
|
1325
|
+
fixedWidth,
|
|
1326
|
+
fixedHeight
|
|
1327
|
+
});
|
|
1109
1328
|
const dragLayoutProps = useImageDragLayout();
|
|
1110
1329
|
const handleCaptionClick = useCallback((e) => {
|
|
1111
1330
|
e.stopPropagation();
|
|
@@ -1121,7 +1340,7 @@ function ImageEditContent() {
|
|
|
1121
1340
|
setReplaceOpen,
|
|
1122
1341
|
setFocusCaptionOnOpen
|
|
1123
1342
|
]);
|
|
1124
|
-
const figureStyle =
|
|
1343
|
+
const figureStyle = imageDisplayCssVars(displaySize);
|
|
1125
1344
|
return /* @__PURE__ */ jsxs("div", {
|
|
1126
1345
|
className: `${editTrigger} ${semanticClassNames.editTrigger}`,
|
|
1127
1346
|
ref: wrapperRef,
|
|
@@ -1129,6 +1348,7 @@ function ImageEditContent() {
|
|
|
1129
1348
|
onMouseLeave: () => setHovering(false),
|
|
1130
1349
|
children: [src ? /* @__PURE__ */ jsxs("figure", {
|
|
1131
1350
|
className: `${root} ${semanticClassNames.root}`,
|
|
1351
|
+
"data-display": imageDisplayDataAttr(displaySize),
|
|
1132
1352
|
"data-layout": layout,
|
|
1133
1353
|
style: figureStyle,
|
|
1134
1354
|
...dragLayoutProps,
|
|
@@ -1143,6 +1363,12 @@ function ImageEditContent() {
|
|
|
1143
1363
|
loading: "lazy",
|
|
1144
1364
|
src,
|
|
1145
1365
|
width,
|
|
1366
|
+
style: displaySize.mode === "fixed-height" ? {
|
|
1367
|
+
width: "auto",
|
|
1368
|
+
height: "auto",
|
|
1369
|
+
maxWidth: "100%",
|
|
1370
|
+
maxHeight: "100%"
|
|
1371
|
+
} : void 0,
|
|
1146
1372
|
onError: () => setLoadState("error"),
|
|
1147
1373
|
onLoad: () => setLoadState("loaded")
|
|
1148
1374
|
}),
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
:root{--rc-text:#000;--rc-text-secondary:#262626;--rc-text-tertiary:#737373;--rc-text-quaternary:#a3a3a3;--rc-bg:#fff;--rc-bg-secondary:#fafafa;--rc-bg-tertiary:#f5f5f5;--rc-fill:#e8e8e8;--rc-fill-secondary:#eee;--rc-fill-tertiary:#f5f5f5;--rc-fill-quaternary:#fafafa;--rc-border:#f5f5f5;--rc-accent:#2563eb;--rc-accent-light:#2563eb20;--rc-link:#2563eb;--rc-code-text:#404040;--rc-code-bg:#f5f5f5;--rc-hr-border:#e5e5e5;--rc-quote-border:#2563eb;--rc-quote-bg:#f5f5f5;--rc-alert-info:#006bb7;--rc-alert-warning:#c50;--rc-alert-tip:#1c0;--rc-alert-caution:#c01;--rc-alert-important:#50c;--rc-max-width:700px;--rc-shadow-top-bar:0 8px 30px #0000001f, 0 2px 8px #0000000f;--rc-shadow-modal:0 10px 15px -3px #0000001a, 0 4px 6px -4px #0000001a;--rc-shadow-menu:0 1px 4px #0000000a, 0 4px 16px #00000014;--rc-space-xs:4px;--rc-space-sm:8px;--rc-space-md:16px;--rc-space-lg:24px;--rc-space-xl:32px;--rc-font-family-sans:"PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-font-family-serif:"Noto Serif CJK SC", "Source Han Serif SC", "Source Han Serif", "source-han-serif-sc", "Songti SC", STSong, "华文宋体", serif;--rc-font-family-kai:"楷体", KaiTi, STKaiti, "Kaiti SC", "LXGW WenKai", "霞鹜文楷", "Noto Serif CJK SC", serif;--rc-font-mono:"SF Mono", SFMono-Regular, ui-monospace, "DejaVu Sans Mono", Menlo, Consolas, monospace;--rc-font-size-2xs:.625em;--rc-font-size-xs:.75em;--rc-font-size-sm:.8125em;--rc-font-size-md:.875em;--rc-font-size-lg:1.25em;--rc-font-size-base:16px;--rc-font-size-small:14px;--rc-line-height:1.7;--rc-line-height-tight:1.4;--rc-font-family:"PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-radius-sm:4px;--rc-radius-md:8px;--rc-radius-lg:12px}:root.dark,[data-theme=dark]{--rc-text:#fafafa;--rc-text-secondary:#a3a3a3;--rc-text-tertiary:#737373;--rc-text-quaternary:#525252;--rc-bg:#0a0a0a;--rc-bg-secondary:#171717;--rc-bg-tertiary:#262626;--rc-fill:#2a2a2a;--rc-fill-secondary:#222;--rc-fill-tertiary:#1a1a1a;--rc-fill-quaternary:#141414;--rc-border:#262626;--rc-accent:#60a5fa;--rc-accent-light:#60a5fa20;--rc-link:#60a5fa;--rc-code-text:#d4d4d4;--rc-code-bg:#262626;--rc-hr-border:#262626;--rc-quote-border:#60a5fa;--rc-quote-bg:#262626;--rc-alert-info:#7db9e5;--rc-alert-warning:#da864a;--rc-alert-tip:#54da48;--rc-alert-caution:#e16973;--rc-alert-important:#9966e0;--rc-shadow-top-bar:0 8px 30px #00000073, 0 2px 8px #0000004d;--rc-shadow-modal:0 10px 15px -3px #0006, 0 4px 6px -4px #00000059;--rc-shadow-menu:0 1px 4px #00000040, 0 4px 16px #0006}._7eow1s0{--rc-text:#000;--rc-text-secondary:#262626;--rc-text-tertiary:#737373;--rc-text-quaternary:#a3a3a3;--rc-bg:#fff;--rc-bg-secondary:#fafafa;--rc-bg-tertiary:#f5f5f5;--rc-fill:#e8e8e8;--rc-fill-secondary:#eee;--rc-fill-tertiary:#f5f5f5;--rc-fill-quaternary:#fafafa;--rc-border:#f5f5f5;--rc-accent:#2563eb;--rc-accent-light:#2563eb20;--rc-link:#2563eb;--rc-code-text:#404040;--rc-code-bg:#f5f5f5;--rc-hr-border:#e5e5e5;--rc-quote-border:#2563eb;--rc-quote-bg:#f5f5f5;--rc-alert-info:#006bb7;--rc-alert-warning:#c50;--rc-alert-tip:#1c0;--rc-alert-caution:#c01;--rc-alert-important:#50c;--rc-max-width:700px;--rc-shadow-top-bar:0 8px 30px #0000001f, 0 2px 8px #0000000f;--rc-shadow-modal:0 10px 15px -3px #0000001a, 0 4px 6px -4px #0000001a;--rc-shadow-menu:0 1px 4px #0000000a, 0 4px 16px #00000014;--rc-space-xs:4px;--rc-space-sm:8px;--rc-space-md:16px;--rc-space-lg:24px;--rc-space-xl:32px;--rc-font-family-sans:"PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-font-family-serif:"Noto Serif CJK SC", "Source Han Serif SC", "Source Han Serif", "source-han-serif-sc", "Songti SC", STSong, "华文宋体", serif;--rc-font-family-kai:"楷体", KaiTi, STKaiti, "Kaiti SC", "LXGW WenKai", "霞鹜文楷", "Noto Serif CJK SC", serif;--rc-font-mono:"SF Mono", SFMono-Regular, ui-monospace, "DejaVu Sans Mono", Menlo, Consolas, monospace;--rc-font-size-2xs:.625em;--rc-font-size-xs:.75em;--rc-font-size-sm:.8125em;--rc-font-size-md:.875em;--rc-font-size-lg:1.25em;--rc-font-size-base:16px;--rc-font-size-small:14px;--rc-line-height:1.7;--rc-line-height-tight:1.4;--rc-font-family:"PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-radius-sm:4px;--rc-radius-md:8px;--rc-radius-lg:12px}._7eow1s1{--rc-text:#000;--rc-text-secondary:#262626;--rc-text-tertiary:#737373;--rc-text-quaternary:#a3a3a3;--rc-bg:#fff;--rc-bg-secondary:#fafafa;--rc-bg-tertiary:#f5f5f5;--rc-fill:#e8e8e8;--rc-fill-secondary:#eee;--rc-fill-tertiary:#f5f5f5;--rc-fill-quaternary:#fafafa;--rc-border:#f5f5f5;--rc-accent:#2563eb;--rc-accent-light:#2563eb20;--rc-link:#2563eb;--rc-code-text:#404040;--rc-code-bg:#f5f5f5;--rc-hr-border:#e5e5e5;--rc-quote-border:#2563eb;--rc-quote-bg:#f5f5f5;--rc-alert-info:#006bb7;--rc-alert-warning:#c50;--rc-alert-tip:#1c0;--rc-alert-caution:#c01;--rc-alert-important:#50c;--rc-max-width:700px;--rc-shadow-top-bar:0 8px 30px #0000001f, 0 2px 8px #0000000f;--rc-shadow-modal:0 10px 15px -3px #0000001a, 0 4px 6px -4px #0000001a;--rc-shadow-menu:0 1px 4px #0000000a, 0 4px 16px #00000014;--rc-space-xs:4px;--rc-space-sm:8px;--rc-space-md:16px;--rc-space-lg:24px;--rc-space-xl:32px;--rc-font-family-sans:"PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-font-family-serif:"Noto Serif CJK SC", "Source Han Serif SC", "Source Han Serif", "source-han-serif-sc", "Songti SC", STSong, "华文宋体", serif;--rc-font-family-kai:"楷体", KaiTi, STKaiti, "Kaiti SC", "LXGW WenKai", "霞鹜文楷", "Noto Serif CJK SC", serif;--rc-font-mono:"SF Mono", SFMono-Regular, ui-monospace, "DejaVu Sans Mono", Menlo, Consolas, monospace;--rc-font-size-2xs:.625em;--rc-font-size-xs:.75em;--rc-font-size-sm:.8125em;--rc-font-size-md:.875em;--rc-font-size-lg:1.25em;--rc-font-size-base:16px;--rc-font-size-small:14px;--rc-line-height:1.8;--rc-line-height-tight:1.4;--rc-font-family:"Noto Serif CJK SC", "Source Han Serif SC", "Source Han Serif", "source-han-serif-sc", "Songti SC", STSong, "华文宋体", serif;--rc-radius-sm:4px;--rc-radius-md:8px;--rc-radius-lg:12px}._7eow1s2{--rc-text:#000;--rc-text-secondary:#262626;--rc-text-tertiary:#737373;--rc-text-quaternary:#a3a3a3;--rc-bg:#fff;--rc-bg-secondary:#fafafa;--rc-bg-tertiary:#f5f5f5;--rc-fill:#e8e8e8;--rc-fill-secondary:#eee;--rc-fill-tertiary:#f5f5f5;--rc-fill-quaternary:#fafafa;--rc-border:#f5f5f5;--rc-accent:#2563eb;--rc-accent-light:#2563eb20;--rc-link:#2563eb;--rc-code-text:#404040;--rc-code-bg:#f5f5f5;--rc-hr-border:#e5e5e5;--rc-quote-border:#a3a3a3;--rc-quote-bg:#fafafa;--rc-alert-info:#006bb7;--rc-alert-warning:#c50;--rc-alert-tip:#1c0;--rc-alert-caution:#c01;--rc-alert-important:#50c;--rc-max-width:none;--rc-shadow-top-bar:0 8px 30px #0000001f, 0 2px 8px #0000000f;--rc-shadow-modal:0 10px 15px -3px #0000001a, 0 4px 6px -4px #0000001a;--rc-shadow-menu:0 1px 4px #0000000a, 0 4px 16px #00000014;--rc-space-xs:2px;--rc-space-sm:4px;--rc-space-md:10px;--rc-space-lg:16px;--rc-space-xl:20px;--rc-font-family-sans:"PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-font-family-serif:"Noto Serif CJK SC", "Source Han Serif SC", "Source Han Serif", "source-han-serif-sc", "Songti SC", STSong, "华文宋体", serif;--rc-font-family-kai:"楷体", KaiTi, STKaiti, "Kaiti SC", "LXGW WenKai", "霞鹜文楷", "Noto Serif CJK SC", serif;--rc-font-mono:"SF Mono", SFMono-Regular, ui-monospace, "DejaVu Sans Mono", Menlo, Consolas, monospace;--rc-font-size-2xs:.625em;--rc-font-size-xs:.75em;--rc-font-size-sm:.8125em;--rc-font-size-md:.875em;--rc-font-size-lg:1.25em;--rc-font-size-base:14px;--rc-font-size-small:12px;--rc-line-height:1.5;--rc-line-height-tight:1.3;--rc-font-family:"PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-radius-sm:3px;--rc-radius-md:6px;--rc-radius-lg:12px}.dark ._7eow1s0,[data-theme=dark] ._7eow1s0,.dark._7eow1s0,[data-theme=dark]._7eow1s0,.dark ._7eow1s1,[data-theme=dark] ._7eow1s1,.dark._7eow1s1,[data-theme=dark]._7eow1s1,.dark ._7eow1s2,[data-theme=dark] ._7eow1s2,.dark._7eow1s2,[data-theme=dark]._7eow1s2{--rc-text:#fafafa;--rc-text-secondary:#a3a3a3;--rc-text-tertiary:#737373;--rc-text-quaternary:#525252;--rc-bg:#0a0a0a;--rc-bg-secondary:#171717;--rc-bg-tertiary:#262626;--rc-fill:#2a2a2a;--rc-fill-secondary:#222;--rc-fill-tertiary:#1a1a1a;--rc-fill-quaternary:#141414;--rc-border:#262626;--rc-accent:#60a5fa;--rc-accent-light:#60a5fa20;--rc-link:#60a5fa;--rc-code-text:#d4d4d4;--rc-code-bg:#262626;--rc-hr-border:#262626;--rc-quote-border:#60a5fa;--rc-quote-bg:#262626;--rc-alert-info:#7db9e5;--rc-alert-warning:#da864a;--rc-alert-tip:#54da48;--rc-alert-caution:#e16973;--rc-alert-important:#9966e0;--rc-shadow-top-bar:0 8px 30px #00000073, 0 2px 8px #0000004d;--rc-shadow-modal:0 10px 15px -3px #0006, 0 4px 6px -4px #00000059;--rc-shadow-menu:0 1px 4px #00000040, 0 4px 16px #0006}@keyframes _1n94osf2{0%{opacity:.16;-webkit-mask:linear-gradient(90deg,#000 25%,#000000e6 50%,#0000) 150% 0/400% no-repeat;mask:linear-gradient(90deg,#000 25%,#000000e6 50%,#0000) 150% 0/400% no-repeat}to{opacity:1;-webkit-mask:linear-gradient(90deg,#000 25%,#000000e6 50%,#0000) 0/400% no-repeat;mask:linear-gradient(90deg,#000 25%,#000000e6 50%,#0000) 0/400% no-repeat}}@keyframes _1n94osfb{to{transform:rotate(360deg)}}@keyframes _1n94osfj{0%{opacity:0}to{opacity:1}}._1n94osf0{text-align:center;width:var(--rich-image-display-width,auto);max-width:100%;margin:1.25rem auto}._1n94osf0[data-layout=align-left]{text-align:left;margin-left:0;margin-right:auto}._1n94osf0[data-layout=align-right]{text-align:right;margin-left:auto;margin-right:0}._1n94osf0[data-layout=float-left]{float:left;width:var(--rich-image-display-width,42%);margin:.125rem 1.25rem .875rem 0}._1n94osf0[data-layout=float-right]{float:right;width:var(--rich-image-display-width,42%);margin:.125rem 0 .875rem 1.25rem}.rich-image-wrapper[data-layout^=float] ._1n94osf0{float:none;width:auto;margin:0}._1n94osf1{opacity:.4}.rich-editor__content[data-rich-image-drop-side]{cursor:move}.rich-editor__content[data-rich-image-drop-side=left]{box-shadow:inset 3px 0 0 color-mix(in srgb, var(--rc-accent) 70%, transparent)}.rich-editor__content[data-rich-image-drop-side=right]{box-shadow:inset -3px 0 0 color-mix(in srgb, var(--rc-accent) 70%, transparent)}._1n94osf3{opacity:0;width:100%;max-width:100%;height:auto;display:block;border-radius:0!important}._1n94osf7{opacity:1;animation:.42s _1n94osf2}._1n94osf8{border-radius:var(--rc-radius-md);cursor:zoom-in;justify-content:center;align-items:center;min-height:3rem;transition:transform .25s;display:inline-flex;position:relative;overflow:hidden}._1n94osf8:hover{transform:translateY(-1px)}._1n94osf9{cursor:default}._1n94osf9:hover{transform:none}._1n94osfa{cursor:default}._1n94osfa:hover{transform:none}._1n94osfc{border:2px solid color-mix(in srgb, var(--rc-text-secondary) 45%, transparent);border-top-color:color-mix(in srgb, var(--rc-text) 65%, transparent);border-radius:50%;width:1.65rem;height:1.65rem;animation:.75s linear infinite _1n94osfb;position:absolute}._1n94osfd{white-space:nowrap;font-size:var(--rc-font-size-sm);letter-spacing:-.005em;color:#fff;-webkit-backdrop-filter:blur(20px)saturate(180%);background:#ff3b30a6;border-radius:6px;padding:.3rem .7rem;font-weight:500;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}._1n94osfe{color:var(--rc-text-tertiary);font-size:var(--rc-font-size-md);margin-top:.5rem;line-height:1.5}._1n94osff{margin:var(--rc-space-md) 0;text-align:center}._1n94osfg{border-radius:var(--rc-radius-md);transition:background-color .3s;display:inline-block;position:relative;overflow:hidden}._1n94osfh{opacity:0;transition:opacity .3s}._1n94osfi{opacity:1;transition:opacity .3s}._1n94osfk{z-index:9999;cursor:zoom-out;background-color:#000000d9;justify-content:center;align-items:center;animation:.2s _1n94osfj;display:flex;position:fixed;top:0;bottom:0;left:0;right:0}._1n94osfl{object-fit:contain;border-radius:0;max-width:90vw;max-height:90vh}.rich-image{margin:var(--rc-space-md) 0;text-align:center}.rich-image figcaption{font-size:var(--rc-font-size-md);color:var(--rc-text-secondary);margin-top:var(--rc-space-sm);line-height:var(--rc-line-height-tight)}.rich-image-container{border-radius:var(--rc-radius-md);transition:background-color .3s;display:inline-block;position:relative;overflow:hidden}.rich-image-hidden{opacity:0;transition:opacity .3s}.rich-image-visible{opacity:1;transition:opacity .3s}.rich-image-zoom-overlay{z-index:9999;cursor:zoom-out;background-color:#000000d9;justify-content:center;align-items:center;animation:.2s _1n94osfj;display:flex;position:fixed;top:0;bottom:0;left:0;right:0}.rich-image-zoom-img{object-fit:contain;border-radius:0;max-width:90vw;max-height:90vh}._1n94osfm{cursor:default;display:block;position:relative}._1n94osfn{border:2px dashed var(--rc-border);border-radius:var(--rc-radius-md);color:var(--rc-text-secondary);font-size:var(--rc-font-size-md);cursor:pointer;flex-direction:column;justify-content:center;align-items:center;gap:8px;padding:2rem;transition:border-color .2s,color .2s,background-color .2s;display:flex}._1n94osfn:hover{border-color:var(--rc-accent);color:var(--rc-text);background-color:color-mix(in srgb, var(--rc-accent) 8%, transparent)}._1n94osfo{z-index:20;border:1px solid var(--rc-border);background:color-mix(in srgb, var(--rc-bg) 96%, transparent);box-shadow:var(--rc-shadow-top-bar);opacity:0;pointer-events:none;border-radius:10px;align-items:center;gap:4px;padding:4px;transition:opacity .15s;display:inline-flex;position:absolute;top:-2.5rem;left:50%;transform:translate(-50%)}._1n94osfp{opacity:1;pointer-events:auto}._1n94osfq{width:30px;height:30px;color:var(--rc-text-secondary);cursor:pointer;background:0 0;border:none;border-radius:8px;justify-content:center;align-items:center;transition:background-color .15s,color .15s;display:inline-flex}._1n94osfq:hover{color:var(--rc-text);background-color:var(--rc-fill-secondary)}._1n94osfr:hover{color:var(--rc-alert-caution);background-color:color-mix(in srgb, var(--rc-alert-caution) 12%, transparent)}._1n94osfs{width:360px;font-size:var(--rc-font-size-base);font-family:var(--rc-font-family);z-index:30;flex-direction:column;gap:8px;padding:12px;display:flex;position:relative}._1n94osft{background-color:var(--rc-bg-secondary);border-radius:6px;align-items:center;gap:8px;min-width:0;padding:6px 10px;display:flex}._1n94osfu{color:var(--rc-text-secondary);flex-shrink:0}._1n94osfv{-webkit-appearance:none;appearance:none;color:inherit;font-size:var(--rc-font-size-sm);background-color:#0000;border:none;outline:none;flex:1;min-width:0;padding:0}._1n94osfv::placeholder{color:var(--rc-text-secondary)}._1n94osfw{border-radius:var(--rc-radius-md);border:1.5px dashed var(--rc-border);min-height:138px;color:var(--rc-text-secondary);cursor:pointer;flex-direction:column;justify-content:center;align-items:center;gap:.45rem;transition:border-color .15s,background-color .15s;display:flex}._1n94osfw:hover{border-color:color-mix(in srgb, var(--rc-accent) 45%, transparent);color:var(--rc-text);background-color:color-mix(in srgb, var(--rc-accent) 7%, transparent)}._1n94osfx{border-radius:var(--rc-radius-md);border:1px solid var(--rc-border);background-color:color-mix(in srgb, var(--rc-text) 2%, transparent);overflow:hidden}._1n94osfx img{object-fit:cover;width:100%;max-height:188px;display:block}._1n94osfy{color:var(--rc-text-secondary);font-size:var(--rc-font-size-xs);align-items:center;gap:.4rem;display:inline-flex}._1n94osfz{cursor:ew-resize;touch-action:none;opacity:0;z-index:10;background:#ffffffeb;border:1px solid #0000002e;border-radius:9999px;width:6px;height:36px;max-height:50%;transition:opacity .15s;position:absolute;top:50%;transform:translateY(-50%);box-shadow:0 1px 3px #00000040}._1n94osf10{left:6px}._1n94osf11{right:6px}._1n94osf12{opacity:1}._1n94osf13{font-family:var(--rc-font-family);z-index:30;align-items:center;gap:4px;padding:4px;display:flex}._1n94osf13._1n94osf13{width:-moz-fit-content;width:fit-content}._1n94osf14{align-items:center;width:132px;height:24px;display:flex;position:relative}._1n94osf15{-webkit-appearance:none;appearance:none;cursor:pointer;background:0 0;width:100%;height:24px;margin:0}._1n94osf15::-webkit-slider-runnable-track{background:linear-gradient(to right, var(--rc-text-secondary) var(--fill), var(--rc-fill) var(--fill));border-radius:9999px;height:3px}._1n94osf15::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;background-color:var(--rc-bg);border:1px solid var(--rc-border);cursor:ew-resize;border-radius:50%;width:12px;height:12px;margin-top:-4.5px;box-shadow:0 1px 3px #0003}._1n94osf15::-moz-range-track{background:linear-gradient(to right, var(--rc-text-secondary) var(--fill), var(--rc-fill) var(--fill));border-radius:9999px;height:3px}._1n94osf15::-moz-range-thumb{-webkit-appearance:none;appearance:none;background-color:var(--rc-bg);border:1px solid var(--rc-border);cursor:ew-resize;border-radius:50%;width:12px;height:12px;box-shadow:0 1px 3px #0003}._1n94osf16{background-color:var(--rc-bg);pointer-events:none;border-radius:50%;width:3px;height:3px;position:absolute;top:50%;transform:translate(-50%,-50%)}._1n94osf17{text-align:right;min-width:34px;font-size:var(--rc-font-size-xs);font-variant-numeric:tabular-nums;color:var(--rc-text-secondary)}._1n94osf18{height:26px;color:var(--rc-text-secondary);font-size:var(--rc-font-size-xs);cursor:pointer;background:0 0;border:none;border-radius:6px;justify-content:center;align-items:center;padding:0 8px;font-weight:500;transition:background-color .15s,color .15s;display:inline-flex}._1n94osf18:hover,._1n94osf19{color:var(--rc-text);background-color:var(--rc-fill-secondary)}@media (max-width:640px){._1n94osf0[data-layout=float-left],._1n94osf0[data-layout=float-right]{float:none;width:auto;margin:1.25rem auto}}
|
|
1
|
+
:root{--rc-text:#000;--rc-text-secondary:#262626;--rc-text-tertiary:#737373;--rc-text-quaternary:#a3a3a3;--rc-bg:#fff;--rc-bg-secondary:#fafafa;--rc-bg-tertiary:#f5f5f5;--rc-fill:#e8e8e8;--rc-fill-secondary:#eee;--rc-fill-tertiary:#f5f5f5;--rc-fill-quaternary:#fafafa;--rc-border:#f5f5f5;--rc-accent:#2563eb;--rc-accent-light:#2563eb20;--rc-link:#2563eb;--rc-code-text:#404040;--rc-code-bg:#f5f5f5;--rc-hr-border:#e5e5e5;--rc-quote-border:#2563eb;--rc-quote-bg:#f5f5f5;--rc-alert-info:#006bb7;--rc-alert-warning:#c50;--rc-alert-tip:#1c0;--rc-alert-caution:#c01;--rc-alert-important:#50c;--rc-max-width:700px;--rc-shadow-top-bar:0 8px 30px #0000001f, 0 2px 8px #0000000f;--rc-shadow-modal:0 10px 15px -3px #0000001a, 0 4px 6px -4px #0000001a;--rc-shadow-menu:0 1px 4px #0000000a, 0 4px 16px #00000014;--rc-space-xs:4px;--rc-space-sm:8px;--rc-space-md:16px;--rc-space-lg:24px;--rc-space-xl:32px;--rc-font-family-sans:"PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-font-family-serif:"Noto Serif CJK SC", "Source Han Serif SC", "Source Han Serif", "source-han-serif-sc", "Songti SC", STSong, "华文宋体", serif;--rc-font-family-kai:"楷体", KaiTi, STKaiti, "Kaiti SC", "LXGW WenKai", "霞鹜文楷", "Noto Serif CJK SC", serif;--rc-font-mono:"SF Mono", SFMono-Regular, ui-monospace, "DejaVu Sans Mono", Menlo, Consolas, monospace;--rc-font-size-2xs:.625em;--rc-font-size-xs:.75em;--rc-font-size-sm:.8125em;--rc-font-size-md:.875em;--rc-font-size-lg:1.25em;--rc-font-size-base:16px;--rc-font-size-small:14px;--rc-line-height:1.7;--rc-line-height-tight:1.4;--rc-font-family:"PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-radius-sm:4px;--rc-radius-md:8px;--rc-radius-lg:12px}:root.dark,[data-theme=dark]{--rc-text:#fafafa;--rc-text-secondary:#a3a3a3;--rc-text-tertiary:#737373;--rc-text-quaternary:#525252;--rc-bg:#0a0a0a;--rc-bg-secondary:#171717;--rc-bg-tertiary:#262626;--rc-fill:#2a2a2a;--rc-fill-secondary:#222;--rc-fill-tertiary:#1a1a1a;--rc-fill-quaternary:#141414;--rc-border:#262626;--rc-accent:#60a5fa;--rc-accent-light:#60a5fa20;--rc-link:#60a5fa;--rc-code-text:#d4d4d4;--rc-code-bg:#262626;--rc-hr-border:#262626;--rc-quote-border:#60a5fa;--rc-quote-bg:#262626;--rc-alert-info:#7db9e5;--rc-alert-warning:#da864a;--rc-alert-tip:#54da48;--rc-alert-caution:#e16973;--rc-alert-important:#9966e0;--rc-shadow-top-bar:0 8px 30px #00000073, 0 2px 8px #0000004d;--rc-shadow-modal:0 10px 15px -3px #0006, 0 4px 6px -4px #00000059;--rc-shadow-menu:0 1px 4px #00000040, 0 4px 16px #0006}._7eow1s0{--rc-text:#000;--rc-text-secondary:#262626;--rc-text-tertiary:#737373;--rc-text-quaternary:#a3a3a3;--rc-bg:#fff;--rc-bg-secondary:#fafafa;--rc-bg-tertiary:#f5f5f5;--rc-fill:#e8e8e8;--rc-fill-secondary:#eee;--rc-fill-tertiary:#f5f5f5;--rc-fill-quaternary:#fafafa;--rc-border:#f5f5f5;--rc-accent:#2563eb;--rc-accent-light:#2563eb20;--rc-link:#2563eb;--rc-code-text:#404040;--rc-code-bg:#f5f5f5;--rc-hr-border:#e5e5e5;--rc-quote-border:#2563eb;--rc-quote-bg:#f5f5f5;--rc-alert-info:#006bb7;--rc-alert-warning:#c50;--rc-alert-tip:#1c0;--rc-alert-caution:#c01;--rc-alert-important:#50c;--rc-max-width:700px;--rc-shadow-top-bar:0 8px 30px #0000001f, 0 2px 8px #0000000f;--rc-shadow-modal:0 10px 15px -3px #0000001a, 0 4px 6px -4px #0000001a;--rc-shadow-menu:0 1px 4px #0000000a, 0 4px 16px #00000014;--rc-space-xs:4px;--rc-space-sm:8px;--rc-space-md:16px;--rc-space-lg:24px;--rc-space-xl:32px;--rc-font-family-sans:"PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-font-family-serif:"Noto Serif CJK SC", "Source Han Serif SC", "Source Han Serif", "source-han-serif-sc", "Songti SC", STSong, "华文宋体", serif;--rc-font-family-kai:"楷体", KaiTi, STKaiti, "Kaiti SC", "LXGW WenKai", "霞鹜文楷", "Noto Serif CJK SC", serif;--rc-font-mono:"SF Mono", SFMono-Regular, ui-monospace, "DejaVu Sans Mono", Menlo, Consolas, monospace;--rc-font-size-2xs:.625em;--rc-font-size-xs:.75em;--rc-font-size-sm:.8125em;--rc-font-size-md:.875em;--rc-font-size-lg:1.25em;--rc-font-size-base:16px;--rc-font-size-small:14px;--rc-line-height:1.7;--rc-line-height-tight:1.4;--rc-font-family:"PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-radius-sm:4px;--rc-radius-md:8px;--rc-radius-lg:12px}._7eow1s1{--rc-text:#000;--rc-text-secondary:#262626;--rc-text-tertiary:#737373;--rc-text-quaternary:#a3a3a3;--rc-bg:#fff;--rc-bg-secondary:#fafafa;--rc-bg-tertiary:#f5f5f5;--rc-fill:#e8e8e8;--rc-fill-secondary:#eee;--rc-fill-tertiary:#f5f5f5;--rc-fill-quaternary:#fafafa;--rc-border:#f5f5f5;--rc-accent:#2563eb;--rc-accent-light:#2563eb20;--rc-link:#2563eb;--rc-code-text:#404040;--rc-code-bg:#f5f5f5;--rc-hr-border:#e5e5e5;--rc-quote-border:#2563eb;--rc-quote-bg:#f5f5f5;--rc-alert-info:#006bb7;--rc-alert-warning:#c50;--rc-alert-tip:#1c0;--rc-alert-caution:#c01;--rc-alert-important:#50c;--rc-max-width:700px;--rc-shadow-top-bar:0 8px 30px #0000001f, 0 2px 8px #0000000f;--rc-shadow-modal:0 10px 15px -3px #0000001a, 0 4px 6px -4px #0000001a;--rc-shadow-menu:0 1px 4px #0000000a, 0 4px 16px #00000014;--rc-space-xs:4px;--rc-space-sm:8px;--rc-space-md:16px;--rc-space-lg:24px;--rc-space-xl:32px;--rc-font-family-sans:"PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-font-family-serif:"Noto Serif CJK SC", "Source Han Serif SC", "Source Han Serif", "source-han-serif-sc", "Songti SC", STSong, "华文宋体", serif;--rc-font-family-kai:"楷体", KaiTi, STKaiti, "Kaiti SC", "LXGW WenKai", "霞鹜文楷", "Noto Serif CJK SC", serif;--rc-font-mono:"SF Mono", SFMono-Regular, ui-monospace, "DejaVu Sans Mono", Menlo, Consolas, monospace;--rc-font-size-2xs:.625em;--rc-font-size-xs:.75em;--rc-font-size-sm:.8125em;--rc-font-size-md:.875em;--rc-font-size-lg:1.25em;--rc-font-size-base:16px;--rc-font-size-small:14px;--rc-line-height:1.8;--rc-line-height-tight:1.4;--rc-font-family:"Noto Serif CJK SC", "Source Han Serif SC", "Source Han Serif", "source-han-serif-sc", "Songti SC", STSong, "华文宋体", serif;--rc-radius-sm:4px;--rc-radius-md:8px;--rc-radius-lg:12px}._7eow1s2{--rc-text:#000;--rc-text-secondary:#262626;--rc-text-tertiary:#737373;--rc-text-quaternary:#a3a3a3;--rc-bg:#fff;--rc-bg-secondary:#fafafa;--rc-bg-tertiary:#f5f5f5;--rc-fill:#e8e8e8;--rc-fill-secondary:#eee;--rc-fill-tertiary:#f5f5f5;--rc-fill-quaternary:#fafafa;--rc-border:#f5f5f5;--rc-accent:#2563eb;--rc-accent-light:#2563eb20;--rc-link:#2563eb;--rc-code-text:#404040;--rc-code-bg:#f5f5f5;--rc-hr-border:#e5e5e5;--rc-quote-border:#a3a3a3;--rc-quote-bg:#fafafa;--rc-alert-info:#006bb7;--rc-alert-warning:#c50;--rc-alert-tip:#1c0;--rc-alert-caution:#c01;--rc-alert-important:#50c;--rc-max-width:none;--rc-shadow-top-bar:0 8px 30px #0000001f, 0 2px 8px #0000000f;--rc-shadow-modal:0 10px 15px -3px #0000001a, 0 4px 6px -4px #0000001a;--rc-shadow-menu:0 1px 4px #0000000a, 0 4px 16px #00000014;--rc-space-xs:2px;--rc-space-sm:4px;--rc-space-md:10px;--rc-space-lg:16px;--rc-space-xl:20px;--rc-font-family-sans:"PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-font-family-serif:"Noto Serif CJK SC", "Source Han Serif SC", "Source Han Serif", "source-han-serif-sc", "Songti SC", STSong, "华文宋体", serif;--rc-font-family-kai:"楷体", KaiTi, STKaiti, "Kaiti SC", "LXGW WenKai", "霞鹜文楷", "Noto Serif CJK SC", serif;--rc-font-mono:"SF Mono", SFMono-Regular, ui-monospace, "DejaVu Sans Mono", Menlo, Consolas, monospace;--rc-font-size-2xs:.625em;--rc-font-size-xs:.75em;--rc-font-size-sm:.8125em;--rc-font-size-md:.875em;--rc-font-size-lg:1.25em;--rc-font-size-base:14px;--rc-font-size-small:12px;--rc-line-height:1.5;--rc-line-height-tight:1.3;--rc-font-family:"PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-radius-sm:3px;--rc-radius-md:6px;--rc-radius-lg:12px}.dark ._7eow1s0,[data-theme=dark] ._7eow1s0,.dark._7eow1s0,[data-theme=dark]._7eow1s0,.dark ._7eow1s1,[data-theme=dark] ._7eow1s1,.dark._7eow1s1,[data-theme=dark]._7eow1s1,.dark ._7eow1s2,[data-theme=dark] ._7eow1s2,.dark._7eow1s2,[data-theme=dark]._7eow1s2{--rc-text:#fafafa;--rc-text-secondary:#a3a3a3;--rc-text-tertiary:#737373;--rc-text-quaternary:#525252;--rc-bg:#0a0a0a;--rc-bg-secondary:#171717;--rc-bg-tertiary:#262626;--rc-fill:#2a2a2a;--rc-fill-secondary:#222;--rc-fill-tertiary:#1a1a1a;--rc-fill-quaternary:#141414;--rc-border:#262626;--rc-accent:#60a5fa;--rc-accent-light:#60a5fa20;--rc-link:#60a5fa;--rc-code-text:#d4d4d4;--rc-code-bg:#262626;--rc-hr-border:#262626;--rc-quote-border:#60a5fa;--rc-quote-bg:#262626;--rc-alert-info:#7db9e5;--rc-alert-warning:#da864a;--rc-alert-tip:#54da48;--rc-alert-caution:#e16973;--rc-alert-important:#9966e0;--rc-shadow-top-bar:0 8px 30px #00000073, 0 2px 8px #0000004d;--rc-shadow-modal:0 10px 15px -3px #0006, 0 4px 6px -4px #00000059;--rc-shadow-menu:0 1px 4px #00000040, 0 4px 16px #0006}@keyframes _1n94osf2{0%{opacity:.16;-webkit-mask:linear-gradient(90deg,#000 25%,#000000e6 50%,#0000) 150% 0/400% no-repeat;mask:linear-gradient(90deg,#000 25%,#000000e6 50%,#0000) 150% 0/400% no-repeat}to{opacity:1;-webkit-mask:linear-gradient(90deg,#000 25%,#000000e6 50%,#0000) 0/400% no-repeat;mask:linear-gradient(90deg,#000 25%,#000000e6 50%,#0000) 0/400% no-repeat}}@keyframes _1n94osfb{to{transform:rotate(360deg)}}@keyframes _1n94osfj{0%{opacity:0}to{opacity:1}}._1n94osf0{text-align:center;width:var(--rich-image-display-width,auto);max-width:100%;max-height:var(--rich-image-display-height,none);margin:1.25rem auto}._1n94osf0[data-layout=align-left]{text-align:left;margin-left:0;margin-right:auto}._1n94osf0[data-layout=align-right]{text-align:right;margin-left:auto;margin-right:0}._1n94osf0[data-layout=float-left]{float:left;width:var(--rich-image-display-width,42%);margin:.125rem 1.25rem .875rem 0}._1n94osf0[data-layout=float-right]{float:right;width:var(--rich-image-display-width,42%);margin:.125rem 0 .875rem 1.25rem}._1n94osf0[data-display=fixed-height],._1n94osf0[data-layout=float-left][data-display=fixed-height],._1n94osf0[data-layout=float-right][data-display=fixed-height]{width:auto}.rich-image-wrapper[data-layout^=float] ._1n94osf0{float:none;width:auto;margin:0}._1n94osf1{opacity:.4}.rich-editor__content[data-rich-image-drop-side]{cursor:move}.rich-editor__content[data-rich-image-drop-side=left]{box-shadow:inset 3px 0 0 color-mix(in srgb, var(--rc-accent) 70%, transparent)}.rich-editor__content[data-rich-image-drop-side=right]{box-shadow:inset -3px 0 0 color-mix(in srgb, var(--rc-accent) 70%, transparent)}._1n94osf3{opacity:0;width:100%;max-width:100%;height:auto;display:block;border-radius:0!important}._1n94osf7{opacity:1;animation:.42s _1n94osf2}._1n94osf8{border-radius:var(--rc-radius-md);cursor:zoom-in;justify-content:center;align-items:center;min-height:3rem;transition:transform .25s;display:inline-flex;position:relative;overflow:hidden}._1n94osf8:hover{transform:translateY(-1px)}._1n94osf9{cursor:default}._1n94osf9:hover{transform:none}._1n94osfa{cursor:default}._1n94osfa:hover{transform:none}._1n94osf0[data-display=fixed-height] ._1n94osf3{width:auto;max-width:100%;height:auto;max-height:var(--rich-image-display-height)}._1n94osf0[data-display=fixed-height] ._1n94osf8{width:auto;max-width:100%;max-height:var(--rich-image-display-height)}._1n94osfc{border:2px solid color-mix(in srgb, var(--rc-text-secondary) 45%, transparent);border-top-color:color-mix(in srgb, var(--rc-text) 65%, transparent);border-radius:50%;width:1.65rem;height:1.65rem;animation:.75s linear infinite _1n94osfb;position:absolute}._1n94osfd{white-space:nowrap;font-size:var(--rc-font-size-sm);letter-spacing:-.005em;color:#fff;-webkit-backdrop-filter:blur(20px)saturate(180%);background:#ff3b30a6;border-radius:6px;padding:.3rem .7rem;font-weight:500;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}._1n94osfe{color:var(--rc-text-tertiary);font-size:var(--rc-font-size-md);margin-top:.5rem;line-height:1.5}._1n94osff{margin:var(--rc-space-md) 0;text-align:center}._1n94osfg{border-radius:var(--rc-radius-md);transition:background-color .3s;display:inline-block;position:relative;overflow:hidden}._1n94osfh{opacity:0;transition:opacity .3s}._1n94osfi{opacity:1;transition:opacity .3s}._1n94osfk{z-index:9999;cursor:zoom-out;background-color:#000000d9;justify-content:center;align-items:center;animation:.2s _1n94osfj;display:flex;position:fixed;top:0;bottom:0;left:0;right:0}._1n94osfl{object-fit:contain;border-radius:0;max-width:90vw;max-height:90vh}.rich-image{margin:var(--rc-space-md) 0;text-align:center}.rich-image figcaption{font-size:var(--rc-font-size-md);color:var(--rc-text-secondary);margin-top:var(--rc-space-sm);line-height:var(--rc-line-height-tight)}.rich-image-container{border-radius:var(--rc-radius-md);transition:background-color .3s;display:inline-block;position:relative;overflow:hidden}.rich-image-hidden{opacity:0;transition:opacity .3s}.rich-image-visible{opacity:1;transition:opacity .3s}.rich-image-zoom-overlay{z-index:9999;cursor:zoom-out;background-color:#000000d9;justify-content:center;align-items:center;animation:.2s _1n94osfj;display:flex;position:fixed;top:0;bottom:0;left:0;right:0}.rich-image-zoom-img{object-fit:contain;border-radius:0;max-width:90vw;max-height:90vh}._1n94osfm{cursor:default;display:block;position:relative}._1n94osfn{border:2px dashed var(--rc-border);border-radius:var(--rc-radius-md);color:var(--rc-text-secondary);font-size:var(--rc-font-size-md);cursor:pointer;flex-direction:column;justify-content:center;align-items:center;gap:8px;padding:2rem;transition:border-color .2s,color .2s,background-color .2s;display:flex}._1n94osfn:hover{border-color:var(--rc-accent);color:var(--rc-text);background-color:color-mix(in srgb, var(--rc-accent) 8%, transparent)}._1n94osfo{z-index:20;border:1px solid var(--rc-border);background:color-mix(in srgb, var(--rc-bg) 96%, transparent);box-shadow:var(--rc-shadow-top-bar);opacity:0;pointer-events:none;border-radius:10px;align-items:center;gap:4px;padding:4px;transition:opacity .15s;display:inline-flex;position:absolute;top:-2.5rem;left:50%;transform:translate(-50%)}._1n94osfp{opacity:1;pointer-events:auto}._1n94osfq{width:30px;height:30px;color:var(--rc-text-secondary);cursor:pointer;background:0 0;border:none;border-radius:8px;justify-content:center;align-items:center;transition:background-color .15s,color .15s;display:inline-flex}._1n94osfq:hover{color:var(--rc-text);background-color:var(--rc-fill-secondary)}._1n94osfr:hover{color:var(--rc-alert-caution);background-color:color-mix(in srgb, var(--rc-alert-caution) 12%, transparent)}._1n94osfs{width:360px;font-size:var(--rc-font-size-base);font-family:var(--rc-font-family);z-index:30;flex-direction:column;gap:8px;padding:12px;display:flex;position:relative}._1n94osft{background-color:var(--rc-bg-secondary);border-radius:6px;align-items:center;gap:8px;min-width:0;padding:6px 10px;display:flex}._1n94osfu{color:var(--rc-text-secondary);flex-shrink:0}._1n94osfv{-webkit-appearance:none;appearance:none;color:inherit;font-size:var(--rc-font-size-sm);background-color:#0000;border:none;outline:none;flex:1;min-width:0;padding:0}._1n94osfv::placeholder{color:var(--rc-text-secondary)}._1n94osfw{border-radius:var(--rc-radius-md);border:1.5px dashed var(--rc-border);min-height:138px;color:var(--rc-text-secondary);cursor:pointer;flex-direction:column;justify-content:center;align-items:center;gap:.45rem;transition:border-color .15s,background-color .15s;display:flex}._1n94osfw:hover{border-color:color-mix(in srgb, var(--rc-accent) 45%, transparent);color:var(--rc-text);background-color:color-mix(in srgb, var(--rc-accent) 7%, transparent)}._1n94osfx{border-radius:var(--rc-radius-md);border:1px solid var(--rc-border);background-color:color-mix(in srgb, var(--rc-text) 2%, transparent);overflow:hidden}._1n94osfx img{object-fit:cover;width:100%;max-height:188px;display:block}._1n94osfy{color:var(--rc-text-secondary);font-size:var(--rc-font-size-xs);align-items:center;gap:.4rem;display:inline-flex}._1n94osfz{cursor:ew-resize;touch-action:none;opacity:0;z-index:10;background:#ffffffeb;border:1px solid #0000002e;border-radius:9999px;width:6px;height:36px;max-height:50%;transition:opacity .15s;position:absolute;top:50%;transform:translateY(-50%);box-shadow:0 1px 3px #00000040}._1n94osf10{left:6px}._1n94osf11{right:6px}._1n94osf12{opacity:1}._1n94osf13{font-family:var(--rc-font-family);z-index:30;align-items:center;gap:4px;padding:4px;display:flex}._1n94osf13._1n94osf13{width:-moz-fit-content;width:fit-content}._1n94osf14{font-family:var(--rc-font-family);z-index:30;flex-direction:column;align-items:stretch;gap:2px;padding:4px;display:flex}._1n94osf14._1n94osf14{width:272px}._1n94osf15{align-items:center;gap:4px;min-height:26px;display:flex}._1n94osf16{flex-shrink:0;align-items:center;gap:6px;margin-left:auto;padding-left:8px;display:flex}._1n94osf17{flex:1;align-items:center;height:24px;display:flex;position:relative}._1n94osf18{-webkit-appearance:none;appearance:none;cursor:pointer;background:0 0;width:100%;height:24px;margin:0}._1n94osf18::-webkit-slider-runnable-track{background:linear-gradient(to right, var(--rc-text-secondary) var(--fill), var(--rc-fill) var(--fill));border-radius:9999px;height:3px}._1n94osf18::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;background-color:var(--rc-bg);border:1px solid var(--rc-border);cursor:ew-resize;border-radius:50%;width:12px;height:12px;margin-top:-4.5px;box-shadow:0 1px 3px #0003}._1n94osf18::-moz-range-track{background:linear-gradient(to right, var(--rc-text-secondary) var(--fill), var(--rc-fill) var(--fill));border-radius:9999px;height:3px}._1n94osf18::-moz-range-thumb{-webkit-appearance:none;appearance:none;background-color:var(--rc-bg);border:1px solid var(--rc-border);cursor:ew-resize;border-radius:50%;width:12px;height:12px;box-shadow:0 1px 3px #0003}._1n94osf19{background-color:var(--rc-bg);pointer-events:none;border-radius:50%;width:3px;height:3px;position:absolute;top:50%;transform:translate(-50%,-50%)}._1n94osf1a{box-sizing:border-box;border:1px solid var(--rc-border);background-color:var(--rc-bg-secondary);width:52px;height:26px;color:var(--rc-text);font-size:var(--rc-font-size-xs);font-variant-numeric:tabular-nums;text-align:center;border-radius:6px;justify-content:center;align-items:center;line-height:24px;display:inline-flex;overflow:hidden}._1n94osf1b{-webkit-appearance:none;appearance:none;-moz-appearance:textfield;outline:none;min-width:0;padding:0}._1n94osf1b:focus{border-color:var(--rc-text-secondary)}._1n94osf1c{box-sizing:border-box;text-align:right;width:48px;font-size:var(--rc-font-size-xs);font-variant-numeric:tabular-nums;color:var(--rc-text-tertiary)}._1n94osf1d{height:26px;color:var(--rc-text-secondary);font-size:var(--rc-font-size-xs);cursor:pointer;background:0 0;border:none;border-radius:6px;justify-content:center;align-items:center;padding:0 8px;font-weight:500;transition:background-color .15s,color .15s;display:inline-flex}._1n94osf1d:hover,._1n94osf1e{color:var(--rc-text);background-color:var(--rc-fill-secondary)}@media (max-width:640px){._1n94osf0[data-layout=float-left],._1n94osf0[data-layout=float-right]{float:none;width:auto;margin:1.25rem auto}}
|
|
2
2
|
/*$vite$:1*/
|
package/dist/static.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as ImageRenderer } from "./ImageRenderer-
|
|
1
|
+
import { t as ImageRenderer } from "./ImageRenderer-B3TgOJEU.js";
|
|
2
2
|
export { ImageRenderer };
|
package/dist/styles.css.d.ts
CHANGED
|
@@ -66,10 +66,15 @@ export declare const resizeHandleLeft: string;
|
|
|
66
66
|
export declare const resizeHandleRight: string;
|
|
67
67
|
export declare const resizeHandleVisible: string;
|
|
68
68
|
export declare const controlPanel: string;
|
|
69
|
+
export declare const sizePanel: string;
|
|
70
|
+
export declare const sizePanelRow: string;
|
|
71
|
+
export declare const sizeReadout: string;
|
|
69
72
|
export declare const sizeSliderWrap: string;
|
|
70
73
|
export declare const sizeSlider: string;
|
|
71
74
|
export declare const sizeSliderTick: string;
|
|
72
|
-
export declare const
|
|
75
|
+
export declare const sizeValueField: string;
|
|
76
|
+
export declare const sizePxInput: string;
|
|
77
|
+
export declare const sizeEquiv: string;
|
|
73
78
|
export declare const sizeOption: string;
|
|
74
79
|
export declare const editToolbarButtonActive: string;
|
|
75
80
|
//# sourceMappingURL=styles.css.d.ts.map
|
package/dist/styles.css.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"styles.css.d.ts","sourceRoot":"","sources":["../src/styles.css.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;CAwBrB,CAAC;AAIX,eAAO,MAAM,IAAI,
|
|
1
|
+
{"version":3,"file":"styles.css.d.ts","sourceRoot":"","sources":["../src/styles.css.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;CAwBrB,CAAC;AAIX,eAAO,MAAM,IAAI,QA8Cf,CAAC;AAWH,eAAO,MAAM,aAAa,QAExB,CAAC;AAyBH,eAAO,MAAM,KAAK,QAOhB,CAAC;AAEH,eAAO,MAAM,UAAU,gDAIrB,CAAC;AAEH,eAAO,MAAM,YAAY,QAGvB,CAAC;AAEH,eAAO,MAAM,KAAK,QAehB,CAAC;AAEH,eAAO,MAAM,aAAa,QAOxB,CAAC;AAEH,eAAO,MAAM,WAAW,QAOtB,CAAC;AAiBH,eAAO,MAAM,MAAM,QAQjB,CAAC;AAEH,eAAO,MAAM,UAAU,QAerB,CAAC;AAEH,eAAO,MAAM,OAAO,QAKlB,CAAC;AAEH,eAAO,MAAM,yBAAyB;;;;;;;CAO5B,CAAC;AAgCX,eAAO,MAAM,WAAW,QAA2B,CAAC;AACpD,eAAO,MAAM,gBAAgB,QAAgC,CAAC;AAC9D,eAAO,MAAM,aAAa,QAA6B,CAAC;AACxD,eAAO,MAAM,cAAc,QAA8B,CAAC;AA0B1D,eAAO,MAAM,kBAAkB,QAAkC,CAAC;AAClE,eAAO,MAAM,gBAAgB,QAAgC,CAAC;AAU9D,eAAO,MAAM,WAAW,QAItB,CAAC;AAEH,eAAO,MAAM,eAAe,QAoB1B,CAAC;AAEH,eAAO,MAAM,WAAW,QAiBtB,CAAC;AAEH,eAAO,MAAM,kBAAkB,QAG7B,CAAC;AAEH,eAAO,MAAM,iBAAiB,QAkB5B,CAAC;AAEH,eAAO,MAAM,uBAAuB,QAOlC,CAAC;AAEH,eAAO,MAAM,SAAS,QAUpB,CAAC;AAEH,eAAO,MAAM,SAAS,QAQpB,CAAC;AAEH,eAAO,MAAM,aAAa,QAGxB,CAAC;AAEH,eAAO,MAAM,SAAS,QAepB,CAAC;AAEH,eAAO,MAAM,iBAAiB,QAmB5B,CAAC;AAEH,eAAO,MAAM,cAAc,QAKzB,CAAC;AASH,eAAO,MAAM,SAAS,QAMpB,CAAC;AAEH,eAAO,MAAM,YAAY,QAgBvB,CAAC;AAEH,eAAO,MAAM,gBAAgB,QAAqB,CAAC;AACnD,eAAO,MAAM,iBAAiB,QAAsB,CAAC;AAErD,eAAO,MAAM,mBAAmB,QAE9B,CAAC;AAEH,eAAO,MAAM,YAAY,QAOvB,CAAC;AAQH,eAAO,MAAM,SAAS,QAQpB,CAAC;AAMH,eAAO,MAAM,YAAY,QAKvB,CAAC;AAEH,eAAO,MAAM,WAAW,QAOtB,CAAC;AAEH,eAAO,MAAM,cAAc,QAMzB,CAAC;AAaH,eAAO,MAAM,UAAU,QAwBrB,CAAC;AAEH,eAAO,MAAM,cAAc,QASzB,CAAC;AAEH,eAAO,MAAM,cAAc,QAgBzB,CAAC;AAEH,eAAO,MAAM,WAAW,QAWtB,CAAC;AAEH,eAAO,MAAM,SAAS,QAOpB,CAAC;AAEH,eAAO,MAAM,UAAU,QAoBrB,CAAC;AAEH,eAAO,MAAM,uBAAuB,QAGlC,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ImageLayout } from '@haklex/rich-editor/nodes';
|
|
1
|
+
import { ImageDisplaySize, ImageLayout } from '@haklex/rich-editor/nodes';
|
|
2
2
|
export declare function useImageActions(): {
|
|
3
3
|
commitMeta: () => void;
|
|
4
4
|
closeReplacePanel: () => void;
|
|
@@ -10,7 +10,7 @@ export declare function useImageActions(): {
|
|
|
10
10
|
handleDuplicate: () => void;
|
|
11
11
|
handleDownload: () => void;
|
|
12
12
|
handleDelete: () => void;
|
|
13
|
-
|
|
13
|
+
handleSetDisplaySize: (size: ImageDisplaySize) => void;
|
|
14
14
|
handleSetLayout: (layout?: ImageLayout) => void;
|
|
15
15
|
};
|
|
16
16
|
//# sourceMappingURL=useImageActions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useImageActions.d.ts","sourceRoot":"","sources":["../src/useImageActions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"useImageActions.d.ts","sourceRoot":"","sources":["../src/useImageActions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAqD/E,wBAAgB,eAAe;;;8BA0Gd,IAAI,GAAG,IAAI;;;wCA6Db,OAAO;;;;;iCA/EX,gBAAgB;+BASb,WAAW;EA2FxB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useImageResize.d.ts","sourceRoot":"","sources":["../src/useImageResize.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useImageResize.d.ts","sourceRoot":"","sources":["../src/useImageResize.ts"],"names":[],"mappings":"AAsBA,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,OAAO,CAAC;AAI1C,wBAAgB,cAAc;+BAQlB,KAAK,CAAC,YAAY,CAAC,WAAW,CAAC,QAAQ,UAAU;EA+G5D"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@haklex/rich-renderer-image",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.37.0",
|
|
4
4
|
"description": "Image renderer with blurhash",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"react-dom": "^19.2.8",
|
|
37
37
|
"typescript": "^7.0.2",
|
|
38
38
|
"unplugin-dts": "^1.0.3",
|
|
39
|
-
"vite": "^8.2.
|
|
39
|
+
"vite": "^8.2.2"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
42
|
"@lexical/react": "^0.49.0",
|
|
@@ -45,9 +45,9 @@
|
|
|
45
45
|
"lucide-react": "^1.0.0",
|
|
46
46
|
"react": ">=19",
|
|
47
47
|
"react-dom": ">=19",
|
|
48
|
-
"@haklex/rich-editor": "^0.
|
|
49
|
-
"@haklex/rich-editor
|
|
50
|
-
"@haklex/rich-style-token": "^0.
|
|
48
|
+
"@haklex/rich-editor-ui": "^0.37.0",
|
|
49
|
+
"@haklex/rich-editor": "^0.37.0",
|
|
50
|
+
"@haklex/rich-style-token": "^0.37.0"
|
|
51
51
|
},
|
|
52
52
|
"publishConfig": {
|
|
53
53
|
"access": "public"
|