payload-intl 0.2.2 → 0.2.3

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.
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  import { jsx as l } from "react/jsx-runtime";
2
3
  import { defaultEditorFeatures as p, defaultEditorConfig as f } from "@payloadcms/richtext-lexical";
3
4
  import { sanitizeClientEditorConfig as g, RenderLexical as E, getEnabledNodes as S } from "@payloadcms/richtext-lexical/client";
@@ -1 +1 @@
1
- {"version":3,"file":"LexicalInput.js","sources":["../../../src/components/inputs/LexicalInput.tsx"],"sourcesContent":["import type {\n DefaultNodeTypes,\n TypedEditorState,\n} from \"@payloadcms/richtext-lexical\";\nimport type { SerializedEditorState } from \"@payloadcms/richtext-lexical/lexical\";\nimport {\n defaultEditorConfig,\n defaultEditorFeatures,\n} from \"@payloadcms/richtext-lexical\";\nimport {\n getEnabledNodes,\n RenderLexical,\n sanitizeClientEditorConfig,\n} from \"@payloadcms/richtext-lexical/client\";\nimport { $getRoot } from \"@payloadcms/richtext-lexical/lexical\";\nimport { createHeadlessEditor } from \"@payloadcms/richtext-lexical/lexical/headless\";\nimport {\n $generateHtmlFromNodes,\n $generateNodesFromDOM,\n} from \"@payloadcms/richtext-lexical/lexical/html\";\nimport { useCallback, useMemo, useRef } from \"react\";\n\nimport type { InputWrapperProps } from \"./InputWrapper\";\nimport { InputWrapper } from \"./InputWrapper\";\n\nexport interface LexicalInputProps extends InputWrapperProps {\n lang: string;\n value: string;\n onChange: (value: string) => void;\n onBlur: () => void;\n}\n\nexport function LexicalInput({\n error,\n label,\n value,\n onChange,\n className,\n}: LexicalInputProps): React.ReactNode {\n const editor = useHtmlLexicalAdapter({\n html: value,\n onChange,\n });\n\n return (\n <InputWrapper label={label} error={error} className={className}>\n <RenderLexical\n field={{\n name: \"myCustomEditor\",\n label: false,\n type: \"richText\",\n }}\n value={editor.value}\n setValue={(val) => editor.setValue(val as SerializedEditorState)}\n schemaPath=\"global.intl-plugin.editorTemplate\"\n />\n </InputWrapper>\n );\n}\n\nconst EMPTY_STATE: TypedEditorState<DefaultNodeTypes> = {\n root: {\n children: [\n {\n children: [],\n direction: null,\n textFormat: 0,\n format: \"left\",\n indent: 0,\n type: \"paragraph\",\n version: 1,\n },\n ],\n direction: null,\n format: \"\",\n indent: 0,\n type: \"root\",\n version: 1,\n },\n};\n\nconst editorConfig = sanitizeClientEditorConfig(\n // @ts-expect-error - it works\n defaultEditorFeatures,\n defaultEditorConfig,\n);\n\ninterface UseHtmlLexicalAdapterProps {\n html: string;\n onChange: (html: string) => void;\n}\n\nexport function useHtmlLexicalAdapter({\n html,\n onChange,\n}: UseHtmlLexicalAdapterProps) {\n // 1. Maintain a persistent headless editor for conversion\n const headlessEditor = useRef(\n createHeadlessEditor({\n nodes: getEnabledNodes({\n editorConfig,\n }),\n }),\n );\n\n // 2. HTML -> SerializedState\n const getSerializedState = useCallback(\n (htmlString: string): SerializedEditorState => {\n const editor = headlessEditor.current;\n editor.update(\n () => {\n const parser = new DOMParser();\n const dom = parser.parseFromString(htmlString, \"text/html\");\n const nodes = $generateNodesFromDOM(editor, dom);\n\n const root = $getRoot();\n root.clear().append(...nodes);\n },\n { discrete: true },\n );\n\n return editor.getEditorState().toJSON();\n },\n [],\n );\n\n // 3. Memoize the initial value to prevent unnecessary re-renders\n const value = useMemo(() => {\n const serializedState = getSerializedState(html);\n\n if (serializedState.root.children.length === 0) {\n return EMPTY_STATE;\n }\n\n return serializedState;\n }, [html, getSerializedState]);\n\n // 4. SerializedState -> HTML\n const setValue = useCallback(\n (serializedState: SerializedEditorState) => {\n const editor = headlessEditor.current;\n\n // Update headless editor to match the incoming state\n editor.setEditorState(editor.parseEditorState(serializedState));\n\n // Generate HTML and broadcast if it has changed\n editor.read(() => {\n const newHtml = $generateHtmlFromNodes(editor);\n if (newHtml !== html) {\n onChange(newHtml);\n }\n });\n },\n [html, onChange],\n );\n\n return { value: value as TypedEditorState<DefaultNodeTypes>, setValue };\n}\n"],"names":["LexicalInput","error","label","value","onChange","className","editor","useHtmlLexicalAdapter","jsx","InputWrapper","RenderLexical","val","EMPTY_STATE","editorConfig","sanitizeClientEditorConfig","defaultEditorFeatures","defaultEditorConfig","html","headlessEditor","useRef","createHeadlessEditor","getEnabledNodes","getSerializedState","useCallback","htmlString","dom","nodes","$generateNodesFromDOM","$getRoot","useMemo","serializedState","setValue","newHtml","$generateHtmlFromNodes"],"mappings":";;;;;;;;AAgCO,SAASA,EAAa;AAAA,EAC3B,OAAAC;AAAA,EACA,OAAAC;AAAA,EACA,OAAAC;AAAA,EACA,UAAAC;AAAA,EACA,WAAAC;AACF,GAAuC;AACrC,QAAMC,IAASC,EAAsB;AAAA,IACnC,MAAMJ;AAAA,IACN,UAAAC;AAAA,EAAA,CACD;AAED,SACE,gBAAAI,EAACC,GAAA,EAAa,OAAAP,GAAc,OAAAD,GAAc,WAAAI,GACxC,UAAA,gBAAAG;AAAA,IAACE;AAAA,IAAA;AAAA,MACC,OAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO;AAAA,QACP,MAAM;AAAA,MAAA;AAAA,MAER,OAAOJ,EAAO;AAAA,MACd,UAAU,CAACK,MAAQL,EAAO,SAASK,CAA4B;AAAA,MAC/D,YAAW;AAAA,IAAA;AAAA,EAAA,GAEf;AAEJ;AAEA,MAAMC,IAAkD;AAAA,EACtD,MAAM;AAAA,IACJ,UAAU;AAAA,MACR;AAAA,QACE,UAAU,CAAA;AAAA,QACV,WAAW;AAAA,QACX,YAAY;AAAA,QACZ,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,SAAS;AAAA,MAAA;AAAA,IACX;AAAA,IAEF,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,SAAS;AAAA,EAAA;AAEb,GAEMC,IAAeC;AAAA;AAAA,EAEnBC;AAAA,EACAC;AACF;AAOO,SAAST,EAAsB;AAAA,EACpC,MAAAU;AAAA,EACA,UAAAb;AACF,GAA+B;AAE7B,QAAMc,IAAiBC;AAAA,IACrBC,EAAqB;AAAA,MACnB,OAAOC,EAAgB;AAAA,QACrB,cAAAR;AAAA,MAAA,CACD;AAAA,IAAA,CACF;AAAA,EAAA,GAIGS,IAAqBC;AAAA,IACzB,CAACC,MAA8C;AAC7C,YAAMlB,IAASY,EAAe;AAC9B,aAAAZ,EAAO;AAAA,QACL,MAAM;AAEJ,gBAAMmB,IADS,IAAI,UAAA,EACA,gBAAgBD,GAAY,WAAW,GACpDE,IAAQC,EAAsBrB,GAAQmB,CAAG;AAG/C,UADaG,EAAA,EACR,MAAA,EAAQ,OAAO,GAAGF,CAAK;AAAA,QAC9B;AAAA,QACA,EAAE,UAAU,GAAA;AAAA,MAAK,GAGZpB,EAAO,eAAA,EAAiB,OAAA;AAAA,IACjC;AAAA,IACA,CAAA;AAAA,EAAC,GAIGH,IAAQ0B,EAAQ,MAAM;AAC1B,UAAMC,IAAkBR,EAAmBL,CAAI;AAE/C,WAAIa,EAAgB,KAAK,SAAS,WAAW,IACpClB,IAGFkB;AAAA,EACT,GAAG,CAACb,GAAMK,CAAkB,CAAC,GAGvBS,IAAWR;AAAA,IACf,CAACO,MAA2C;AAC1C,YAAMxB,IAASY,EAAe;AAG9B,MAAAZ,EAAO,eAAeA,EAAO,iBAAiBwB,CAAe,CAAC,GAG9DxB,EAAO,KAAK,MAAM;AAChB,cAAM0B,IAAUC,EAAuB3B,CAAM;AAC7C,QAAI0B,MAAYf,KACdb,EAAS4B,CAAO;AAAA,MAEpB,CAAC;AAAA,IACH;AAAA,IACA,CAACf,GAAMb,CAAQ;AAAA,EAAA;AAGjB,SAAO,EAAE,OAAAD,GAAoD,UAAA4B,EAAA;AAC/D;"}
1
+ {"version":3,"file":"LexicalInput.js","sources":["../../../src/components/inputs/LexicalInput.tsx"],"sourcesContent":["\"use client\";\nimport type {\n DefaultNodeTypes,\n TypedEditorState,\n} from \"@payloadcms/richtext-lexical\";\nimport type { SerializedEditorState } from \"@payloadcms/richtext-lexical/lexical\";\nimport {\n defaultEditorConfig,\n defaultEditorFeatures,\n} from \"@payloadcms/richtext-lexical\";\nimport {\n getEnabledNodes,\n RenderLexical,\n sanitizeClientEditorConfig,\n} from \"@payloadcms/richtext-lexical/client\";\nimport { $getRoot } from \"@payloadcms/richtext-lexical/lexical\";\nimport { createHeadlessEditor } from \"@payloadcms/richtext-lexical/lexical/headless\";\nimport {\n $generateHtmlFromNodes,\n $generateNodesFromDOM,\n} from \"@payloadcms/richtext-lexical/lexical/html\";\nimport { useCallback, useMemo, useRef } from \"react\";\n\nimport type { InputWrapperProps } from \"./InputWrapper\";\nimport { InputWrapper } from \"./InputWrapper\";\n\nexport interface LexicalInputProps extends InputWrapperProps {\n lang: string;\n value: string;\n onChange: (value: string) => void;\n onBlur: () => void;\n}\n\nexport function LexicalInput({\n error,\n label,\n value,\n onChange,\n className,\n}: LexicalInputProps): React.ReactNode {\n const editor = useHtmlLexicalAdapter({\n html: value,\n onChange,\n });\n\n return (\n <InputWrapper label={label} error={error} className={className}>\n <RenderLexical\n field={{\n name: \"myCustomEditor\",\n label: false,\n type: \"richText\",\n }}\n value={editor.value}\n setValue={(val) => editor.setValue(val as SerializedEditorState)}\n schemaPath=\"global.intl-plugin.editorTemplate\"\n />\n </InputWrapper>\n );\n}\n\nconst EMPTY_STATE: TypedEditorState<DefaultNodeTypes> = {\n root: {\n children: [\n {\n children: [],\n direction: null,\n textFormat: 0,\n format: \"left\",\n indent: 0,\n type: \"paragraph\",\n version: 1,\n },\n ],\n direction: null,\n format: \"\",\n indent: 0,\n type: \"root\",\n version: 1,\n },\n};\n\nconst editorConfig = sanitizeClientEditorConfig(\n // @ts-expect-error - it works\n defaultEditorFeatures,\n defaultEditorConfig,\n);\n\ninterface UseHtmlLexicalAdapterProps {\n html: string;\n onChange: (html: string) => void;\n}\n\nexport function useHtmlLexicalAdapter({\n html,\n onChange,\n}: UseHtmlLexicalAdapterProps) {\n // 1. Maintain a persistent headless editor for conversion\n const headlessEditor = useRef(\n createHeadlessEditor({\n nodes: getEnabledNodes({\n editorConfig,\n }),\n }),\n );\n\n // 2. HTML -> SerializedState\n const getSerializedState = useCallback(\n (htmlString: string): SerializedEditorState => {\n const editor = headlessEditor.current;\n editor.update(\n () => {\n const parser = new DOMParser();\n const dom = parser.parseFromString(htmlString, \"text/html\");\n const nodes = $generateNodesFromDOM(editor, dom);\n\n const root = $getRoot();\n root.clear().append(...nodes);\n },\n { discrete: true },\n );\n\n return editor.getEditorState().toJSON();\n },\n [],\n );\n\n // 3. Memoize the initial value to prevent unnecessary re-renders\n const value = useMemo(() => {\n const serializedState = getSerializedState(html);\n\n if (serializedState.root.children.length === 0) {\n return EMPTY_STATE;\n }\n\n return serializedState;\n }, [html, getSerializedState]);\n\n // 4. SerializedState -> HTML\n const setValue = useCallback(\n (serializedState: SerializedEditorState) => {\n const editor = headlessEditor.current;\n\n // Update headless editor to match the incoming state\n editor.setEditorState(editor.parseEditorState(serializedState));\n\n // Generate HTML and broadcast if it has changed\n editor.read(() => {\n const newHtml = $generateHtmlFromNodes(editor);\n if (newHtml !== html) {\n onChange(newHtml);\n }\n });\n },\n [html, onChange],\n );\n\n return { value: value as TypedEditorState<DefaultNodeTypes>, setValue };\n}\n"],"names":["LexicalInput","error","label","value","onChange","className","editor","useHtmlLexicalAdapter","jsx","InputWrapper","RenderLexical","val","EMPTY_STATE","editorConfig","sanitizeClientEditorConfig","defaultEditorFeatures","defaultEditorConfig","html","headlessEditor","useRef","createHeadlessEditor","getEnabledNodes","getSerializedState","useCallback","htmlString","dom","nodes","$generateNodesFromDOM","$getRoot","useMemo","serializedState","setValue","newHtml","$generateHtmlFromNodes"],"mappings":";;;;;;;;;AAiCO,SAASA,EAAa;AAAA,EAC3B,OAAAC;AAAA,EACA,OAAAC;AAAA,EACA,OAAAC;AAAA,EACA,UAAAC;AAAA,EACA,WAAAC;AACF,GAAuC;AACrC,QAAMC,IAASC,EAAsB;AAAA,IACnC,MAAMJ;AAAA,IACN,UAAAC;AAAA,EAAA,CACD;AAED,SACE,gBAAAI,EAACC,GAAA,EAAa,OAAAP,GAAc,OAAAD,GAAc,WAAAI,GACxC,UAAA,gBAAAG;AAAA,IAACE;AAAA,IAAA;AAAA,MACC,OAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO;AAAA,QACP,MAAM;AAAA,MAAA;AAAA,MAER,OAAOJ,EAAO;AAAA,MACd,UAAU,CAACK,MAAQL,EAAO,SAASK,CAA4B;AAAA,MAC/D,YAAW;AAAA,IAAA;AAAA,EAAA,GAEf;AAEJ;AAEA,MAAMC,IAAkD;AAAA,EACtD,MAAM;AAAA,IACJ,UAAU;AAAA,MACR;AAAA,QACE,UAAU,CAAA;AAAA,QACV,WAAW;AAAA,QACX,YAAY;AAAA,QACZ,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,SAAS;AAAA,MAAA;AAAA,IACX;AAAA,IAEF,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,SAAS;AAAA,EAAA;AAEb,GAEMC,IAAeC;AAAA;AAAA,EAEnBC;AAAA,EACAC;AACF;AAOO,SAAST,EAAsB;AAAA,EACpC,MAAAU;AAAA,EACA,UAAAb;AACF,GAA+B;AAE7B,QAAMc,IAAiBC;AAAA,IACrBC,EAAqB;AAAA,MACnB,OAAOC,EAAgB;AAAA,QACrB,cAAAR;AAAA,MAAA,CACD;AAAA,IAAA,CACF;AAAA,EAAA,GAIGS,IAAqBC;AAAA,IACzB,CAACC,MAA8C;AAC7C,YAAMlB,IAASY,EAAe;AAC9B,aAAAZ,EAAO;AAAA,QACL,MAAM;AAEJ,gBAAMmB,IADS,IAAI,UAAA,EACA,gBAAgBD,GAAY,WAAW,GACpDE,IAAQC,EAAsBrB,GAAQmB,CAAG;AAG/C,UADaG,EAAA,EACR,MAAA,EAAQ,OAAO,GAAGF,CAAK;AAAA,QAC9B;AAAA,QACA,EAAE,UAAU,GAAA;AAAA,MAAK,GAGZpB,EAAO,eAAA,EAAiB,OAAA;AAAA,IACjC;AAAA,IACA,CAAA;AAAA,EAAC,GAIGH,IAAQ0B,EAAQ,MAAM;AAC1B,UAAMC,IAAkBR,EAAmBL,CAAI;AAE/C,WAAIa,EAAgB,KAAK,SAAS,WAAW,IACpClB,IAGFkB;AAAA,EACT,GAAG,CAACb,GAAMK,CAAkB,CAAC,GAGvBS,IAAWR;AAAA,IACf,CAACO,MAA2C;AAC1C,YAAMxB,IAASY,EAAe;AAG9B,MAAAZ,EAAO,eAAeA,EAAO,iBAAiBwB,CAAe,CAAC,GAG9DxB,EAAO,KAAK,MAAM;AAChB,cAAM0B,IAAUC,EAAuB3B,CAAM;AAC7C,QAAI0B,MAAYf,KACdb,EAAS4B,CAAO;AAAA,MAEpB,CAAC;AAAA,IACH;AAAA,IACA,CAACf,GAAMb,CAAQ;AAAA,EAAA;AAGjB,SAAO,EAAE,OAAAD,GAAoD,UAAA4B,EAAA;AAC/D;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "payload-intl",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "Payload Plugin for I18N using ICU Messages",
5
5
  "license": "MIT",
6
6
  "author": "Michael Zeltner",