@haklex/rich-ext-nested-doc 0.0.62
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/LICENSE +28 -0
- package/dist/NestedDocDialogEditorContext.d.ts +10 -0
- package/dist/NestedDocDialogEditorContext.d.ts.map +1 -0
- package/dist/NestedDocEditDecorator.d.ts +9 -0
- package/dist/NestedDocEditDecorator.d.ts.map +1 -0
- package/dist/NestedDocEditNode.d.ts +17 -0
- package/dist/NestedDocEditNode.d.ts.map +1 -0
- package/dist/NestedDocNode.d.ts +23 -0
- package/dist/NestedDocNode.d.ts.map +1 -0
- package/dist/NestedDocPlugin.d.ts +4 -0
- package/dist/NestedDocPlugin.d.ts.map +1 -0
- package/dist/NestedDocRenderer.d.ts +5 -0
- package/dist/NestedDocRenderer.d.ts.map +1 -0
- package/dist/NestedDocStaticDecorator.d.ts +7 -0
- package/dist/NestedDocStaticDecorator.d.ts.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.mjs +287 -0
- package/dist/rich-ext-nested-doc.css +1 -0
- package/dist/static.d.ts +8 -0
- package/dist/static.d.ts.map +1 -0
- package/dist/static.mjs +12 -0
- package/dist/styles.css.d.ts +27 -0
- package/dist/styles.css.d.ts.map +1 -0
- package/dist/transformer-CqZLVEDu.js +228 -0
- package/dist/transformer.d.ts +3 -0
- package/dist/transformer.d.ts.map +1 -0
- package/dist/utils.d.ts +4 -0
- package/dist/utils.d.ts.map +1 -0
- package/package.json +57 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
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.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { LexicalEditor, SerializedEditorState } from 'lexical';
|
|
2
|
+
import { ComponentType } from 'react';
|
|
3
|
+
export interface NestedDocDialogEditorProps {
|
|
4
|
+
initialValue: SerializedEditorState;
|
|
5
|
+
onEditorReady: (editor: LexicalEditor | null) => void;
|
|
6
|
+
}
|
|
7
|
+
export type NestedDocDialogEditorComponent = ComponentType<NestedDocDialogEditorProps>;
|
|
8
|
+
export declare const NestedDocDialogEditorProvider: import('react').Provider<NestedDocDialogEditorComponent | null>;
|
|
9
|
+
export declare function useNestedDocDialogEditor(): NestedDocDialogEditorComponent | null;
|
|
10
|
+
//# sourceMappingURL=NestedDocDialogEditorContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NestedDocDialogEditorContext.d.ts","sourceRoot":"","sources":["../src/NestedDocDialogEditorContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAA;AACnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAG1C,MAAM,WAAW,0BAA0B;IACzC,YAAY,EAAE,qBAAqB,CAAA;IACnC,aAAa,EAAE,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,KAAK,IAAI,CAAA;CACtD;AAED,MAAM,MAAM,8BAA8B,GACxC,aAAa,CAAC,0BAA0B,CAAC,CAAA;AAK3C,eAAO,MAAM,6BAA6B,iEACH,CAAA;AAEvC,wBAAgB,wBAAwB,IAAI,8BAA8B,GAAG,IAAI,CAEhF"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { LexicalEditor, SerializedEditorState } from 'lexical';
|
|
2
|
+
interface NestedDocEditDecoratorProps {
|
|
3
|
+
nodeKey: string;
|
|
4
|
+
contentEditor: LexicalEditor;
|
|
5
|
+
contentState: SerializedEditorState;
|
|
6
|
+
}
|
|
7
|
+
export declare function NestedDocEditDecorator({ nodeKey, contentEditor, contentState, }: NestedDocEditDecoratorProps): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=NestedDocEditDecorator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NestedDocEditDecorator.d.ts","sourceRoot":"","sources":["../src/NestedDocEditDecorator.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAA;AAmCnE,UAAU,2BAA2B;IACnC,OAAO,EAAE,MAAM,CAAA;IACf,aAAa,EAAE,aAAa,CAAA;IAC5B,YAAY,EAAE,qBAAqB,CAAA;CACpC;AAED,wBAAgB,sBAAsB,CAAC,EACrC,OAAO,EACP,aAAa,EACb,YAAY,GACb,EAAE,2BAA2B,2CAyE7B"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { CommandItemConfig } from '@haklex/rich-editor';
|
|
2
|
+
import { EditorConfig, LexicalEditor, SerializedEditorState } from 'lexical';
|
|
3
|
+
import { ReactElement } from 'react';
|
|
4
|
+
import { NestedDocNode, SerializedNestedDocNode } from './NestedDocNode';
|
|
5
|
+
export declare class NestedDocEditNode extends NestedDocNode {
|
|
6
|
+
__contentEditor: LexicalEditor;
|
|
7
|
+
static commandItems: CommandItemConfig[];
|
|
8
|
+
static clone(node: NestedDocEditNode): NestedDocEditNode;
|
|
9
|
+
constructor(contentState?: SerializedEditorState, key?: string);
|
|
10
|
+
getContentEditor(): LexicalEditor;
|
|
11
|
+
static importJSON(serializedNode: SerializedNestedDocNode): NestedDocEditNode;
|
|
12
|
+
exportJSON(): SerializedNestedDocNode;
|
|
13
|
+
decorate(_editor: LexicalEditor, _config: EditorConfig): ReactElement;
|
|
14
|
+
}
|
|
15
|
+
export declare function $createNestedDocEditNode(contentState?: SerializedEditorState): NestedDocEditNode;
|
|
16
|
+
export declare function $isNestedDocEditNode(node: unknown): node is NestedDocEditNode;
|
|
17
|
+
//# sourceMappingURL=NestedDocEditNode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NestedDocEditNode.d.ts","sourceRoot":"","sources":["../src/NestedDocEditNode.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,iBAAiB,EAGvB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,qBAAqB,EACtB,MAAM,SAAS,CAAA;AAGhB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAA;AAIzC,OAAO,EAAE,aAAa,EAAE,KAAK,uBAAuB,EAAE,MAAM,iBAAiB,CAAA;AAa7E,qBAAa,iBAAkB,SAAQ,aAAa;IAClD,eAAe,EAAE,aAAa,CAAA;IAE9B,MAAM,CAAC,YAAY,EAAE,iBAAiB,EAAE,CAevC;IAED,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,iBAAiB,GAAG,iBAAiB;gBAM5C,YAAY,CAAC,EAAE,qBAAqB,EAAE,GAAG,CAAC,EAAE,MAAM;IAS9D,gBAAgB,IAAI,aAAa;IAIjC,MAAM,CAAC,UAAU,CACf,cAAc,EAAE,uBAAuB,GACtC,iBAAiB;IAIpB,UAAU,IAAI,uBAAuB;IASrC,QAAQ,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,YAAY,GAAG,YAAY;CAOtE;AAED,wBAAgB,wBAAwB,CACtC,YAAY,CAAC,EAAE,qBAAqB,GACnC,iBAAiB,CAEnB;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,iBAAiB,CAE7E"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { EditorConfig, LexicalEditor, LexicalNode, NodeKey, SerializedEditorState, SerializedLexicalNode, Spread, DecoratorNode } from 'lexical';
|
|
2
|
+
import { ReactElement } from 'react';
|
|
3
|
+
export type SerializedNestedDocNode = Spread<{
|
|
4
|
+
content: SerializedEditorState;
|
|
5
|
+
}, SerializedLexicalNode>;
|
|
6
|
+
export declare class NestedDocNode extends DecoratorNode<ReactElement> {
|
|
7
|
+
__contentState: SerializedEditorState;
|
|
8
|
+
static getType(): string;
|
|
9
|
+
static clone(node: NestedDocNode): NestedDocNode;
|
|
10
|
+
constructor(contentState?: SerializedEditorState, key?: NodeKey);
|
|
11
|
+
createDOM(_config: EditorConfig): HTMLElement;
|
|
12
|
+
updateDOM(): boolean;
|
|
13
|
+
isInline(): boolean;
|
|
14
|
+
getContentState(): SerializedEditorState;
|
|
15
|
+
setContentState(state: SerializedEditorState): void;
|
|
16
|
+
getTextContent(): string;
|
|
17
|
+
static importJSON(serializedNode: SerializedNestedDocNode): NestedDocNode;
|
|
18
|
+
exportJSON(): SerializedNestedDocNode;
|
|
19
|
+
decorate(_editor: LexicalEditor, _config: EditorConfig): ReactElement;
|
|
20
|
+
}
|
|
21
|
+
export declare function $createNestedDocNode(contentState?: SerializedEditorState): NestedDocNode;
|
|
22
|
+
export declare function $isNestedDocNode(node: LexicalNode | null | undefined): node is NestedDocNode;
|
|
23
|
+
//# sourceMappingURL=NestedDocNode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NestedDocNode.d.ts","sourceRoot":"","sources":["../src/NestedDocNode.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,WAAW,EACX,OAAO,EACP,qBAAqB,EACrB,qBAAqB,EACrB,MAAM,EACP,MAAM,SAAS,CAAA;AAChB,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AACvC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAA;AAKzC,MAAM,MAAM,uBAAuB,GAAG,MAAM,CAC1C;IACE,OAAO,EAAE,qBAAqB,CAAA;CAC/B,EACD,qBAAqB,CACtB,CAAA;AAED,qBAAa,aAAc,SAAQ,aAAa,CAAC,YAAY,CAAC;IAC5D,cAAc,EAAE,qBAAqB,CAAA;IAErC,MAAM,CAAC,OAAO,IAAI,MAAM;IAIxB,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,aAAa,GAAG,aAAa;gBAIpC,YAAY,CAAC,EAAE,qBAAqB,EAAE,GAAG,CAAC,EAAE,OAAO;IA2B/D,SAAS,CAAC,OAAO,EAAE,YAAY,GAAG,WAAW;IAM7C,SAAS,IAAI,OAAO;IAIpB,QAAQ,IAAI,OAAO;IAInB,eAAe,IAAI,qBAAqB;IAIxC,eAAe,CAAC,KAAK,EAAE,qBAAqB,GAAG,IAAI;IAKnD,cAAc,IAAI,MAAM;IAIxB,MAAM,CAAC,UAAU,CAAC,cAAc,EAAE,uBAAuB,GAAG,aAAa;IAIzE,UAAU,IAAI,uBAAuB;IASrC,QAAQ,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,YAAY,GAAG,YAAY;CAKtE;AAED,wBAAgB,oBAAoB,CAClC,YAAY,CAAC,EAAE,qBAAqB,GACnC,aAAa,CAEf;AAED,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,GACnC,IAAI,IAAI,aAAa,CAEvB"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { SerializedEditorState } from 'lexical';
|
|
2
|
+
export declare const INSERT_NESTED_DOC_COMMAND: import('lexical').LexicalCommand<void | SerializedEditorState<import('lexical').SerializedLexicalNode>>;
|
|
3
|
+
export declare function NestedDocPlugin(): null;
|
|
4
|
+
//# sourceMappingURL=NestedDocPlugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NestedDocPlugin.d.ts","sourceRoot":"","sources":["../src/NestedDocPlugin.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAA;AAMpD,eAAO,MAAM,yBAAyB,yGAC4B,CAAA;AAElE,wBAAgB,eAAe,SAe9B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NestedDocRenderer.d.ts","sourceRoot":"","sources":["../src/NestedDocRenderer.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAA;AAEpD,wBAAgB,iBAAiB,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,qBAAqB,CAAA;CAAE,2CAU5E"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { SerializedEditorState } from 'lexical';
|
|
2
|
+
interface NestedDocStaticDecoratorProps {
|
|
3
|
+
contentState: SerializedEditorState;
|
|
4
|
+
}
|
|
5
|
+
export declare function NestedDocStaticDecorator({ contentState, }: NestedDocStaticDecoratorProps): import("react/jsx-runtime").JSX.Element | null;
|
|
6
|
+
export {};
|
|
7
|
+
//# sourceMappingURL=NestedDocStaticDecorator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NestedDocStaticDecorator.d.ts","sourceRoot":"","sources":["../src/NestedDocStaticDecorator.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAA;AAUpD,UAAU,6BAA6B;IACrC,YAAY,EAAE,qBAAqB,CAAA;CACpC;AAED,wBAAgB,wBAAwB,CAAC,EACvC,YAAY,GACb,EAAE,6BAA6B,kDA2D/B"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Klass, LexicalNode } from 'lexical';
|
|
2
|
+
export type { NestedDocDialogEditorComponent, NestedDocDialogEditorProps, } from './NestedDocDialogEditorContext';
|
|
3
|
+
export { NestedDocDialogEditorProvider, useNestedDocDialogEditor, } from './NestedDocDialogEditorContext';
|
|
4
|
+
export { NestedDocEditDecorator } from './NestedDocEditDecorator';
|
|
5
|
+
export { $createNestedDocEditNode, $isNestedDocEditNode, NestedDocEditNode, } from './NestedDocEditNode';
|
|
6
|
+
export type { SerializedNestedDocNode } from './NestedDocNode';
|
|
7
|
+
export { $createNestedDocNode, $isNestedDocNode, NestedDocNode, } from './NestedDocNode';
|
|
8
|
+
export { INSERT_NESTED_DOC_COMMAND, NestedDocPlugin } from './NestedDocPlugin';
|
|
9
|
+
export { NestedDocRenderer } from './NestedDocRenderer';
|
|
10
|
+
export { NestedDocStaticDecorator } from './NestedDocStaticDecorator';
|
|
11
|
+
export { NESTED_DOC_BLOCK_TRANSFORMER } from './transformer';
|
|
12
|
+
export declare const nestedDocNodes: Array<Klass<LexicalNode>>;
|
|
13
|
+
export declare const nestedDocEditNodes: Array<Klass<LexicalNode>>;
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,iBAAiB,CAAA;AAExB,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAKjD,YAAY,EACV,8BAA8B,EAC9B,0BAA0B,GAC3B,MAAM,gCAAgC,CAAA;AACvC,OAAO,EACL,6BAA6B,EAC7B,wBAAwB,GACzB,MAAM,gCAAgC,CAAA;AACvC,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAA;AACjE,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,qBAAqB,CAAA;AAC5B,YAAY,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAA;AAC9D,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,aAAa,GACd,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,yBAAyB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAC9E,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AACvD,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAA;AACrE,OAAO,EAAE,4BAA4B,EAAE,MAAM,eAAe,CAAA;AAE5D,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,CAAmB,CAAA;AACxE,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,CAAuB,CAAA"}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
|
+
import { t as truncateEditorState, h as hasRenderableEditorState, d as dialogPopup, e as editOverlayRoot, p as previewSurface, N as NestedDocRenderer, a as previewEmpty, b as editOverlay, $ as $isNestedDocNode, c as dialogShell, f as dialogHeader, g as dialogHeaderMain, i as dialogHeaderIcon, j as dialogHeaderText, k as dialogTitle, l as editorArea, m as dialogFooter, n as dialogActions, s as secondaryButton, o as primaryButton, q as NestedDocNode } from "./transformer-CqZLVEDu.js";
|
|
5
|
+
import { r, u, v } from "./transformer-CqZLVEDu.js";
|
|
6
|
+
import { useColorScheme, editorTheme, getResolvedEditNodes } from "@haklex/rich-editor";
|
|
7
|
+
import { $getNodeByKey, $insertNodes, createEditor, createCommand, COMMAND_PRIORITY_EDITOR } from "lexical";
|
|
8
|
+
import { Pencil, FileText, X, Save } from "lucide-react";
|
|
9
|
+
import { createContext, use, useMemo, useCallback, useRef, createElement, useEffect } from "react";
|
|
10
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
|
+
import { usePortalTheme } from "@haklex/rich-style-token";
|
|
12
|
+
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
|
|
13
|
+
const NestedDocDialogEditorContext = createContext(null);
|
|
14
|
+
const NestedDocDialogEditorProvider = NestedDocDialogEditorContext.Provider;
|
|
15
|
+
function useNestedDocDialogEditor() {
|
|
16
|
+
return use(NestedDocDialogEditorContext);
|
|
17
|
+
}
|
|
18
|
+
const PREVIEW_NODE_LIMIT = 6;
|
|
19
|
+
const EMPTY_EDITOR_STATE = {
|
|
20
|
+
root: {
|
|
21
|
+
children: [
|
|
22
|
+
{
|
|
23
|
+
children: [],
|
|
24
|
+
direction: "ltr",
|
|
25
|
+
format: "",
|
|
26
|
+
indent: 0,
|
|
27
|
+
type: "paragraph",
|
|
28
|
+
version: 1,
|
|
29
|
+
textFormat: 0,
|
|
30
|
+
textStyle: ""
|
|
31
|
+
}
|
|
32
|
+
],
|
|
33
|
+
direction: "ltr",
|
|
34
|
+
format: "",
|
|
35
|
+
indent: 0,
|
|
36
|
+
type: "root",
|
|
37
|
+
version: 1
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
function NestedDocEditDecorator({
|
|
41
|
+
nodeKey,
|
|
42
|
+
contentEditor,
|
|
43
|
+
contentState
|
|
44
|
+
}) {
|
|
45
|
+
const [editor] = useLexicalComposerContext();
|
|
46
|
+
const colorScheme = useColorScheme();
|
|
47
|
+
const { className: portalClassName } = usePortalTheme();
|
|
48
|
+
const DialogEditor = useNestedDocDialogEditor();
|
|
49
|
+
const previewState = useMemo(
|
|
50
|
+
() => truncateEditorState(contentState, PREVIEW_NODE_LIMIT),
|
|
51
|
+
[contentState]
|
|
52
|
+
);
|
|
53
|
+
const hasPreview = hasRenderableEditorState(previewState);
|
|
54
|
+
const handleOpenDialog = useCallback(async () => {
|
|
55
|
+
if (!DialogEditor) return;
|
|
56
|
+
const { presentDialog } = await import("@haklex/rich-editor-ui");
|
|
57
|
+
presentDialog({
|
|
58
|
+
content: ({ dismiss }) => /* @__PURE__ */ jsx(
|
|
59
|
+
NestedDocDialogContent,
|
|
60
|
+
{
|
|
61
|
+
initialState: contentEditor.getEditorState().toJSON(),
|
|
62
|
+
parentEditor: editor,
|
|
63
|
+
nodeKey,
|
|
64
|
+
contentEditor,
|
|
65
|
+
onDismiss: dismiss,
|
|
66
|
+
DialogEditor
|
|
67
|
+
}
|
|
68
|
+
),
|
|
69
|
+
className: dialogPopup,
|
|
70
|
+
portalClassName,
|
|
71
|
+
theme: colorScheme,
|
|
72
|
+
showCloseButton: true,
|
|
73
|
+
clickOutsideToDismiss: false
|
|
74
|
+
});
|
|
75
|
+
}, [
|
|
76
|
+
DialogEditor,
|
|
77
|
+
colorScheme,
|
|
78
|
+
contentEditor,
|
|
79
|
+
editor,
|
|
80
|
+
nodeKey,
|
|
81
|
+
portalClassName
|
|
82
|
+
]);
|
|
83
|
+
return /* @__PURE__ */ jsxs(
|
|
84
|
+
"div",
|
|
85
|
+
{
|
|
86
|
+
className: editOverlayRoot,
|
|
87
|
+
onClick: handleOpenDialog,
|
|
88
|
+
role: "button",
|
|
89
|
+
tabIndex: 0,
|
|
90
|
+
"aria-label": "Open nested document editor",
|
|
91
|
+
onKeyDown: (event) => {
|
|
92
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
93
|
+
event.preventDefault();
|
|
94
|
+
handleOpenDialog();
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
children: [
|
|
98
|
+
/* @__PURE__ */ jsx("div", { className: "rich-nested-doc-content", children: hasPreview ? /* @__PURE__ */ jsx("div", { className: previewSurface, children: /* @__PURE__ */ jsx(NestedDocRenderer, { value: previewState }) }) : /* @__PURE__ */ jsx("p", { className: previewEmpty, children: "Empty nested document. Click to edit." }) }),
|
|
99
|
+
/* @__PURE__ */ jsx("div", { className: editOverlay, "aria-hidden": true, children: /* @__PURE__ */ jsx(Pencil, { size: 24 }) })
|
|
100
|
+
]
|
|
101
|
+
}
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
function NestedDocDialogContent({
|
|
105
|
+
initialState,
|
|
106
|
+
parentEditor,
|
|
107
|
+
nodeKey,
|
|
108
|
+
contentEditor,
|
|
109
|
+
onDismiss,
|
|
110
|
+
DialogEditor
|
|
111
|
+
}) {
|
|
112
|
+
const dialogEditorRef = useRef(null);
|
|
113
|
+
const safeInitialState = initialState?.root?.children?.length > 0 ? initialState : EMPTY_EDITOR_STATE;
|
|
114
|
+
const handleDone = useCallback(() => {
|
|
115
|
+
const dialogEditor = dialogEditorRef.current;
|
|
116
|
+
if (dialogEditor) {
|
|
117
|
+
const newState = dialogEditor.getEditorState().toJSON();
|
|
118
|
+
const parsed = contentEditor.parseEditorState(newState);
|
|
119
|
+
contentEditor.setEditorState(parsed);
|
|
120
|
+
parentEditor.update(() => {
|
|
121
|
+
const node = $getNodeByKey(nodeKey);
|
|
122
|
+
if ($isNestedDocNode(node)) {
|
|
123
|
+
node.setContentState(newState);
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
onDismiss();
|
|
128
|
+
}, [contentEditor, nodeKey, onDismiss, parentEditor]);
|
|
129
|
+
const handleKeyDownCapture = useCallback(
|
|
130
|
+
(event) => {
|
|
131
|
+
const isModifier = event.metaKey || event.ctrlKey;
|
|
132
|
+
if (!isModifier) return;
|
|
133
|
+
if (event.key === "Enter" || event.key.toLowerCase() === "s") {
|
|
134
|
+
event.preventDefault();
|
|
135
|
+
handleDone();
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
[handleDone]
|
|
139
|
+
);
|
|
140
|
+
const handleEditorReady = useCallback((editor) => {
|
|
141
|
+
dialogEditorRef.current = editor;
|
|
142
|
+
}, []);
|
|
143
|
+
return /* @__PURE__ */ jsxs("div", { className: dialogShell, onKeyDownCapture: handleKeyDownCapture, children: [
|
|
144
|
+
/* @__PURE__ */ jsx("div", { className: dialogHeader, children: /* @__PURE__ */ jsxs("div", { className: dialogHeaderMain, children: [
|
|
145
|
+
/* @__PURE__ */ jsx("span", { className: dialogHeaderIcon, children: /* @__PURE__ */ jsx(FileText, { size: 18 }) }),
|
|
146
|
+
/* @__PURE__ */ jsx("div", { className: dialogHeaderText, children: /* @__PURE__ */ jsx("h3", { className: dialogTitle, children: "Nested document" }) })
|
|
147
|
+
] }) }),
|
|
148
|
+
/* @__PURE__ */ jsx("div", { className: editorArea, children: /* @__PURE__ */ jsx(
|
|
149
|
+
DialogEditor,
|
|
150
|
+
{
|
|
151
|
+
initialValue: safeInitialState,
|
|
152
|
+
onEditorReady: handleEditorReady
|
|
153
|
+
}
|
|
154
|
+
) }),
|
|
155
|
+
/* @__PURE__ */ jsx("div", { className: dialogFooter, children: /* @__PURE__ */ jsxs("div", { className: dialogActions, children: [
|
|
156
|
+
/* @__PURE__ */ jsxs(
|
|
157
|
+
"button",
|
|
158
|
+
{
|
|
159
|
+
type: "button",
|
|
160
|
+
className: secondaryButton,
|
|
161
|
+
onClick: onDismiss,
|
|
162
|
+
children: [
|
|
163
|
+
/* @__PURE__ */ jsx(X, { size: 15 }),
|
|
164
|
+
"Cancel"
|
|
165
|
+
]
|
|
166
|
+
}
|
|
167
|
+
),
|
|
168
|
+
/* @__PURE__ */ jsxs(
|
|
169
|
+
"button",
|
|
170
|
+
{
|
|
171
|
+
type: "button",
|
|
172
|
+
className: primaryButton,
|
|
173
|
+
onClick: handleDone,
|
|
174
|
+
children: [
|
|
175
|
+
/* @__PURE__ */ jsx(Save, { size: 15 }),
|
|
176
|
+
"Save"
|
|
177
|
+
]
|
|
178
|
+
}
|
|
179
|
+
)
|
|
180
|
+
] }) })
|
|
181
|
+
] });
|
|
182
|
+
}
|
|
183
|
+
function createContentEditor() {
|
|
184
|
+
return createEditor({
|
|
185
|
+
namespace: "NestedDocContent",
|
|
186
|
+
nodes: getResolvedEditNodes(),
|
|
187
|
+
theme: editorTheme,
|
|
188
|
+
onError: (error) => {
|
|
189
|
+
console.error("[NestedDocContent]", error);
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
const _NestedDocEditNode = class _NestedDocEditNode extends NestedDocNode {
|
|
194
|
+
constructor(contentState, key) {
|
|
195
|
+
super(contentState, key);
|
|
196
|
+
__publicField(this, "__contentEditor");
|
|
197
|
+
this.__contentEditor = createContentEditor();
|
|
198
|
+
if (contentState) {
|
|
199
|
+
const editorState = this.__contentEditor.parseEditorState(contentState);
|
|
200
|
+
this.__contentEditor.setEditorState(editorState);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
static clone(node) {
|
|
204
|
+
const cloned = new _NestedDocEditNode(node.__contentState, node.__key);
|
|
205
|
+
cloned.__contentEditor = node.__contentEditor;
|
|
206
|
+
return cloned;
|
|
207
|
+
}
|
|
208
|
+
getContentEditor() {
|
|
209
|
+
return this.__contentEditor;
|
|
210
|
+
}
|
|
211
|
+
static importJSON(serializedNode) {
|
|
212
|
+
return new _NestedDocEditNode(serializedNode.content);
|
|
213
|
+
}
|
|
214
|
+
exportJSON() {
|
|
215
|
+
return {
|
|
216
|
+
...super.exportJSON(),
|
|
217
|
+
type: "nested-doc",
|
|
218
|
+
content: this.__contentEditor.getEditorState().toJSON(),
|
|
219
|
+
version: 1
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
decorate(_editor, _config) {
|
|
223
|
+
return createElement(NestedDocEditDecorator, {
|
|
224
|
+
nodeKey: this.__key,
|
|
225
|
+
contentEditor: this.__contentEditor,
|
|
226
|
+
contentState: this.__contentState
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
__publicField(_NestedDocEditNode, "commandItems", [
|
|
231
|
+
{
|
|
232
|
+
title: "Nested Document",
|
|
233
|
+
icon: createElement(FileText, { size: 20 }),
|
|
234
|
+
description: "Embed a collapsible nested document",
|
|
235
|
+
keywords: ["nested", "document", "nested-doc", "embed"],
|
|
236
|
+
section: "ADVANCED",
|
|
237
|
+
placement: ["slash", "toolbar"],
|
|
238
|
+
group: "insert",
|
|
239
|
+
onSelect: (editor) => {
|
|
240
|
+
editor.update(() => {
|
|
241
|
+
$insertNodes([$createNestedDocEditNode()]);
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
]);
|
|
246
|
+
let NestedDocEditNode = _NestedDocEditNode;
|
|
247
|
+
function $createNestedDocEditNode(contentState) {
|
|
248
|
+
return new NestedDocEditNode(contentState);
|
|
249
|
+
}
|
|
250
|
+
function $isNestedDocEditNode(node) {
|
|
251
|
+
return node instanceof NestedDocEditNode;
|
|
252
|
+
}
|
|
253
|
+
const INSERT_NESTED_DOC_COMMAND = createCommand("INSERT_NESTED_DOC");
|
|
254
|
+
function NestedDocPlugin() {
|
|
255
|
+
const [editor] = useLexicalComposerContext();
|
|
256
|
+
useEffect(() => {
|
|
257
|
+
return editor.registerCommand(
|
|
258
|
+
INSERT_NESTED_DOC_COMMAND,
|
|
259
|
+
(contentState) => {
|
|
260
|
+
$insertNodes([$createNestedDocEditNode(contentState || void 0)]);
|
|
261
|
+
return true;
|
|
262
|
+
},
|
|
263
|
+
COMMAND_PRIORITY_EDITOR
|
|
264
|
+
);
|
|
265
|
+
}, [editor]);
|
|
266
|
+
return null;
|
|
267
|
+
}
|
|
268
|
+
const nestedDocNodes = [NestedDocNode];
|
|
269
|
+
const nestedDocEditNodes = [NestedDocEditNode];
|
|
270
|
+
export {
|
|
271
|
+
$createNestedDocEditNode,
|
|
272
|
+
r as $createNestedDocNode,
|
|
273
|
+
$isNestedDocEditNode,
|
|
274
|
+
$isNestedDocNode,
|
|
275
|
+
INSERT_NESTED_DOC_COMMAND,
|
|
276
|
+
u as NESTED_DOC_BLOCK_TRANSFORMER,
|
|
277
|
+
NestedDocDialogEditorProvider,
|
|
278
|
+
NestedDocEditDecorator,
|
|
279
|
+
NestedDocEditNode,
|
|
280
|
+
NestedDocNode,
|
|
281
|
+
NestedDocPlugin,
|
|
282
|
+
NestedDocRenderer,
|
|
283
|
+
v as NestedDocStaticDecorator,
|
|
284
|
+
nestedDocEditNodes,
|
|
285
|
+
nestedDocNodes,
|
|
286
|
+
useNestedDocDialogEditor
|
|
287
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:root{--rc-text: #000;--rc-text-secondary: #27272a;--rc-text-tertiary: #71717a;--rc-text-quaternary: #a1a1aa;--rc-bg: #ffffff;--rc-bg-secondary: #fafafa;--rc-bg-tertiary: #f4f4f5;--rc-fill: #e8e8ec;--rc-fill-secondary: #eeeeef;--rc-fill-tertiary: #f4f4f6;--rc-fill-quaternary: #f9f9fa;--rc-border: #f4f4f5;--rc-accent: #2563eb;--rc-accent-light: #2563eb20;--rc-link: #2563eb;--rc-code-text: #3f3f46;--rc-code-bg: #f4f4f5;--rc-hr-border: #e4e4e7;--rc-quote-border: #2563eb;--rc-quote-bg: #eff6ff;--rc-alert-info: #006bb7;--rc-alert-warning: #cc5500;--rc-alert-tip: #11cc00;--rc-alert-caution: #cc0011;--rc-alert-important: #5500cc;--rc-max-width: 700px;--rc-shadow-top-bar: 0 8px 30px rgba(0, 0, 0, .12), 0 2px 8px rgba(0, 0, 0, .06);--rc-shadow-modal: 0 10px 15px -3px rgba(0,0,0,.1), 0 4px 6px -4px rgba(0,0,0,.1);--rc-shadow-menu: 0 1px 4px rgba(0,0,0,.04), 0 4px 16px rgba(0,0,0,.08);--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-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{--rc-text: #fafafa;--rc-text-secondary: #a1a1aa;--rc-text-tertiary: #71717a;--rc-text-quaternary: #52525b;--rc-bg: #09090b;--rc-bg-secondary: #18181b;--rc-bg-tertiary: #27272a;--rc-fill: #2a2a2f;--rc-fill-secondary: #222226;--rc-fill-tertiary: #1b1b1f;--rc-fill-quaternary: #131316;--rc-border: #27272a;--rc-accent: #60a5fa;--rc-accent-light: #60a5fa20;--rc-link: #60a5fa;--rc-code-text: #e4e4e7;--rc-code-bg: #27272a;--rc-hr-border: #27272a;--rc-quote-border: #60a5fa;--rc-quote-bg: #1e3a5f;--rc-alert-info: #7db9e5;--rc-alert-warning: #da864a;--rc-alert-tip: #54da48;--rc-alert-caution: #e16973;--rc-alert-important: #9966e0;--rc-max-width: 700px;--rc-shadow-top-bar: 0 8px 30px rgba(0, 0, 0, .45), 0 2px 8px rgba(0, 0, 0, .3);--rc-shadow-modal: 0 10px 15px -3px rgba(0,0,0,.4), 0 4px 6px -4px rgba(0,0,0,.35);--rc-shadow-menu: 0 1px 4px rgba(0,0,0,.25), 0 4px 16px rgba(0,0,0,.4);--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-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}._1kl9cd60{--rc-text: #000;--rc-text-secondary: #27272a;--rc-text-tertiary: #71717a;--rc-text-quaternary: #a1a1aa;--rc-bg: #ffffff;--rc-bg-secondary: #fafafa;--rc-bg-tertiary: #f4f4f5;--rc-fill: #e8e8ec;--rc-fill-secondary: #eeeeef;--rc-fill-tertiary: #f4f4f6;--rc-fill-quaternary: #f9f9fa;--rc-border: #f4f4f5;--rc-accent: #2563eb;--rc-accent-light: #2563eb20;--rc-link: #2563eb;--rc-code-text: #3f3f46;--rc-code-bg: #f4f4f5;--rc-hr-border: #e4e4e7;--rc-quote-border: #2563eb;--rc-quote-bg: #eff6ff;--rc-alert-info: #006bb7;--rc-alert-warning: #cc5500;--rc-alert-tip: #11cc00;--rc-alert-caution: #cc0011;--rc-alert-important: #5500cc;--rc-max-width: 700px;--rc-shadow-top-bar: 0 8px 30px rgba(0, 0, 0, .12), 0 2px 8px rgba(0, 0, 0, .06);--rc-shadow-modal: 0 10px 15px -3px rgba(0,0,0,.1), 0 4px 6px -4px rgba(0,0,0,.1);--rc-shadow-menu: 0 1px 4px rgba(0,0,0,.04), 0 4px 16px rgba(0,0,0,.08);--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-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}._1kl9cd61{--rc-text: #000;--rc-text-secondary: #27272a;--rc-text-tertiary: #71717a;--rc-text-quaternary: #a1a1aa;--rc-bg: #ffffff;--rc-bg-secondary: #fafafa;--rc-bg-tertiary: #f4f4f5;--rc-fill: #e8e8ec;--rc-fill-secondary: #eeeeef;--rc-fill-tertiary: #f4f4f6;--rc-fill-quaternary: #f9f9fa;--rc-border: #f4f4f5;--rc-accent: #2563eb;--rc-accent-light: #2563eb20;--rc-link: #2563eb;--rc-code-text: #3f3f46;--rc-code-bg: #f4f4f5;--rc-hr-border: #e4e4e7;--rc-quote-border: #2563eb;--rc-quote-bg: #eff6ff;--rc-alert-info: #006bb7;--rc-alert-warning: #cc5500;--rc-alert-tip: #11cc00;--rc-alert-caution: #cc0011;--rc-alert-important: #5500cc;--rc-max-width: 700px;--rc-shadow-top-bar: 0 8px 30px rgba(0, 0, 0, .12), 0 2px 8px rgba(0, 0, 0, .06);--rc-shadow-modal: 0 10px 15px -3px rgba(0,0,0,.1), 0 4px 6px -4px rgba(0,0,0,.1);--rc-shadow-menu: 0 1px 4px rgba(0,0,0,.04), 0 4px 16px rgba(0,0,0,.08);--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-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}._1kl9cd62{--rc-text: #000;--rc-text-secondary: #27272a;--rc-text-tertiary: #71717a;--rc-text-quaternary: #a1a1aa;--rc-bg: #ffffff;--rc-bg-secondary: #fafafa;--rc-bg-tertiary: #f4f4f5;--rc-fill: #e8e8ec;--rc-fill-secondary: #eeeeef;--rc-fill-tertiary: #f4f4f6;--rc-fill-quaternary: #f9f9fa;--rc-border: #f4f4f5;--rc-accent: #2563eb;--rc-accent-light: #2563eb20;--rc-link: #2563eb;--rc-code-text: #3f3f46;--rc-code-bg: #f4f4f5;--rc-hr-border: #e4e4e7;--rc-quote-border: #a1a1aa;--rc-quote-bg: #fafafa;--rc-alert-info: #006bb7;--rc-alert-warning: #cc5500;--rc-alert-tip: #11cc00;--rc-alert-caution: #cc0011;--rc-alert-important: #5500cc;--rc-max-width: none;--rc-shadow-top-bar: 0 8px 30px rgba(0, 0, 0, .12), 0 2px 8px rgba(0, 0, 0, .06);--rc-shadow-modal: 0 10px 15px -3px rgba(0,0,0,.1), 0 4px 6px -4px rgba(0,0,0,.1);--rc-shadow-menu: 0 1px 4px rgba(0,0,0,.04), 0 4px 16px rgba(0,0,0,.08);--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-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: 8px}.dark ._1kl9cd60,[data-theme=dark] ._1kl9cd60,.dark._1kl9cd60,[data-theme=dark]._1kl9cd60,.dark ._1kl9cd61,[data-theme=dark] ._1kl9cd61,.dark._1kl9cd61,[data-theme=dark]._1kl9cd61,.dark ._1kl9cd62,[data-theme=dark] ._1kl9cd62,.dark._1kl9cd62,[data-theme=dark]._1kl9cd62{--rc-text: #fafafa;--rc-text-secondary: #a1a1aa;--rc-text-tertiary: #71717a;--rc-text-quaternary: #52525b;--rc-bg: #09090b;--rc-bg-secondary: #18181b;--rc-bg-tertiary: #27272a;--rc-fill: #2a2a2f;--rc-fill-secondary: #222226;--rc-fill-tertiary: #1b1b1f;--rc-fill-quaternary: #131316;--rc-border: #27272a;--rc-accent: #60a5fa;--rc-accent-light: #60a5fa20;--rc-link: #60a5fa;--rc-code-text: #e4e4e7;--rc-code-bg: #27272a;--rc-hr-border: #27272a;--rc-quote-border: #60a5fa;--rc-quote-bg: #1e3a5f;--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 rgba(0, 0, 0, .45), 0 2px 8px rgba(0, 0, 0, .3);--rc-shadow-modal: 0 10px 15px -3px rgba(0,0,0,.4), 0 4px 6px -4px rgba(0,0,0,.35);--rc-shadow-menu: 0 1px 4px rgba(0,0,0,.25), 0 4px 16px rgba(0,0,0,.4)}@keyframes ds1tv41{to{--rc-hl-highlighted: 1}}@keyframes ds1tv42{0%{background-color:#ef44443d}to{background-color:transparent}}.ds1tv40{font-family:var(--rc-font-family);font-size:var(--rc-font-size-base);line-height:var(--rc-line-height);color:var(--rc-text);word-wrap:break-word;overflow-wrap:break-word}.ds1tv40 .rich-paragraph{margin:0 0 1em;line-height:var(--rc-line-height)}.ds1tv40 .rich-text-bold{font-weight:700}.ds1tv40 .rich-text-italic{font-style:italic}.ds1tv40 .rich-text-underline{text-decoration:underline}.ds1tv40 .rich-text-strikethrough{text-decoration:line-through}.ds1tv40 .rich-text-superscript{vertical-align:super;font-size:.8em}.ds1tv40 .rich-text-subscript{vertical-align:sub;font-size:.8em}.ds1tv40 .rich-text-code{font-family:var(--rc-font-mono);font-size:.9em;background-color:var(--rc-code-bg);color:var(--rc-code-text);padding:2px 6px;border-radius:var(--rc-radius-sm);border:1px solid var(--rc-border)}.ds1tv40 mark{background:transparent}.ds1tv40 .rich-text-highlight{--rc-hl-lightness: .3;--rc-hl-highlighted: 1;--rc-hl-color: oklch(from var(--rc-accent) l c h / var(--rc-hl-lightness));background:linear-gradient(120deg,var(--rc-hl-color, lightblue) 50%,transparent 50%) 110% 0 / 200% 100% no-repeat;background-position:calc((1 - var(--rc-hl-highlighted)) * 110%) 0;color:var(--rc-text);transition:background-position 1s}[contenteditable=true] .rich-text-highlight{--rc-hl-highlighted: 1;animation:none}[data-theme=dark] .ds1tv40 .rich-text-highlight{--rc-hl-lightness: .35}.ds1tv40 :is(.rich-heading-h1,.rich-heading-h2,.rich-heading-h3,.rich-heading-h4,.rich-heading-h5,.rich-heading-h6){position:relative}.ds1tv40 .rich-heading-anchor{position:absolute;left:-1.25rem;top:0;bottom:0;display:flex;align-items:center;text-decoration:none;color:var(--rc-text-secondary);opacity:0;transition:opacity .15s ease;font-size:.8rem}.ds1tv40 .rich-heading-anchor svg{flex-shrink:0}.ds1tv40 :is(.rich-heading-h1,.rich-heading-h2,.rich-heading-h3,.rich-heading-h4,.rich-heading-h5,.rich-heading-h6):hover .rich-heading-anchor{opacity:.5}.ds1tv40 :is(.rich-heading-h1,.rich-heading-h2,.rich-heading-h3,.rich-heading-h4,.rich-heading-h5,.rich-heading-h6):hover .rich-heading-anchor:hover{opacity:1}[contenteditable=true] .rich-heading-h1:before,[contenteditable=true] .rich-heading-h2:before,[contenteditable=true] .rich-heading-h3:before,[contenteditable=true] .rich-heading-h4:before,[contenteditable=true] .rich-heading-h5:before,[contenteditable=true] .rich-heading-h6:before{position:absolute;left:-1.5rem;bottom:.5rem;display:flex;font-size:.5rem;font-weight:600;color:var(--rc-text-secondary);opacity:.6;pointer-events:none;font-family:var(--rc-font-mono)}[contenteditable=true] .rich-heading-h1:before{content:"H1"}[contenteditable=true] .rich-heading-h2:before{content:"H2"}[contenteditable=true] .rich-heading-h3:before{content:"H3"}[contenteditable=true] .rich-heading-h4:before{content:"H4"}[contenteditable=true] .rich-heading-h5:before{content:"H5"}[contenteditable=true] .rich-heading-h6:before{content:"H6"}.ds1tv40 .rich-heading-h1{font-size:2em;font-weight:700;line-height:var(--rc-line-height-tight);margin-top:1.5em;margin-bottom:.5em}.ds1tv40 .rich-heading-h2{font-size:1.5em;font-weight:700;line-height:var(--rc-line-height-tight);margin-top:1.4em;margin-bottom:.45em}.ds1tv40 .rich-heading-h3{font-size:1.25em;font-weight:600;line-height:var(--rc-line-height-tight);margin-top:1.3em;margin-bottom:.4em}.ds1tv40 .rich-heading-h4{font-size:1.125em;font-weight:600;line-height:var(--rc-line-height-tight);margin-top:1.2em;margin-bottom:.35em}.ds1tv40 .rich-heading-h5{font-size:1em;font-weight:600;line-height:var(--rc-line-height-tight);margin-top:1.1em;margin-bottom:.3em}.ds1tv40 .rich-heading-h6{font-size:.875em;font-weight:600;line-height:var(--rc-line-height-tight);margin-top:1em;margin-bottom:.25em;color:var(--rc-text)}.ds1tv40 .rich-link{color:var(--rc-link);text-decoration:none;transition:color .2s ease}.ds1tv40 .rich-link:hover{text-decoration:underline}.ds1tv40 .rich-link[data-favicon=loaded]:before{content:"";display:inline-block;width:1em;height:1em;margin-right:.2em;vertical-align:-.125em;background-image:var(--rc-link-favicon);background-size:contain;background-repeat:no-repeat;background-position:center;border-radius:2px}.ds1tv40 .rich-link-favicon{display:inline-flex;align-items:center;margin-right:.15em;vertical-align:-.125em}.ds1tv40 .rich-link-favicon img{width:1em;height:1em;border-radius:2px;object-fit:contain}.ds1tv40 .rich-link-favicon svg{width:.9em;height:.9em}.ds1tv40 .rich-list-ol{list-style-type:decimal;padding-left:var(--rc-space-lg);margin-bottom:1em}.ds1tv40 .rich-list-ul{list-style-type:disc;padding-left:var(--rc-space-lg);margin-bottom:1em}.ds1tv40 .rich-list-item{margin-bottom:.25em}.ds1tv40 .rich-list-nested-item{list-style-type:none}.ds1tv40 .rich-list-nested-item .rich-list-ol{list-style-type:lower-alpha}.ds1tv40 .rich-list-nested-item .rich-list-ul{list-style-type:circle}.ds1tv40 .rich-checklist{list-style-type:none;padding-left:0}.ds1tv40 .rich-list-item.rich-list-item-checked,.ds1tv40 .rich-list-item.rich-list-item-unchecked{--rc-cb-size: 1.125rem;position:relative;padding-left:2em;list-style-type:none;outline:none}.ds1tv40 .rich-list-item.rich-list-item-unchecked:before,.ds1tv40 .rich-list-item.rich-list-item-checked:before{content:"";position:absolute;left:0;top:calc((1lh - var(--rc-cb-size)) / 2);width:var(--rc-cb-size);height:var(--rc-cb-size);border:2px solid color-mix(in oklab,var(--rc-text-secondary) 60%,transparent);border-radius:var(--rc-radius-sm);box-sizing:border-box;cursor:pointer;vertical-align:middle;color:var(--rc-text);background-color:transparent;transition:background-color .2s ease,border-color .2s ease,box-shadow .2s ease}[contenteditable=true] .ds1tv40 .rich-list-item.rich-list-item-unchecked:hover:before{border-color:color-mix(in oklab,var(--rc-text-secondary) 80%,transparent)}.ds1tv40 .rich-list-item.rich-list-item-unchecked:after,.ds1tv40 .rich-list-item.rich-list-item-checked:after{content:"";position:absolute;left:0;top:calc((1lh - var(--rc-cb-size)) / 2);width:var(--rc-cb-size);height:var(--rc-cb-size);opacity:0;clip-path:polygon(20% 100%,20% 80%,50% 80%,50% 80%,70% 80%,70% 100%);background-color:#fff;box-sizing:border-box;display:block;pointer-events:none;transform:rotate(45deg);transform-origin:center;transition:clip-path .25s cubic-bezier(.34,1.56,.64,1),opacity .15s}.ds1tv40 .rich-list-item.rich-list-item-checked:before{background-color:var(--rc-accent);border-color:var(--rc-accent);box-shadow:0 0 0 1px var(--rc-accent)}.ds1tv40 .rich-list-item.rich-list-item-checked:after{clip-path:polygon(20% 100%,20% 80%,50% 80%,50% 0%,70% 0%,70% 100%);opacity:1;transform:rotate(45deg) scale(.7)}.ds1tv40 .rich-list-item-checked{text-decoration:line-through;color:var(--rc-text-secondary)}.ds1tv40 .rich-quote{border-left:4px solid var(--rc-quote-border);background-color:var(--rc-quote-bg);margin:var(--rc-space-md) 0;padding:var(--rc-space-sm) var(--rc-space-md);font-style:italic;color:var(--rc-text-secondary);border-radius:0 var(--rc-radius-sm) var(--rc-radius-sm) 0}.ds1tv40 .rich-quote>.rich-paragraph:first-child{margin-top:0}.ds1tv40 .rich-quote>.rich-paragraph:last-child{margin-bottom:0}.ds1tv40 .rich-hr{border:none;border-top:1px solid var(--rc-hr-border);margin:var(--rc-space-lg) auto;width:60px}.ds1tv40 .rich-table-scrollable-wrapper{overflow-x:auto}.ds1tv40 .rich-table{width:100%;border-collapse:separate;border-spacing:0;margin:var(--rc-space-lg) 0;font-size:var(--rc-font-size-small);border:1px solid var(--rc-border);border-radius:var(--rc-radius-md);overflow:hidden}.ds1tv40 .rich-table-cell{border:none;border-bottom:1px solid var(--rc-border);border-right:1px solid var(--rc-border);padding:1.25em var(--rc-space-lg);text-align:left;vertical-align:middle;line-height:1.5}.ds1tv40 .rich-table-cell:last-child{border-right:none}.ds1tv40 .rich-table tbody tr:last-child .rich-table-cell{border-bottom:none}.ds1tv40 .rich-table-cell .rich-paragraph{margin:0;padding:0;line-height:inherit}.ds1tv40 .rich-table-cell>:first-child{margin-top:0}.ds1tv40 .rich-table-cell>:last-child{margin-bottom:0}.ds1tv40 .rich-table-cell-header{border:none;border-bottom:1px solid var(--rc-border);border-right:1px solid var(--rc-border);padding:var(--rc-space-md) var(--rc-space-lg);text-align:left;font-weight:600;font-size:.75em;text-transform:uppercase;letter-spacing:.05em;color:var(--rc-text-secondary);background-color:var(--rc-bg-secondary);vertical-align:middle;line-height:1.5;position:sticky;top:0;z-index:1}.ds1tv40 .rich-table-cell-header:last-child{border-right:none}.ds1tv40 .rich-table-cell-header .rich-paragraph{margin:0;padding:0;line-height:inherit}.ds1tv40 .rich-table-cell-header>:first-child{margin-top:0}.ds1tv40 .rich-table-cell-header>:last-child{margin-bottom:0}.ds1tv40 img{max-width:100%;height:auto;border-radius:var(--rc-radius-md)}.ds1tv40 .rich-spoiler{background-color:var(--rc-text);color:transparent;border-radius:var(--rc-radius-sm);padding-inline:4px;cursor:pointer;transition:background-color .3s ease,color .3s ease;user-select:none}[contenteditable=true] .rich-spoiler{background-color:color-mix(in srgb,var(--rc-text) 30%,transparent);color:inherit;user-select:auto;cursor:text}.ds1tv40 .rich-spoiler:hover,.ds1tv40 .rich-spoiler-revealed{background-color:transparent;color:inherit;user-select:auto}.ds1tv40 .rich-ruby{ruby-position:over;ruby-align:center}.ds1tv40 .rich-ruby-rt{font-size:.58em;line-height:1;color:var(--rc-text-secondary);user-select:none}[contenteditable=true] .rich-ruby[data-ruby]{position:relative;display:inline-block;padding-top:.72em;line-height:1.2}[contenteditable=true] .rich-ruby[data-ruby]:before{content:attr(data-ruby);position:absolute;left:0;right:0;top:0;transform:translateY(-.68em);font-size:.58em;line-height:1;text-align:center;color:var(--rc-text-secondary);pointer-events:none;white-space:nowrap}.ds1tv40 .rich-footnote{vertical-align:super;font-size:.8em}.ds1tv40 .rich-footnote-ref{display:inline-flex;align-items:center;justify-content:center;min-width:1.5em;text-decoration:none;color:var(--rc-accent);background-color:var(--rc-accent-light);border-radius:999px;padding:0 .35em;line-height:1.45;font-weight:600;font-size:.82em;transition:filter .15s ease}.ds1tv40 .rich-footnote-ref:hover{filter:brightness(.96)}.ds1tv40 .rich-footnote-highlight{animation:ds1tv42 1.2s ease-out}.ds1tv40 .rich-footnote-ref-wrapper{position:relative;display:inline}.ds1tv40 .rich-footnote-section{margin-top:var(--rc-space-lg)}.ds1tv40 .rich-footnote-section-divider{border:none;border-top:1px solid var(--rc-border);margin:var(--rc-space-lg) 0 var(--rc-space-md)}.ds1tv40 .rich-footnote-section-list{list-style-type:decimal;padding-left:var(--rc-space-lg);font-size:var(--rc-font-size-small);color:var(--rc-text-secondary);line-height:1.6}.ds1tv40 .rich-footnote-section-item{margin-bottom:var(--rc-space-sm);padding-left:var(--rc-space-xs)}.ds1tv40 .rich-footnote-back-ref{display:inline-flex;align-items:center;margin-left:var(--rc-space-xs);color:var(--rc-accent);text-decoration:none;font-size:.85em;transition:opacity .15s ease;font-family:var(--rc-font-mono)}.ds1tv40 .rich-footnote-back-ref:hover{opacity:.7}.ds1tv40 .rich-footnote-section-item-edit{display:flex;align-items:center;gap:var(--rc-space-sm);list-style-type:none}.ds1tv40 .rich-footnote-section-item-num{flex-shrink:0;color:var(--rc-text-secondary);font-size:var(--rc-font-size-small);font-weight:600;min-width:1.5em}.ds1tv40 .rich-footnote-section-item-input{flex:1;border:1px solid var(--rc-border);border-radius:var(--rc-radius-sm);padding:var(--rc-space-xs) var(--rc-space-sm);font-size:var(--rc-font-size-small);color:var(--rc-text);background-color:transparent;outline:none;transition:border-color .15s ease}.ds1tv40 .rich-footnote-section-item-input:focus{border-color:var(--rc-accent)}.ds1tv40 .rich-footnote-section-item-remove{flex-shrink:0;display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;border:none;background:none;color:var(--rc-text-secondary);cursor:pointer;border-radius:var(--rc-radius-sm);font-size:14px;transition:color .15s ease,background-color .15s ease}.ds1tv40 .rich-footnote-section-item-remove:hover{color:#ef4444;background-color:#ef44441a}.rich-drag-handle{position:absolute;display:flex;align-items:center;justify-content:center;width:20px;height:20px;cursor:grab;border-radius:var(--rc-radius-sm);color:var(--rc-text-secondary);opacity:.4;transition:opacity .15s ease,background-color .15s ease;z-index:10}.rich-drag-handle:hover{opacity:1;background-color:var(--rc-fill-secondary)}.rich-drag-handle:active{cursor:grabbing}.rich-drop-indicator{position:absolute;height:2px;background-color:var(--rc-accent);border-radius:1px;pointer-events:none;z-index:10}.ds1tv40 .rich-alert{margin:2em 0;padding:0 1em;background-color:transparent;border:none;border-radius:0}.ds1tv40>*:first-child,.ds1tv40 .rich-editor__content>*:first-child{margin-top:0}.ds1tv40>*:last-child,.ds1tv40 .rich-editor__content>*:last-child{margin-bottom:0}@supports (animation-timeline: view()){.ds1tv40 .rich-text-highlight{--rc-hl-highlighted: 0;animation:ds1tv41 steps(1) both;animation-timeline:view();animation-range:entry 100% cover 10%}}._1pke0ca0{max-width:var(--rc-max-width);font-size:var(--rc-font-size-base);line-height:1.75;color:var(--rc-text)}._1pke0ca0 .rich-paragraph{margin-top:1.5em;margin-bottom:1.5em}._1pke0ca0 .rich-heading-h1{color:var(--rc-text);font-weight:800;font-size:3em;margin-top:0;margin-bottom:.8333333333333334em;line-height:1}._1pke0ca0 .rich-heading-h2{color:var(--rc-text);font-weight:700;font-size:1.875em;margin-top:1.8666666666666667em;margin-bottom:1.0666666666666667em;line-height:1.3333333}._1pke0ca0 .rich-heading-h3{color:var(--rc-text);font-weight:600;font-size:1.5em;margin-top:1.6666666666666667em;margin-bottom:.6666666666666666em;line-height:1.5}._1pke0ca0 .rich-heading-h4{color:var(--rc-text);font-weight:600;margin-top:2em;margin-bottom:.5em;line-height:1.5625}._1pke0ca0 .rich-heading-h2+*,._1pke0ca0 .rich-heading-h3+*,._1pke0ca0 .rich-heading-h4+*{margin-top:0}._1pke0ca0 .rich-quote{font-weight:500;font-style:italic;color:var(--rc-text);border-left-width:.25rem;border-left-style:solid;border-left-color:var(--rc-quote-border);margin-top:2.5em;margin-bottom:2.5em;padding-left:1.5em;background-color:transparent;border-radius:0;quotes:"“""”""‘""’"}._1pke0ca0 .rich-quote .rich-paragraph:first-of-type:before{content:open-quote}._1pke0ca0 .rich-quote .rich-paragraph:last-of-type:after{content:close-quote}._1pke0ca0 .rich-quote .rich-paragraph:first-child{margin-top:0}._1pke0ca0 .rich-quote .rich-paragraph:last-child{margin-bottom:0}._1pke0ca0 .rich-text-code{color:var(--rc-text);font-weight:600;font-size:.875em;background-color:var(--rc-code-bg);padding:.2em .4em;border-radius:var(--rc-radius-sm);font-family:var(--rc-font-mono)}._1pke0ca0 .rich-text-code:before,._1pke0ca0 .rich-text-code:after{content:"`";color:var(--rc-text-secondary);opacity:.5}._1pke0ca0 .rich-code-block{color:var(--rc-text);background-color:var(--rc-code-bg);border-radius:.375rem;margin-top:2em;margin-bottom:2em;font-size:.875em;line-height:1.75}._1pke0ca0 .rich-code-block pre{padding:1em 1.5em;margin:0}._1pke0ca0 .rich-list-ul,._1pke0ca0 .rich-list-ol{margin-top:1.5em;margin-bottom:1.5em;padding-left:1.75em}._1pke0ca0 .rich-list-item{margin-top:.75em;margin-bottom:.75em;padding-left:.5em}._1pke0ca0 .rich-list-item .rich-paragraph{margin-top:1em;margin-bottom:1em}._1pke0ca0 .rich-list-item>.rich-paragraph:first-child{margin-top:1.5em}._1pke0ca0 .rich-list-item>.rich-paragraph:last-child{margin-bottom:1.5em}._1pke0ca0 .rich-list-ul .rich-list-ul,._1pke0ca0 .rich-list-ul .rich-list-ol,._1pke0ca0 .rich-list-ol .rich-list-ul,._1pke0ca0 .rich-list-ol .rich-list-ol{margin-top:1em;margin-bottom:1em}._1pke0ca0 .rich-table{margin-top:2em;margin-bottom:2em;font-size:.875em;line-height:1.5}._1pke0ca0 .rich-table .rich-paragraph{margin:0;padding:0;line-height:inherit}._1pke0ca0 .rich-image{margin-top:2em;margin-bottom:2em}._1pke0ca0 .rich-image>*{margin-top:0;margin-bottom:0}._1pke0ca0 .rich-image figcaption{color:var(--rc-text-secondary);font-size:.875em;line-height:1.5;margin-top:1em}._1pke0ca0 .rich-hr{border-color:var(--rc-hr-border);border-top-width:1px;width:60px;margin:3.5em auto}._1pke0ca0 .rich-hr+*{margin-top:0}._1pke0ca0 .rich-link{font-weight:500;text-decoration:underline}._1pke0ca0 .rich-banner,._1pke0ca0 .rich-code-snippet,._1pke0ca0 .rich-details{margin:2em 0}._1pke0ca0>*:first-child{margin-top:0}._1pke0ca0>*:last-child{margin-bottom:0}._1iyoz3l0{font-size:var(--rc-font-size-base);line-height:var(--rc-line-height)}._1iyoz3l0 .rich-paragraph{margin-bottom:.6em}._1iyoz3l0 .rich-heading-h1{font-size:1.35em;font-weight:700;margin-top:.8em;margin-bottom:.3em}._1iyoz3l0 .rich-heading-h2{font-size:1.2em;font-weight:700;margin-top:.7em;margin-bottom:.25em}._1iyoz3l0 .rich-heading-h3{font-size:1.1em;font-weight:600;margin-top:.6em;margin-bottom:.2em}._1iyoz3l0 .rich-heading-h4{font-size:1em;font-weight:600;margin-top:.5em;margin-bottom:.15em}._1iyoz3l0 .rich-heading-h5{font-size:.9em;font-weight:600;margin-top:.45em;margin-bottom:.1em}._1iyoz3l0 .rich-heading-h6{font-size:.85em;font-weight:600;margin-top:.4em;margin-bottom:.1em}._1iyoz3l0 .rich-quote{border-left-width:3px;padding:var(--rc-space-sm) var(--rc-space-md);margin:var(--rc-space-sm) 0;font-size:.95em}._1iyoz3l0 .rich-list-ol,._1iyoz3l0 .rich-list-ul{margin-bottom:.6em;padding-left:var(--rc-space-md)}._1iyoz3l0 .rich-list-item{margin-bottom:.1em}._1iyoz3l0 .rich-code-block{margin:var(--rc-space-sm) 0;border-radius:var(--rc-radius-sm);font-size:var(--rc-font-size-small)}._1iyoz3l0 .rich-code-block pre{padding:var(--rc-space-sm)}._1iyoz3l0 .line:before{display:none!important}._1iyoz3l0 .rich-table{margin:var(--rc-space-sm) 0;font-size:var(--rc-font-size-small)}._1iyoz3l0 .rich-table-cell,._1iyoz3l0 .rich-table-cell-header{padding:var(--rc-space-xs) var(--rc-space-sm)}._1iyoz3l0 .rich-image{margin:var(--rc-space-sm) 0}._1iyoz3l0 .rich-image figcaption{font-size:var(--rc-font-size-small)}._1iyoz3l0 .rich-hr{border:none;border-top:1px solid var(--rc-hr-border);margin:var(--rc-space-lg) auto;width:60px}._1iyoz3l0 .rich-alert{padding:var(--rc-space-sm) var(--rc-space-md);padding-left:var(--rc-space-lg);margin:var(--rc-space-sm) 0}._1iyoz3l0 .rich-katex-block{padding:var(--rc-space-sm) 0;margin:var(--rc-space-sm) 0}.g7jfj60{max-width:var(--rc-max-width);font-size:var(--rc-font-size-base);line-height:1.8;color:var(--rc-text)}.g7jfj60>.rich-paragraph,.g7jfj60 .rich-editor__content>.rich-paragraph,.g7jfj60 .rich-content__body>.rich-paragraph{margin-top:1.25em;margin-bottom:1.25em;line-height:1.8}.g7jfj60>.rich-paragraph:first-of-type,.g7jfj60 .rich-editor__content>.rich-paragraph:first-of-type,.g7jfj60 .rich-content__body>.rich-paragraph:first-of-type{margin-top:0;margin-bottom:2rem}.g7jfj60>.rich-paragraph:not(:first-of-type)>[data-lexical-text]:first-child,.g7jfj60 .rich-editor__content>.rich-paragraph:not(:first-of-type)>[data-lexical-text]:first-child,.g7jfj60 .rich-content__body>.rich-paragraph:not(:first-of-type)>[data-lexical-text]:first-child{margin-inline-start:2rem}.g7jfj60>.rich-paragraph:first-of-type:first-letter,.g7jfj60 .rich-content__body>.rich-paragraph:first-of-type:first-letter{float:left;font-size:2.4em;margin-right:.2em;line-height:1}.g7jfj60 .rich-editor__content>.rich-paragraph:first-of-type:first-letter{font-size:1.5em;font-weight:700;color:var(--rc-accent)}.g7jfj60>.rich-paragraph:last-child,.g7jfj60 .rich-editor__content>.rich-paragraph:last-child,.g7jfj60 .rich-content__body>.rich-paragraph:last-child{margin-bottom:0}.g7jfj60 .rich-text-bold{font-family:var(--rc-font-family);font-weight:600;color:var(--rc-text)}.g7jfj60 .rich-heading-h1{font-size:2.25em;font-weight:800;line-height:1.1111111;margin-top:0;margin-bottom:.8888889em;letter-spacing:-.025em;color:var(--rc-text)}.g7jfj60 .rich-heading-h2{font-size:1.5em;font-weight:700;line-height:1.3333333;margin-top:2em;margin-bottom:1em;letter-spacing:-.025em;color:var(--rc-text)}.g7jfj60 .rich-heading-h2+*{margin-top:0}.g7jfj60 .rich-heading-h3{font-size:1.25em;font-weight:600;line-height:1.6;margin-top:1.6em;margin-bottom:.6em;letter-spacing:-.025em;color:var(--rc-text)}.g7jfj60 .rich-heading-h3+*{margin-top:0}.g7jfj60 .rich-heading-h4{font-size:1.125em;font-weight:600;line-height:1.5;margin-top:1.5em;margin-bottom:.5em;color:var(--rc-text)}.g7jfj60 .rich-heading-h4+*{margin-top:0}.g7jfj60 .rich-heading-h5{font-size:1em;font-weight:600;line-height:1.5;margin-top:1.5em;margin-bottom:.5em;color:var(--rc-text)}.g7jfj60 .rich-heading-h5+*{margin-top:0}.g7jfj60 .rich-heading-h6{font-size:.875em;font-weight:600;line-height:1.5;margin-top:1.5em;margin-bottom:.5em;color:var(--rc-text);text-transform:uppercase}.g7jfj60 .rich-heading-h6+*{margin-top:0}.g7jfj60 .rich-quote{font-style:normal;line-height:1.8;color:inherit;border-left:none;background-color:color-mix(in srgb,var(--rc-accent) 10%,transparent);margin-top:1.6em;margin-bottom:1.6em;margin-left:-1rem;margin-right:-1rem;padding:1em 2em;border-radius:0}.g7jfj60 .rich-quote .rich-paragraph:first-child:first-letter{float:none;font-size:inherit;margin-right:0}.g7jfj60 .rich-link{font-weight:500;text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:2px;transition:color .15s ease}.g7jfj60 .rich-link:hover{text-decoration-thickness:2px}.g7jfj60 .rich-text-code{font-size:.875em;font-family:var(--rc-font-mono);font-weight:500;padding:.2em .4em;border-radius:var(--rc-radius-sm);background-color:var(--rc-code-bg)}.g7jfj60 .rich-list-ol,.g7jfj60 .rich-list-ul{margin-top:1.25em;margin-bottom:1.25em;padding-left:1.625em}.g7jfj60 .rich-list-ol{list-style-type:decimal}.g7jfj60 .rich-list-ul{list-style-type:disc}.g7jfj60 .rich-list-item{margin-top:.5em;margin-bottom:.5em;padding-left:.375em}.g7jfj60 .rich-list-item::marker{color:var(--rc-text-secondary)}.g7jfj60 .rich-code-block{font-size:.875em;line-height:1.7142857;margin-top:1.7142857em;margin-bottom:1.7142857em;border-radius:var(--rc-radius-md);overflow-x:auto}.g7jfj60 .rich-code-block pre{padding:.8571429em 1.1428571em;margin:0}.g7jfj60 .rich-table{margin-top:2em;margin-bottom:2em;font-size:.875em;line-height:1.7142857}.g7jfj60 .rich-table .rich-paragraph{margin:0;padding:0;line-height:inherit}.g7jfj60 .rich-table .rich-paragraph:first-child:first-letter{float:none;font-size:inherit;margin-right:0}.g7jfj60 .rich-image{margin-top:2em;margin-bottom:2em}.g7jfj60 .rich-image img{border-radius:var(--rc-radius-md)}.g7jfj60 .rich-image figcaption{font-size:.875em;line-height:1.4285714;margin-top:.8571429em;color:var(--rc-text-secondary);text-align:center}.g7jfj60 .rich-hr{border:none;border-top:1px solid var(--rc-hr-border);opacity:.2;margin-top:.5rem;margin-bottom:.5rem;width:60px;margin-left:auto;margin-right:auto}.g7jfj60 .rich-katex-block{margin-top:1.6em;margin-bottom:1.6em;overflow-x:auto;padding:1em 0}.g7jfj60 .rich-spoiler{border-radius:var(--rc-radius-sm);padding-inline:.25em}.g7jfj60>*:first-child{margin-top:0}.g7jfj60>*:last-child{margin-bottom:0}._1an6v8d0{position:relative;display:block;cursor:pointer;margin:var(--rc-space-md) 0;border-radius:var(--rc-radius-md);border:1px solid var(--rc-border);overflow:clip}._1an6v8d1{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:#00000059;color:#fff;opacity:0;pointer-events:none;transition:opacity .2s,background .2s}._1an6v8d0:hover ._1an6v8d1{opacity:1;background:#00000080}.ds1tv40 .rich-nested-doc-content{padding:var(--rc-space-md);max-height:400px;overflow:clip}._1an6v8d2._1an6v8d2{padding:0;gap:0;width:700px;max-width:90vw;max-height:min(900px,calc(100vh - 1rem));overflow:hidden}._1an6v8d3{display:grid;grid-template-rows:auto minmax(0,1fr) auto;height:min(800px,calc(100vh - 1rem));background:var(--rc-bg)}._1an6v8d4{display:grid;gap:0;padding:.75rem 3rem .75rem .875rem;border-bottom:1px solid var(--rc-border);background:linear-gradient(180deg,color-mix(in srgb,var(--rc-text) 3%,transparent),transparent)}._1an6v8d5{display:flex;align-items:center;gap:.75rem}._1an6v8d6{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:var(--rc-radius-sm);background:color-mix(in srgb,var(--rc-accent) 14%,transparent);color:var(--rc-text);flex-shrink:0}._1an6v8d7{min-width:0}._1an6v8d8{margin:0;font-size:1.125rem;font-weight:700;line-height:1.1;color:var(--rc-text)}._1an6v8d9{padding:0 .75rem .5rem;border-bottom:1px solid var(--rc-border);background:var(--rc-bg)}._1an6v8da{margin:0;max-width:none;border-radius:0;position:sticky;top:0}._1an6v8da{border:none;box-shadow:none;background-color:transparent;backdrop-filter:none}._1an6v8da>div{padding-inline:0}._1an6v8db{min-height:0;overflow:hidden;background:linear-gradient(180deg,color-mix(in srgb,var(--rc-text) 2%,transparent),transparent)}._1an6v8db .rich-editor{display:flex;flex-direction:column;height:100%}._1an6v8db .ds1tv40>*:first-child{border-top:none;border-left:none;border-right:none;box-shadow:none;border-radius:0;margin:0;max-width:none;backdrop-filter:none;background-color:transparent}._1an6v8dc{height:100%;overflow-y:auto;overflow-x:hidden;scrollbar-gutter:stable both-edges}._1an6v8dd{display:flex;min-height:100%;background:var(--rc-bg);overflow:hidden}._1an6v8de{flex:1;min-height:460px;padding:1.25rem 1.5rem 1.75rem;outline:none;overflow:visible}._1an6v8df{display:flex;align-items:center;justify-content:flex-end;gap:1rem;padding:.875rem 1.25rem 1rem;border-top:1px solid var(--rc-border);background:color-mix(in srgb,var(--rc-text) 2%,transparent)}._1an6v8dg{display:flex;align-items:center;gap:.625rem;flex-shrink:0}._1an6v8dh{display:inline-flex;align-items:center;justify-content:center;gap:.45rem;height:36px;padding:0 .875rem;border-radius:var(--rc-radius-sm);border:1px solid transparent;font-size:var(--rc-font-size-xs);font-weight:600;cursor:pointer;transition:background-color .15s ease,border-color .15s ease,color .15s ease}._1an6v8di{border-color:var(--rc-border);background:var(--rc-bg);color:var(--rc-text-secondary)}._1an6v8di:hover{background:var(--rc-fill-secondary);color:var(--rc-text)}._1an6v8dj{background:var(--rc-text);color:var(--rc-bg)}._1an6v8dj:hover{background:color-mix(in srgb,var(--rc-text) 86%,transparent)}._1an6v8dk{position:relative;display:block;cursor:pointer;margin:var(--rc-space-md) 0;border-radius:var(--rc-radius-md);border:1px solid var(--rc-border);overflow:clip}._1an6v8dl{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:#00000040;color:#fff;opacity:0;pointer-events:none;transition:opacity .2s;z-index:1}._1an6v8dk:hover ._1an6v8dl{opacity:1}._1an6v8dm{position:absolute;bottom:0;left:0;right:0;height:4rem;background:linear-gradient(to bottom,transparent,var(--rc-bg));pointer-events:none}._1an6v8dn._1an6v8dn{display:flex;flex-direction:column;width:700px;max-width:90vw;height:min(800px,calc(100vh - 2rem));max-height:min(800px,calc(100vh - 2rem));overflow:hidden}._1an6v8do{flex:1;min-height:0;margin:-1.5rem;padding:1.5rem;overflow-y:auto;overflow-x:hidden}._1an6v8dp{pointer-events:none}._1an6v8dq{margin:0;color:var(--rc-text-secondary);font-size:var(--rc-font-size-md);opacity:.72}._1an6v8de .rich-paragraph:first-child,._1an6v8dp .rich-paragraph:first-child{margin-top:0}._1an6v8dp .rich-paragraph:last-child{margin-bottom:0}
|
package/dist/static.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Klass, LexicalNode } from 'lexical';
|
|
2
|
+
export type { SerializedNestedDocNode } from './NestedDocNode';
|
|
3
|
+
export { $createNestedDocNode, $isNestedDocNode, NestedDocNode, } from './NestedDocNode';
|
|
4
|
+
export { NestedDocRenderer } from './NestedDocRenderer';
|
|
5
|
+
export { NestedDocStaticDecorator } from './NestedDocStaticDecorator';
|
|
6
|
+
export { NESTED_DOC_BLOCK_TRANSFORMER } from './transformer';
|
|
7
|
+
export declare const nestedDocNodes: Array<Klass<LexicalNode>>;
|
|
8
|
+
//# sourceMappingURL=static.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"static.d.ts","sourceRoot":"","sources":["../src/static.ts"],"names":[],"mappings":"AAAA,OAAO,iBAAiB,CAAA;AAExB,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAIjD,YAAY,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAA;AAC9D,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,aAAa,GACd,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AACvD,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAA;AACrE,OAAO,EAAE,4BAA4B,EAAE,MAAM,eAAe,CAAA;AAE5D,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,CAAmB,CAAA"}
|
package/dist/static.mjs
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { q as NestedDocNode } from "./transformer-CqZLVEDu.js";
|
|
2
|
+
import { r, $, u, N, v } from "./transformer-CqZLVEDu.js";
|
|
3
|
+
const nestedDocNodes = [NestedDocNode];
|
|
4
|
+
export {
|
|
5
|
+
r as $createNestedDocNode,
|
|
6
|
+
$ as $isNestedDocNode,
|
|
7
|
+
u as NESTED_DOC_BLOCK_TRANSFORMER,
|
|
8
|
+
NestedDocNode,
|
|
9
|
+
N as NestedDocRenderer,
|
|
10
|
+
v as NestedDocStaticDecorator,
|
|
11
|
+
nestedDocNodes
|
|
12
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export declare const editOverlayRoot: string;
|
|
2
|
+
export declare const editOverlay: string;
|
|
3
|
+
export declare const dialogPopup: string;
|
|
4
|
+
export declare const dialogShell: string;
|
|
5
|
+
export declare const dialogHeader: string;
|
|
6
|
+
export declare const dialogHeaderMain: string;
|
|
7
|
+
export declare const dialogHeaderIcon: string;
|
|
8
|
+
export declare const dialogHeaderText: string;
|
|
9
|
+
export declare const dialogTitle: string;
|
|
10
|
+
export declare const dialogToolbarSection: string;
|
|
11
|
+
export declare const dialogToolbar: string;
|
|
12
|
+
export declare const editorArea: string;
|
|
13
|
+
export declare const editorScrollContainer: string;
|
|
14
|
+
export declare const editorCard: string;
|
|
15
|
+
export declare const editorEditable: string;
|
|
16
|
+
export declare const dialogFooter: string;
|
|
17
|
+
export declare const dialogActions: string;
|
|
18
|
+
export declare const secondaryButton: string;
|
|
19
|
+
export declare const primaryButton: string;
|
|
20
|
+
export declare const staticOverlayRoot: string;
|
|
21
|
+
export declare const staticOverlay: string;
|
|
22
|
+
export declare const staticGradientMask: string;
|
|
23
|
+
export declare const staticDialogPopup: string;
|
|
24
|
+
export declare const staticDialogBody: string;
|
|
25
|
+
export declare const previewSurface: string;
|
|
26
|
+
export declare const previewEmpty: string;
|
|
27
|
+
//# sourceMappingURL=styles.css.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styles.css.d.ts","sourceRoot":"","sources":["../src/styles.css.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,eAAe,QAQ1B,CAAA;AAEF,eAAO,MAAM,WAAW,QAiBtB,CAAA;AAQF,eAAO,MAAM,WAAW,QAAY,CAAA;AAWpC,eAAO,MAAM,WAAW,QAKtB,CAAA;AAEF,eAAO,MAAM,YAAY,QAMvB,CAAA;AAEF,eAAO,MAAM,gBAAgB,QAI3B,CAAA;AAEF,eAAO,MAAM,gBAAgB,QAU3B,CAAA;AAEF,eAAO,MAAM,gBAAgB,QAE3B,CAAA;AAEF,eAAO,MAAM,WAAW,QAMtB,CAAA;AAEF,eAAO,MAAM,oBAAoB,QAI/B,CAAA;AAEF,eAAO,MAAM,aAAa,QAMxB,CAAA;AAaF,eAAO,MAAM,UAAU,QAKrB,CAAA;AAoBF,eAAO,MAAM,qBAAqB,QAKhC,CAAA;AAEF,eAAO,MAAM,UAAU,QAKrB,CAAA;AAEF,eAAO,MAAM,cAAc,QAMzB,CAAA;AAEF,eAAO,MAAM,YAAY,QAQvB,CAAA;AAEF,eAAO,MAAM,aAAa,QAKxB,CAAA;AAkBF,eAAO,MAAM,eAAe,QAa1B,CAAA;AAEF,eAAO,MAAM,aAAa,QAWxB,CAAA;AAEF,eAAO,MAAM,iBAAiB,QAQ5B,CAAA;AAEF,eAAO,MAAM,aAAa,QAiBxB,CAAA;AAEF,eAAO,MAAM,kBAAkB,QAQ7B,CAAA;AAEF,eAAO,MAAM,iBAAiB,QAAY,CAAA;AAY1C,eAAO,MAAM,gBAAgB,QAO3B,CAAA;AAEF,eAAO,MAAM,cAAc,QAEzB,CAAA;AAEF,eAAO,MAAM,YAAY,QAKvB,CAAA"}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
|
+
import { extractTextContent as extractTextContent$1 } from "@haklex/rich-editor";
|
|
5
|
+
import { useOptionalNestedContentRenderer, useVariant, useColorScheme, extractTextContent } from "@haklex/rich-editor/static";
|
|
6
|
+
import { DecoratorNode } from "lexical";
|
|
7
|
+
import { useMemo, useCallback, createElement } from "react";
|
|
8
|
+
import { jsx, Fragment, jsxs } from "react/jsx-runtime";
|
|
9
|
+
import { usePortalTheme } from "@haklex/rich-style-token";
|
|
10
|
+
import { Maximize2 } from "lucide-react";
|
|
11
|
+
import { RichRenderer } from "@haklex/rich-static-renderer";
|
|
12
|
+
var editOverlayRoot = "_1an6v8d0";
|
|
13
|
+
var editOverlay = "_1an6v8d1";
|
|
14
|
+
var dialogPopup = "_1an6v8d2";
|
|
15
|
+
var dialogShell = "_1an6v8d3";
|
|
16
|
+
var dialogHeader = "_1an6v8d4";
|
|
17
|
+
var dialogHeaderMain = "_1an6v8d5";
|
|
18
|
+
var dialogHeaderIcon = "_1an6v8d6";
|
|
19
|
+
var dialogHeaderText = "_1an6v8d7";
|
|
20
|
+
var dialogTitle = "_1an6v8d8";
|
|
21
|
+
var editorArea = "_1an6v8db";
|
|
22
|
+
var dialogFooter = "_1an6v8df";
|
|
23
|
+
var dialogActions = "_1an6v8dg";
|
|
24
|
+
var secondaryButton = "_1an6v8di _1an6v8dh";
|
|
25
|
+
var primaryButton = "_1an6v8dj _1an6v8dh";
|
|
26
|
+
var staticOverlayRoot = "_1an6v8dk";
|
|
27
|
+
var staticOverlay = "_1an6v8dl";
|
|
28
|
+
var staticGradientMask = "_1an6v8dm";
|
|
29
|
+
var staticDialogPopup = "_1an6v8dn";
|
|
30
|
+
var staticDialogBody = "_1an6v8do";
|
|
31
|
+
var previewSurface = "_1an6v8dp";
|
|
32
|
+
var previewEmpty = "_1an6v8dq";
|
|
33
|
+
function NestedDocRenderer({ value }) {
|
|
34
|
+
const renderNestedContent = useOptionalNestedContentRenderer();
|
|
35
|
+
const variant = useVariant();
|
|
36
|
+
const theme = useColorScheme();
|
|
37
|
+
if (renderNestedContent) {
|
|
38
|
+
return /* @__PURE__ */ jsx(Fragment, { children: renderNestedContent(value) });
|
|
39
|
+
}
|
|
40
|
+
return /* @__PURE__ */ jsx(RichRenderer, { value, variant, theme });
|
|
41
|
+
}
|
|
42
|
+
function truncateEditorState(state, maxNodes) {
|
|
43
|
+
const root = state.root;
|
|
44
|
+
if (!root?.children || root.children.length <= maxNodes) return state;
|
|
45
|
+
return {
|
|
46
|
+
...state,
|
|
47
|
+
root: {
|
|
48
|
+
...root,
|
|
49
|
+
children: root.children.slice(0, maxNodes)
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
function hasRenderableEditorState(state) {
|
|
54
|
+
const children = state.root?.children ?? [];
|
|
55
|
+
if (children.length === 0) return false;
|
|
56
|
+
if (children.length > 1) return true;
|
|
57
|
+
const first = children[0];
|
|
58
|
+
if (!first) return false;
|
|
59
|
+
if (first.type !== "paragraph") return true;
|
|
60
|
+
return first.children?.some((child) => {
|
|
61
|
+
if (child.type !== "text") return true;
|
|
62
|
+
return Boolean(child.text?.trim());
|
|
63
|
+
}) ?? false;
|
|
64
|
+
}
|
|
65
|
+
const PREVIEW_NODE_LIMIT = 6;
|
|
66
|
+
function NestedDocStaticDecorator({
|
|
67
|
+
contentState
|
|
68
|
+
}) {
|
|
69
|
+
const colorScheme = useColorScheme();
|
|
70
|
+
const { className: portalClassName } = usePortalTheme();
|
|
71
|
+
const children = contentState.root?.children ?? [];
|
|
72
|
+
const needsTruncation = children.length > PREVIEW_NODE_LIMIT;
|
|
73
|
+
const previewState = useMemo(
|
|
74
|
+
() => truncateEditorState(contentState, PREVIEW_NODE_LIMIT),
|
|
75
|
+
[contentState]
|
|
76
|
+
);
|
|
77
|
+
const hasPreview = hasRenderableEditorState(contentState);
|
|
78
|
+
const handleOpen = useCallback(async () => {
|
|
79
|
+
const { presentDialog } = await import("@haklex/rich-editor-ui");
|
|
80
|
+
presentDialog({
|
|
81
|
+
content: () => /* @__PURE__ */ jsx("div", { className: staticDialogBody, children: /* @__PURE__ */ jsx(NestedDocRenderer, { value: contentState }) }),
|
|
82
|
+
className: staticDialogPopup,
|
|
83
|
+
portalClassName,
|
|
84
|
+
theme: colorScheme,
|
|
85
|
+
showCloseButton: true,
|
|
86
|
+
clickOutsideToDismiss: true
|
|
87
|
+
});
|
|
88
|
+
}, [colorScheme, contentState, portalClassName]);
|
|
89
|
+
if (!hasPreview) {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
return /* @__PURE__ */ jsxs(
|
|
93
|
+
"div",
|
|
94
|
+
{
|
|
95
|
+
className: staticOverlayRoot,
|
|
96
|
+
onClick: handleOpen,
|
|
97
|
+
role: "button",
|
|
98
|
+
tabIndex: 0,
|
|
99
|
+
onKeyDown: (e) => {
|
|
100
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
101
|
+
e.preventDefault();
|
|
102
|
+
handleOpen();
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
children: [
|
|
106
|
+
/* @__PURE__ */ jsx("div", { className: "rich-nested-doc-content", children: /* @__PURE__ */ jsx("div", { className: previewSurface, children: /* @__PURE__ */ jsx(NestedDocRenderer, { value: previewState }) }) }),
|
|
107
|
+
needsTruncation && /* @__PURE__ */ jsx("div", { className: staticGradientMask, "aria-hidden": true }),
|
|
108
|
+
/* @__PURE__ */ jsx("div", { className: staticOverlay, "aria-hidden": true, children: /* @__PURE__ */ jsx(Maximize2, { size: 24 }) })
|
|
109
|
+
]
|
|
110
|
+
}
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
class NestedDocNode extends DecoratorNode {
|
|
114
|
+
constructor(contentState, key) {
|
|
115
|
+
super(key);
|
|
116
|
+
__publicField(this, "__contentState");
|
|
117
|
+
this.__contentState = contentState || {
|
|
118
|
+
root: {
|
|
119
|
+
children: [
|
|
120
|
+
{
|
|
121
|
+
type: "paragraph",
|
|
122
|
+
children: [],
|
|
123
|
+
direction: null,
|
|
124
|
+
format: "",
|
|
125
|
+
indent: 0,
|
|
126
|
+
textFormat: 0,
|
|
127
|
+
textStyle: "",
|
|
128
|
+
version: 1
|
|
129
|
+
}
|
|
130
|
+
],
|
|
131
|
+
direction: null,
|
|
132
|
+
format: "",
|
|
133
|
+
indent: 0,
|
|
134
|
+
type: "root",
|
|
135
|
+
version: 1
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
static getType() {
|
|
140
|
+
return "nested-doc";
|
|
141
|
+
}
|
|
142
|
+
static clone(node) {
|
|
143
|
+
return new NestedDocNode(node.__contentState, node.__key);
|
|
144
|
+
}
|
|
145
|
+
createDOM(_config) {
|
|
146
|
+
const div = document.createElement("div");
|
|
147
|
+
div.className = "rich-nested-doc";
|
|
148
|
+
return div;
|
|
149
|
+
}
|
|
150
|
+
updateDOM() {
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
isInline() {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
getContentState() {
|
|
157
|
+
return this.getLatest().__contentState;
|
|
158
|
+
}
|
|
159
|
+
setContentState(state) {
|
|
160
|
+
const writable = this.getWritable();
|
|
161
|
+
writable.__contentState = state;
|
|
162
|
+
}
|
|
163
|
+
getTextContent() {
|
|
164
|
+
return extractTextContent(this.__contentState);
|
|
165
|
+
}
|
|
166
|
+
static importJSON(serializedNode) {
|
|
167
|
+
return new NestedDocNode(serializedNode.content);
|
|
168
|
+
}
|
|
169
|
+
exportJSON() {
|
|
170
|
+
return {
|
|
171
|
+
...super.exportJSON(),
|
|
172
|
+
type: "nested-doc",
|
|
173
|
+
content: this.__contentState,
|
|
174
|
+
version: 1
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
decorate(_editor, _config) {
|
|
178
|
+
return createElement(NestedDocStaticDecorator, {
|
|
179
|
+
contentState: this.__contentState
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
function $createNestedDocNode(contentState) {
|
|
184
|
+
return new NestedDocNode(contentState);
|
|
185
|
+
}
|
|
186
|
+
function $isNestedDocNode(node) {
|
|
187
|
+
return node instanceof NestedDocNode;
|
|
188
|
+
}
|
|
189
|
+
const NESTED_DOC_BLOCK_TRANSFORMER = {
|
|
190
|
+
dependencies: [],
|
|
191
|
+
export: (node) => {
|
|
192
|
+
if (!$isNestedDocNode(node)) return null;
|
|
193
|
+
const text = extractTextContent$1(node.getContentState());
|
|
194
|
+
return `<nested-doc>
|
|
195
|
+
${text}
|
|
196
|
+
</nested-doc>`;
|
|
197
|
+
},
|
|
198
|
+
regExp: /a^/,
|
|
199
|
+
replace: () => {
|
|
200
|
+
},
|
|
201
|
+
type: "element"
|
|
202
|
+
};
|
|
203
|
+
export {
|
|
204
|
+
$isNestedDocNode as $,
|
|
205
|
+
NestedDocRenderer as N,
|
|
206
|
+
previewEmpty as a,
|
|
207
|
+
editOverlay as b,
|
|
208
|
+
dialogShell as c,
|
|
209
|
+
dialogPopup as d,
|
|
210
|
+
editOverlayRoot as e,
|
|
211
|
+
dialogHeader as f,
|
|
212
|
+
dialogHeaderMain as g,
|
|
213
|
+
hasRenderableEditorState as h,
|
|
214
|
+
dialogHeaderIcon as i,
|
|
215
|
+
dialogHeaderText as j,
|
|
216
|
+
dialogTitle as k,
|
|
217
|
+
editorArea as l,
|
|
218
|
+
dialogFooter as m,
|
|
219
|
+
dialogActions as n,
|
|
220
|
+
primaryButton as o,
|
|
221
|
+
previewSurface as p,
|
|
222
|
+
NestedDocNode as q,
|
|
223
|
+
$createNestedDocNode as r,
|
|
224
|
+
secondaryButton as s,
|
|
225
|
+
truncateEditorState as t,
|
|
226
|
+
NESTED_DOC_BLOCK_TRANSFORMER as u,
|
|
227
|
+
NestedDocStaticDecorator as v
|
|
228
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transformer.d.ts","sourceRoot":"","sources":["../src/transformer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AAK3D,eAAO,MAAM,4BAA4B,EAAE,kBAU1C,CAAA"}
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { SerializedEditorState } from 'lexical';
|
|
2
|
+
export declare function truncateEditorState(state: SerializedEditorState, maxNodes: number): SerializedEditorState;
|
|
3
|
+
export declare function hasRenderableEditorState(state: SerializedEditorState): boolean;
|
|
4
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAA;AAEpD,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,qBAAqB,EAC5B,QAAQ,EAAE,MAAM,GACf,qBAAqB,CAWvB;AAED,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,qBAAqB,GAC3B,OAAO,CAwBT"}
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@haklex/rich-ext-nested-doc",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "0.0.62",
|
|
5
|
+
"description": "Nested document extension for haklex rich editor",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"import": "./dist/index.mjs",
|
|
10
|
+
"types": "./dist/index.d.ts"
|
|
11
|
+
},
|
|
12
|
+
"./static": {
|
|
13
|
+
"import": "./dist/static.mjs",
|
|
14
|
+
"types": "./dist/static.d.ts"
|
|
15
|
+
},
|
|
16
|
+
"./style.css": "./dist/rich-ext-nested-doc.css"
|
|
17
|
+
},
|
|
18
|
+
"main": "./dist/index.mjs",
|
|
19
|
+
"files": [
|
|
20
|
+
"dist"
|
|
21
|
+
],
|
|
22
|
+
"peerDependencies": {
|
|
23
|
+
"@lexical/react": "^0.41.0",
|
|
24
|
+
"lexical": "^0.41.0",
|
|
25
|
+
"lucide-react": "^0.574.0",
|
|
26
|
+
"react": ">=19",
|
|
27
|
+
"react-dom": ">=19"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@haklex/rich-editor-ui": "0.0.62",
|
|
31
|
+
"@haklex/rich-style-token": "0.0.62",
|
|
32
|
+
"@haklex/rich-editor": "0.0.62",
|
|
33
|
+
"@haklex/rich-static-renderer": "0.0.62"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@lexical/react": "^0.41.0",
|
|
37
|
+
"@types/react": "^19.2.14",
|
|
38
|
+
"@types/react-dom": "^19.2.3",
|
|
39
|
+
"@vanilla-extract/css": "^1.18.0",
|
|
40
|
+
"@vanilla-extract/vite-plugin": "^5.1.4",
|
|
41
|
+
"lexical": "^0.41.0",
|
|
42
|
+
"lucide-react": "^0.577.0",
|
|
43
|
+
"react": "19.2.4",
|
|
44
|
+
"react-dom": "19.2.4",
|
|
45
|
+
"typescript": "^5.9.3",
|
|
46
|
+
"vite": "^7.3.1",
|
|
47
|
+
"vite-plugin-dts": "^4.5.4"
|
|
48
|
+
},
|
|
49
|
+
"publishConfig": {
|
|
50
|
+
"access": "public"
|
|
51
|
+
},
|
|
52
|
+
"scripts": {
|
|
53
|
+
"build": "vite build",
|
|
54
|
+
"dev:build": "vite build --watch"
|
|
55
|
+
},
|
|
56
|
+
"types": "./dist/index.d.ts"
|
|
57
|
+
}
|