@tiny-codes/react-easy 1.4.1 → 1.4.2

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/CHANGELOG.md CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ## 1.4.2
6
+
7
+ 2025-8-10
8
+
9
+ ### Features
10
+
11
+ - ✨ `SelectNode` component now supports `onXXX` event props like `onClick`, `onMouseEnter`, etc.
12
+
5
13
  ## 1.4.1
6
14
 
7
15
  2025-8-10
@@ -223,6 +223,8 @@ export function updateDomProps(dom, props) {
223
223
  });
224
224
  } else if (key === 'className' && value) {
225
225
  dom.className = value;
226
+ } else if (key.startsWith('on') && typeof value === 'function') {
227
+ dom[key.toLowerCase()] = value;
226
228
  } else if (value !== undefined && value !== null) {
227
229
  dom.setAttribute(key, value.toString());
228
230
  }
@@ -1 +1 @@
1
- {"version":3,"names":["$createTextNode","$getRoot","$getSelection","$isDecoratorNode","$isElementNode","$isParagraphNode","$isRangeSelection","$isTextNode","$createDivNode","$isDivNode","insertNodeAtCursor","editor","node","update","selection","lastNode","focus","getNode","append","insertAfter","insertNodes","selectNext","root","nodeToInsert","container","style","display","insertTextAtCursor","text","textNode","insertText","getLastChild","clearEditorContent","state","getEditorState","stateJson","toJSON","newJson","_objectSpread","children","direction","format","indent","type","version","textFormat","textStyle","emptyState","parseEditorState","JSON","stringify","setEditorState","clear","findNode","predicate","matched","findNodes","stopOnFirstMatch","options","read","traverse","result","push","getChildren","_iterator","_createForOfIteratorHelper","_step","s","n","done","child","value","length","err","e","f","updateDomProps","dom","props","Array","from","attributes","forEach","attr","name","startsWith","removeAttribute","Object","entries","_ref","_ref2","_slicedToArray","key","_ref3","_ref4","styleKey","styleValue","undefined","className","setAttribute","toString","updateDomStyle","_ref5","_ref6","getDomAttributes","styles","styleName"],"sources":["../../../../src/components/Lexical/helpers/index.ts"],"sourcesContent":["import type { CSSProperties, HtmlHTMLAttributes } from 'react';\nimport type { LexicalEditor, LexicalNode } from 'lexical';\nimport {\n $createTextNode,\n $getRoot,\n $getSelection,\n $isDecoratorNode,\n $isElementNode,\n $isParagraphNode,\n $isRangeSelection,\n $isTextNode,\n} from 'lexical';\nimport { $createDivNode, $isDivNode } from '../nodes/DivNode';\n\n/**\n * - EN: Insert a node at the current cursor position.\n * - CN: 将节点插入到当前光标位置。\n *\n * @param editor LexicalEditor instance | LexicalEditor 实例\n * @param node Node to insert | 要插入的节点\n */\nexport function insertNodeAtCursor(editor: LexicalEditor, node: LexicalNode): void {\n editor.update(() => {\n const selection = $getSelection();\n if (selection) {\n if ($isRangeSelection(selection)) {\n // 如果没有选取,则直接在根节点末尾插入\n const lastNode = selection.focus.getNode();\n if (lastNode) {\n if ($isParagraphNode(lastNode)) {\n lastNode.append(node);\n } else if ($isTextNode(lastNode)) {\n // 如果最后一个节点是文本节点,则在其后插入 SelectNode\n lastNode.insertAfter(node);\n } else if ($isDivNode(lastNode)) {\n lastNode.append(node);\n } else {\n selection.insertNodes([node]);\n }\n node.selectNext();\n }\n } else {\n selection.insertNodes([node]);\n node.selectNext();\n }\n } else {\n const root = $getRoot();\n let nodeToInsert: LexicalNode = node;\n if ($isElementNode(node) || $isDecoratorNode(node)) {\n nodeToInsert = node;\n } else {\n const container = $createDivNode({\n style: { display: 'inline-block' },\n });\n container.append(node);\n nodeToInsert = container;\n }\n root.append(nodeToInsert);\n node.selectNext();\n }\n });\n}\n\n/**\n * - EN: Insert text at the current cursor position.\n * - CN: 将文本插入到当前光标位置。\n *\n * @param editor LexicalEditor instance | LexicalEditor 实例\n * @param text Text to insert | 要插入的文本\n */\nexport function insertTextAtCursor(editor: LexicalEditor, text: string): void {\n editor?.update(() => {\n const textNode = $createTextNode(text);\n const root = $getRoot();\n const selection = $getSelection();\n if (selection) {\n // 插入光标位置\n selection.insertText(text);\n } else {\n // 如果没有选取,则直接在根节点末尾插入\n const lastNode = root.getLastChild();\n if (lastNode && $isParagraphNode(lastNode)) {\n lastNode.append(textNode);\n } else {\n const container = $createDivNode({\n style: { display: 'inline-block' },\n });\n container.append(textNode);\n root.append(container);\n }\n }\n });\n}\n\n/**\n * - EN: Clear the editor content.\n * - CN: 清空编辑器内容。\n *\n * @param editor LexicalEditor instance | LexicalEditor 实例\n */\nexport function clearEditorContent(editor: LexicalEditor) {\n const state = editor.getEditorState();\n const stateJson = state.toJSON();\n // 默认创建一个ParagraphNode\n const newJson = {\n ...stateJson,\n root: {\n ...stateJson.root,\n children: [\n {\n children: [],\n direction: null,\n format: '',\n indent: 0,\n type: 'paragraph',\n version: 1,\n textFormat: 0,\n textStyle: '',\n },\n ],\n },\n };\n const emptyState = editor.parseEditorState(JSON.stringify(newJson));\n editor.setEditorState(emptyState);\n editor.update(() => {\n const root = $getRoot();\n root.clear();\n });\n}\n\n/**\n * - EN: Find the first node that matches the predicate.\n * - CN: 查找第一个符合条件的节点。\n *\n * @param editor LexicalEditor instance | LexicalEditor 实例\n * @param predicate Function to test whether a node matches | 用于匹配节点的函数\n *\n * @returns The matched node, or undefined | 符合条件的第一个节点,或 undefined\n */\nexport function findNode<T extends LexicalNode>(\n editor: LexicalEditor,\n predicate: (node: LexicalNode) => boolean\n): T | undefined {\n const matched = findNodes<T>(editor, predicate, { stopOnFirstMatch: true });\n return matched[0];\n}\n/**\n * - EN: Find all nodes that match the predicate.\n * - CN: 查找所有符合条件的节点数组。\n *\n * @param editor LexicalEditor instance | LexicalEditor 实例\n * @param predicate Function to test whether a node matches | 用于匹配节点的函数\n * @param options Options | 选项\n *\n * @returns An array of matched nodes | 符合条件的节点数组\n */\nexport function findNodes<T extends LexicalNode>(\n editor: LexicalEditor,\n predicate: (node: LexicalNode) => boolean,\n options?: {\n stopOnFirstMatch?: boolean;\n }\n): T[] {\n const matched: T[] = [];\n editor.getEditorState().read(() => {\n const root = $getRoot();\n const traverse = (node: LexicalNode, result: T[]) => {\n if (predicate(node)) {\n result.push(node as unknown as T);\n if (options?.stopOnFirstMatch) {\n return;\n }\n }\n if ($isElementNode(node)) {\n const children = node.getChildren();\n for (const child of children) {\n traverse(child, result);\n if (options?.stopOnFirstMatch && result.length > 0) {\n return;\n }\n }\n }\n };\n traverse(root, matched);\n });\n return matched;\n}\n\n/**\n * - EN: Update properties on a DOM element.\n * - CN: 更新 DOM 元素的属性。\n *\n * @param dom Target DOM element to update | 要更新的 DOM 元素\n * @param props Props to set on the element | 要设置的属性\n */\nexport function updateDomProps(dom: HTMLElement | undefined, props: HtmlHTMLAttributes<HTMLElement>): void {\n if (!dom) return;\n Array.from(dom.attributes).forEach((attr) => {\n if (!attr.name.startsWith('data-lexical')) {\n dom.removeAttribute(attr.name);\n }\n });\n\n dom.removeAttribute('style');\n dom.removeAttribute('class');\n\n if (props) {\n Object.entries(props).forEach(([key, value]) => {\n if (key === 'style' && value) {\n Object.entries(value as CSSProperties).forEach(([styleKey, styleValue]) => {\n if (styleValue !== undefined) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (dom.style as any)[styleKey] = styleValue;\n }\n });\n } else if (key === 'className' && value) {\n dom.className = value as string;\n } else if (value !== undefined && value !== null) {\n dom.setAttribute(key, value.toString());\n }\n });\n }\n}\n\n/**\n * - EN: Update style on a DOM element.\n * - CN: 更新 DOM 元素的样式。\n *\n * @param dom Target DOM element to update | 要更新的 DOM 元素\n * @param style Style to set | 要设置的样式\n */\nexport function updateDomStyle(dom: HTMLElement | undefined, style: CSSProperties | undefined): void {\n if (!dom) return;\n dom.removeAttribute('style');\n if (style) {\n Object.entries(style).forEach(([styleKey, styleValue]) => {\n if (styleValue !== undefined) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (dom.style as any)[styleKey] = styleValue;\n }\n });\n }\n}\n\n/**\n * - EN: Get attributes from a DOM element.\n * - CN: 从 DOM 元素获取属性。\n *\n * @param dom Target DOM element | 目标 DOM 元素\n *\n * @returns Element attributes | 元素属性\n */\nexport function getDomAttributes(dom: HTMLElement | undefined): HtmlHTMLAttributes<HTMLElement> | undefined {\n if (!dom) return undefined;\n\n const attributes: HtmlHTMLAttributes<HTMLElement> = {};\n Array.from(dom.attributes).forEach((attr) => {\n if (attr.name === 'class' || attr.name === 'style') {\n return;\n }\n attributes[attr.name as keyof HtmlHTMLAttributes<HTMLElement>] = attr.value;\n });\n\n if (dom.className) {\n attributes.className = dom.className;\n }\n\n if (dom.style) {\n const styles: CSSProperties = {};\n Array.from(dom.style).forEach((styleName) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (styles as any)[styleName] = (dom.style as any)[styleName];\n });\n attributes.style = styles;\n }\n\n return attributes;\n}\n"],"mappings":"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"}
1
+ {"version":3,"names":["$createTextNode","$getRoot","$getSelection","$isDecoratorNode","$isElementNode","$isParagraphNode","$isRangeSelection","$isTextNode","$createDivNode","$isDivNode","insertNodeAtCursor","editor","node","update","selection","lastNode","focus","getNode","append","insertAfter","insertNodes","selectNext","root","nodeToInsert","container","style","display","insertTextAtCursor","text","textNode","insertText","getLastChild","clearEditorContent","state","getEditorState","stateJson","toJSON","newJson","_objectSpread","children","direction","format","indent","type","version","textFormat","textStyle","emptyState","parseEditorState","JSON","stringify","setEditorState","clear","findNode","predicate","matched","findNodes","stopOnFirstMatch","options","read","traverse","result","push","getChildren","_iterator","_createForOfIteratorHelper","_step","s","n","done","child","value","length","err","e","f","updateDomProps","dom","props","Array","from","attributes","forEach","attr","name","startsWith","removeAttribute","Object","entries","_ref","_ref2","_slicedToArray","key","_ref3","_ref4","styleKey","styleValue","undefined","className","toLowerCase","setAttribute","toString","updateDomStyle","_ref5","_ref6","getDomAttributes","styles","styleName"],"sources":["../../../../src/components/Lexical/helpers/index.ts"],"sourcesContent":["import type { CSSProperties, HtmlHTMLAttributes } from 'react';\nimport type { LexicalEditor, LexicalNode } from 'lexical';\nimport {\n $createTextNode,\n $getRoot,\n $getSelection,\n $isDecoratorNode,\n $isElementNode,\n $isParagraphNode,\n $isRangeSelection,\n $isTextNode,\n} from 'lexical';\nimport { $createDivNode, $isDivNode } from '../nodes/DivNode';\n\n/**\n * - EN: Insert a node at the current cursor position.\n * - CN: 将节点插入到当前光标位置。\n *\n * @param editor LexicalEditor instance | LexicalEditor 实例\n * @param node Node to insert | 要插入的节点\n */\nexport function insertNodeAtCursor(editor: LexicalEditor, node: LexicalNode): void {\n editor.update(() => {\n const selection = $getSelection();\n if (selection) {\n if ($isRangeSelection(selection)) {\n // 如果没有选取,则直接在根节点末尾插入\n const lastNode = selection.focus.getNode();\n if (lastNode) {\n if ($isParagraphNode(lastNode)) {\n lastNode.append(node);\n } else if ($isTextNode(lastNode)) {\n // 如果最后一个节点是文本节点,则在其后插入 SelectNode\n lastNode.insertAfter(node);\n } else if ($isDivNode(lastNode)) {\n lastNode.append(node);\n } else {\n selection.insertNodes([node]);\n }\n node.selectNext();\n }\n } else {\n selection.insertNodes([node]);\n node.selectNext();\n }\n } else {\n const root = $getRoot();\n let nodeToInsert: LexicalNode = node;\n if ($isElementNode(node) || $isDecoratorNode(node)) {\n nodeToInsert = node;\n } else {\n const container = $createDivNode({\n style: { display: 'inline-block' },\n });\n container.append(node);\n nodeToInsert = container;\n }\n root.append(nodeToInsert);\n node.selectNext();\n }\n });\n}\n\n/**\n * - EN: Insert text at the current cursor position.\n * - CN: 将文本插入到当前光标位置。\n *\n * @param editor LexicalEditor instance | LexicalEditor 实例\n * @param text Text to insert | 要插入的文本\n */\nexport function insertTextAtCursor(editor: LexicalEditor, text: string): void {\n editor?.update(() => {\n const textNode = $createTextNode(text);\n const root = $getRoot();\n const selection = $getSelection();\n if (selection) {\n // 插入光标位置\n selection.insertText(text);\n } else {\n // 如果没有选取,则直接在根节点末尾插入\n const lastNode = root.getLastChild();\n if (lastNode && $isParagraphNode(lastNode)) {\n lastNode.append(textNode);\n } else {\n const container = $createDivNode({\n style: { display: 'inline-block' },\n });\n container.append(textNode);\n root.append(container);\n }\n }\n });\n}\n\n/**\n * - EN: Clear the editor content.\n * - CN: 清空编辑器内容。\n *\n * @param editor LexicalEditor instance | LexicalEditor 实例\n */\nexport function clearEditorContent(editor: LexicalEditor) {\n const state = editor.getEditorState();\n const stateJson = state.toJSON();\n // 默认创建一个ParagraphNode\n const newJson = {\n ...stateJson,\n root: {\n ...stateJson.root,\n children: [\n {\n children: [],\n direction: null,\n format: '',\n indent: 0,\n type: 'paragraph',\n version: 1,\n textFormat: 0,\n textStyle: '',\n },\n ],\n },\n };\n const emptyState = editor.parseEditorState(JSON.stringify(newJson));\n editor.setEditorState(emptyState);\n editor.update(() => {\n const root = $getRoot();\n root.clear();\n });\n}\n\n/**\n * - EN: Find the first node that matches the predicate.\n * - CN: 查找第一个符合条件的节点。\n *\n * @param editor LexicalEditor instance | LexicalEditor 实例\n * @param predicate Function to test whether a node matches | 用于匹配节点的函数\n *\n * @returns The matched node, or undefined | 符合条件的第一个节点,或 undefined\n */\nexport function findNode<T extends LexicalNode>(\n editor: LexicalEditor,\n predicate: (node: LexicalNode) => boolean\n): T | undefined {\n const matched = findNodes<T>(editor, predicate, { stopOnFirstMatch: true });\n return matched[0];\n}\n/**\n * - EN: Find all nodes that match the predicate.\n * - CN: 查找所有符合条件的节点数组。\n *\n * @param editor LexicalEditor instance | LexicalEditor 实例\n * @param predicate Function to test whether a node matches | 用于匹配节点的函数\n * @param options Options | 选项\n *\n * @returns An array of matched nodes | 符合条件的节点数组\n */\nexport function findNodes<T extends LexicalNode>(\n editor: LexicalEditor,\n predicate: (node: LexicalNode) => boolean,\n options?: {\n stopOnFirstMatch?: boolean;\n }\n): T[] {\n const matched: T[] = [];\n editor.getEditorState().read(() => {\n const root = $getRoot();\n const traverse = (node: LexicalNode, result: T[]) => {\n if (predicate(node)) {\n result.push(node as unknown as T);\n if (options?.stopOnFirstMatch) {\n return;\n }\n }\n if ($isElementNode(node)) {\n const children = node.getChildren();\n for (const child of children) {\n traverse(child, result);\n if (options?.stopOnFirstMatch && result.length > 0) {\n return;\n }\n }\n }\n };\n traverse(root, matched);\n });\n return matched;\n}\n\n/**\n * - EN: Update properties on a DOM element.\n * - CN: 更新 DOM 元素的属性。\n *\n * @param dom Target DOM element to update | 要更新的 DOM 元素\n * @param props Props to set on the element | 要设置的属性\n */\nexport function updateDomProps(dom: HTMLElement | undefined, props: HtmlHTMLAttributes<HTMLElement>): void {\n if (!dom) return;\n Array.from(dom.attributes).forEach((attr) => {\n if (!attr.name.startsWith('data-lexical')) {\n dom.removeAttribute(attr.name);\n }\n });\n\n dom.removeAttribute('style');\n dom.removeAttribute('class');\n\n if (props) {\n Object.entries(props).forEach(([key, value]) => {\n if (key === 'style' && value) {\n Object.entries(value as CSSProperties).forEach(([styleKey, styleValue]) => {\n if (styleValue !== undefined) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (dom.style as any)[styleKey] = styleValue;\n }\n });\n } else if (key === 'className' && value) {\n dom.className = value as string;\n } else if (key.startsWith('on') && typeof value === 'function') {\n dom[key.toLowerCase() as 'onclick'] = value as (event: MouseEvent) => void;\n } else if (value !== undefined && value !== null) {\n dom.setAttribute(key, value.toString());\n }\n });\n }\n}\n\n/**\n * - EN: Update style on a DOM element.\n * - CN: 更新 DOM 元素的样式。\n *\n * @param dom Target DOM element to update | 要更新的 DOM 元素\n * @param style Style to set | 要设置的样式\n */\nexport function updateDomStyle(dom: HTMLElement | undefined, style: CSSProperties | undefined): void {\n if (!dom) return;\n dom.removeAttribute('style');\n if (style) {\n Object.entries(style).forEach(([styleKey, styleValue]) => {\n if (styleValue !== undefined) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (dom.style as any)[styleKey] = styleValue;\n }\n });\n }\n}\n\n/**\n * - EN: Get attributes from a DOM element.\n * - CN: 从 DOM 元素获取属性。\n *\n * @param dom Target DOM element | 目标 DOM 元素\n *\n * @returns Element attributes | 元素属性\n */\nexport function getDomAttributes(dom: HTMLElement | undefined): HtmlHTMLAttributes<HTMLElement> | undefined {\n if (!dom) return undefined;\n\n const attributes: HtmlHTMLAttributes<HTMLElement> = {};\n Array.from(dom.attributes).forEach((attr) => {\n if (attr.name === 'class' || attr.name === 'style') {\n return;\n }\n attributes[attr.name as keyof HtmlHTMLAttributes<HTMLElement>] = attr.value;\n });\n\n if (dom.className) {\n attributes.className = dom.className;\n }\n\n if (dom.style) {\n const styles: CSSProperties = {};\n Array.from(dom.style).forEach((styleName) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (styles as any)[styleName] = (dom.style as any)[styleName];\n });\n attributes.style = styles;\n }\n\n return attributes;\n}\n"],"mappings":"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"}
@@ -161,12 +161,12 @@ export var SelectNode = /*#__PURE__*/function (_BaseDecoratorNode) {
161
161
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
162
162
  function SelectComponent(_ref) {
163
163
  var node = _ref.node;
164
+ var underlyingProps = node.getUnderlyingProps(node.__props);
164
165
  /* eslint-disable @typescript-eslint/no-unused-vars */
165
- var _ref2 = node.__props || {},
166
- textContentMode = _ref2.textContentMode,
167
- spaceAround = _ref2.spaceAround,
168
- containerStyle = _ref2.containerStyle,
169
- selectProps = _objectWithoutProperties(_ref2, _excluded);
166
+ var textContentMode = underlyingProps.textContentMode,
167
+ spaceAround = underlyingProps.spaceAround,
168
+ containerStyle = underlyingProps.containerStyle,
169
+ selectProps = _objectWithoutProperties(underlyingProps, _excluded);
170
170
  /* eslint-enable @typescript-eslint/no-unused-vars */
171
171
  var _useLexicalComposerCo = useLexicalComposerContext(),
172
172
  _useLexicalComposerCo2 = _slicedToArray(_useLexicalComposerCo, 1),
@@ -1 +1 @@
1
- {"version":3,"names":["useCallback","useLexicalComposerContext","Select","insertNodeAtCursor","updateDomStyle","BaseDecoratorNode","jsx","_jsx","SelectNode","_BaseDecoratorNode","_inherits","_super","_createSuper","props","_props$defaultValue","_this","_classCallCheck","call","_defineProperty","_assertThisInitialized","__value","defaultValue","undefined","_createClass","key","value","exportJSON","_objectSpread","_get","_getPrototypeOf","prototype","__props","type","getType","version","createDOM","_this$__props","span","document","createElement","containerStyle","updateDOM","decorate","SelectComponent","node","isInline","getTextContent","_this$__props2","_this2","_this$__props4","content","valueContent","String","textContentMode","_this$__props3","option","options","find","opt","label","spaceAround","concat","getValue","setValue","writable","getWritable","getPropValue","propName","_this$__props5","setProps","clone","getKey","importJSON","serializedNode","$createSelectNode","_ref","_ref2","selectProps","_objectWithoutProperties","_excluded","_useLexicalComposerCo","_useLexicalComposerCo2","_slicedToArray","editor","handleChange","update","_node$__props","_node$__props$onChang","onChange","handleClear","_node$__props2","_node$__props2$onClea","onClear","$isSelectNode","$insertSelectNode","selectNode","paddingLeft","paddingRight"],"sources":["../../../../src/components/Lexical/nodes/SelectNode.tsx"],"sourcesContent":["import { type CSSProperties, type ReactNode, useCallback } from 'react';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport { Select } from 'antd';\nimport type { SelectProps } from 'antd';\nimport type { BaseOptionType, DefaultOptionType } from 'antd/es/select';\nimport type { LexicalEditor, LexicalNode, SerializedLexicalNode, Spread } from 'lexical';\nimport { insertNodeAtCursor, updateDomStyle } from '../helpers';\nimport type { BaseDecoratorNodeProps } from './base';\nimport { BaseDecoratorNode } from './base';\n\n/**\n * - EN: Props for SelectNode, extending antd Select props plus behavior flags.\n * - CN: SelectNode 的属性,基于 antd Select 属性并附加行为标记。\n */\nexport interface SelectNodeProps<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ValueType = any,\n OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType,\n> extends SelectProps<ValueType, OptionType>,\n BaseDecoratorNodeProps {\n /**\n * - EN: When reading editor textContent, whether to use option label or value. Default `value`.\n * - CN: 在获取 editor 的 textContent 时,使用选项的 label 还是 value。默认 `value`。\n * - label: use option label as text\n * - value: use option value as text\n */\n textContentMode?: 'label' | 'value';\n /**\n * - EN: Add a space around textContent. Default `true`.\n * - CN: 是否在 textContent 两边添加一个空格,默认 `true`。\n */\n spaceAround?: boolean;\n /**\n * - EN: Container DOM style.\n * - CN: 容器样式。\n */\n containerStyle?: CSSProperties;\n}\n\nexport class SelectNode<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ValueType = any,\n OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType,\n> extends BaseDecoratorNode<ReactNode, SelectNodeProps<ValueType, OptionType>> {\n __value: ValueType | undefined;\n\n constructor(props?: SelectNodeProps<ValueType, OptionType> & { key?: string }) {\n super(props);\n this.__value = props?.defaultValue ?? undefined;\n }\n static getType(): string {\n return 'antd.Select';\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n static clone<ValueType = any, OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType>(\n node: SelectNode<ValueType, OptionType>\n ): SelectNode<ValueType, OptionType> {\n return new SelectNode<ValueType, OptionType>({ ...node.__props, key: node.getKey() });\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n static importJSON<ValueType = any, OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType>(\n serializedNode: SerializedSelectNode<ValueType, OptionType>\n ): SelectNode<ValueType, OptionType> {\n return $createSelectNode(serializedNode.props);\n }\n\n exportJSON(): SerializedSelectNode<ValueType, OptionType> {\n return {\n ...super.exportJSON(),\n props: this.__props,\n type: this.getType(),\n version: 1,\n };\n }\n\n createDOM(): HTMLElement {\n const span = document.createElement('span');\n updateDomStyle(span, this.__props?.containerStyle);\n return span;\n }\n\n updateDOM(): false {\n return false;\n }\n\n decorate(): ReactNode {\n return <SelectComponent node={this} />;\n }\n\n isInline(): boolean {\n return true;\n }\n\n getTextContent(): string {\n let content: string;\n const valueContent = this.__value ? String(this.__value) : '';\n if (this.__props?.textContentMode === 'label') {\n const option = this.__props?.options?.find((opt) => opt.value === this.__value);\n content = option?.label ? String(option.label) : valueContent;\n } else {\n content = valueContent;\n }\n if (this.__props?.spaceAround !== false) {\n return ` ${content} `;\n }\n return content;\n }\n\n getValue(): ValueType | undefined {\n return this.__value;\n }\n\n setValue(value: ValueType | undefined): void {\n const writable = this.getWritable();\n writable.__value = value;\n }\n\n getPropValue(\n propName: keyof SelectNodeProps<ValueType, OptionType>\n ): SelectNodeProps<ValueType, OptionType>[typeof propName] {\n return this.__props?.[propName];\n }\n\n setProps(props: Partial<SelectNodeProps<ValueType, OptionType>>): void {\n const writable = this.getWritable();\n writable.__props = {\n ...writable.__props,\n ...props,\n };\n }\n}\n\n/**\n * - EN: React decorator component rendered for SelectNode.\n * - CN: SelectNode 对应的 React 装饰组件。\n *\n * @param node The bound SelectNode instance | 关联的 SelectNode 实例\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction SelectComponent<ValueType = any, OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType>({\n node,\n}: SelectComponentProps<ValueType, OptionType>): ReactNode {\n /* eslint-disable @typescript-eslint/no-unused-vars */\n const { textContentMode, spaceAround, containerStyle, ...selectProps } = node.__props || {};\n /* eslint-enable @typescript-eslint/no-unused-vars */\n const [editor] = useLexicalComposerContext();\n\n const handleChange = useCallback<NonNullable<SelectNodeProps<ValueType, OptionType>['onChange']>>(\n (value, options) => {\n editor.update(() => {\n node.setValue(value);\n node.__props?.onChange?.(value, options);\n });\n },\n [editor, node]\n );\n\n const handleClear = useCallback(() => {\n editor.update(() => {\n node.setValue(undefined);\n node.__props?.onClear?.();\n });\n }, [editor, node]);\n\n return <Select {...selectProps} value={node.getValue()} onChange={handleChange} onClear={handleClear} />;\n}\n\n/**\n * - EN: Factory to create a SelectNode.\n * - CN: 创建 SelectNode 的工厂函数。\n *\n * @param props Props for the Select node | Select 节点的属性\n */\nexport function $createSelectNode<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ValueType = any,\n OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType,\n>(props?: SelectNodeProps<ValueType, OptionType>): SelectNode<ValueType, OptionType> {\n return new SelectNode<ValueType, OptionType>(props);\n}\n\n/**\n * - EN: Type guard to check whether a node is SelectNode.\n * - CN: 判断节点是否为 SelectNode 的类型守卫。\n *\n * @param node Node to test | 要检测的节点\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function $isSelectNode(node: LexicalNode | null | undefined): node is SelectNode<any, any> {\n return node instanceof SelectNode;\n}\n\n/**\n * - EN: Insert a SelectNode at the current cursor position.\n * - CN: 在当前光标位置插入一个 SelectNode。\n *\n * @param editor LexicalEditor instance | LexicalEditor 实例\n * @param props Props for the Select node | Select 节点的属性\n */\nexport function $insertSelectNode<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ValueType = any,\n OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType,\n>(editor: LexicalEditor, props: SelectNodeProps<ValueType, OptionType>): void {\n editor.update(() => {\n const selectNode = $createSelectNode<ValueType, OptionType>({\n ...props,\n containerStyle: {\n paddingLeft: '8px',\n paddingRight: '8px',\n ...props.containerStyle,\n },\n });\n insertNodeAtCursor(editor, selectNode);\n });\n}\n\n/**\n * - EN: Props passed to the Select decorator component.\n * - CN: 传递给 Select 装饰组件的属性。\n */\ninterface SelectComponentProps<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ValueType = any,\n OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType,\n> {\n node: SelectNode<ValueType, OptionType>;\n}\ntype SerializedSelectNode<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ValueType = any,\n OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType,\n> = Spread<\n {\n props?: SelectNodeProps<ValueType, OptionType>;\n },\n SerializedLexicalNode\n>;\n"],"mappings":"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"}
1
+ {"version":3,"names":["useCallback","useLexicalComposerContext","Select","insertNodeAtCursor","updateDomStyle","BaseDecoratorNode","jsx","_jsx","SelectNode","_BaseDecoratorNode","_inherits","_super","_createSuper","props","_props$defaultValue","_this","_classCallCheck","call","_defineProperty","_assertThisInitialized","__value","defaultValue","undefined","_createClass","key","value","exportJSON","_objectSpread","_get","_getPrototypeOf","prototype","__props","type","getType","version","createDOM","_this$__props","span","document","createElement","containerStyle","updateDOM","decorate","SelectComponent","node","isInline","getTextContent","_this$__props2","_this2","_this$__props4","content","valueContent","String","textContentMode","_this$__props3","option","options","find","opt","label","spaceAround","concat","getValue","setValue","writable","getWritable","getPropValue","propName","_this$__props5","setProps","clone","getKey","importJSON","serializedNode","$createSelectNode","_ref","underlyingProps","getUnderlyingProps","selectProps","_objectWithoutProperties","_excluded","_useLexicalComposerCo","_useLexicalComposerCo2","_slicedToArray","editor","handleChange","update","_node$__props","_node$__props$onChang","onChange","handleClear","_node$__props2","_node$__props2$onClea","onClear","$isSelectNode","$insertSelectNode","selectNode","paddingLeft","paddingRight"],"sources":["../../../../src/components/Lexical/nodes/SelectNode.tsx"],"sourcesContent":["import { type CSSProperties, type ReactNode, useCallback } from 'react';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport { Select } from 'antd';\nimport type { SelectProps } from 'antd';\nimport type { BaseOptionType, DefaultOptionType } from 'antd/es/select';\nimport type { LexicalEditor, LexicalNode, SerializedLexicalNode, Spread } from 'lexical';\nimport { insertNodeAtCursor, updateDomStyle } from '../helpers';\nimport type { BaseDecoratorNodeProps } from './base';\nimport { BaseDecoratorNode } from './base';\n\n/**\n * - EN: Props for SelectNode, extending antd Select props plus behavior flags.\n * - CN: SelectNode 的属性,基于 antd Select 属性并附加行为标记。\n */\nexport interface SelectNodeProps<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ValueType = any,\n OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType,\n> extends SelectProps<ValueType, OptionType>,\n BaseDecoratorNodeProps {\n /**\n * - EN: When reading editor textContent, whether to use option label or value. Default `value`.\n * - CN: 在获取 editor 的 textContent 时,使用选项的 label 还是 value。默认 `value`。\n * - label: use option label as text\n * - value: use option value as text\n */\n textContentMode?: 'label' | 'value';\n /**\n * - EN: Add a space around textContent. Default `true`.\n * - CN: 是否在 textContent 两边添加一个空格,默认 `true`。\n */\n spaceAround?: boolean;\n /**\n * - EN: Container DOM style.\n * - CN: 容器样式。\n */\n containerStyle?: CSSProperties;\n}\n\nexport class SelectNode<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ValueType = any,\n OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType,\n> extends BaseDecoratorNode<ReactNode, SelectNodeProps<ValueType, OptionType>> {\n __value: ValueType | undefined;\n\n constructor(props?: SelectNodeProps<ValueType, OptionType> & { key?: string }) {\n super(props);\n this.__value = props?.defaultValue ?? undefined;\n }\n static getType(): string {\n return 'antd.Select';\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n static clone<ValueType = any, OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType>(\n node: SelectNode<ValueType, OptionType>\n ): SelectNode<ValueType, OptionType> {\n return new SelectNode<ValueType, OptionType>({ ...node.__props, key: node.getKey() });\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n static importJSON<ValueType = any, OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType>(\n serializedNode: SerializedSelectNode<ValueType, OptionType>\n ): SelectNode<ValueType, OptionType> {\n return $createSelectNode(serializedNode.props);\n }\n\n exportJSON(): SerializedSelectNode<ValueType, OptionType> {\n return {\n ...super.exportJSON(),\n props: this.__props,\n type: this.getType(),\n version: 1,\n };\n }\n\n createDOM(): HTMLElement {\n const span = document.createElement('span');\n updateDomStyle(span, this.__props?.containerStyle);\n return span;\n }\n\n updateDOM(): false {\n return false;\n }\n\n decorate(): ReactNode {\n return <SelectComponent node={this} />;\n }\n\n isInline(): boolean {\n return true;\n }\n\n getTextContent(): string {\n let content: string;\n const valueContent = this.__value ? String(this.__value) : '';\n if (this.__props?.textContentMode === 'label') {\n const option = this.__props?.options?.find((opt) => opt.value === this.__value);\n content = option?.label ? String(option.label) : valueContent;\n } else {\n content = valueContent;\n }\n if (this.__props?.spaceAround !== false) {\n return ` ${content} `;\n }\n return content;\n }\n\n getValue(): ValueType | undefined {\n return this.__value;\n }\n\n setValue(value: ValueType | undefined): void {\n const writable = this.getWritable();\n writable.__value = value;\n }\n\n getPropValue(\n propName: keyof SelectNodeProps<ValueType, OptionType>\n ): SelectNodeProps<ValueType, OptionType>[typeof propName] {\n return this.__props?.[propName];\n }\n\n setProps(props: Partial<SelectNodeProps<ValueType, OptionType>>): void {\n const writable = this.getWritable();\n writable.__props = {\n ...writable.__props,\n ...props,\n };\n }\n}\n\n/**\n * - EN: React decorator component rendered for SelectNode.\n * - CN: SelectNode 对应的 React 装饰组件。\n *\n * @param node The bound SelectNode instance | 关联的 SelectNode 实例\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction SelectComponent<ValueType = any, OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType>({\n node,\n}: SelectComponentProps<ValueType, OptionType>): ReactNode {\n const underlyingProps = node.getUnderlyingProps(node.__props);\n /* eslint-disable @typescript-eslint/no-unused-vars */\n const { textContentMode, spaceAround, containerStyle, ...selectProps } = underlyingProps;\n /* eslint-enable @typescript-eslint/no-unused-vars */\n const [editor] = useLexicalComposerContext();\n\n const handleChange = useCallback<NonNullable<SelectNodeProps<ValueType, OptionType>['onChange']>>(\n (value, options) => {\n editor.update(() => {\n node.setValue(value);\n node.__props?.onChange?.(value, options);\n });\n },\n [editor, node]\n );\n\n const handleClear = useCallback(() => {\n editor.update(() => {\n node.setValue(undefined);\n node.__props?.onClear?.();\n });\n }, [editor, node]);\n\n return <Select {...selectProps} value={node.getValue()} onChange={handleChange} onClear={handleClear} />;\n}\n\n/**\n * - EN: Factory to create a SelectNode.\n * - CN: 创建 SelectNode 的工厂函数。\n *\n * @param props Props for the Select node | Select 节点的属性\n */\nexport function $createSelectNode<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ValueType = any,\n OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType,\n>(props?: SelectNodeProps<ValueType, OptionType>): SelectNode<ValueType, OptionType> {\n return new SelectNode<ValueType, OptionType>(props);\n}\n\n/**\n * - EN: Type guard to check whether a node is SelectNode.\n * - CN: 判断节点是否为 SelectNode 的类型守卫。\n *\n * @param node Node to test | 要检测的节点\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function $isSelectNode(node: LexicalNode | null | undefined): node is SelectNode<any, any> {\n return node instanceof SelectNode;\n}\n\n/**\n * - EN: Insert a SelectNode at the current cursor position.\n * - CN: 在当前光标位置插入一个 SelectNode。\n *\n * @param editor LexicalEditor instance | LexicalEditor 实例\n * @param props Props for the Select node | Select 节点的属性\n */\nexport function $insertSelectNode<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ValueType = any,\n OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType,\n>(editor: LexicalEditor, props: SelectNodeProps<ValueType, OptionType>): void {\n editor.update(() => {\n const selectNode = $createSelectNode<ValueType, OptionType>({\n ...props,\n containerStyle: {\n paddingLeft: '8px',\n paddingRight: '8px',\n ...props.containerStyle,\n },\n });\n insertNodeAtCursor(editor, selectNode);\n });\n}\n\n/**\n * - EN: Props passed to the Select decorator component.\n * - CN: 传递给 Select 装饰组件的属性。\n */\ninterface SelectComponentProps<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ValueType = any,\n OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType,\n> {\n node: SelectNode<ValueType, OptionType>;\n}\ntype SerializedSelectNode<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ValueType = any,\n OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType,\n> = Spread<\n {\n props?: SelectNodeProps<ValueType, OptionType>;\n },\n SerializedLexicalNode\n>;\n"],"mappings":"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"}
@@ -168,6 +168,8 @@ function updateDomProps(dom, props) {
168
168
  });
169
169
  } else if (key === "className" && value) {
170
170
  dom.className = value;
171
+ } else if (key.startsWith("on") && typeof value === "function") {
172
+ dom[key.toLowerCase()] = value;
171
173
  } else if (value !== void 0 && value !== null) {
172
174
  dom.setAttribute(key, value.toString());
173
175
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/components/Lexical/helpers/index.ts"],
4
- "sourcesContent": ["import type { CSSProperties, HtmlHTMLAttributes } from 'react';\nimport type { LexicalEditor, LexicalNode } from 'lexical';\nimport {\n $createTextNode,\n $getRoot,\n $getSelection,\n $isDecoratorNode,\n $isElementNode,\n $isParagraphNode,\n $isRangeSelection,\n $isTextNode,\n} from 'lexical';\nimport { $createDivNode, $isDivNode } from '../nodes/DivNode';\n\n/**\n * - EN: Insert a node at the current cursor position.\n * - CN: 将节点插入到当前光标位置。\n *\n * @param editor LexicalEditor instance | LexicalEditor 实例\n * @param node Node to insert | 要插入的节点\n */\nexport function insertNodeAtCursor(editor: LexicalEditor, node: LexicalNode): void {\n editor.update(() => {\n const selection = $getSelection();\n if (selection) {\n if ($isRangeSelection(selection)) {\n // 如果没有选取,则直接在根节点末尾插入\n const lastNode = selection.focus.getNode();\n if (lastNode) {\n if ($isParagraphNode(lastNode)) {\n lastNode.append(node);\n } else if ($isTextNode(lastNode)) {\n // 如果最后一个节点是文本节点,则在其后插入 SelectNode\n lastNode.insertAfter(node);\n } else if ($isDivNode(lastNode)) {\n lastNode.append(node);\n } else {\n selection.insertNodes([node]);\n }\n node.selectNext();\n }\n } else {\n selection.insertNodes([node]);\n node.selectNext();\n }\n } else {\n const root = $getRoot();\n let nodeToInsert: LexicalNode = node;\n if ($isElementNode(node) || $isDecoratorNode(node)) {\n nodeToInsert = node;\n } else {\n const container = $createDivNode({\n style: { display: 'inline-block' },\n });\n container.append(node);\n nodeToInsert = container;\n }\n root.append(nodeToInsert);\n node.selectNext();\n }\n });\n}\n\n/**\n * - EN: Insert text at the current cursor position.\n * - CN: 将文本插入到当前光标位置。\n *\n * @param editor LexicalEditor instance | LexicalEditor 实例\n * @param text Text to insert | 要插入的文本\n */\nexport function insertTextAtCursor(editor: LexicalEditor, text: string): void {\n editor?.update(() => {\n const textNode = $createTextNode(text);\n const root = $getRoot();\n const selection = $getSelection();\n if (selection) {\n // 插入光标位置\n selection.insertText(text);\n } else {\n // 如果没有选取,则直接在根节点末尾插入\n const lastNode = root.getLastChild();\n if (lastNode && $isParagraphNode(lastNode)) {\n lastNode.append(textNode);\n } else {\n const container = $createDivNode({\n style: { display: 'inline-block' },\n });\n container.append(textNode);\n root.append(container);\n }\n }\n });\n}\n\n/**\n * - EN: Clear the editor content.\n * - CN: 清空编辑器内容。\n *\n * @param editor LexicalEditor instance | LexicalEditor 实例\n */\nexport function clearEditorContent(editor: LexicalEditor) {\n const state = editor.getEditorState();\n const stateJson = state.toJSON();\n // 默认创建一个ParagraphNode\n const newJson = {\n ...stateJson,\n root: {\n ...stateJson.root,\n children: [\n {\n children: [],\n direction: null,\n format: '',\n indent: 0,\n type: 'paragraph',\n version: 1,\n textFormat: 0,\n textStyle: '',\n },\n ],\n },\n };\n const emptyState = editor.parseEditorState(JSON.stringify(newJson));\n editor.setEditorState(emptyState);\n editor.update(() => {\n const root = $getRoot();\n root.clear();\n });\n}\n\n/**\n * - EN: Find the first node that matches the predicate.\n * - CN: 查找第一个符合条件的节点。\n *\n * @param editor LexicalEditor instance | LexicalEditor 实例\n * @param predicate Function to test whether a node matches | 用于匹配节点的函数\n *\n * @returns The matched node, or undefined | 符合条件的第一个节点,或 undefined\n */\nexport function findNode<T extends LexicalNode>(\n editor: LexicalEditor,\n predicate: (node: LexicalNode) => boolean\n): T | undefined {\n const matched = findNodes<T>(editor, predicate, { stopOnFirstMatch: true });\n return matched[0];\n}\n/**\n * - EN: Find all nodes that match the predicate.\n * - CN: 查找所有符合条件的节点数组。\n *\n * @param editor LexicalEditor instance | LexicalEditor 实例\n * @param predicate Function to test whether a node matches | 用于匹配节点的函数\n * @param options Options | 选项\n *\n * @returns An array of matched nodes | 符合条件的节点数组\n */\nexport function findNodes<T extends LexicalNode>(\n editor: LexicalEditor,\n predicate: (node: LexicalNode) => boolean,\n options?: {\n stopOnFirstMatch?: boolean;\n }\n): T[] {\n const matched: T[] = [];\n editor.getEditorState().read(() => {\n const root = $getRoot();\n const traverse = (node: LexicalNode, result: T[]) => {\n if (predicate(node)) {\n result.push(node as unknown as T);\n if (options?.stopOnFirstMatch) {\n return;\n }\n }\n if ($isElementNode(node)) {\n const children = node.getChildren();\n for (const child of children) {\n traverse(child, result);\n if (options?.stopOnFirstMatch && result.length > 0) {\n return;\n }\n }\n }\n };\n traverse(root, matched);\n });\n return matched;\n}\n\n/**\n * - EN: Update properties on a DOM element.\n * - CN: 更新 DOM 元素的属性。\n *\n * @param dom Target DOM element to update | 要更新的 DOM 元素\n * @param props Props to set on the element | 要设置的属性\n */\nexport function updateDomProps(dom: HTMLElement | undefined, props: HtmlHTMLAttributes<HTMLElement>): void {\n if (!dom) return;\n Array.from(dom.attributes).forEach((attr) => {\n if (!attr.name.startsWith('data-lexical')) {\n dom.removeAttribute(attr.name);\n }\n });\n\n dom.removeAttribute('style');\n dom.removeAttribute('class');\n\n if (props) {\n Object.entries(props).forEach(([key, value]) => {\n if (key === 'style' && value) {\n Object.entries(value as CSSProperties).forEach(([styleKey, styleValue]) => {\n if (styleValue !== undefined) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (dom.style as any)[styleKey] = styleValue;\n }\n });\n } else if (key === 'className' && value) {\n dom.className = value as string;\n } else if (value !== undefined && value !== null) {\n dom.setAttribute(key, value.toString());\n }\n });\n }\n}\n\n/**\n * - EN: Update style on a DOM element.\n * - CN: 更新 DOM 元素的样式。\n *\n * @param dom Target DOM element to update | 要更新的 DOM 元素\n * @param style Style to set | 要设置的样式\n */\nexport function updateDomStyle(dom: HTMLElement | undefined, style: CSSProperties | undefined): void {\n if (!dom) return;\n dom.removeAttribute('style');\n if (style) {\n Object.entries(style).forEach(([styleKey, styleValue]) => {\n if (styleValue !== undefined) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (dom.style as any)[styleKey] = styleValue;\n }\n });\n }\n}\n\n/**\n * - EN: Get attributes from a DOM element.\n * - CN: 从 DOM 元素获取属性。\n *\n * @param dom Target DOM element | 目标 DOM 元素\n *\n * @returns Element attributes | 元素属性\n */\nexport function getDomAttributes(dom: HTMLElement | undefined): HtmlHTMLAttributes<HTMLElement> | undefined {\n if (!dom) return undefined;\n\n const attributes: HtmlHTMLAttributes<HTMLElement> = {};\n Array.from(dom.attributes).forEach((attr) => {\n if (attr.name === 'class' || attr.name === 'style') {\n return;\n }\n attributes[attr.name as keyof HtmlHTMLAttributes<HTMLElement>] = attr.value;\n });\n\n if (dom.className) {\n attributes.className = dom.className;\n }\n\n if (dom.style) {\n const styles: CSSProperties = {};\n Array.from(dom.style).forEach((styleName) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (styles as any)[styleName] = (dom.style as any)[styleName];\n });\n attributes.style = styles;\n }\n\n return attributes;\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { CSSProperties, HtmlHTMLAttributes } from 'react';\nimport type { LexicalEditor, LexicalNode } from 'lexical';\nimport {\n $createTextNode,\n $getRoot,\n $getSelection,\n $isDecoratorNode,\n $isElementNode,\n $isParagraphNode,\n $isRangeSelection,\n $isTextNode,\n} from 'lexical';\nimport { $createDivNode, $isDivNode } from '../nodes/DivNode';\n\n/**\n * - EN: Insert a node at the current cursor position.\n * - CN: 将节点插入到当前光标位置。\n *\n * @param editor LexicalEditor instance | LexicalEditor 实例\n * @param node Node to insert | 要插入的节点\n */\nexport function insertNodeAtCursor(editor: LexicalEditor, node: LexicalNode): void {\n editor.update(() => {\n const selection = $getSelection();\n if (selection) {\n if ($isRangeSelection(selection)) {\n // 如果没有选取,则直接在根节点末尾插入\n const lastNode = selection.focus.getNode();\n if (lastNode) {\n if ($isParagraphNode(lastNode)) {\n lastNode.append(node);\n } else if ($isTextNode(lastNode)) {\n // 如果最后一个节点是文本节点,则在其后插入 SelectNode\n lastNode.insertAfter(node);\n } else if ($isDivNode(lastNode)) {\n lastNode.append(node);\n } else {\n selection.insertNodes([node]);\n }\n node.selectNext();\n }\n } else {\n selection.insertNodes([node]);\n node.selectNext();\n }\n } else {\n const root = $getRoot();\n let nodeToInsert: LexicalNode = node;\n if ($isElementNode(node) || $isDecoratorNode(node)) {\n nodeToInsert = node;\n } else {\n const container = $createDivNode({\n style: { display: 'inline-block' },\n });\n container.append(node);\n nodeToInsert = container;\n }\n root.append(nodeToInsert);\n node.selectNext();\n }\n });\n}\n\n/**\n * - EN: Insert text at the current cursor position.\n * - CN: 将文本插入到当前光标位置。\n *\n * @param editor LexicalEditor instance | LexicalEditor 实例\n * @param text Text to insert | 要插入的文本\n */\nexport function insertTextAtCursor(editor: LexicalEditor, text: string): void {\n editor?.update(() => {\n const textNode = $createTextNode(text);\n const root = $getRoot();\n const selection = $getSelection();\n if (selection) {\n // 插入光标位置\n selection.insertText(text);\n } else {\n // 如果没有选取,则直接在根节点末尾插入\n const lastNode = root.getLastChild();\n if (lastNode && $isParagraphNode(lastNode)) {\n lastNode.append(textNode);\n } else {\n const container = $createDivNode({\n style: { display: 'inline-block' },\n });\n container.append(textNode);\n root.append(container);\n }\n }\n });\n}\n\n/**\n * - EN: Clear the editor content.\n * - CN: 清空编辑器内容。\n *\n * @param editor LexicalEditor instance | LexicalEditor 实例\n */\nexport function clearEditorContent(editor: LexicalEditor) {\n const state = editor.getEditorState();\n const stateJson = state.toJSON();\n // 默认创建一个ParagraphNode\n const newJson = {\n ...stateJson,\n root: {\n ...stateJson.root,\n children: [\n {\n children: [],\n direction: null,\n format: '',\n indent: 0,\n type: 'paragraph',\n version: 1,\n textFormat: 0,\n textStyle: '',\n },\n ],\n },\n };\n const emptyState = editor.parseEditorState(JSON.stringify(newJson));\n editor.setEditorState(emptyState);\n editor.update(() => {\n const root = $getRoot();\n root.clear();\n });\n}\n\n/**\n * - EN: Find the first node that matches the predicate.\n * - CN: 查找第一个符合条件的节点。\n *\n * @param editor LexicalEditor instance | LexicalEditor 实例\n * @param predicate Function to test whether a node matches | 用于匹配节点的函数\n *\n * @returns The matched node, or undefined | 符合条件的第一个节点,或 undefined\n */\nexport function findNode<T extends LexicalNode>(\n editor: LexicalEditor,\n predicate: (node: LexicalNode) => boolean\n): T | undefined {\n const matched = findNodes<T>(editor, predicate, { stopOnFirstMatch: true });\n return matched[0];\n}\n/**\n * - EN: Find all nodes that match the predicate.\n * - CN: 查找所有符合条件的节点数组。\n *\n * @param editor LexicalEditor instance | LexicalEditor 实例\n * @param predicate Function to test whether a node matches | 用于匹配节点的函数\n * @param options Options | 选项\n *\n * @returns An array of matched nodes | 符合条件的节点数组\n */\nexport function findNodes<T extends LexicalNode>(\n editor: LexicalEditor,\n predicate: (node: LexicalNode) => boolean,\n options?: {\n stopOnFirstMatch?: boolean;\n }\n): T[] {\n const matched: T[] = [];\n editor.getEditorState().read(() => {\n const root = $getRoot();\n const traverse = (node: LexicalNode, result: T[]) => {\n if (predicate(node)) {\n result.push(node as unknown as T);\n if (options?.stopOnFirstMatch) {\n return;\n }\n }\n if ($isElementNode(node)) {\n const children = node.getChildren();\n for (const child of children) {\n traverse(child, result);\n if (options?.stopOnFirstMatch && result.length > 0) {\n return;\n }\n }\n }\n };\n traverse(root, matched);\n });\n return matched;\n}\n\n/**\n * - EN: Update properties on a DOM element.\n * - CN: 更新 DOM 元素的属性。\n *\n * @param dom Target DOM element to update | 要更新的 DOM 元素\n * @param props Props to set on the element | 要设置的属性\n */\nexport function updateDomProps(dom: HTMLElement | undefined, props: HtmlHTMLAttributes<HTMLElement>): void {\n if (!dom) return;\n Array.from(dom.attributes).forEach((attr) => {\n if (!attr.name.startsWith('data-lexical')) {\n dom.removeAttribute(attr.name);\n }\n });\n\n dom.removeAttribute('style');\n dom.removeAttribute('class');\n\n if (props) {\n Object.entries(props).forEach(([key, value]) => {\n if (key === 'style' && value) {\n Object.entries(value as CSSProperties).forEach(([styleKey, styleValue]) => {\n if (styleValue !== undefined) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (dom.style as any)[styleKey] = styleValue;\n }\n });\n } else if (key === 'className' && value) {\n dom.className = value as string;\n } else if (key.startsWith('on') && typeof value === 'function') {\n dom[key.toLowerCase() as 'onclick'] = value as (event: MouseEvent) => void;\n } else if (value !== undefined && value !== null) {\n dom.setAttribute(key, value.toString());\n }\n });\n }\n}\n\n/**\n * - EN: Update style on a DOM element.\n * - CN: 更新 DOM 元素的样式。\n *\n * @param dom Target DOM element to update | 要更新的 DOM 元素\n * @param style Style to set | 要设置的样式\n */\nexport function updateDomStyle(dom: HTMLElement | undefined, style: CSSProperties | undefined): void {\n if (!dom) return;\n dom.removeAttribute('style');\n if (style) {\n Object.entries(style).forEach(([styleKey, styleValue]) => {\n if (styleValue !== undefined) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (dom.style as any)[styleKey] = styleValue;\n }\n });\n }\n}\n\n/**\n * - EN: Get attributes from a DOM element.\n * - CN: 从 DOM 元素获取属性。\n *\n * @param dom Target DOM element | 目标 DOM 元素\n *\n * @returns Element attributes | 元素属性\n */\nexport function getDomAttributes(dom: HTMLElement | undefined): HtmlHTMLAttributes<HTMLElement> | undefined {\n if (!dom) return undefined;\n\n const attributes: HtmlHTMLAttributes<HTMLElement> = {};\n Array.from(dom.attributes).forEach((attr) => {\n if (attr.name === 'class' || attr.name === 'style') {\n return;\n }\n attributes[attr.name as keyof HtmlHTMLAttributes<HTMLElement>] = attr.value;\n });\n\n if (dom.className) {\n attributes.className = dom.className;\n }\n\n if (dom.style) {\n const styles: CSSProperties = {};\n Array.from(dom.style).forEach((styleName) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (styles as any)[styleName] = (dom.style as any)[styleName];\n });\n attributes.style = styles;\n }\n\n return attributes;\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,qBASO;AACP,qBAA2C;AASpC,SAAS,mBAAmB,QAAuB,MAAyB;AACjF,SAAO,OAAO,MAAM;AAClB,UAAM,gBAAY,8BAAc;AAChC,QAAI,WAAW;AACb,cAAI,kCAAkB,SAAS,GAAG;AAEhC,cAAM,WAAW,UAAU,MAAM,QAAQ;AACzC,YAAI,UAAU;AACZ,kBAAI,iCAAiB,QAAQ,GAAG;AAC9B,qBAAS,OAAO,IAAI;AAAA,UACtB,eAAW,4BAAY,QAAQ,GAAG;AAEhC,qBAAS,YAAY,IAAI;AAAA,UAC3B,eAAW,2BAAW,QAAQ,GAAG;AAC/B,qBAAS,OAAO,IAAI;AAAA,UACtB,OAAO;AACL,sBAAU,YAAY,CAAC,IAAI,CAAC;AAAA,UAC9B;AACA,eAAK,WAAW;AAAA,QAClB;AAAA,MACF,OAAO;AACL,kBAAU,YAAY,CAAC,IAAI,CAAC;AAC5B,aAAK,WAAW;AAAA,MAClB;AAAA,IACF,OAAO;AACL,YAAM,WAAO,yBAAS;AACtB,UAAI,eAA4B;AAChC,cAAI,+BAAe,IAAI,SAAK,iCAAiB,IAAI,GAAG;AAClD,uBAAe;AAAA,MACjB,OAAO;AACL,cAAM,gBAAY,+BAAe;AAAA,UAC/B,OAAO,EAAE,SAAS,eAAe;AAAA,QACnC,CAAC;AACD,kBAAU,OAAO,IAAI;AACrB,uBAAe;AAAA,MACjB;AACA,WAAK,OAAO,YAAY;AACxB,WAAK,WAAW;AAAA,IAClB;AAAA,EACF,CAAC;AACH;AASO,SAAS,mBAAmB,QAAuB,MAAoB;AAC5E,mCAAQ,OAAO,MAAM;AACnB,UAAM,eAAW,gCAAgB,IAAI;AACrC,UAAM,WAAO,yBAAS;AACtB,UAAM,gBAAY,8BAAc;AAChC,QAAI,WAAW;AAEb,gBAAU,WAAW,IAAI;AAAA,IAC3B,OAAO;AAEL,YAAM,WAAW,KAAK,aAAa;AACnC,UAAI,gBAAY,iCAAiB,QAAQ,GAAG;AAC1C,iBAAS,OAAO,QAAQ;AAAA,MAC1B,OAAO;AACL,cAAM,gBAAY,+BAAe;AAAA,UAC/B,OAAO,EAAE,SAAS,eAAe;AAAA,QACnC,CAAC;AACD,kBAAU,OAAO,QAAQ;AACzB,aAAK,OAAO,SAAS;AAAA,MACvB;AAAA,IACF;AAAA,EACF;AACF;AAQO,SAAS,mBAAmB,QAAuB;AACxD,QAAM,QAAQ,OAAO,eAAe;AACpC,QAAM,YAAY,MAAM,OAAO;AAE/B,QAAM,UAAU;AAAA,IACd,GAAG;AAAA,IACH,MAAM;AAAA,MACJ,GAAG,UAAU;AAAA,MACb,UAAU;AAAA,QACR;AAAA,UACE,UAAU,CAAC;AAAA,UACX,WAAW;AAAA,UACX,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR,MAAM;AAAA,UACN,SAAS;AAAA,UACT,YAAY;AAAA,UACZ,WAAW;AAAA,QACb;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,QAAM,aAAa,OAAO,iBAAiB,KAAK,UAAU,OAAO,CAAC;AAClE,SAAO,eAAe,UAAU;AAChC,SAAO,OAAO,MAAM;AAClB,UAAM,WAAO,yBAAS;AACtB,SAAK,MAAM;AAAA,EACb,CAAC;AACH;AAWO,SAAS,SACd,QACA,WACe;AACf,QAAM,UAAU,UAAa,QAAQ,WAAW,EAAE,kBAAkB,KAAK,CAAC;AAC1E,SAAO,QAAQ,CAAC;AAClB;AAWO,SAAS,UACd,QACA,WACA,SAGK;AACL,QAAM,UAAe,CAAC;AACtB,SAAO,eAAe,EAAE,KAAK,MAAM;AACjC,UAAM,WAAO,yBAAS;AACtB,UAAM,WAAW,CAAC,MAAmB,WAAgB;AACnD,UAAI,UAAU,IAAI,GAAG;AACnB,eAAO,KAAK,IAAoB;AAChC,YAAI,mCAAS,kBAAkB;AAC7B;AAAA,QACF;AAAA,MACF;AACA,cAAI,+BAAe,IAAI,GAAG;AACxB,cAAM,WAAW,KAAK,YAAY;AAClC,mBAAW,SAAS,UAAU;AAC5B,mBAAS,OAAO,MAAM;AACtB,eAAI,mCAAS,qBAAoB,OAAO,SAAS,GAAG;AAClD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,aAAS,MAAM,OAAO;AAAA,EACxB,CAAC;AACD,SAAO;AACT;AASO,SAAS,eAAe,KAA8B,OAA8C;AACzG,MAAI,CAAC;AAAK;AACV,QAAM,KAAK,IAAI,UAAU,EAAE,QAAQ,CAAC,SAAS;AAC3C,QAAI,CAAC,KAAK,KAAK,WAAW,cAAc,GAAG;AACzC,UAAI,gBAAgB,KAAK,IAAI;AAAA,IAC/B;AAAA,EACF,CAAC;AAED,MAAI,gBAAgB,OAAO;AAC3B,MAAI,gBAAgB,OAAO;AAE3B,MAAI,OAAO;AACT,WAAO,QAAQ,KAAK,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AAC9C,UAAI,QAAQ,WAAW,OAAO;AAC5B,eAAO,QAAQ,KAAsB,EAAE,QAAQ,CAAC,CAAC,UAAU,UAAU,MAAM;AACzE,cAAI,eAAe,QAAW;AAE5B,YAAC,IAAI,MAAc,QAAQ,IAAI;AAAA,UACjC;AAAA,QACF,CAAC;AAAA,MACH,WAAW,QAAQ,eAAe,OAAO;AACvC,YAAI,YAAY;AAAA,MAClB,WAAW,IAAI,WAAW,IAAI,KAAK,OAAO,UAAU,YAAY;AAC9D,YAAI,IAAI,YAAY,CAAc,IAAI;AAAA,MACxC,WAAW,UAAU,UAAa,UAAU,MAAM;AAChD,YAAI,aAAa,KAAK,MAAM,SAAS,CAAC;AAAA,MACxC;AAAA,IACF,CAAC;AAAA,EACH;AACF;AASO,SAAS,eAAe,KAA8B,OAAwC;AACnG,MAAI,CAAC;AAAK;AACV,MAAI,gBAAgB,OAAO;AAC3B,MAAI,OAAO;AACT,WAAO,QAAQ,KAAK,EAAE,QAAQ,CAAC,CAAC,UAAU,UAAU,MAAM;AACxD,UAAI,eAAe,QAAW;AAE5B,QAAC,IAAI,MAAc,QAAQ,IAAI;AAAA,MACjC;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAUO,SAAS,iBAAiB,KAA2E;AAC1G,MAAI,CAAC;AAAK,WAAO;AAEjB,QAAM,aAA8C,CAAC;AACrD,QAAM,KAAK,IAAI,UAAU,EAAE,QAAQ,CAAC,SAAS;AAC3C,QAAI,KAAK,SAAS,WAAW,KAAK,SAAS,SAAS;AAClD;AAAA,IACF;AACA,eAAW,KAAK,IAA6C,IAAI,KAAK;AAAA,EACxE,CAAC;AAED,MAAI,IAAI,WAAW;AACjB,eAAW,YAAY,IAAI;AAAA,EAC7B;AAEA,MAAI,IAAI,OAAO;AACb,UAAM,SAAwB,CAAC;AAC/B,UAAM,KAAK,IAAI,KAAK,EAAE,QAAQ,CAAC,cAAc;AAE3C,MAAC,OAAe,SAAS,IAAK,IAAI,MAAc,SAAS;AAAA,IAC3D,CAAC;AACD,eAAW,QAAQ;AAAA,EACrB;AAEA,SAAO;AACT;",
6
6
  "names": []
7
7
  }
@@ -106,7 +106,8 @@ var SelectNode = class extends import_base.BaseDecoratorNode {
106
106
  function SelectComponent({
107
107
  node
108
108
  }) {
109
- const { textContentMode, spaceAround, containerStyle, ...selectProps } = node.__props || {};
109
+ const underlyingProps = node.getUnderlyingProps(node.__props);
110
+ const { textContentMode, spaceAround, containerStyle, ...selectProps } = underlyingProps;
110
111
  const [editor] = (0, import_LexicalComposerContext.useLexicalComposerContext)();
111
112
  const handleChange = (0, import_react.useCallback)(
112
113
  (value, options) => {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/components/Lexical/nodes/SelectNode.tsx"],
4
- "sourcesContent": ["import { type CSSProperties, type ReactNode, useCallback } from 'react';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport { Select } from 'antd';\nimport type { SelectProps } from 'antd';\nimport type { BaseOptionType, DefaultOptionType } from 'antd/es/select';\nimport type { LexicalEditor, LexicalNode, SerializedLexicalNode, Spread } from 'lexical';\nimport { insertNodeAtCursor, updateDomStyle } from '../helpers';\nimport type { BaseDecoratorNodeProps } from './base';\nimport { BaseDecoratorNode } from './base';\n\n/**\n * - EN: Props for SelectNode, extending antd Select props plus behavior flags.\n * - CN: SelectNode 的属性,基于 antd Select 属性并附加行为标记。\n */\nexport interface SelectNodeProps<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ValueType = any,\n OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType,\n> extends SelectProps<ValueType, OptionType>,\n BaseDecoratorNodeProps {\n /**\n * - EN: When reading editor textContent, whether to use option label or value. Default `value`.\n * - CN: 在获取 editor 的 textContent 时,使用选项的 label 还是 value。默认 `value`。\n * - label: use option label as text\n * - value: use option value as text\n */\n textContentMode?: 'label' | 'value';\n /**\n * - EN: Add a space around textContent. Default `true`.\n * - CN: 是否在 textContent 两边添加一个空格,默认 `true`。\n */\n spaceAround?: boolean;\n /**\n * - EN: Container DOM style.\n * - CN: 容器样式。\n */\n containerStyle?: CSSProperties;\n}\n\nexport class SelectNode<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ValueType = any,\n OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType,\n> extends BaseDecoratorNode<ReactNode, SelectNodeProps<ValueType, OptionType>> {\n __value: ValueType | undefined;\n\n constructor(props?: SelectNodeProps<ValueType, OptionType> & { key?: string }) {\n super(props);\n this.__value = props?.defaultValue ?? undefined;\n }\n static getType(): string {\n return 'antd.Select';\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n static clone<ValueType = any, OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType>(\n node: SelectNode<ValueType, OptionType>\n ): SelectNode<ValueType, OptionType> {\n return new SelectNode<ValueType, OptionType>({ ...node.__props, key: node.getKey() });\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n static importJSON<ValueType = any, OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType>(\n serializedNode: SerializedSelectNode<ValueType, OptionType>\n ): SelectNode<ValueType, OptionType> {\n return $createSelectNode(serializedNode.props);\n }\n\n exportJSON(): SerializedSelectNode<ValueType, OptionType> {\n return {\n ...super.exportJSON(),\n props: this.__props,\n type: this.getType(),\n version: 1,\n };\n }\n\n createDOM(): HTMLElement {\n const span = document.createElement('span');\n updateDomStyle(span, this.__props?.containerStyle);\n return span;\n }\n\n updateDOM(): false {\n return false;\n }\n\n decorate(): ReactNode {\n return <SelectComponent node={this} />;\n }\n\n isInline(): boolean {\n return true;\n }\n\n getTextContent(): string {\n let content: string;\n const valueContent = this.__value ? String(this.__value) : '';\n if (this.__props?.textContentMode === 'label') {\n const option = this.__props?.options?.find((opt) => opt.value === this.__value);\n content = option?.label ? String(option.label) : valueContent;\n } else {\n content = valueContent;\n }\n if (this.__props?.spaceAround !== false) {\n return ` ${content} `;\n }\n return content;\n }\n\n getValue(): ValueType | undefined {\n return this.__value;\n }\n\n setValue(value: ValueType | undefined): void {\n const writable = this.getWritable();\n writable.__value = value;\n }\n\n getPropValue(\n propName: keyof SelectNodeProps<ValueType, OptionType>\n ): SelectNodeProps<ValueType, OptionType>[typeof propName] {\n return this.__props?.[propName];\n }\n\n setProps(props: Partial<SelectNodeProps<ValueType, OptionType>>): void {\n const writable = this.getWritable();\n writable.__props = {\n ...writable.__props,\n ...props,\n };\n }\n}\n\n/**\n * - EN: React decorator component rendered for SelectNode.\n * - CN: SelectNode 对应的 React 装饰组件。\n *\n * @param node The bound SelectNode instance | 关联的 SelectNode 实例\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction SelectComponent<ValueType = any, OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType>({\n node,\n}: SelectComponentProps<ValueType, OptionType>): ReactNode {\n /* eslint-disable @typescript-eslint/no-unused-vars */\n const { textContentMode, spaceAround, containerStyle, ...selectProps } = node.__props || {};\n /* eslint-enable @typescript-eslint/no-unused-vars */\n const [editor] = useLexicalComposerContext();\n\n const handleChange = useCallback<NonNullable<SelectNodeProps<ValueType, OptionType>['onChange']>>(\n (value, options) => {\n editor.update(() => {\n node.setValue(value);\n node.__props?.onChange?.(value, options);\n });\n },\n [editor, node]\n );\n\n const handleClear = useCallback(() => {\n editor.update(() => {\n node.setValue(undefined);\n node.__props?.onClear?.();\n });\n }, [editor, node]);\n\n return <Select {...selectProps} value={node.getValue()} onChange={handleChange} onClear={handleClear} />;\n}\n\n/**\n * - EN: Factory to create a SelectNode.\n * - CN: 创建 SelectNode 的工厂函数。\n *\n * @param props Props for the Select node | Select 节点的属性\n */\nexport function $createSelectNode<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ValueType = any,\n OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType,\n>(props?: SelectNodeProps<ValueType, OptionType>): SelectNode<ValueType, OptionType> {\n return new SelectNode<ValueType, OptionType>(props);\n}\n\n/**\n * - EN: Type guard to check whether a node is SelectNode.\n * - CN: 判断节点是否为 SelectNode 的类型守卫。\n *\n * @param node Node to test | 要检测的节点\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function $isSelectNode(node: LexicalNode | null | undefined): node is SelectNode<any, any> {\n return node instanceof SelectNode;\n}\n\n/**\n * - EN: Insert a SelectNode at the current cursor position.\n * - CN: 在当前光标位置插入一个 SelectNode。\n *\n * @param editor LexicalEditor instance | LexicalEditor 实例\n * @param props Props for the Select node | Select 节点的属性\n */\nexport function $insertSelectNode<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ValueType = any,\n OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType,\n>(editor: LexicalEditor, props: SelectNodeProps<ValueType, OptionType>): void {\n editor.update(() => {\n const selectNode = $createSelectNode<ValueType, OptionType>({\n ...props,\n containerStyle: {\n paddingLeft: '8px',\n paddingRight: '8px',\n ...props.containerStyle,\n },\n });\n insertNodeAtCursor(editor, selectNode);\n });\n}\n\n/**\n * - EN: Props passed to the Select decorator component.\n * - CN: 传递给 Select 装饰组件的属性。\n */\ninterface SelectComponentProps<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ValueType = any,\n OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType,\n> {\n node: SelectNode<ValueType, OptionType>;\n}\ntype SerializedSelectNode<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ValueType = any,\n OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType,\n> = Spread<\n {\n props?: SelectNodeProps<ValueType, OptionType>;\n },\n SerializedLexicalNode\n>;\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { type CSSProperties, type ReactNode, useCallback } from 'react';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport { Select } from 'antd';\nimport type { SelectProps } from 'antd';\nimport type { BaseOptionType, DefaultOptionType } from 'antd/es/select';\nimport type { LexicalEditor, LexicalNode, SerializedLexicalNode, Spread } from 'lexical';\nimport { insertNodeAtCursor, updateDomStyle } from '../helpers';\nimport type { BaseDecoratorNodeProps } from './base';\nimport { BaseDecoratorNode } from './base';\n\n/**\n * - EN: Props for SelectNode, extending antd Select props plus behavior flags.\n * - CN: SelectNode 的属性,基于 antd Select 属性并附加行为标记。\n */\nexport interface SelectNodeProps<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ValueType = any,\n OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType,\n> extends SelectProps<ValueType, OptionType>,\n BaseDecoratorNodeProps {\n /**\n * - EN: When reading editor textContent, whether to use option label or value. Default `value`.\n * - CN: 在获取 editor 的 textContent 时,使用选项的 label 还是 value。默认 `value`。\n * - label: use option label as text\n * - value: use option value as text\n */\n textContentMode?: 'label' | 'value';\n /**\n * - EN: Add a space around textContent. Default `true`.\n * - CN: 是否在 textContent 两边添加一个空格,默认 `true`。\n */\n spaceAround?: boolean;\n /**\n * - EN: Container DOM style.\n * - CN: 容器样式。\n */\n containerStyle?: CSSProperties;\n}\n\nexport class SelectNode<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ValueType = any,\n OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType,\n> extends BaseDecoratorNode<ReactNode, SelectNodeProps<ValueType, OptionType>> {\n __value: ValueType | undefined;\n\n constructor(props?: SelectNodeProps<ValueType, OptionType> & { key?: string }) {\n super(props);\n this.__value = props?.defaultValue ?? undefined;\n }\n static getType(): string {\n return 'antd.Select';\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n static clone<ValueType = any, OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType>(\n node: SelectNode<ValueType, OptionType>\n ): SelectNode<ValueType, OptionType> {\n return new SelectNode<ValueType, OptionType>({ ...node.__props, key: node.getKey() });\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n static importJSON<ValueType = any, OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType>(\n serializedNode: SerializedSelectNode<ValueType, OptionType>\n ): SelectNode<ValueType, OptionType> {\n return $createSelectNode(serializedNode.props);\n }\n\n exportJSON(): SerializedSelectNode<ValueType, OptionType> {\n return {\n ...super.exportJSON(),\n props: this.__props,\n type: this.getType(),\n version: 1,\n };\n }\n\n createDOM(): HTMLElement {\n const span = document.createElement('span');\n updateDomStyle(span, this.__props?.containerStyle);\n return span;\n }\n\n updateDOM(): false {\n return false;\n }\n\n decorate(): ReactNode {\n return <SelectComponent node={this} />;\n }\n\n isInline(): boolean {\n return true;\n }\n\n getTextContent(): string {\n let content: string;\n const valueContent = this.__value ? String(this.__value) : '';\n if (this.__props?.textContentMode === 'label') {\n const option = this.__props?.options?.find((opt) => opt.value === this.__value);\n content = option?.label ? String(option.label) : valueContent;\n } else {\n content = valueContent;\n }\n if (this.__props?.spaceAround !== false) {\n return ` ${content} `;\n }\n return content;\n }\n\n getValue(): ValueType | undefined {\n return this.__value;\n }\n\n setValue(value: ValueType | undefined): void {\n const writable = this.getWritable();\n writable.__value = value;\n }\n\n getPropValue(\n propName: keyof SelectNodeProps<ValueType, OptionType>\n ): SelectNodeProps<ValueType, OptionType>[typeof propName] {\n return this.__props?.[propName];\n }\n\n setProps(props: Partial<SelectNodeProps<ValueType, OptionType>>): void {\n const writable = this.getWritable();\n writable.__props = {\n ...writable.__props,\n ...props,\n };\n }\n}\n\n/**\n * - EN: React decorator component rendered for SelectNode.\n * - CN: SelectNode 对应的 React 装饰组件。\n *\n * @param node The bound SelectNode instance | 关联的 SelectNode 实例\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction SelectComponent<ValueType = any, OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType>({\n node,\n}: SelectComponentProps<ValueType, OptionType>): ReactNode {\n const underlyingProps = node.getUnderlyingProps(node.__props);\n /* eslint-disable @typescript-eslint/no-unused-vars */\n const { textContentMode, spaceAround, containerStyle, ...selectProps } = underlyingProps;\n /* eslint-enable @typescript-eslint/no-unused-vars */\n const [editor] = useLexicalComposerContext();\n\n const handleChange = useCallback<NonNullable<SelectNodeProps<ValueType, OptionType>['onChange']>>(\n (value, options) => {\n editor.update(() => {\n node.setValue(value);\n node.__props?.onChange?.(value, options);\n });\n },\n [editor, node]\n );\n\n const handleClear = useCallback(() => {\n editor.update(() => {\n node.setValue(undefined);\n node.__props?.onClear?.();\n });\n }, [editor, node]);\n\n return <Select {...selectProps} value={node.getValue()} onChange={handleChange} onClear={handleClear} />;\n}\n\n/**\n * - EN: Factory to create a SelectNode.\n * - CN: 创建 SelectNode 的工厂函数。\n *\n * @param props Props for the Select node | Select 节点的属性\n */\nexport function $createSelectNode<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ValueType = any,\n OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType,\n>(props?: SelectNodeProps<ValueType, OptionType>): SelectNode<ValueType, OptionType> {\n return new SelectNode<ValueType, OptionType>(props);\n}\n\n/**\n * - EN: Type guard to check whether a node is SelectNode.\n * - CN: 判断节点是否为 SelectNode 的类型守卫。\n *\n * @param node Node to test | 要检测的节点\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function $isSelectNode(node: LexicalNode | null | undefined): node is SelectNode<any, any> {\n return node instanceof SelectNode;\n}\n\n/**\n * - EN: Insert a SelectNode at the current cursor position.\n * - CN: 在当前光标位置插入一个 SelectNode。\n *\n * @param editor LexicalEditor instance | LexicalEditor 实例\n * @param props Props for the Select node | Select 节点的属性\n */\nexport function $insertSelectNode<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ValueType = any,\n OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType,\n>(editor: LexicalEditor, props: SelectNodeProps<ValueType, OptionType>): void {\n editor.update(() => {\n const selectNode = $createSelectNode<ValueType, OptionType>({\n ...props,\n containerStyle: {\n paddingLeft: '8px',\n paddingRight: '8px',\n ...props.containerStyle,\n },\n });\n insertNodeAtCursor(editor, selectNode);\n });\n}\n\n/**\n * - EN: Props passed to the Select decorator component.\n * - CN: 传递给 Select 装饰组件的属性。\n */\ninterface SelectComponentProps<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ValueType = any,\n OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType,\n> {\n node: SelectNode<ValueType, OptionType>;\n}\ntype SerializedSelectNode<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ValueType = any,\n OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType,\n> = Spread<\n {\n props?: SelectNodeProps<ValueType, OptionType>;\n },\n SerializedLexicalNode\n>;\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAgE;AAChE,oCAA0C;AAC1C,kBAAuB;AAIvB,qBAAmD;AAEnD,kBAAkC;AA+B3B,IAAM,aAAN,cAIG,8BAAqE;AAAA,EAG7E,YAAY,OAAmE;AAC7E,UAAM,KAAK;AACX,SAAK,WAAU,+BAAO,iBAAgB;AAAA,EACxC;AAAA,EACA,OAAO,UAAkB;AACvB,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,OAAO,MACL,MACmC;AACnC,WAAO,IAAI,WAAkC,EAAE,GAAG,KAAK,SAAS,KAAK,KAAK,OAAO,EAAE,CAAC;AAAA,EACtF;AAAA;AAAA,EAGA,OAAO,WACL,gBACmC;AACnC,WAAO,kBAAkB,eAAe,KAAK;AAAA,EAC/C;AAAA,EAEA,aAA0D;AACxD,WAAO;AAAA,MACL,GAAG,MAAM,WAAW;AAAA,MACpB,OAAO,KAAK;AAAA,MACZ,MAAM,KAAK,QAAQ;AAAA,MACnB,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EAEA,YAAyB;AA7E3B;AA8EI,UAAM,OAAO,SAAS,cAAc,MAAM;AAC1C,uCAAe,OAAM,UAAK,YAAL,mBAAc,cAAc;AACjD,WAAO;AAAA,EACT;AAAA,EAEA,YAAmB;AACjB,WAAO;AAAA,EACT;AAAA,EAEA,WAAsB;AACpB,WAAO,oCAAC,mBAAgB,MAAM,MAAM;AAAA,EACtC;AAAA,EAEA,WAAoB;AAClB,WAAO;AAAA,EACT;AAAA,EAEA,iBAAyB;AA/F3B;AAgGI,QAAI;AACJ,UAAM,eAAe,KAAK,UAAU,OAAO,KAAK,OAAO,IAAI;AAC3D,UAAI,UAAK,YAAL,mBAAc,qBAAoB,SAAS;AAC7C,YAAM,UAAS,gBAAK,YAAL,mBAAc,YAAd,mBAAuB,KAAK,CAAC,QAAQ,IAAI,UAAU,KAAK;AACvE,iBAAU,iCAAQ,SAAQ,OAAO,OAAO,KAAK,IAAI;AAAA,IACnD,OAAO;AACL,gBAAU;AAAA,IACZ;AACA,UAAI,UAAK,YAAL,mBAAc,iBAAgB,OAAO;AACvC,aAAO,IAAI;AAAA,IACb;AACA,WAAO;AAAA,EACT;AAAA,EAEA,WAAkC;AAChC,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,SAAS,OAAoC;AAC3C,UAAM,WAAW,KAAK,YAAY;AAClC,aAAS,UAAU;AAAA,EACrB;AAAA,EAEA,aACE,UACyD;AAzH7D;AA0HI,YAAO,UAAK,YAAL,mBAAe;AAAA,EACxB;AAAA,EAEA,SAAS,OAA8D;AACrE,UAAM,WAAW,KAAK,YAAY;AAClC,aAAS,UAAU;AAAA,MACjB,GAAG,SAAS;AAAA,MACZ,GAAG;AAAA,IACL;AAAA,EACF;AACF;AASA,SAAS,gBAA4G;AAAA,EACnH;AACF,GAA2D;AACzD,QAAM,kBAAkB,KAAK,mBAAmB,KAAK,OAAO;AAE5D,QAAM,EAAE,iBAAiB,aAAa,gBAAgB,GAAG,YAAY,IAAI;AAEzE,QAAM,CAAC,MAAM,QAAI,yDAA0B;AAE3C,QAAM,mBAAe;AAAA,IACnB,CAAC,OAAO,YAAY;AAClB,aAAO,OAAO,MAAM;AAxJ1B;AAyJQ,aAAK,SAAS,KAAK;AACnB,yBAAK,YAAL,mBAAc,aAAd,4BAAyB,OAAO;AAAA,MAClC,CAAC;AAAA,IACH;AAAA,IACA,CAAC,QAAQ,IAAI;AAAA,EACf;AAEA,QAAM,kBAAc,0BAAY,MAAM;AACpC,WAAO,OAAO,MAAM;AAjKxB;AAkKM,WAAK,SAAS,MAAS;AACvB,uBAAK,YAAL,mBAAc,YAAd;AAAA,IACF,CAAC;AAAA,EACH,GAAG,CAAC,QAAQ,IAAI,CAAC;AAEjB,SAAO,oCAAC,sBAAQ,GAAG,aAAa,OAAO,KAAK,SAAS,GAAG,UAAU,cAAc,SAAS,aAAa;AACxG;AAQO,SAAS,kBAId,OAAmF;AACnF,SAAO,IAAI,WAAkC,KAAK;AACpD;AASO,SAAS,cAAc,MAAoE;AAChG,SAAO,gBAAgB;AACzB;AASO,SAAS,kBAId,QAAuB,OAAqD;AAC5E,SAAO,OAAO,MAAM;AAClB,UAAM,aAAa,kBAAyC;AAAA,MAC1D,GAAG;AAAA,MACH,gBAAgB;AAAA,QACd,aAAa;AAAA,QACb,cAAc;AAAA,QACd,GAAG,MAAM;AAAA,MACX;AAAA,IACF,CAAC;AACD,2CAAmB,QAAQ,UAAU;AAAA,EACvC,CAAC;AACH;",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tiny-codes/react-easy",
3
- "version": "1.4.1",
3
+ "version": "1.4.2",
4
4
  "description": "Simplify React and AntDesign development with practical components and hooks",
5
5
  "keywords": [
6
6
  "react",