payload-intl 1.2.2 → 1.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.
Files changed (163) hide show
  1. package/dist/components/MessageFormField.d.ts +15 -0
  2. package/dist/components/MessageFormField.d.ts.map +1 -0
  3. package/dist/components/{MessageController.js → MessageFormField.js} +5 -3
  4. package/dist/components/MessageFormField.js.map +1 -0
  5. package/dist/components/MessagesForm.d.ts +3 -1
  6. package/dist/components/MessagesForm.d.ts.map +1 -1
  7. package/dist/components/MessagesForm.js +25 -36
  8. package/dist/components/MessagesForm.js.map +1 -1
  9. package/dist/components/{MessageFormContext.d.ts → MessagesFormProvider.d.ts} +6 -2
  10. package/dist/components/MessagesFormProvider.d.ts.map +1 -0
  11. package/dist/components/{MessageFormContext.js → MessagesFormProvider.js} +8 -4
  12. package/dist/components/MessagesFormProvider.js.map +1 -0
  13. package/dist/components/MessagesLink.js +5 -2
  14. package/dist/components/MessagesLink.js.map +1 -1
  15. package/dist/components/MessagesView.d.ts +1 -1
  16. package/dist/components/MessagesView.d.ts.map +1 -1
  17. package/dist/components/MessagesView.js +13 -4
  18. package/dist/components/MessagesView.js.map +1 -1
  19. package/dist/components/actions/CopyMessages.d.ts +2 -0
  20. package/dist/components/actions/CopyMessages.d.ts.map +1 -0
  21. package/dist/components/actions/{Move.js → CopyMessages.js} +6 -6
  22. package/dist/components/actions/CopyMessages.js.map +1 -0
  23. package/dist/components/actions/JsonImport.d.ts +4 -1
  24. package/dist/components/actions/JsonImport.d.ts.map +1 -1
  25. package/dist/components/actions/JsonImport.js +7 -25
  26. package/dist/components/actions/JsonImport.js.map +1 -1
  27. package/dist/components/hooks/useHtmlLexicalAdapter.d.ts +12 -0
  28. package/dist/components/hooks/useHtmlLexicalAdapter.d.ts.map +1 -0
  29. package/dist/components/hooks/useHtmlLexicalAdapter.js +63 -0
  30. package/dist/components/hooks/useHtmlLexicalAdapter.js.map +1 -0
  31. package/dist/components/hooks/useMessagesFormSubmit.d.ts +11 -0
  32. package/dist/components/hooks/useMessagesFormSubmit.d.ts.map +1 -0
  33. package/dist/components/hooks/useMessagesFormSubmit.js +44 -0
  34. package/dist/components/hooks/useMessagesFormSubmit.js.map +1 -0
  35. package/dist/components/inputs/FieldWrapper.d.ts +9 -0
  36. package/dist/components/inputs/FieldWrapper.d.ts.map +1 -0
  37. package/dist/components/inputs/FieldWrapper.js +24 -0
  38. package/dist/components/inputs/FieldWrapper.js.map +1 -0
  39. package/dist/components/inputs/{InputWrapper.module.css → FieldWrapper.module.css} +2 -12
  40. package/dist/components/inputs/LexicalInput.d.ts +2 -13
  41. package/dist/components/inputs/LexicalInput.d.ts.map +1 -1
  42. package/dist/components/inputs/LexicalInput.js +4 -63
  43. package/dist/components/inputs/LexicalInput.js.map +1 -1
  44. package/dist/components/inputs/MessageInput.d.ts +6 -3
  45. package/dist/components/inputs/MessageInput.d.ts.map +1 -1
  46. package/dist/components/inputs/MessageInput.js +47 -43
  47. package/dist/components/inputs/MessageInput.js.map +1 -1
  48. package/dist/components/inputs/MessageInput.module.css +23 -4
  49. package/dist/components/inputs/ReferencePopover.d.ts +7 -0
  50. package/dist/components/inputs/ReferencePopover.d.ts.map +1 -0
  51. package/dist/components/inputs/ReferencePopover.js +42 -0
  52. package/dist/components/inputs/ReferencePopover.js.map +1 -0
  53. package/dist/components/inputs/ReferencePopover.module.css +70 -0
  54. package/dist/components/inputs/SingleLinePlugin.d.ts +2 -0
  55. package/dist/components/inputs/SingleLinePlugin.d.ts.map +1 -0
  56. package/dist/components/inputs/SingleLinePlugin.js +24 -0
  57. package/dist/components/inputs/SingleLinePlugin.js.map +1 -0
  58. package/dist/components/inputs/variables/VariableChip.d.ts.map +1 -1
  59. package/dist/components/inputs/variables/VariableChip.js +31 -32
  60. package/dist/components/inputs/variables/VariableChip.js.map +1 -1
  61. package/dist/components/inputs/variables/VariableChip.module.css +3 -3
  62. package/dist/components/inputs/variables/VariableSuggestion.d.ts +4 -0
  63. package/dist/components/inputs/variables/VariableSuggestion.d.ts.map +1 -0
  64. package/dist/components/inputs/variables/VariableSuggestion.js +24 -0
  65. package/dist/components/inputs/variables/VariableSuggestion.js.map +1 -0
  66. package/dist/components/inputs/variables/editors/PluralVariableEditor.d.ts.map +1 -1
  67. package/dist/components/inputs/variables/editors/PluralVariableEditor.js +62 -60
  68. package/dist/components/inputs/variables/editors/PluralVariableEditor.js.map +1 -1
  69. package/dist/components/inputs/variables/editors/PluralVariableEditor.module.css +4 -4
  70. package/dist/components/inputs/variables/editors/TemporalVariableEditor.d.ts +11 -0
  71. package/dist/components/inputs/variables/editors/TemporalVariableEditor.d.ts.map +1 -0
  72. package/dist/components/inputs/variables/editors/{DateVariableEditor.js → TemporalVariableEditor.js} +3 -3
  73. package/dist/components/inputs/variables/editors/TemporalVariableEditor.js.map +1 -0
  74. package/dist/components/inputs/variables/pickers/NumericVariableEditor.d.ts +7 -0
  75. package/dist/components/inputs/variables/pickers/{NumericVariablePicker.d.ts.map → NumericVariableEditor.d.ts.map} +1 -1
  76. package/dist/components/inputs/variables/pickers/{NumericVariablePicker.js → NumericVariableEditor.js} +15 -9
  77. package/dist/components/inputs/variables/pickers/NumericVariableEditor.js.map +1 -0
  78. package/dist/components/inputs/variables/pickers/{NumericVariablePicker.module.css → NumericVariableEditor.module.css} +3 -3
  79. package/dist/components/inputs/variables/pickers/TemporalVariablePicker.d.ts +7 -0
  80. package/dist/components/inputs/variables/pickers/TemporalVariablePicker.d.ts.map +1 -0
  81. package/dist/components/inputs/variables/pickers/TemporalVariablePicker.js +57 -0
  82. package/dist/components/inputs/variables/pickers/TemporalVariablePicker.js.map +1 -0
  83. package/dist/components/inputs/variables/pickers/{TemporalElementEditor.module.css → TemporalVariablePicker.module.css} +3 -3
  84. package/dist/components/layout/GroupStatusDot.d.ts +6 -0
  85. package/dist/components/layout/GroupStatusDot.d.ts.map +1 -0
  86. package/dist/components/layout/GroupStatusDot.js +24 -0
  87. package/dist/components/layout/GroupStatusDot.js.map +1 -0
  88. package/dist/components/layout/MessageField.d.ts +2 -1
  89. package/dist/components/layout/MessageField.d.ts.map +1 -1
  90. package/dist/components/layout/MessageField.js +52 -33
  91. package/dist/components/layout/MessageField.js.map +1 -1
  92. package/dist/components/layout/MessageField.module.css +21 -10
  93. package/dist/components/layout/MessagesTabs.d.ts.map +1 -1
  94. package/dist/components/layout/MessagesTabs.js +3 -5
  95. package/dist/components/layout/MessagesTabs.js.map +1 -1
  96. package/dist/components/layout/MessagesTree.d.ts +1 -1
  97. package/dist/components/layout/MessagesTree.d.ts.map +1 -1
  98. package/dist/components/layout/MessagesTree.js +33 -43
  99. package/dist/components/layout/MessagesTree.js.map +1 -1
  100. package/dist/components/layout/MessagesTree.module.css +10 -5
  101. package/dist/components/layout/StatusDot.d.ts +7 -0
  102. package/dist/components/layout/StatusDot.d.ts.map +1 -0
  103. package/dist/components/layout/StatusDot.js +12 -0
  104. package/dist/components/layout/StatusDot.js.map +1 -0
  105. package/dist/components/layout/StatusDot.module.css +16 -0
  106. package/dist/const.d.ts +2 -2
  107. package/dist/const.js +1 -1
  108. package/dist/entities.js +1 -1
  109. package/dist/internals/index.d.ts.map +1 -0
  110. package/dist/internals/index.js.map +1 -0
  111. package/dist/internals/procedure.d.ts.map +1 -0
  112. package/dist/internals/procedure.js.map +1 -0
  113. package/dist/internals/urls.d.ts.map +1 -0
  114. package/dist/internals/urls.js.map +1 -0
  115. package/dist/internals/utils.d.ts.map +1 -0
  116. package/dist/internals/utils.js.map +1 -0
  117. package/dist/utils/sanitize.d.ts +7 -6
  118. package/dist/utils/sanitize.d.ts.map +1 -1
  119. package/dist/utils/sanitize.js +11 -8
  120. package/dist/utils/sanitize.js.map +1 -1
  121. package/package.json +4 -3
  122. package/dist/_common/index.d.ts.map +0 -1
  123. package/dist/_common/index.js.map +0 -1
  124. package/dist/_common/procedure.d.ts.map +0 -1
  125. package/dist/_common/procedure.js.map +0 -1
  126. package/dist/_common/urls.d.ts.map +0 -1
  127. package/dist/_common/urls.js.map +0 -1
  128. package/dist/_common/utils.d.ts.map +0 -1
  129. package/dist/_common/utils.js.map +0 -1
  130. package/dist/components/MessageController.d.ts +0 -13
  131. package/dist/components/MessageController.d.ts.map +0 -1
  132. package/dist/components/MessageController.js.map +0 -1
  133. package/dist/components/MessageFormContext.d.ts.map +0 -1
  134. package/dist/components/MessageFormContext.js.map +0 -1
  135. package/dist/components/actions/Move.d.ts +0 -2
  136. package/dist/components/actions/Move.d.ts.map +0 -1
  137. package/dist/components/actions/Move.js.map +0 -1
  138. package/dist/components/inputs/InputWrapper.d.ts +0 -8
  139. package/dist/components/inputs/InputWrapper.d.ts.map +0 -1
  140. package/dist/components/inputs/InputWrapper.js +0 -34
  141. package/dist/components/inputs/InputWrapper.js.map +0 -1
  142. package/dist/components/inputs/variables/editors/DateVariableEditor.d.ts +0 -10
  143. package/dist/components/inputs/variables/editors/DateVariableEditor.d.ts.map +0 -1
  144. package/dist/components/inputs/variables/editors/DateVariableEditor.js.map +0 -1
  145. package/dist/components/inputs/variables/editors/TimeVariableEditor.d.ts +0 -10
  146. package/dist/components/inputs/variables/editors/TimeVariableEditor.d.ts.map +0 -1
  147. package/dist/components/inputs/variables/editors/TimeVariableEditor.js +0 -15
  148. package/dist/components/inputs/variables/editors/TimeVariableEditor.js.map +0 -1
  149. package/dist/components/inputs/variables/pickers/NumericVariablePicker.d.ts +0 -7
  150. package/dist/components/inputs/variables/pickers/NumericVariablePicker.js.map +0 -1
  151. package/dist/components/inputs/variables/pickers/TemporalElementEditor.d.ts +0 -7
  152. package/dist/components/inputs/variables/pickers/TemporalElementEditor.d.ts.map +0 -1
  153. package/dist/components/inputs/variables/pickers/TemporalElementEditor.js +0 -58
  154. package/dist/components/inputs/variables/pickers/TemporalElementEditor.js.map +0 -1
  155. /package/dist/components/actions/{Move.module.css → CopyMessages.module.css} +0 -0
  156. /package/dist/{_common → internals}/index.d.ts +0 -0
  157. /package/dist/{_common → internals}/index.js +0 -0
  158. /package/dist/{_common → internals}/procedure.d.ts +0 -0
  159. /package/dist/{_common → internals}/procedure.js +0 -0
  160. /package/dist/{_common → internals}/urls.d.ts +0 -0
  161. /package/dist/{_common → internals}/urls.js +0 -0
  162. /package/dist/{_common → internals}/utils.d.ts +0 -0
  163. /package/dist/{_common → internals}/utils.js +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/hooks/useHtmlLexicalAdapter.ts"],"sourcesContent":["import type {\n DefaultNodeTypes,\n TypedEditorState,\n} from '@payloadcms/richtext-lexical';\nimport {\n defaultEditorConfig,\n defaultEditorFeatures,\n} from '@payloadcms/richtext-lexical';\nimport {\n buildDefaultEditorState,\n getEnabledNodes,\n sanitizeClientEditorConfig,\n} from '@payloadcms/richtext-lexical/client';\nimport type { SerializedEditorState } from '@payloadcms/richtext-lexical/lexical';\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\nconst EMPTY_STATE = buildDefaultEditorState({});\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: sanitizeClientEditorConfig(\n // @ts-expect-error - FIXME\n defaultEditorFeatures,\n defaultEditorConfig,\n ),\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":["defaultEditorConfig","defaultEditorFeatures","buildDefaultEditorState","getEnabledNodes","sanitizeClientEditorConfig","$getRoot","createHeadlessEditor","$generateHtmlFromNodes","$generateNodesFromDOM","useCallback","useMemo","useRef","EMPTY_STATE","useHtmlLexicalAdapter","html","onChange","headlessEditor","nodes","editorConfig","getSerializedState","htmlString","editor","current","update","parser","DOMParser","dom","parseFromString","root","clear","append","discrete","getEditorState","toJSON","value","serializedState","children","length","setValue","setEditorState","parseEditorState","read","newHtml"],"mappings":"AAIA,SACEA,mBAAmB,EACnBC,qBAAqB,QAChB,+BAA+B;AACtC,SACEC,uBAAuB,EACvBC,eAAe,EACfC,0BAA0B,QACrB,sCAAsC;AAE7C,SAASC,QAAQ,QAAQ,uCAAuC;AAChE,SAASC,oBAAoB,QAAQ,gDAAgD;AACrF,SACEC,sBAAsB,EACtBC,qBAAqB,QAChB,4CAA4C;AACnD,SAASC,WAAW,EAAEC,OAAO,EAAEC,MAAM,QAAQ,QAAQ;AAErD,MAAMC,cAAcV,wBAAwB,CAAC;AAO7C,OAAO,SAASW,sBAAsB,EACpCC,IAAI,EACJC,QAAQ,EACmB;IAC3B,0DAA0D;IAC1D,MAAMC,iBAAiBL,OACrBL,qBAAqB;QACnBW,OAAOd,gBAAgB;YACrBe,cAAcd,2BACZ,2BAA2B;YAC3BH,uBACAD;QAEJ;IACF;IAGF,6BAA6B;IAC7B,MAAMmB,qBAAqBV,YACzB,CAACW;QACC,MAAMC,SAASL,eAAeM,OAAO;QACrCD,OAAOE,MAAM,CACX;YACE,MAAMC,SAAS,IAAIC;YACnB,MAAMC,MAAMF,OAAOG,eAAe,CAACP,YAAY;YAC/C,MAAMH,QAAQT,sBAAsBa,QAAQK;YAE5C,MAAME,OAAOvB;YACbuB,KAAKC,KAAK,GAAGC,MAAM,IAAIb;QACzB,GACA;YAAEc,UAAU;QAAK;QAGnB,OAAOV,OAAOW,cAAc,GAAGC,MAAM;IACvC,GACA,EAAE;IAGJ,iEAAiE;IACjE,MAAMC,QAAQxB,QAAQ;QACpB,MAAMyB,kBAAkBhB,mBAAmBL;QAE3C,IAAIqB,gBAAgBP,IAAI,CAACQ,QAAQ,CAACC,MAAM,KAAK,GAAG;YAC9C,OAAOzB;QACT;QAEA,OAAOuB;IACT,GAAG;QAACrB;QAAMK;KAAmB;IAE7B,6BAA6B;IAC7B,MAAMmB,WAAW7B,YACf,CAAC0B;QACC,MAAMd,SAASL,eAAeM,OAAO;QAErC,qDAAqD;QACrDD,OAAOkB,cAAc,CAAClB,OAAOmB,gBAAgB,CAACL;QAE9C,gDAAgD;QAChDd,OAAOoB,IAAI,CAAC;YACV,MAAMC,UAAUnC,uBAAuBc;YACvC,IAAIqB,YAAY5B,MAAM;gBACpBC,SAAS2B;YACX;QACF;IACF,GACA;QAAC5B;QAAMC;KAAS;IAGlB,OAAO;QAAEmB,OAAOA;QAA6CI;IAAS;AACxE"}
@@ -0,0 +1,11 @@
1
+ import type { UseFormReturn } from 'react-hook-form';
2
+ import type { FormValues } from '../../components/MessagesFormProvider';
3
+ import type { DeepPartial, Messages, Translations } from '../../types';
4
+ interface UseMessagesFormSubmitOptions {
5
+ endpointUrl: string;
6
+ defaultValues: Translations<DeepPartial<Messages>>;
7
+ form: UseFormReturn<FormValues>;
8
+ }
9
+ export declare function useMessagesFormSubmit({ endpointUrl, defaultValues, form, }: UseMessagesFormSubmitOptions): (currentValues: FormValues) => Promise<void>;
10
+ export {};
11
+ //# sourceMappingURL=useMessagesFormSubmit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useMessagesFormSubmit.d.ts","sourceRoot":"","sources":["../../../src/components/hooks/useMessagesFormSubmit.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAC;AACpE,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAGnE,UAAU,4BAA4B;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,YAAY,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC;IACnD,IAAI,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;CACjC;AAED,wBAAgB,qBAAqB,CAAC,EACpC,WAAW,EACX,aAAa,EACb,IAAI,GACL,EAAE,4BAA4B,mBAGc,UAAU,mBAyCtD"}
@@ -0,0 +1,44 @@
1
+ import { toast, useDocumentEvents } from '@payloadcms/ui';
2
+ import { isEqual } from 'lodash-es';
3
+ import { getErrorMessage } from '../../utils/error-handling';
4
+ export function useMessagesFormSubmit({ endpointUrl, defaultValues, form }) {
5
+ const { reportUpdate } = useDocumentEvents();
6
+ const handleSubmit = async (currentValues)=>{
7
+ const toastId = toast.loading('Saving...');
8
+ const changes = Object.entries(currentValues).reduce((acc, [locale, value])=>{
9
+ const hasChanged = !isEqual(value, defaultValues[locale]);
10
+ if (!hasChanged) return acc;
11
+ acc[locale] = value;
12
+ return acc;
13
+ }, {});
14
+ try {
15
+ const response = await fetch(endpointUrl, {
16
+ method: 'PUT',
17
+ headers: {
18
+ 'Content-Type': 'application/json'
19
+ },
20
+ body: JSON.stringify(changes)
21
+ });
22
+ if (!response.ok) {
23
+ const error = await getErrorMessage(response);
24
+ throw new Error(error);
25
+ }
26
+ form.reset(currentValues);
27
+ reportUpdate({
28
+ entitySlug: 'messages',
29
+ operation: 'update',
30
+ updatedAt: new Date().toISOString()
31
+ });
32
+ toast.success('Saved', {
33
+ id: toastId
34
+ });
35
+ } catch (error) {
36
+ toast.error(`Failed to save: ${error instanceof Error ? error.message : 'Unknown error'}`, {
37
+ id: toastId
38
+ });
39
+ }
40
+ };
41
+ return handleSubmit;
42
+ }
43
+
44
+ //# sourceMappingURL=useMessagesFormSubmit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/hooks/useMessagesFormSubmit.ts"],"sourcesContent":["import { toast, useDocumentEvents } from '@payloadcms/ui';\nimport { isEqual } from 'lodash-es';\nimport type { UseFormReturn } from 'react-hook-form';\nimport type { FormValues } from '@/components/MessagesFormProvider';\nimport type { DeepPartial, Messages, Translations } from '@/types';\nimport { getErrorMessage } from '@/utils/error-handling';\n\ninterface UseMessagesFormSubmitOptions {\n endpointUrl: string;\n defaultValues: Translations<DeepPartial<Messages>>;\n form: UseFormReturn<FormValues>;\n}\n\nexport function useMessagesFormSubmit({\n endpointUrl,\n defaultValues,\n form,\n}: UseMessagesFormSubmitOptions) {\n const { reportUpdate } = useDocumentEvents();\n\n const handleSubmit = async (currentValues: FormValues) => {\n const toastId = toast.loading('Saving...');\n const changes = Object.entries(currentValues).reduce<\n Translations<Messages>\n >((acc, [locale, value]) => {\n const hasChanged = !isEqual(value, defaultValues[locale]);\n if (!hasChanged) return acc;\n acc[locale] = value;\n return acc;\n }, {});\n\n try {\n const response = await fetch(endpointUrl, {\n method: 'PUT',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(changes),\n });\n\n if (!response.ok) {\n const error = await getErrorMessage(response);\n throw new Error(error);\n }\n\n form.reset(currentValues);\n reportUpdate({\n entitySlug: 'messages',\n operation: 'update',\n updatedAt: new Date().toISOString(),\n });\n toast.success('Saved', { id: toastId });\n } catch (error) {\n toast.error(\n `Failed to save: ${error instanceof Error ? error.message : 'Unknown error'}`,\n { id: toastId },\n );\n }\n };\n\n return handleSubmit;\n}\n"],"names":["toast","useDocumentEvents","isEqual","getErrorMessage","useMessagesFormSubmit","endpointUrl","defaultValues","form","reportUpdate","handleSubmit","currentValues","toastId","loading","changes","Object","entries","reduce","acc","locale","value","hasChanged","response","fetch","method","headers","body","JSON","stringify","ok","error","Error","reset","entitySlug","operation","updatedAt","Date","toISOString","success","id","message"],"mappings":"AAAA,SAASA,KAAK,EAAEC,iBAAiB,QAAQ,iBAAiB;AAC1D,SAASC,OAAO,QAAQ,YAAY;AAIpC,SAASC,eAAe,QAAQ,yBAAyB;AAQzD,OAAO,SAASC,sBAAsB,EACpCC,WAAW,EACXC,aAAa,EACbC,IAAI,EACyB;IAC7B,MAAM,EAAEC,YAAY,EAAE,GAAGP;IAEzB,MAAMQ,eAAe,OAAOC;QAC1B,MAAMC,UAAUX,MAAMY,OAAO,CAAC;QAC9B,MAAMC,UAAUC,OAAOC,OAAO,CAACL,eAAeM,MAAM,CAElD,CAACC,KAAK,CAACC,QAAQC,MAAM;YACrB,MAAMC,aAAa,CAAClB,QAAQiB,OAAOb,aAAa,CAACY,OAAO;YACxD,IAAI,CAACE,YAAY,OAAOH;YACxBA,GAAG,CAACC,OAAO,GAAGC;YACd,OAAOF;QACT,GAAG,CAAC;QAEJ,IAAI;YACF,MAAMI,WAAW,MAAMC,MAAMjB,aAAa;gBACxCkB,QAAQ;gBACRC,SAAS;oBACP,gBAAgB;gBAClB;gBACAC,MAAMC,KAAKC,SAAS,CAACd;YACvB;YAEA,IAAI,CAACQ,SAASO,EAAE,EAAE;gBAChB,MAAMC,QAAQ,MAAM1B,gBAAgBkB;gBACpC,MAAM,IAAIS,MAAMD;YAClB;YAEAtB,KAAKwB,KAAK,CAACrB;YACXF,aAAa;gBACXwB,YAAY;gBACZC,WAAW;gBACXC,WAAW,IAAIC,OAAOC,WAAW;YACnC;YACApC,MAAMqC,OAAO,CAAC,SAAS;gBAAEC,IAAI3B;YAAQ;QACvC,EAAE,OAAOkB,OAAO;YACd7B,MAAM6B,KAAK,CACT,CAAC,gBAAgB,EAAEA,iBAAiBC,QAAQD,MAAMU,OAAO,GAAG,iBAAiB,EAC7E;gBAAED,IAAI3B;YAAQ;QAElB;IACF;IAEA,OAAOF;AACT"}
@@ -0,0 +1,9 @@
1
+ import type { FieldError } from 'react-hook-form';
2
+ export interface FieldWrapperProps {
3
+ label?: string;
4
+ error: FieldError | undefined;
5
+ className?: string;
6
+ reference?: string;
7
+ }
8
+ export declare function FieldWrapper({ label, error, reference, className, children, }: React.PropsWithChildren<FieldWrapperProps>): import("react/jsx-runtime").JSX.Element;
9
+ //# sourceMappingURL=FieldWrapper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FieldWrapper.d.ts","sourceRoot":"","sources":["../../../src/components/inputs/FieldWrapper.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAKlD,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,UAAU,GAAG,SAAS,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,KAAK,EACL,SAAS,EACT,SAAS,EACT,QAAQ,GACT,EAAE,KAAK,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,2CAa5C"}
@@ -0,0 +1,24 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import clsx from 'clsx';
3
+ import styles from './FieldWrapper.module.css';
4
+ import { ReferencePopover } from './ReferencePopover';
5
+ export function FieldWrapper({ label, error, reference, className, children }) {
6
+ return /*#__PURE__*/ _jsxs("div", {
7
+ className: clsx(styles.wrapper, className),
8
+ children: [
9
+ /*#__PURE__*/ _jsx(ReferencePopover, {
10
+ reference: reference,
11
+ children: /*#__PURE__*/ _jsx("fieldset", {
12
+ className: clsx(styles.fieldset, error && styles.fieldsetError),
13
+ children: children
14
+ })
15
+ }),
16
+ error?.message && /*#__PURE__*/ _jsx("p", {
17
+ className: styles.errorMessage,
18
+ children: error.message
19
+ })
20
+ ]
21
+ });
22
+ }
23
+
24
+ //# sourceMappingURL=FieldWrapper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/inputs/FieldWrapper.tsx"],"sourcesContent":["import { FieldLabel } from '@payloadcms/ui';\nimport clsx from 'clsx';\nimport type { FieldError } from 'react-hook-form';\n\nimport styles from './FieldWrapper.module.css';\nimport { ReferencePopover } from './ReferencePopover';\n\nexport interface FieldWrapperProps {\n label?: string;\n error: FieldError | undefined;\n className?: string;\n reference?: string;\n}\n\nexport function FieldWrapper({\n label,\n error,\n reference,\n className,\n children,\n}: React.PropsWithChildren<FieldWrapperProps>) {\n return (\n <div className={clsx(styles.wrapper, className)}>\n <ReferencePopover reference={reference}>\n <fieldset\n className={clsx(styles.fieldset, error && styles.fieldsetError)}\n >\n {children}\n </fieldset>\n </ReferencePopover>\n {error?.message && <p className={styles.errorMessage}>{error.message}</p>}\n </div>\n );\n}\n"],"names":["clsx","styles","ReferencePopover","FieldWrapper","label","error","reference","className","children","div","wrapper","fieldset","fieldsetError","message","p","errorMessage"],"mappings":";AACA,OAAOA,UAAU,OAAO;AAGxB,OAAOC,YAAY,4BAA4B;AAC/C,SAASC,gBAAgB,QAAQ,qBAAqB;AAStD,OAAO,SAASC,aAAa,EAC3BC,KAAK,EACLC,KAAK,EACLC,SAAS,EACTC,SAAS,EACTC,QAAQ,EACmC;IAC3C,qBACE,MAACC;QAAIF,WAAWP,KAAKC,OAAOS,OAAO,EAAEH;;0BACnC,KAACL;gBAAiBI,WAAWA;0BAC3B,cAAA,KAACK;oBACCJ,WAAWP,KAAKC,OAAOU,QAAQ,EAAEN,SAASJ,OAAOW,aAAa;8BAE7DJ;;;YAGJH,OAAOQ,yBAAW,KAACC;gBAAEP,WAAWN,OAAOc,YAAY;0BAAGV,MAAMQ,OAAO;;;;AAG1E"}
@@ -8,22 +8,12 @@
8
8
 
9
9
  .fieldset {
10
10
  margin-inline: 0;
11
+ padding: 0;
12
+ border: none;
11
13
  flex: 1;
12
- border-radius: var(--style-radius-m);
13
- overflow: visible;
14
- }
15
-
16
- .fieldset:focus-within {
17
- border-color: var(--theme-elevation-400);
18
- }
19
-
20
- .fieldsetError {
21
- border: 1px solid var(--theme-error-400);
22
- background-color: var(--theme-error-100);
23
14
  }
24
15
 
25
16
  .legend {
26
- margin-left: -0.5rem;
27
17
  padding-inline: 0.375rem;
28
18
  font-size: var(--font-size-base);
29
19
  }
@@ -1,20 +1,9 @@
1
- import type { DefaultNodeTypes, TypedEditorState } from '@payloadcms/richtext-lexical';
2
- import type { SerializedEditorState } from '@payloadcms/richtext-lexical/lexical';
3
- import type { InputWrapperProps } from './InputWrapper';
4
- export interface LexicalInputProps extends InputWrapperProps {
1
+ import type { FieldWrapperProps } from './FieldWrapper';
2
+ export interface LexicalInputProps extends FieldWrapperProps {
5
3
  lang: string;
6
4
  value: string;
7
5
  onChange: (value: string) => void;
8
6
  onBlur: () => void;
9
7
  }
10
8
  export declare function LexicalInput({ error, label, value, onChange, className, }: LexicalInputProps): React.ReactNode;
11
- interface UseHtmlLexicalAdapterProps {
12
- html: string;
13
- onChange: (html: string) => void;
14
- }
15
- export declare function useHtmlLexicalAdapter({ html, onChange, }: UseHtmlLexicalAdapterProps): {
16
- value: TypedEditorState<DefaultNodeTypes>;
17
- setValue: (serializedState: SerializedEditorState) => void;
18
- };
19
- export {};
20
9
  //# sourceMappingURL=LexicalInput.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"LexicalInput.d.ts","sourceRoot":"","sources":["../../../src/components/inputs/LexicalInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AAWtC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sCAAsC,CAAC;AASlF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAGxD,MAAM,WAAW,iBAAkB,SAAQ,iBAAiB;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAED,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,KAAK,EACL,KAAK,EACL,QAAQ,EACR,SAAS,GACV,EAAE,iBAAiB,GAAG,KAAK,CAAC,SAAS,CAoBrC;AAID,UAAU,0BAA0B;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAClC;AAED,wBAAgB,qBAAqB,CAAC,EACpC,IAAI,EACJ,QAAQ,GACT,EAAE,0BAA0B;WAiEF,gBAAgB,CAAC,gBAAgB,CAAC;gCAjBvC,qBAAqB;EAkB1C"}
1
+ {"version":3,"file":"LexicalInput.d.ts","sourceRoot":"","sources":["../../../src/components/inputs/LexicalInput.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAGxD,MAAM,WAAW,iBAAkB,SAAQ,iBAAiB;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAED,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,KAAK,EACL,KAAK,EACL,QAAQ,EACR,SAAS,GACV,EAAE,iBAAiB,GAAG,KAAK,CAAC,SAAS,CAoBrC"}
@@ -1,17 +1,13 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { defaultEditorConfig, defaultEditorFeatures } from '@payloadcms/richtext-lexical';
3
- import { buildDefaultEditorState, getEnabledNodes, RenderLexical, sanitizeClientEditorConfig } from '@payloadcms/richtext-lexical/client';
4
- import { $getRoot } from '@payloadcms/richtext-lexical/lexical';
5
- import { createHeadlessEditor } from '@payloadcms/richtext-lexical/lexical/headless';
6
- import { $generateHtmlFromNodes, $generateNodesFromDOM } from '@payloadcms/richtext-lexical/lexical/html';
7
- import { useCallback, useMemo, useRef } from 'react';
8
- import { InputWrapper } from './InputWrapper';
2
+ import { RenderLexical } from '@payloadcms/richtext-lexical/client';
3
+ import { useHtmlLexicalAdapter } from '../hooks/useHtmlLexicalAdapter';
4
+ import { FieldWrapper } from './FieldWrapper';
9
5
  export function LexicalInput({ error, label, value, onChange, className }) {
10
6
  const editor = useHtmlLexicalAdapter({
11
7
  html: value,
12
8
  onChange
13
9
  });
14
- return /*#__PURE__*/ _jsx(InputWrapper, {
10
+ return /*#__PURE__*/ _jsx(FieldWrapper, {
15
11
  className: className,
16
12
  error: error,
17
13
  label: label,
@@ -27,60 +23,5 @@ export function LexicalInput({ error, label, value, onChange, className }) {
27
23
  })
28
24
  });
29
25
  }
30
- const EMPTY_STATE = buildDefaultEditorState({});
31
- export function useHtmlLexicalAdapter({ html, onChange }) {
32
- // 1. Maintain a persistent headless editor for conversion
33
- const headlessEditor = useRef(createHeadlessEditor({
34
- nodes: getEnabledNodes({
35
- editorConfig: sanitizeClientEditorConfig(// @ts-expect-error - FIXME
36
- defaultEditorFeatures, defaultEditorConfig)
37
- })
38
- }));
39
- // 2. HTML -> SerializedState
40
- const getSerializedState = useCallback((htmlString)=>{
41
- const editor = headlessEditor.current;
42
- editor.update(()=>{
43
- const parser = new DOMParser();
44
- const dom = parser.parseFromString(htmlString, 'text/html');
45
- const nodes = $generateNodesFromDOM(editor, dom);
46
- const root = $getRoot();
47
- root.clear().append(...nodes);
48
- }, {
49
- discrete: true
50
- });
51
- return editor.getEditorState().toJSON();
52
- }, []);
53
- // 3. Memoize the initial value to prevent unnecessary re-renders
54
- const value = useMemo(()=>{
55
- const serializedState = getSerializedState(html);
56
- if (serializedState.root.children.length === 0) {
57
- return EMPTY_STATE;
58
- }
59
- return serializedState;
60
- }, [
61
- html,
62
- getSerializedState
63
- ]);
64
- // 4. SerializedState -> HTML
65
- const setValue = useCallback((serializedState)=>{
66
- const editor = headlessEditor.current;
67
- // Update headless editor to match the incoming state
68
- editor.setEditorState(editor.parseEditorState(serializedState));
69
- // Generate HTML and broadcast if it has changed
70
- editor.read(()=>{
71
- const newHtml = $generateHtmlFromNodes(editor);
72
- if (newHtml !== html) {
73
- onChange(newHtml);
74
- }
75
- });
76
- }, [
77
- html,
78
- onChange
79
- ]);
80
- return {
81
- value: value,
82
- setValue
83
- };
84
- }
85
26
 
86
27
  //# sourceMappingURL=LexicalInput.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/inputs/LexicalInput.tsx"],"sourcesContent":["import type {\n DefaultNodeTypes,\n TypedEditorState,\n} from '@payloadcms/richtext-lexical';\nimport {\n defaultEditorConfig,\n defaultEditorFeatures,\n} from '@payloadcms/richtext-lexical';\nimport {\n buildDefaultEditorState,\n getEnabledNodes,\n RenderLexical,\n sanitizeClientEditorConfig,\n} from '@payloadcms/richtext-lexical/client';\nimport type { SerializedEditorState } from '@payloadcms/richtext-lexical/lexical';\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 className={className} error={error} label={label}>\n <RenderLexical\n field={{\n name: 'myCustomEditor',\n label: false,\n type: 'richText',\n }}\n schemaPath=\"global.intl-plugin.editorTemplate\"\n setValue={(val) => editor.setValue(val as SerializedEditorState)}\n value={editor.value}\n />\n </InputWrapper>\n );\n}\n\nconst EMPTY_STATE = buildDefaultEditorState({});\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: sanitizeClientEditorConfig(\n // @ts-expect-error - FIXME\n defaultEditorFeatures,\n defaultEditorConfig,\n ),\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":["defaultEditorConfig","defaultEditorFeatures","buildDefaultEditorState","getEnabledNodes","RenderLexical","sanitizeClientEditorConfig","$getRoot","createHeadlessEditor","$generateHtmlFromNodes","$generateNodesFromDOM","useCallback","useMemo","useRef","InputWrapper","LexicalInput","error","label","value","onChange","className","editor","useHtmlLexicalAdapter","html","field","name","type","schemaPath","setValue","val","EMPTY_STATE","headlessEditor","nodes","editorConfig","getSerializedState","htmlString","current","update","parser","DOMParser","dom","parseFromString","root","clear","append","discrete","getEditorState","toJSON","serializedState","children","length","setEditorState","parseEditorState","read","newHtml"],"mappings":";AAIA,SACEA,mBAAmB,EACnBC,qBAAqB,QAChB,+BAA+B;AACtC,SACEC,uBAAuB,EACvBC,eAAe,EACfC,aAAa,EACbC,0BAA0B,QACrB,sCAAsC;AAE7C,SAASC,QAAQ,QAAQ,uCAAuC;AAChE,SAASC,oBAAoB,QAAQ,gDAAgD;AACrF,SACEC,sBAAsB,EACtBC,qBAAqB,QAChB,4CAA4C;AACnD,SAASC,WAAW,EAAEC,OAAO,EAAEC,MAAM,QAAQ,QAAQ;AAGrD,SAASC,YAAY,QAAQ,iBAAiB;AAS9C,OAAO,SAASC,aAAa,EAC3BC,KAAK,EACLC,KAAK,EACLC,KAAK,EACLC,QAAQ,EACRC,SAAS,EACS;IAClB,MAAMC,SAASC,sBAAsB;QACnCC,MAAML;QACNC;IACF;IAEA,qBACE,KAACL;QAAaM,WAAWA;QAAWJ,OAAOA;QAAOC,OAAOA;kBACvD,cAAA,KAACZ;YACCmB,OAAO;gBACLC,MAAM;gBACNR,OAAO;gBACPS,MAAM;YACR;YACAC,YAAW;YACXC,UAAU,CAACC,MAAQR,OAAOO,QAAQ,CAACC;YACnCX,OAAOG,OAAOH,KAAK;;;AAI3B;AAEA,MAAMY,cAAc3B,wBAAwB,CAAC;AAO7C,OAAO,SAASmB,sBAAsB,EACpCC,IAAI,EACJJ,QAAQ,EACmB;IAC3B,0DAA0D;IAC1D,MAAMY,iBAAiBlB,OACrBL,qBAAqB;QACnBwB,OAAO5B,gBAAgB;YACrB6B,cAAc3B,2BACZ,2BAA2B;YAC3BJ,uBACAD;QAEJ;IACF;IAGF,6BAA6B;IAC7B,MAAMiC,qBAAqBvB,YACzB,CAACwB;QACC,MAAMd,SAASU,eAAeK,OAAO;QACrCf,OAAOgB,MAAM,CACX;YACE,MAAMC,SAAS,IAAIC;YACnB,MAAMC,MAAMF,OAAOG,eAAe,CAACN,YAAY;YAC/C,MAAMH,QAAQtB,sBAAsBW,QAAQmB;YAE5C,MAAME,OAAOnC;YACbmC,KAAKC,KAAK,GAAGC,MAAM,IAAIZ;QACzB,GACA;YAAEa,UAAU;QAAK;QAGnB,OAAOxB,OAAOyB,cAAc,GAAGC,MAAM;IACvC,GACA,EAAE;IAGJ,iEAAiE;IACjE,MAAM7B,QAAQN,QAAQ;QACpB,MAAMoC,kBAAkBd,mBAAmBX;QAE3C,IAAIyB,gBAAgBN,IAAI,CAACO,QAAQ,CAACC,MAAM,KAAK,GAAG;YAC9C,OAAOpB;QACT;QAEA,OAAOkB;IACT,GAAG;QAACzB;QAAMW;KAAmB;IAE7B,6BAA6B;IAC7B,MAAMN,WAAWjB,YACf,CAACqC;QACC,MAAM3B,SAASU,eAAeK,OAAO;QAErC,qDAAqD;QACrDf,OAAO8B,cAAc,CAAC9B,OAAO+B,gBAAgB,CAACJ;QAE9C,gDAAgD;QAChD3B,OAAOgC,IAAI,CAAC;YACV,MAAMC,UAAU7C,uBAAuBY;YACvC,IAAIiC,YAAY/B,MAAM;gBACpBJ,SAASmC;YACX;QACF;IACF,GACA;QAAC/B;QAAMJ;KAAS;IAGlB,OAAO;QAAED,OAAOA;QAA6CU;IAAS;AACxE"}
1
+ {"version":3,"sources":["../../../src/components/inputs/LexicalInput.tsx"],"sourcesContent":["import { RenderLexical } from '@payloadcms/richtext-lexical/client';\nimport type { SerializedEditorState } from '@payloadcms/richtext-lexical/lexical';\nimport { useHtmlLexicalAdapter } from '../hooks/useHtmlLexicalAdapter';\nimport type { FieldWrapperProps } from './FieldWrapper';\nimport { FieldWrapper } from './FieldWrapper';\n\nexport interface LexicalInputProps extends FieldWrapperProps {\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 <FieldWrapper className={className} error={error} label={label}>\n <RenderLexical\n field={{\n name: 'myCustomEditor',\n label: false,\n type: 'richText',\n }}\n schemaPath=\"global.intl-plugin.editorTemplate\"\n setValue={(val) => editor.setValue(val as SerializedEditorState)}\n value={editor.value}\n />\n </FieldWrapper>\n );\n}\n"],"names":["RenderLexical","useHtmlLexicalAdapter","FieldWrapper","LexicalInput","error","label","value","onChange","className","editor","html","field","name","type","schemaPath","setValue","val"],"mappings":";AAAA,SAASA,aAAa,QAAQ,sCAAsC;AAEpE,SAASC,qBAAqB,QAAQ,iCAAiC;AAEvE,SAASC,YAAY,QAAQ,iBAAiB;AAS9C,OAAO,SAASC,aAAa,EAC3BC,KAAK,EACLC,KAAK,EACLC,KAAK,EACLC,QAAQ,EACRC,SAAS,EACS;IAClB,MAAMC,SAASR,sBAAsB;QACnCS,MAAMJ;QACNC;IACF;IAEA,qBACE,KAACL;QAAaM,WAAWA;QAAWJ,OAAOA;QAAOC,OAAOA;kBACvD,cAAA,KAACL;YACCW,OAAO;gBACLC,MAAM;gBACNP,OAAO;gBACPQ,MAAM;YACR;YACAC,YAAW;YACXC,UAAU,CAACC,MAAQP,OAAOM,QAAQ,CAACC;YACnCV,OAAOG,OAAOH,KAAK;;;AAI3B"}
@@ -1,11 +1,14 @@
1
1
  import type { TemplateVariable } from '../../types';
2
- import type { InputWrapperProps } from './InputWrapper';
3
- export interface MessageInputProps extends InputWrapperProps {
2
+ import type { FieldWrapperProps } from './FieldWrapper';
3
+ export interface MessageInputProps extends FieldWrapperProps {
4
4
  value: string;
5
5
  lang: string;
6
6
  variables: TemplateVariable[];
7
7
  onChange: (value: string) => void;
8
8
  onBlur: () => void;
9
+ readOnly?: boolean;
10
+ multiline?: boolean;
11
+ reference?: string;
9
12
  }
10
- export declare function MessageInput({ label, value, lang, error, variables, onChange, onBlur, className, }: MessageInputProps): import("react/jsx-runtime").JSX.Element;
13
+ export declare function MessageInput({ label, value, lang, error, variables, onChange, onBlur, className, multiline, reference, }: MessageInputProps): import("react/jsx-runtime").JSX.Element;
11
14
  //# sourceMappingURL=MessageInput.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"MessageInput.d.ts","sourceRoot":"","sources":["../../../src/components/inputs/MessageInput.tsx"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAShD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAMxD,MAAM,WAAW,iBAAkB,SAAQ,iBAAiB;IAC1D,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,gBAAgB,EAAE,CAAC;IAC9B,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAsCD,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,KAAK,EACL,IAAI,EACJ,KAAK,EACL,SAAS,EACT,QAAQ,EACR,MAAM,EACN,SAAS,GACV,EAAE,iBAAiB,2CAiEnB"}
1
+ {"version":3,"file":"MessageInput.d.ts","sourceRoot":"","sources":["../../../src/components/inputs/MessageInput.tsx"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAShD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AA2BxD,MAAM,WAAW,iBAAkB,SAAQ,iBAAiB;IAC1D,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,gBAAgB,EAAE,CAAC;IAC9B,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,KAAK,EACL,IAAI,EACJ,KAAK,EACL,SAAS,EACT,QAAQ,EACR,MAAM,EACN,SAAS,EACT,SAAS,EACT,SAAS,GACV,EAAE,iBAAiB,2CAuFnB"}
@@ -2,44 +2,40 @@
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { $getRoot } from '@payloadcms/richtext-lexical/lexical';
4
4
  import { LexicalComposer } from '@payloadcms/richtext-lexical/lexical/react/LexicalComposer';
5
+ import { useLexicalComposerContext } from '@payloadcms/richtext-lexical/lexical/react/LexicalComposerContext';
5
6
  import { ContentEditable } from '@payloadcms/richtext-lexical/lexical/react/LexicalContentEditable';
6
7
  import { LexicalErrorBoundary } from '@payloadcms/richtext-lexical/lexical/react/LexicalErrorBoundary';
7
8
  import { HistoryPlugin } from '@payloadcms/richtext-lexical/lexical/react/LexicalHistoryPlugin';
8
9
  import { OnChangePlugin } from '@payloadcms/richtext-lexical/lexical/react/LexicalOnChangePlugin';
9
10
  import { PlainTextPlugin } from '@payloadcms/richtext-lexical/lexical/react/LexicalPlainTextPlugin';
11
+ import clsx from 'clsx';
10
12
  import { BeautifulMentionNode, BeautifulMentionsPlugin } from 'lexical-beautiful-mentions';
11
- import { forwardRef, useCallback, useMemo } from 'react';
13
+ import { useCallback, useEffect, useMemo } from 'react';
12
14
  import { formatVariableLabel } from '../../utils/format';
13
15
  import { isTagElement } from '../../utils/guards';
14
16
  import { parseIcuToLexicalState, serializeICUMessage } from '../../utils/icu-tranform';
15
- import { InputWrapper } from './InputWrapper';
17
+ import { FieldWrapper } from './FieldWrapper';
16
18
  import styles from './MessageInput.module.css';
19
+ import { SingleLinePlugin } from './SingleLinePlugin';
17
20
  import { VariableMentionNode } from './variables/VariableNode';
18
- import suggestionStyles from './variables/VariableSuggestion.module.css';
19
- const MentionMenu = /*#__PURE__*/ forwardRef(({ loading: _, ...props }, ref)=>/*#__PURE__*/ _jsx("ul", {
20
- ...props,
21
- className: suggestionStyles.list,
22
- ref: ref
23
- }));
24
- const MentionMenuItem = /*#__PURE__*/ forwardRef((props, ref)=>/*#__PURE__*/ _jsx("li", {
25
- "aria-selected": props.selected,
26
- className: [
27
- suggestionStyles.item,
28
- props.selected ? suggestionStyles.itemSelected : undefined
29
- ].filter(Boolean).join(' '),
30
- onClick: props.onClick,
31
- onKeyDown: props.onKeyDown,
32
- onMouseDown: props.onMouseDown,
33
- onMouseEnter: props.onMouseEnter,
34
- ref: ref,
35
- // biome-ignore lint/a11y/noNoninteractiveElementToInteractiveRole: standard WAI-ARIA listbox/option pattern
36
- role: "option",
37
- tabIndex: -1,
38
- children: typeof props.item.data?.label === 'string' ? props.item.data.label : props.item.displayValue
39
- }));
40
- // TODO add variable editor (style, options, etc)
41
- // TODO add tooltip to show all variables
42
- export function MessageInput({ label, value, lang, error, variables, onChange, onBlur, className }) {
21
+ import { MentionMenu, MentionMenuItem } from './variables/VariableSuggestion';
22
+ function SyncValuePlugin({ value }) {
23
+ const [editor] = useLexicalComposerContext();
24
+ useEffect(()=>{
25
+ const currentText = editor.getEditorState().read(()=>$getRoot().getTextContent());
26
+ if (value !== currentText) {
27
+ queueMicrotask(()=>{
28
+ const newState = editor.parseEditorState(JSON.stringify(parseIcuToLexicalState(value)));
29
+ editor.setEditorState(newState);
30
+ });
31
+ }
32
+ }, [
33
+ value,
34
+ editor
35
+ ]);
36
+ return null;
37
+ }
38
+ export function MessageInput({ label, value, lang, error, variables, onChange, onBlur, className, multiline, reference }) {
43
39
  const handleChange = useCallback((editorState)=>{
44
40
  editorState.read(()=>{
45
41
  onChange($getRoot().getTextContent());
@@ -63,35 +59,43 @@ export function MessageInput({ label, value, lang, error, variables, onChange, o
63
59
  }, [
64
60
  variables
65
61
  ]);
66
- const initialConfig = {
67
- namespace: 'ICUMessageEditor',
68
- nodes: [
69
- VariableMentionNode,
70
- {
71
- replace: BeautifulMentionNode,
72
- with: (node)=>new VariableMentionNode(node.getTrigger(), node.getValue(), node.getData())
73
- }
74
- ],
75
- editorState: JSON.stringify(parseIcuToLexicalState(value)),
76
- onError: console.error
77
- };
78
- return /*#__PURE__*/ _jsx(InputWrapper, {
62
+ // biome-ignore lint/correctness/useExhaustiveDependencies: LexicalComposer only reads initialConfig on mount
63
+ const initialConfig = useMemo(()=>({
64
+ namespace: 'ICUMessageEditor',
65
+ nodes: [
66
+ VariableMentionNode,
67
+ {
68
+ replace: BeautifulMentionNode,
69
+ with: (node)=>new VariableMentionNode(node.getTrigger(), node.getValue(), node.getData()),
70
+ withKlass: VariableMentionNode
71
+ }
72
+ ],
73
+ editorState: JSON.stringify(parseIcuToLexicalState(value)),
74
+ editable: true,
75
+ onError: console.error
76
+ }), []);
77
+ return /*#__PURE__*/ _jsx(FieldWrapper, {
79
78
  className: className,
80
79
  error: error,
81
80
  label: label,
81
+ reference: reference,
82
82
  children: /*#__PURE__*/ _jsx(LexicalComposer, {
83
83
  initialConfig: initialConfig,
84
84
  children: /*#__PURE__*/ _jsxs("div", {
85
- className: styles.editor,
85
+ className: clsx(styles.editor, multiline && styles.multiline),
86
86
  lang: lang,
87
- onBlur: onBlur,
88
87
  children: [
89
88
  /*#__PURE__*/ _jsx(PlainTextPlugin, {
90
89
  contentEditable: /*#__PURE__*/ _jsx(ContentEditable, {
91
- className: styles.contentEditable
90
+ className: clsx(styles.contentEditable, error && styles.contentEditableError),
91
+ onBlur: onBlur
92
92
  }),
93
93
  ErrorBoundary: LexicalErrorBoundary
94
94
  }),
95
+ multiline && /*#__PURE__*/ _jsx(SingleLinePlugin, {}),
96
+ /*#__PURE__*/ _jsx(SyncValuePlugin, {
97
+ value: value
98
+ }),
95
99
  /*#__PURE__*/ _jsx(OnChangePlugin, {
96
100
  onChange: handleChange
97
101
  }),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/inputs/MessageInput.tsx"],"sourcesContent":["'use client';\n\nimport type { EditorState } from '@payloadcms/richtext-lexical/lexical';\nimport { $getRoot } from '@payloadcms/richtext-lexical/lexical';\nimport { LexicalComposer } from '@payloadcms/richtext-lexical/lexical/react/LexicalComposer';\nimport { ContentEditable } from '@payloadcms/richtext-lexical/lexical/react/LexicalContentEditable';\nimport { LexicalErrorBoundary } from '@payloadcms/richtext-lexical/lexical/react/LexicalErrorBoundary';\nimport { HistoryPlugin } from '@payloadcms/richtext-lexical/lexical/react/LexicalHistoryPlugin';\nimport { OnChangePlugin } from '@payloadcms/richtext-lexical/lexical/react/LexicalOnChangePlugin';\nimport { PlainTextPlugin } from '@payloadcms/richtext-lexical/lexical/react/LexicalPlainTextPlugin';\nimport {\n BeautifulMentionNode,\n type BeautifulMentionsMenuItemProps,\n type BeautifulMentionsMenuProps,\n BeautifulMentionsPlugin,\n} from 'lexical-beautiful-mentions';\nimport { forwardRef, useCallback, useMemo } from 'react';\nimport type { TemplateVariable } from '@/types';\n\nimport { formatVariableLabel } from '@/utils/format';\nimport { isTagElement } from '@/utils/guards';\nimport {\n parseIcuToLexicalState,\n serializeICUMessage,\n} from '@/utils/icu-tranform';\n\nimport type { InputWrapperProps } from './InputWrapper';\nimport { InputWrapper } from './InputWrapper';\nimport styles from './MessageInput.module.css';\nimport { VariableMentionNode } from './variables/VariableNode';\nimport suggestionStyles from './variables/VariableSuggestion.module.css';\n\nexport interface MessageInputProps extends InputWrapperProps {\n value: string;\n lang: string;\n variables: TemplateVariable[];\n onChange: (value: string) => void;\n onBlur: () => void;\n}\n\nconst MentionMenu = forwardRef<HTMLUListElement, BeautifulMentionsMenuProps>(\n ({ loading: _, ...props }, ref) => (\n <ul {...props} className={suggestionStyles.list} ref={ref} />\n ),\n);\n\nconst MentionMenuItem = forwardRef<\n HTMLLIElement,\n BeautifulMentionsMenuItemProps\n>((props, ref) => (\n <li\n aria-selected={props.selected}\n className={[\n suggestionStyles.item,\n props.selected ? suggestionStyles.itemSelected : undefined,\n ]\n .filter(Boolean)\n .join(' ')}\n onClick={props.onClick}\n onKeyDown={props.onKeyDown}\n onMouseDown={props.onMouseDown}\n onMouseEnter={props.onMouseEnter}\n ref={ref}\n // biome-ignore lint/a11y/noNoninteractiveElementToInteractiveRole: standard WAI-ARIA listbox/option pattern\n role=\"option\"\n tabIndex={-1}\n >\n {typeof props.item.data?.label === 'string'\n ? props.item.data.label\n : props.item.displayValue}\n </li>\n));\n\n// TODO add variable editor (style, options, etc)\n// TODO add tooltip to show all variables\n\nexport function MessageInput({\n label,\n value,\n lang,\n error,\n variables,\n onChange,\n onBlur,\n className,\n}: MessageInputProps) {\n const handleChange = useCallback(\n (editorState: EditorState) => {\n editorState.read(() => {\n onChange($getRoot().getTextContent());\n });\n },\n [onChange],\n );\n\n const mentionItems = useMemo(() => {\n const toItem = (v: TemplateVariable) => ({\n value: v.value,\n label: formatVariableLabel(v),\n icu: serializeICUMessage([v]),\n });\n\n return {\n '@': variables.map(toItem),\n '{': variables.filter((v) => !isTagElement(v)).map(toItem),\n '<': variables.filter((v) => isTagElement(v)).map(toItem),\n };\n }, [variables]);\n\n const initialConfig = {\n namespace: 'ICUMessageEditor',\n nodes: [\n VariableMentionNode,\n {\n replace: BeautifulMentionNode,\n with: (node: BeautifulMentionNode) =>\n new VariableMentionNode(\n node.getTrigger(),\n node.getValue(),\n node.getData(),\n ),\n },\n ],\n editorState: JSON.stringify(parseIcuToLexicalState(value)),\n onError: console.error,\n };\n\n return (\n <InputWrapper className={className} error={error} label={label}>\n <LexicalComposer initialConfig={initialConfig}>\n {/* biome-ignore lint/a11y/noStaticElementInteractions: onBlur captures focus-leave from the Lexical contentEditable */}\n <div className={styles.editor} lang={lang} onBlur={onBlur}>\n <PlainTextPlugin\n contentEditable={\n <ContentEditable className={styles.contentEditable} />\n }\n ErrorBoundary={LexicalErrorBoundary}\n />\n <OnChangePlugin onChange={handleChange} />\n <HistoryPlugin />\n <BeautifulMentionsPlugin\n items={mentionItems}\n menuAnchorClassName={styles.menuAnchor}\n menuComponent={MentionMenu}\n menuItemComponent={MentionMenuItem}\n />\n </div>\n </LexicalComposer>\n </InputWrapper>\n );\n}\n"],"names":["$getRoot","LexicalComposer","ContentEditable","LexicalErrorBoundary","HistoryPlugin","OnChangePlugin","PlainTextPlugin","BeautifulMentionNode","BeautifulMentionsPlugin","forwardRef","useCallback","useMemo","formatVariableLabel","isTagElement","parseIcuToLexicalState","serializeICUMessage","InputWrapper","styles","VariableMentionNode","suggestionStyles","MentionMenu","loading","_","props","ref","ul","className","list","MentionMenuItem","li","aria-selected","selected","item","itemSelected","undefined","filter","Boolean","join","onClick","onKeyDown","onMouseDown","onMouseEnter","role","tabIndex","data","label","displayValue","MessageInput","value","lang","error","variables","onChange","onBlur","handleChange","editorState","read","getTextContent","mentionItems","toItem","v","icu","map","initialConfig","namespace","nodes","replace","with","node","getTrigger","getValue","getData","JSON","stringify","onError","console","div","editor","contentEditable","ErrorBoundary","items","menuAnchorClassName","menuAnchor","menuComponent","menuItemComponent"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/components/inputs/MessageInput.tsx"],"sourcesContent":["'use client';\n\nimport type { EditorState } from '@payloadcms/richtext-lexical/lexical';\nimport { $getRoot } from '@payloadcms/richtext-lexical/lexical';\nimport { LexicalComposer } from '@payloadcms/richtext-lexical/lexical/react/LexicalComposer';\nimport { useLexicalComposerContext } from '@payloadcms/richtext-lexical/lexical/react/LexicalComposerContext';\nimport { ContentEditable } from '@payloadcms/richtext-lexical/lexical/react/LexicalContentEditable';\nimport { LexicalErrorBoundary } from '@payloadcms/richtext-lexical/lexical/react/LexicalErrorBoundary';\nimport { HistoryPlugin } from '@payloadcms/richtext-lexical/lexical/react/LexicalHistoryPlugin';\nimport { OnChangePlugin } from '@payloadcms/richtext-lexical/lexical/react/LexicalOnChangePlugin';\nimport { PlainTextPlugin } from '@payloadcms/richtext-lexical/lexical/react/LexicalPlainTextPlugin';\nimport clsx from 'clsx';\nimport {\n BeautifulMentionNode,\n BeautifulMentionsPlugin,\n} from 'lexical-beautiful-mentions';\nimport { useCallback, useEffect, useMemo } from 'react';\nimport type { TemplateVariable } from '@/types';\n\nimport { formatVariableLabel } from '@/utils/format';\nimport { isTagElement } from '@/utils/guards';\nimport {\n parseIcuToLexicalState,\n serializeICUMessage,\n} from '@/utils/icu-tranform';\n\nimport type { FieldWrapperProps } from './FieldWrapper';\nimport { FieldWrapper } from './FieldWrapper';\nimport styles from './MessageInput.module.css';\nimport { SingleLinePlugin } from './SingleLinePlugin';\nimport { VariableMentionNode } from './variables/VariableNode';\nimport { MentionMenu, MentionMenuItem } from './variables/VariableSuggestion';\n\nfunction SyncValuePlugin({ value }: { value: string }) {\n const [editor] = useLexicalComposerContext();\n\n useEffect(() => {\n const currentText = editor\n .getEditorState()\n .read(() => $getRoot().getTextContent());\n if (value !== currentText) {\n queueMicrotask(() => {\n const newState = editor.parseEditorState(\n JSON.stringify(parseIcuToLexicalState(value)),\n );\n editor.setEditorState(newState);\n });\n }\n }, [value, editor]);\n\n return null;\n}\n\nexport interface MessageInputProps extends FieldWrapperProps {\n value: string;\n lang: string;\n variables: TemplateVariable[];\n onChange: (value: string) => void;\n onBlur: () => void;\n readOnly?: boolean;\n multiline?: boolean;\n reference?: string;\n}\n\nexport function MessageInput({\n label,\n value,\n lang,\n error,\n variables,\n onChange,\n onBlur,\n className,\n multiline,\n reference,\n}: MessageInputProps) {\n const handleChange = useCallback(\n (editorState: EditorState) => {\n editorState.read(() => {\n onChange($getRoot().getTextContent());\n });\n },\n [onChange],\n );\n\n const mentionItems = useMemo(() => {\n const toItem = (v: TemplateVariable) => ({\n value: v.value,\n label: formatVariableLabel(v),\n icu: serializeICUMessage([v]),\n });\n\n return {\n '@': variables.map(toItem),\n '{': variables.filter((v) => !isTagElement(v)).map(toItem),\n '<': variables.filter((v) => isTagElement(v)).map(toItem),\n };\n }, [variables]);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: LexicalComposer only reads initialConfig on mount\n const initialConfig = useMemo(\n () => ({\n namespace: 'ICUMessageEditor',\n nodes: [\n VariableMentionNode,\n {\n replace: BeautifulMentionNode,\n with: (node: BeautifulMentionNode) =>\n new VariableMentionNode(\n node.getTrigger(),\n node.getValue(),\n node.getData(),\n ),\n withKlass: VariableMentionNode,\n },\n ],\n editorState: JSON.stringify(parseIcuToLexicalState(value)),\n editable: true,\n onError: console.error,\n }),\n [],\n );\n\n return (\n <FieldWrapper\n className={className}\n error={error}\n label={label}\n reference={reference}\n >\n <LexicalComposer initialConfig={initialConfig}>\n <div\n className={clsx(styles.editor, multiline && styles.multiline)}\n lang={lang}\n >\n <PlainTextPlugin\n contentEditable={\n <ContentEditable\n className={clsx(\n styles.contentEditable,\n error && styles.contentEditableError,\n )}\n onBlur={onBlur}\n />\n }\n ErrorBoundary={LexicalErrorBoundary}\n />\n {multiline && <SingleLinePlugin />}\n <SyncValuePlugin value={value} />\n <OnChangePlugin onChange={handleChange} />\n <HistoryPlugin />\n\n <BeautifulMentionsPlugin\n items={mentionItems}\n menuAnchorClassName={styles.menuAnchor}\n menuComponent={MentionMenu}\n menuItemComponent={MentionMenuItem}\n />\n </div>\n </LexicalComposer>\n </FieldWrapper>\n );\n}\n"],"names":["$getRoot","LexicalComposer","useLexicalComposerContext","ContentEditable","LexicalErrorBoundary","HistoryPlugin","OnChangePlugin","PlainTextPlugin","clsx","BeautifulMentionNode","BeautifulMentionsPlugin","useCallback","useEffect","useMemo","formatVariableLabel","isTagElement","parseIcuToLexicalState","serializeICUMessage","FieldWrapper","styles","SingleLinePlugin","VariableMentionNode","MentionMenu","MentionMenuItem","SyncValuePlugin","value","editor","currentText","getEditorState","read","getTextContent","queueMicrotask","newState","parseEditorState","JSON","stringify","setEditorState","MessageInput","label","lang","error","variables","onChange","onBlur","className","multiline","reference","handleChange","editorState","mentionItems","toItem","v","icu","map","filter","initialConfig","namespace","nodes","replace","with","node","getTrigger","getValue","getData","withKlass","editable","onError","console","div","contentEditable","contentEditableError","ErrorBoundary","items","menuAnchorClassName","menuAnchor","menuComponent","menuItemComponent"],"mappings":"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"}
@@ -1,25 +1,44 @@
1
1
  .editor {
2
2
  position: relative;
3
+ display: grid;
4
+ align-items: center;
3
5
  min-height: 2rem;
4
6
  font-size: var(--font-size-large);
5
7
  }
6
8
 
9
+ .readOnly {
10
+ opacity: 0.7;
11
+ cursor: default;
12
+ }
13
+
14
+ .multiline {
15
+ min-height: 4rem;
16
+ }
17
+
7
18
  .menuAnchor {
8
19
  z-index: 50;
9
20
  }
10
21
 
11
22
  .contentEditable {
12
23
  outline: none;
24
+ border-radius: var(--style-radius-m);
25
+ background-color: var(--theme-elevation-0);
26
+ border: 1px solid var(--theme-elevation-300);
27
+ padding-block: 0.25rem;
28
+ padding-inline: 0.75rem;
29
+ height: 100%;
13
30
  }
14
31
 
15
32
  .contentEditable:focus {
16
33
  outline: none;
34
+ border-color: var(--theme-elevation-600);
17
35
  }
18
36
 
19
- .contentEditable > :first-child {
20
- margin-top: 0;
37
+ .contentEditableError {
38
+ border-color: var(--theme-error-400);
39
+ background-color: var(--theme-error-100);
21
40
  }
22
41
 
23
- .contentEditable > :last-child {
24
- margin-bottom: 0;
42
+ .contentEditable p {
43
+ margin: 0;
25
44
  }
@@ -0,0 +1,7 @@
1
+ import type { ReactElement } from 'react';
2
+ export interface ReferencePopoverProps {
3
+ reference?: string;
4
+ children: ReactElement;
5
+ }
6
+ export declare function ReferencePopover({ reference, children, }: ReferencePopoverProps): import("react/jsx-runtime").JSX.Element;
7
+ //# sourceMappingURL=ReferencePopover.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ReferencePopover.d.ts","sourceRoot":"","sources":["../../../src/components/inputs/ReferencePopover.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAI1C,MAAM,WAAW,qBAAqB;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,YAAY,CAAC;CACxB;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,SAAS,EACT,QAAQ,GACT,EAAE,qBAAqB,2CAqBvB"}
@@ -0,0 +1,42 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Popover } from '@base-ui/react/popover';
3
+ import { IconX } from '@tabler/icons-react';
4
+ import styles from './ReferencePopover.module.css';
5
+ export function ReferencePopover({ reference, children }) {
6
+ if (!reference) return children;
7
+ return /*#__PURE__*/ _jsxs(Popover.Root, {
8
+ children: [
9
+ /*#__PURE__*/ _jsx(Popover.Trigger, {
10
+ nativeButton: false,
11
+ render: children
12
+ }),
13
+ /*#__PURE__*/ _jsx(Popover.Portal, {
14
+ children: /*#__PURE__*/ _jsx(Popover.Positioner, {
15
+ align: "start",
16
+ side: "top",
17
+ sideOffset: 4,
18
+ children: /*#__PURE__*/ _jsxs(Popover.Popup, {
19
+ className: styles.popup,
20
+ initialFocus: false,
21
+ onMouseDown: (e)=>e.preventDefault(),
22
+ children: [
23
+ /*#__PURE__*/ _jsx(Popover.Close, {
24
+ className: styles.dismiss,
25
+ type: "button",
26
+ children: /*#__PURE__*/ _jsx(IconX, {
27
+ size: 14
28
+ })
29
+ }),
30
+ /*#__PURE__*/ _jsx("p", {
31
+ className: styles.text,
32
+ children: reference
33
+ })
34
+ ]
35
+ })
36
+ })
37
+ })
38
+ ]
39
+ });
40
+ }
41
+
42
+ //# sourceMappingURL=ReferencePopover.js.map