payload-intl 1.1.2 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (208) hide show
  1. package/README.md +62 -221
  2. package/dist/components/MessageController.d.ts +4 -6
  3. package/dist/components/MessageController.d.ts.map +1 -1
  4. package/dist/components/MessageController.js +25 -41
  5. package/dist/components/MessageController.js.map +1 -1
  6. package/dist/components/MessageFormContext.d.ts +29 -0
  7. package/dist/components/MessageFormContext.d.ts.map +1 -0
  8. package/dist/components/MessageFormContext.js +30 -0
  9. package/dist/components/MessageFormContext.js.map +1 -0
  10. package/dist/components/MessagesForm.d.ts +2 -2
  11. package/dist/components/MessagesForm.d.ts.map +1 -1
  12. package/dist/components/MessagesForm.js +126 -112
  13. package/dist/components/MessagesForm.js.map +1 -1
  14. package/dist/components/MessagesForm.module.css +41 -0
  15. package/dist/{exports/link.d.ts → components/MessagesLink.d.ts} +3 -3
  16. package/dist/components/MessagesLink.d.ts.map +1 -0
  17. package/dist/components/MessagesLink.js +19 -0
  18. package/dist/components/MessagesLink.js.map +1 -0
  19. package/dist/components/MessagesView.d.ts +10 -0
  20. package/dist/components/MessagesView.d.ts.map +1 -0
  21. package/dist/components/MessagesView.js +48 -0
  22. package/dist/components/MessagesView.js.map +1 -0
  23. package/dist/components/actions/JsonImport.d.ts.map +1 -1
  24. package/dist/components/actions/JsonImport.js +68 -61
  25. package/dist/components/actions/JsonImport.js.map +1 -1
  26. package/dist/components/actions/JsonImport.module.css +14 -0
  27. package/dist/components/actions/Move.d.ts.map +1 -1
  28. package/dist/components/actions/Move.js +41 -0
  29. package/dist/components/actions/Move.js.map +1 -0
  30. package/dist/components/actions/Move.module.css +8 -0
  31. package/dist/components/inputs/InputWrapper.d.ts +1 -1
  32. package/dist/components/inputs/InputWrapper.d.ts.map +1 -1
  33. package/dist/components/inputs/InputWrapper.js +31 -29
  34. package/dist/components/inputs/InputWrapper.js.map +1 -1
  35. package/dist/components/inputs/InputWrapper.module.css +34 -0
  36. package/dist/components/inputs/LexicalInput.d.ts +3 -3
  37. package/dist/components/inputs/LexicalInput.js +86 -0
  38. package/dist/components/inputs/LexicalInput.js.map +1 -0
  39. package/dist/components/inputs/MessageInput.d.ts +2 -2
  40. package/dist/components/inputs/MessageInput.d.ts.map +1 -1
  41. package/dist/components/inputs/MessageInput.js +110 -37
  42. package/dist/components/inputs/MessageInput.js.map +1 -1
  43. package/dist/components/inputs/MessageInput.module.css +25 -0
  44. package/dist/components/inputs/variables/VariableChip.d.ts +8 -2
  45. package/dist/components/inputs/variables/VariableChip.d.ts.map +1 -1
  46. package/dist/components/inputs/variables/VariableChip.js +86 -64
  47. package/dist/components/inputs/variables/VariableChip.js.map +1 -1
  48. package/dist/components/inputs/variables/VariableChip.module.css +66 -0
  49. package/dist/components/inputs/variables/VariableIcon.d.ts +1 -1
  50. package/dist/components/inputs/variables/VariableIcon.d.ts.map +1 -1
  51. package/dist/components/inputs/variables/VariableIcon.js +35 -0
  52. package/dist/components/inputs/variables/VariableIcon.js.map +1 -0
  53. package/dist/components/inputs/variables/VariableNode.d.ts +11 -0
  54. package/dist/components/inputs/variables/VariableNode.d.ts.map +1 -0
  55. package/dist/components/inputs/variables/VariableNode.js +36 -0
  56. package/dist/components/inputs/variables/VariableNode.js.map +1 -0
  57. package/dist/components/inputs/variables/VariableSuggestion.module.css +34 -0
  58. package/dist/components/inputs/variables/editors/DateVariableEditor.d.ts +2 -2
  59. package/dist/components/inputs/variables/editors/DateVariableEditor.d.ts.map +1 -1
  60. package/dist/components/inputs/variables/editors/DateVariableEditor.js +15 -0
  61. package/dist/components/inputs/variables/editors/DateVariableEditor.js.map +1 -0
  62. package/dist/components/inputs/variables/editors/PluralVariableEditor.d.ts +1 -1
  63. package/dist/components/inputs/variables/editors/PluralVariableEditor.d.ts.map +1 -1
  64. package/dist/components/inputs/variables/editors/PluralVariableEditor.js +191 -172
  65. package/dist/components/inputs/variables/editors/PluralVariableEditor.js.map +1 -1
  66. package/dist/components/inputs/variables/editors/PluralVariableEditor.module.css +149 -0
  67. package/dist/components/inputs/variables/editors/SelectVariableEditor.d.ts +1 -1
  68. package/dist/components/inputs/variables/editors/SelectVariableEditor.d.ts.map +1 -1
  69. package/dist/components/inputs/variables/editors/SelectVariableEditor.js +58 -52
  70. package/dist/components/inputs/variables/editors/SelectVariableEditor.js.map +1 -1
  71. package/dist/components/inputs/variables/editors/SelectVariableEditor.module.css +25 -0
  72. package/dist/components/inputs/variables/editors/TagVariableEditor.d.ts +1 -1
  73. package/dist/components/inputs/variables/editors/TagVariableEditor.d.ts.map +1 -1
  74. package/dist/components/inputs/variables/editors/TagVariableEditor.js +36 -32
  75. package/dist/components/inputs/variables/editors/TagVariableEditor.js.map +1 -1
  76. package/dist/components/inputs/variables/editors/TagVariableEditor.module.css +7 -0
  77. package/dist/components/inputs/variables/editors/TimeVariableEditor.d.ts +2 -2
  78. package/dist/components/inputs/variables/editors/TimeVariableEditor.d.ts.map +1 -1
  79. package/dist/components/inputs/variables/editors/TimeVariableEditor.js +15 -0
  80. package/dist/components/inputs/variables/editors/TimeVariableEditor.js.map +1 -0
  81. package/dist/components/inputs/variables/pickers/NumericVariablePicker.d.ts +1 -1
  82. package/dist/components/inputs/variables/pickers/NumericVariablePicker.d.ts.map +1 -1
  83. package/dist/components/inputs/variables/pickers/NumericVariablePicker.js +48 -51
  84. package/dist/components/inputs/variables/pickers/NumericVariablePicker.js.map +1 -1
  85. package/dist/components/inputs/variables/pickers/NumericVariablePicker.module.css +27 -0
  86. package/dist/components/inputs/variables/pickers/TemporalElementEditor.d.ts +1 -1
  87. package/dist/components/inputs/variables/pickers/TemporalElementEditor.d.ts.map +1 -1
  88. package/dist/components/inputs/variables/pickers/TemporalElementEditor.js +58 -0
  89. package/dist/components/inputs/variables/pickers/TemporalElementEditor.js.map +1 -0
  90. package/dist/components/inputs/variables/pickers/TemporalElementEditor.module.css +27 -0
  91. package/dist/components/layout/MessageField.d.ts +3 -3
  92. package/dist/components/layout/MessageField.d.ts.map +1 -1
  93. package/dist/components/layout/MessageField.js +56 -56
  94. package/dist/components/layout/MessageField.js.map +1 -1
  95. package/dist/components/layout/MessageField.module.css +19 -0
  96. package/dist/components/layout/MessagesTabs.d.ts +1 -1
  97. package/dist/components/layout/MessagesTabs.d.ts.map +1 -1
  98. package/dist/components/layout/MessagesTabs.js +40 -43
  99. package/dist/components/layout/MessagesTabs.js.map +1 -1
  100. package/dist/components/layout/MessagesTabs.module.css +21 -0
  101. package/dist/components/layout/MessagesTree.d.ts +3 -2
  102. package/dist/components/layout/MessagesTree.d.ts.map +1 -1
  103. package/dist/components/layout/MessagesTree.js +65 -67
  104. package/dist/components/layout/MessagesTree.js.map +1 -1
  105. package/dist/components/layout/MessagesTree.module.css +36 -0
  106. package/dist/const.d.ts +8 -9
  107. package/dist/const.d.ts.map +1 -1
  108. package/dist/const.js +16 -13
  109. package/dist/const.js.map +1 -1
  110. package/dist/endpoints/get-messages.d.ts +1 -1
  111. package/dist/endpoints/get-messages.d.ts.map +1 -1
  112. package/dist/endpoints/get-messages.js +7 -13
  113. package/dist/endpoints/get-messages.js.map +1 -1
  114. package/dist/endpoints/set-messages.d.ts +1 -1
  115. package/dist/endpoints/set-messages.d.ts.map +1 -1
  116. package/dist/endpoints/set-messages.js +61 -45
  117. package/dist/endpoints/set-messages.js.map +1 -1
  118. package/dist/entities.d.ts +5 -0
  119. package/dist/entities.d.ts.map +1 -0
  120. package/dist/entities.js +38 -0
  121. package/dist/entities.js.map +1 -0
  122. package/dist/exports/client.d.ts +2 -0
  123. package/dist/exports/client.d.ts.map +1 -0
  124. package/dist/exports/client.js +3 -0
  125. package/dist/exports/client.js.map +1 -0
  126. package/dist/exports/rsc.d.ts +2 -2
  127. package/dist/exports/rsc.d.ts.map +1 -1
  128. package/dist/exports/rsc.js +4 -7
  129. package/dist/exports/rsc.js.map +1 -1
  130. package/dist/hooks.d.ts +4 -0
  131. package/dist/hooks.d.ts.map +1 -0
  132. package/dist/hooks.js +24 -0
  133. package/dist/hooks.js.map +1 -0
  134. package/dist/index.d.ts +20 -3
  135. package/dist/index.d.ts.map +1 -1
  136. package/dist/index.js +64 -80
  137. package/dist/index.js.map +1 -1
  138. package/dist/payload-types.d.ts +258 -0
  139. package/dist/payload-types.d.ts.map +1 -0
  140. package/dist/payload-types.js +15 -0
  141. package/dist/payload-types.js.map +1 -0
  142. package/dist/requests/fetchMessageFromAPI.d.ts +10 -0
  143. package/dist/requests/fetchMessageFromAPI.d.ts.map +1 -0
  144. package/dist/requests/fetchMessageFromAPI.js +15 -0
  145. package/dist/requests/fetchMessageFromAPI.js.map +1 -0
  146. package/dist/requests/fetchMessageFromPayload.d.ts +3 -0
  147. package/dist/requests/fetchMessageFromPayload.d.ts.map +1 -0
  148. package/dist/requests/fetchMessageFromPayload.js +29 -0
  149. package/dist/requests/fetchMessageFromPayload.js.map +1 -0
  150. package/dist/requests/fetchMessages.d.ts +3 -11
  151. package/dist/requests/fetchMessages.d.ts.map +1 -1
  152. package/dist/requests/fetchMessages.js +10 -40
  153. package/dist/requests/fetchMessages.js.map +1 -1
  154. package/dist/types.d.ts +7 -23
  155. package/dist/types.d.ts.map +1 -1
  156. package/dist/types.js +3 -0
  157. package/dist/types.js.map +1 -0
  158. package/dist/utils/config.d.ts +3 -3
  159. package/dist/utils/config.d.ts.map +1 -1
  160. package/dist/utils/config.js +27 -17
  161. package/dist/utils/config.js.map +1 -1
  162. package/dist/utils/error-handling.js +14 -12
  163. package/dist/utils/error-handling.js.map +1 -1
  164. package/dist/utils/format.d.ts +1 -1
  165. package/dist/utils/format.js +21 -13
  166. package/dist/utils/format.js.map +1 -1
  167. package/dist/utils/guards.d.ts +2 -1
  168. package/dist/utils/guards.js +8 -18
  169. package/dist/utils/guards.js.map +1 -1
  170. package/dist/utils/icu-tranform.d.ts +13 -18
  171. package/dist/utils/icu-tranform.d.ts.map +1 -1
  172. package/dist/utils/icu-tranform.js +140 -108
  173. package/dist/utils/icu-tranform.js.map +1 -1
  174. package/dist/utils/sanitize.d.ts +1 -1
  175. package/dist/utils/sanitize.js +36 -17
  176. package/dist/utils/sanitize.js.map +1 -1
  177. package/dist/utils/schema.d.ts +1 -3
  178. package/dist/utils/schema.d.ts.map +1 -1
  179. package/dist/utils/schema.js +42 -34
  180. package/dist/utils/schema.js.map +1 -1
  181. package/dist/utils/validate.d.ts +2 -2
  182. package/dist/utils/validate.js +52 -53
  183. package/dist/utils/validate.js.map +1 -1
  184. package/package.json +35 -52
  185. package/dist/components/inputs/variables/VariableSuggestion.d.ts +0 -9
  186. package/dist/components/inputs/variables/VariableSuggestion.d.ts.map +0 -1
  187. package/dist/components/inputs/variables/VariableSuggestion.js +0 -41
  188. package/dist/components/inputs/variables/VariableSuggestion.js.map +0 -1
  189. package/dist/components/inputs/variables/extension.d.ts +0 -4
  190. package/dist/components/inputs/variables/extension.d.ts.map +0 -1
  191. package/dist/components/inputs/variables/extension.js +0 -93
  192. package/dist/components/inputs/variables/extension.js.map +0 -1
  193. package/dist/context/messages-form.d.ts +0 -29
  194. package/dist/context/messages-form.d.ts.map +0 -1
  195. package/dist/context/messages-form.js +0 -26
  196. package/dist/context/messages-form.js.map +0 -1
  197. package/dist/exports/link.d.ts.map +0 -1
  198. package/dist/exports/link.js +0 -21
  199. package/dist/exports/link.js.map +0 -1
  200. package/dist/exports/view.d.ts +0 -10
  201. package/dist/exports/view.d.ts.map +0 -1
  202. package/dist/exports/view.js +0 -53
  203. package/dist/exports/view.js.map +0 -1
  204. package/dist/styles.css +0 -1
  205. package/dist/utils/cn.d.ts +0 -3
  206. package/dist/utils/cn.d.ts.map +0 -1
  207. package/dist/utils/cn.js +0 -9
  208. package/dist/utils/cn.js.map +0 -1
@@ -0,0 +1,14 @@
1
+ .submenu {
2
+ display: flex;
3
+ flex-direction: column;
4
+ gap: 0.5rem;
5
+ }
6
+
7
+ .icon {
8
+ width: 1.25rem;
9
+ height: 1.25rem;
10
+ }
11
+
12
+ .button {
13
+ margin-block: 0;
14
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"Move.d.ts","sourceRoot":"","sources":["../../../src/components/actions/Move.tsx"],"names":[],"mappings":"AAMA,wBAAgB,IAAI,4CA4BnB"}
1
+ {"version":3,"file":"Move.d.ts","sourceRoot":"","sources":["../../../src/components/actions/Move.tsx"],"names":[],"mappings":"AAQA,wBAAgB,IAAI,4CA4BnB"}
@@ -0,0 +1,41 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Button } from '@payloadcms/ui';
3
+ import { IconBraces } from '@tabler/icons-react';
4
+ import { get } from 'lodash-es';
5
+ import { useMessagesForm } from '../../components/MessageFormContext';
6
+ import styles from './Move.module.css';
7
+ export function Move() {
8
+ const { getValues, setValue, locales } = useMessagesForm();
9
+ const handleMove = ()=>{
10
+ const sourcePath = prompt('Source path');
11
+ if (!sourcePath) {
12
+ return;
13
+ }
14
+ const targetPath = prompt('Target path');
15
+ if (!targetPath) {
16
+ return;
17
+ }
18
+ locales.forEach((locale)=>{
19
+ const sourceValue = get(getValues(), [
20
+ locale,
21
+ sourcePath
22
+ ].join('.'));
23
+ setValue([
24
+ locale,
25
+ targetPath
26
+ ].join('.'), sourceValue);
27
+ });
28
+ };
29
+ return /*#__PURE__*/ _jsx(Button, {
30
+ buttonStyle: "subtle",
31
+ className: styles.button,
32
+ icon: /*#__PURE__*/ _jsx(IconBraces, {
33
+ className: styles.icon
34
+ }),
35
+ iconPosition: "left",
36
+ onClick: handleMove,
37
+ children: "Copy"
38
+ });
39
+ }
40
+
41
+ //# sourceMappingURL=Move.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/actions/Move.tsx"],"sourcesContent":["import { Button } from '@payloadcms/ui';\nimport { IconBraces } from '@tabler/icons-react';\nimport { get } from 'lodash-es';\n\nimport { useMessagesForm } from '@/components/MessageFormContext';\n\nimport styles from './Move.module.css';\n\nexport function Move() {\n const { getValues, setValue, locales } = useMessagesForm();\n const handleMove = () => {\n const sourcePath = prompt('Source path');\n if (!sourcePath) {\n return;\n }\n const targetPath = prompt('Target path');\n if (!targetPath) {\n return;\n }\n\n locales.forEach((locale) => {\n const sourceValue = get(getValues(), [locale, sourcePath].join('.'));\n setValue([locale, targetPath].join('.'), sourceValue);\n });\n };\n return (\n <Button\n buttonStyle=\"subtle\"\n className={styles.button}\n icon={<IconBraces className={styles.icon} />}\n iconPosition=\"left\"\n onClick={handleMove}\n >\n Copy\n </Button>\n );\n}\n"],"names":["Button","IconBraces","get","useMessagesForm","styles","Move","getValues","setValue","locales","handleMove","sourcePath","prompt","targetPath","forEach","locale","sourceValue","join","buttonStyle","className","button","icon","iconPosition","onClick"],"mappings":";AAAA,SAASA,MAAM,QAAQ,iBAAiB;AACxC,SAASC,UAAU,QAAQ,sBAAsB;AACjD,SAASC,GAAG,QAAQ,YAAY;AAEhC,SAASC,eAAe,QAAQ,kCAAkC;AAElE,OAAOC,YAAY,oBAAoB;AAEvC,OAAO,SAASC;IACd,MAAM,EAAEC,SAAS,EAAEC,QAAQ,EAAEC,OAAO,EAAE,GAAGL;IACzC,MAAMM,aAAa;QACjB,MAAMC,aAAaC,OAAO;QAC1B,IAAI,CAACD,YAAY;YACf;QACF;QACA,MAAME,aAAaD,OAAO;QAC1B,IAAI,CAACC,YAAY;YACf;QACF;QAEAJ,QAAQK,OAAO,CAAC,CAACC;YACf,MAAMC,cAAcb,IAAII,aAAa;gBAACQ;gBAAQJ;aAAW,CAACM,IAAI,CAAC;YAC/DT,SAAS;gBAACO;gBAAQF;aAAW,CAACI,IAAI,CAAC,MAAMD;QAC3C;IACF;IACA,qBACE,KAACf;QACCiB,aAAY;QACZC,WAAWd,OAAOe,MAAM;QACxBC,oBAAM,KAACnB;YAAWiB,WAAWd,OAAOgB,IAAI;;QACxCC,cAAa;QACbC,SAASb;kBACV;;AAIL"}
@@ -0,0 +1,8 @@
1
+ .icon {
2
+ width: 1.25rem;
3
+ height: 1.25rem;
4
+ }
5
+
6
+ .button {
7
+ margin-block: 0;
8
+ }
@@ -1,4 +1,4 @@
1
- import { FieldError } from 'react-hook-form';
1
+ import type { FieldError } from 'react-hook-form';
2
2
  export interface InputWrapperProps {
3
3
  label?: string;
4
4
  error: FieldError | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"InputWrapper.d.ts","sourceRoot":"","sources":["../../../src/components/inputs/InputWrapper.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAIlD,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,UAAU,GAAG,SAAS,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,KAAK,EACL,SAAS,EACT,QAAQ,GACT,EAAE,KAAK,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,2CAqB5C"}
1
+ {"version":3,"file":"InputWrapper.d.ts","sourceRoot":"","sources":["../../../src/components/inputs/InputWrapper.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAIlD,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,UAAU,GAAG,SAAS,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,KAAK,EACL,SAAS,EACT,QAAQ,GACT,EAAE,KAAK,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,2CAkB5C"}
@@ -1,32 +1,34 @@
1
- import { jsxs as s, jsx as e } from "react/jsx-runtime";
2
- import { FieldLabel as m } from "@payloadcms/ui";
3
- import { cn as o } from "../../utils/cn.js";
4
- function c({
5
- label: r,
6
- error: l,
7
- className: t,
8
- children: i
9
- }) {
10
- return /* @__PURE__ */ s("div", { className: o("flex h-full min-w-5 flex-col gap-1", t), children: [
11
- /* @__PURE__ */ s(
12
- "fieldset",
13
- {
14
- className: o(
15
- "mx-0 flex-1 rounded-md focus-within:border-elevation-400",
16
- {
17
- "border-error bg-error": l
18
- }
19
- ),
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { FieldLabel } from '@payloadcms/ui';
3
+ import styles from './InputWrapper.module.css';
4
+ export function InputWrapper({ label, error, className, children }) {
5
+ return /*#__PURE__*/ _jsxs("div", {
6
+ className: [
7
+ styles.wrapper,
8
+ className
9
+ ].filter(Boolean).join(' '),
20
10
  children: [
21
- r && /* @__PURE__ */ e("legend", { className: "-ml-2 px-1.5 text-base", children: /* @__PURE__ */ e(m, { label: r }) }),
22
- i
11
+ /*#__PURE__*/ _jsxs("fieldset", {
12
+ className: [
13
+ styles.fieldset,
14
+ error ? styles.fieldsetError : undefined
15
+ ].filter(Boolean).join(' '),
16
+ children: [
17
+ label && /*#__PURE__*/ _jsx("legend", {
18
+ className: styles.legend,
19
+ children: /*#__PURE__*/ _jsx(FieldLabel, {
20
+ label: label
21
+ })
22
+ }),
23
+ children
24
+ ]
25
+ }),
26
+ /*#__PURE__*/ _jsx("p", {
27
+ className: styles.errorMessage,
28
+ children: error?.message
29
+ })
23
30
  ]
24
- }
25
- ),
26
- /* @__PURE__ */ e("p", { className: "text-base text-error", children: l?.message })
27
- ] });
31
+ });
28
32
  }
29
- export {
30
- c as InputWrapper
31
- };
32
- //# sourceMappingURL=InputWrapper.js.map
33
+
34
+ //# sourceMappingURL=InputWrapper.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"InputWrapper.js","sources":["../../../src/components/inputs/InputWrapper.tsx"],"sourcesContent":["import { FieldLabel } from '@payloadcms/ui';\nimport type { FieldError } from 'react-hook-form';\n\nimport { cn } from '@/utils/cn';\n\nexport interface InputWrapperProps {\n label?: string;\n error: FieldError | undefined;\n className?: string;\n}\n\nexport function InputWrapper({\n label,\n error,\n className,\n children,\n}: React.PropsWithChildren<InputWrapperProps>) {\n return (\n <div className={cn('flex h-full min-w-5 flex-col gap-1', className)}>\n <fieldset\n className={cn(\n 'mx-0 flex-1 rounded-md focus-within:border-elevation-400',\n {\n 'border-error bg-error': error,\n },\n )}\n >\n {label && (\n <legend className=\"-ml-2 px-1.5 text-base\">\n <FieldLabel label={label} />\n </legend>\n )}\n {children}\n </fieldset>\n <p className=\"text-base text-error\">{error?.message}</p>\n </div>\n );\n}\n"],"names":["InputWrapper","label","error","className","children","cn","jsxs","jsx","FieldLabel"],"mappings":";;;AAWO,SAASA,EAAa;AAAA,EAC3B,OAAAC;AAAA,EACA,OAAAC;AAAA,EACA,WAAAC;AAAA,EACA,UAAAC;AACF,GAA+C;AAC7C,2BACG,OAAA,EAAI,WAAWC,EAAG,sCAAsCF,CAAS,GAChE,UAAA;AAAA,IAAA,gBAAAG;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAWD;AAAA,UACT;AAAA,UACA;AAAA,YACE,yBAAyBH;AAAA,UAAA;AAAA,QAC3B;AAAA,QAGD,UAAA;AAAA,UAAAD,uBACE,UAAA,EAAO,WAAU,0BAChB,UAAA,gBAAAM,EAACC,GAAA,EAAW,OAAAP,GAAc,EAAA,CAC5B;AAAA,UAEDG;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAEH,gBAAAG,EAAC,KAAA,EAAE,WAAU,wBAAwB,aAAO,QAAA,CAAQ;AAAA,EAAA,GACtD;AAEJ;"}
1
+ {"version":3,"sources":["../../../src/components/inputs/InputWrapper.tsx"],"sourcesContent":["import { FieldLabel } from '@payloadcms/ui';\nimport type { FieldError } from 'react-hook-form';\n\nimport styles from './InputWrapper.module.css';\n\nexport interface InputWrapperProps {\n label?: string;\n error: FieldError | undefined;\n className?: string;\n}\n\nexport function InputWrapper({\n label,\n error,\n className,\n children,\n}: React.PropsWithChildren<InputWrapperProps>) {\n return (\n <div className={[styles.wrapper, className].filter(Boolean).join(' ')}>\n <fieldset\n className={[styles.fieldset, error ? styles.fieldsetError : undefined]\n .filter(Boolean)\n .join(' ')}\n >\n {label && (\n <legend className={styles.legend}>\n <FieldLabel label={label} />\n </legend>\n )}\n {children}\n </fieldset>\n <p className={styles.errorMessage}>{error?.message}</p>\n </div>\n );\n}\n"],"names":["FieldLabel","styles","InputWrapper","label","error","className","children","div","wrapper","filter","Boolean","join","fieldset","fieldsetError","undefined","legend","p","errorMessage","message"],"mappings":";AAAA,SAASA,UAAU,QAAQ,iBAAiB;AAG5C,OAAOC,YAAY,4BAA4B;AAQ/C,OAAO,SAASC,aAAa,EAC3BC,KAAK,EACLC,KAAK,EACLC,SAAS,EACTC,QAAQ,EACmC;IAC3C,qBACE,MAACC;QAAIF,WAAW;YAACJ,OAAOO,OAAO;YAAEH;SAAU,CAACI,MAAM,CAACC,SAASC,IAAI,CAAC;;0BAC/D,MAACC;gBACCP,WAAW;oBAACJ,OAAOW,QAAQ;oBAAER,QAAQH,OAAOY,aAAa,GAAGC;iBAAU,CACnEL,MAAM,CAACC,SACPC,IAAI,CAAC;;oBAEPR,uBACC,KAACY;wBAAOV,WAAWJ,OAAOc,MAAM;kCAC9B,cAAA,KAACf;4BAAWG,OAAOA;;;oBAGtBG;;;0BAEH,KAACU;gBAAEX,WAAWJ,OAAOgB,YAAY;0BAAGb,OAAOc;;;;AAGjD"}
@@ -0,0 +1,34 @@
1
+ .wrapper {
2
+ display: flex;
3
+ height: 100%;
4
+ min-width: 1.25rem;
5
+ flex-direction: column;
6
+ gap: 0.25rem;
7
+ }
8
+
9
+ .fieldset {
10
+ margin-inline: 0;
11
+ 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
+ }
24
+
25
+ .legend {
26
+ margin-left: -0.5rem;
27
+ padding-inline: 0.375rem;
28
+ font-size: var(--font-size-base);
29
+ }
30
+
31
+ .errorMessage {
32
+ font-size: var(--font-size-base);
33
+ color: var(--theme-error-400);
34
+ }
@@ -1,6 +1,6 @@
1
- import { DefaultNodeTypes, TypedEditorState } from '@payloadcms/richtext-lexical';
2
- import { SerializedEditorState } from '@payloadcms/richtext-lexical/lexical';
3
- import { InputWrapperProps } from './InputWrapper';
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
4
  export interface LexicalInputProps extends InputWrapperProps {
5
5
  lang: string;
6
6
  value: string;
@@ -0,0 +1,86 @@
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';
9
+ export function LexicalInput({ error, label, value, onChange, className }) {
10
+ const editor = useHtmlLexicalAdapter({
11
+ html: value,
12
+ onChange
13
+ });
14
+ return /*#__PURE__*/ _jsx(InputWrapper, {
15
+ className: className,
16
+ error: error,
17
+ label: label,
18
+ children: /*#__PURE__*/ _jsx(RenderLexical, {
19
+ field: {
20
+ name: 'myCustomEditor',
21
+ label: false,
22
+ type: 'richText'
23
+ },
24
+ schemaPath: "global.intl-plugin.editorTemplate",
25
+ setValue: (val)=>editor.setValue(val),
26
+ value: editor.value
27
+ })
28
+ });
29
+ }
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
+
86
+ //# sourceMappingURL=LexicalInput.js.map
@@ -0,0 +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,5 +1,5 @@
1
- import { TemplateVariable } from '../../types';
2
- import { InputWrapperProps } from './InputWrapper';
1
+ import type { TemplateVariable } from '../../types';
2
+ import type { InputWrapperProps } from './InputWrapper';
3
3
  export interface MessageInputProps extends InputWrapperProps {
4
4
  value: string;
5
5
  lang: string;
@@ -1 +1 @@
1
- {"version":3,"file":"MessageInput.d.ts","sourceRoot":"","sources":["../../../src/components/inputs/MessageInput.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAIhD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAIxD,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;AAKD,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,KAAK,EACL,IAAI,EACJ,KAAK,EACL,SAAS,EACT,QAAQ,EACR,MAAM,EACN,SAAS,GACV,EAAE,iBAAiB,2CAkBnB"}
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,38 +1,111 @@
1
- import { jsx as r } from "react/jsx-runtime";
2
- import d from "@tiptap/extension-document";
3
- import c from "@tiptap/extension-paragraph";
4
- import u from "@tiptap/extension-text";
5
- import { useEditor as l, EditorContent as x } from "@tiptap/react";
6
- import { parseIcuToProseMirrorJSON as g } from "../../utils/icu-tranform.js";
7
- import { InputWrapper as h } from "./InputWrapper.js";
8
- import { VariableMention as I } from "./variables/extension.js";
9
- function C({
10
- label: o,
11
- value: t,
12
- lang: e,
13
- error: i,
14
- variables: m,
15
- onChange: n,
16
- onBlur: p,
17
- className: a
18
- }) {
19
- const s = l({
20
- immediatelyRender: !1,
21
- content: g(t),
22
- extensions: [d, c, u, I(m)],
23
- onUpdate: ({ editor: f }) => n(f.getText())
24
- });
25
- return /* @__PURE__ */ r(h, { className: a, error: i, label: o, children: /* @__PURE__ */ r(
26
- x,
27
- {
28
- className: "tiptap-editor min-h-8",
29
- editor: s,
30
- lang: e,
31
- onBlur: p
32
- }
33
- ) });
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { $getRoot } from '@payloadcms/richtext-lexical/lexical';
4
+ import { LexicalComposer } from '@payloadcms/richtext-lexical/lexical/react/LexicalComposer';
5
+ import { ContentEditable } from '@payloadcms/richtext-lexical/lexical/react/LexicalContentEditable';
6
+ import { LexicalErrorBoundary } from '@payloadcms/richtext-lexical/lexical/react/LexicalErrorBoundary';
7
+ import { HistoryPlugin } from '@payloadcms/richtext-lexical/lexical/react/LexicalHistoryPlugin';
8
+ import { OnChangePlugin } from '@payloadcms/richtext-lexical/lexical/react/LexicalOnChangePlugin';
9
+ import { PlainTextPlugin } from '@payloadcms/richtext-lexical/lexical/react/LexicalPlainTextPlugin';
10
+ import { BeautifulMentionNode, BeautifulMentionsPlugin } from 'lexical-beautiful-mentions';
11
+ import { forwardRef, useCallback, useMemo } from 'react';
12
+ import { formatVariableLabel } from '../../utils/format';
13
+ import { isTagElement } from '../../utils/guards';
14
+ import { parseIcuToLexicalState, serializeICUMessage } from '../../utils/icu-tranform';
15
+ import { InputWrapper } from './InputWrapper';
16
+ import styles from './MessageInput.module.css';
17
+ 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 }) {
43
+ const handleChange = useCallback((editorState)=>{
44
+ editorState.read(()=>{
45
+ onChange($getRoot().getTextContent());
46
+ });
47
+ }, [
48
+ onChange
49
+ ]);
50
+ const mentionItems = useMemo(()=>{
51
+ const toItem = (v)=>({
52
+ value: v.value,
53
+ label: formatVariableLabel(v),
54
+ icu: serializeICUMessage([
55
+ v
56
+ ])
57
+ });
58
+ return {
59
+ '@': variables.map(toItem),
60
+ '{': variables.filter((v)=>!isTagElement(v)).map(toItem),
61
+ '<': variables.filter((v)=>isTagElement(v)).map(toItem)
62
+ };
63
+ }, [
64
+ variables
65
+ ]);
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, {
79
+ className: className,
80
+ error: error,
81
+ label: label,
82
+ children: /*#__PURE__*/ _jsx(LexicalComposer, {
83
+ initialConfig: initialConfig,
84
+ children: /*#__PURE__*/ _jsxs("div", {
85
+ className: styles.editor,
86
+ lang: lang,
87
+ onBlur: onBlur,
88
+ children: [
89
+ /*#__PURE__*/ _jsx(PlainTextPlugin, {
90
+ contentEditable: /*#__PURE__*/ _jsx(ContentEditable, {
91
+ className: styles.contentEditable
92
+ }),
93
+ ErrorBoundary: LexicalErrorBoundary
94
+ }),
95
+ /*#__PURE__*/ _jsx(OnChangePlugin, {
96
+ onChange: handleChange
97
+ }),
98
+ /*#__PURE__*/ _jsx(HistoryPlugin, {}),
99
+ /*#__PURE__*/ _jsx(BeautifulMentionsPlugin, {
100
+ items: mentionItems,
101
+ menuAnchorClassName: styles.menuAnchor,
102
+ menuComponent: MentionMenu,
103
+ menuItemComponent: MentionMenuItem
104
+ })
105
+ ]
106
+ })
107
+ })
108
+ });
34
109
  }
35
- export {
36
- C as MessageInput
37
- };
38
- //# sourceMappingURL=MessageInput.js.map
110
+
111
+ //# sourceMappingURL=MessageInput.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MessageInput.js","sources":["../../../src/components/inputs/MessageInput.tsx"],"sourcesContent":["import Document from '@tiptap/extension-document';\nimport Paragraph from '@tiptap/extension-paragraph';\nimport Text from '@tiptap/extension-text';\nimport { EditorContent, useEditor } from '@tiptap/react';\nimport type { TemplateVariable } from '@/types';\n\nimport { parseIcuToProseMirrorJSON } from '@/utils/icu-tranform';\n\nimport type { InputWrapperProps } from './InputWrapper';\nimport { InputWrapper } from './InputWrapper';\nimport { VariableMention } from './variables/extension';\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\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 editor = useEditor({\n immediatelyRender: false,\n content: parseIcuToProseMirrorJSON(value),\n extensions: [Document, Paragraph, Text, VariableMention(variables)],\n onUpdate: ({ editor }) => onChange(editor.getText()),\n });\n\n return (\n <InputWrapper className={className} error={error} label={label}>\n <EditorContent\n className=\"tiptap-editor min-h-8\"\n editor={editor}\n lang={lang}\n onBlur={onBlur}\n />\n </InputWrapper>\n );\n}\n"],"names":["MessageInput","label","value","lang","error","variables","onChange","onBlur","className","editor","useEditor","parseIcuToProseMirrorJSON","Document","Paragraph","Text","VariableMention","jsx","InputWrapper","EditorContent"],"mappings":";;;;;;;;AAuBO,SAASA,EAAa;AAAA,EAC3B,OAAAC;AAAA,EACA,OAAAC;AAAA,EACA,MAAAC;AAAA,EACA,OAAAC;AAAA,EACA,WAAAC;AAAA,EACA,UAAAC;AAAA,EACA,QAAAC;AAAA,EACA,WAAAC;AACF,GAAsB;AACpB,QAAMC,IAASC,EAAU;AAAA,IACvB,mBAAmB;AAAA,IACnB,SAASC,EAA0BT,CAAK;AAAA,IACxC,YAAY,CAACU,GAAUC,GAAWC,GAAMC,EAAgBV,CAAS,CAAC;AAAA,IAClE,UAAU,CAAC,EAAE,QAAAI,QAAaH,EAASG,EAAO,QAAA,CAAS;AAAA,EAAA,CACpD;AAED,SACE,gBAAAO,EAACC,GAAA,EAAa,WAAAT,GAAsB,OAAAJ,GAAc,OAAAH,GAChD,UAAA,gBAAAe;AAAA,IAACE;AAAA,IAAA;AAAA,MACC,WAAU;AAAA,MACV,QAAAT;AAAA,MACA,MAAAN;AAAA,MACA,QAAAI;AAAA,IAAA;AAAA,EAAA,GAEJ;AAEJ;"}
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":"AAAA;;AAGA,SAASA,QAAQ,QAAQ,uCAAuC;AAChE,SAASC,eAAe,QAAQ,6DAA6D;AAC7F,SAASC,eAAe,QAAQ,oEAAoE;AACpG,SAASC,oBAAoB,QAAQ,kEAAkE;AACvG,SAASC,aAAa,QAAQ,kEAAkE;AAChG,SAASC,cAAc,QAAQ,mEAAmE;AAClG,SAASC,eAAe,QAAQ,oEAAoE;AACpG,SACEC,oBAAoB,EAGpBC,uBAAuB,QAClB,6BAA6B;AACpC,SAASC,UAAU,EAAEC,WAAW,EAAEC,OAAO,QAAQ,QAAQ;AAGzD,SAASC,mBAAmB,QAAQ,iBAAiB;AACrD,SAASC,YAAY,QAAQ,iBAAiB;AAC9C,SACEC,sBAAsB,EACtBC,mBAAmB,QACd,uBAAuB;AAG9B,SAASC,YAAY,QAAQ,iBAAiB;AAC9C,OAAOC,YAAY,4BAA4B;AAC/C,SAASC,mBAAmB,QAAQ,2BAA2B;AAC/D,OAAOC,sBAAsB,4CAA4C;AAUzE,MAAMC,4BAAcX,WAClB,CAAC,EAAEY,SAASC,CAAC,EAAE,GAAGC,OAAO,EAAEC,oBACzB,KAACC;QAAI,GAAGF,KAAK;QAAEG,WAAWP,iBAAiBQ,IAAI;QAAEH,KAAKA;;AAI1D,MAAMI,gCAAkBnB,WAGtB,CAACc,OAAOC,oBACR,KAACK;QACCC,iBAAeP,MAAMQ,QAAQ;QAC7BL,WAAW;YACTP,iBAAiBa,IAAI;YACrBT,MAAMQ,QAAQ,GAAGZ,iBAAiBc,YAAY,GAAGC;SAClD,CACEC,MAAM,CAACC,SACPC,IAAI,CAAC;QACRC,SAASf,MAAMe,OAAO;QACtBC,WAAWhB,MAAMgB,SAAS;QAC1BC,aAAajB,MAAMiB,WAAW;QAC9BC,cAAclB,MAAMkB,YAAY;QAChCjB,KAAKA;QACL,4GAA4G;QAC5GkB,MAAK;QACLC,UAAU,CAAC;kBAEV,OAAOpB,MAAMS,IAAI,CAACY,IAAI,EAAEC,UAAU,WAC/BtB,MAAMS,IAAI,CAACY,IAAI,CAACC,KAAK,GACrBtB,MAAMS,IAAI,CAACc,YAAY;;AAI/B,iDAAiD;AACjD,yCAAyC;AAEzC,OAAO,SAASC,aAAa,EAC3BF,KAAK,EACLG,KAAK,EACLC,IAAI,EACJC,KAAK,EACLC,SAAS,EACTC,QAAQ,EACRC,MAAM,EACN3B,SAAS,EACS;IAClB,MAAM4B,eAAe5C,YACnB,CAAC6C;QACCA,YAAYC,IAAI,CAAC;YACfJ,SAASpD,WAAWyD,cAAc;QACpC;IACF,GACA;QAACL;KAAS;IAGZ,MAAMM,eAAe/C,QAAQ;QAC3B,MAAMgD,SAAS,CAACC,IAAyB,CAAA;gBACvCZ,OAAOY,EAAEZ,KAAK;gBACdH,OAAOjC,oBAAoBgD;gBAC3BC,KAAK9C,oBAAoB;oBAAC6C;iBAAE;YAC9B,CAAA;QAEA,OAAO;YACL,KAAKT,UAAUW,GAAG,CAACH;YACnB,KAAKR,UAAUhB,MAAM,CAAC,CAACyB,IAAM,CAAC/C,aAAa+C,IAAIE,GAAG,CAACH;YACnD,KAAKR,UAAUhB,MAAM,CAAC,CAACyB,IAAM/C,aAAa+C,IAAIE,GAAG,CAACH;QACpD;IACF,GAAG;QAACR;KAAU;IAEd,MAAMY,gBAAgB;QACpBC,WAAW;QACXC,OAAO;YACL/C;YACA;gBACEgD,SAAS3D;gBACT4D,MAAM,CAACC,OACL,IAAIlD,oBACFkD,KAAKC,UAAU,IACfD,KAAKE,QAAQ,IACbF,KAAKG,OAAO;YAElB;SACD;QACDhB,aAAaiB,KAAKC,SAAS,CAAC3D,uBAAuBkC;QACnD0B,SAASC,QAAQzB,KAAK;IACxB;IAEA,qBACE,KAAClC;QAAaU,WAAWA;QAAWwB,OAAOA;QAAOL,OAAOA;kBACvD,cAAA,KAAC5C;YAAgB8D,eAAeA;sBAE9B,cAAA,MAACa;gBAAIlD,WAAWT,OAAO4D,MAAM;gBAAE5B,MAAMA;gBAAMI,QAAQA;;kCACjD,KAAC/C;wBACCwE,+BACE,KAAC5E;4BAAgBwB,WAAWT,OAAO6D,eAAe;;wBAEpDC,eAAe5E;;kCAEjB,KAACE;wBAAe+C,UAAUE;;kCAC1B,KAAClD;kCACD,KAACI;wBACCwE,OAAOtB;wBACPuB,qBAAqBhE,OAAOiE,UAAU;wBACtCC,eAAe/D;wBACfgE,mBAAmBxD;;;;;;AAM/B"}
@@ -0,0 +1,25 @@
1
+ .editor {
2
+ position: relative;
3
+ min-height: 2rem;
4
+ font-size: var(--font-size-large);
5
+ }
6
+
7
+ .menuAnchor {
8
+ z-index: 50;
9
+ }
10
+
11
+ .contentEditable {
12
+ outline: none;
13
+ }
14
+
15
+ .contentEditable:focus {
16
+ outline: none;
17
+ }
18
+
19
+ .contentEditable > :first-child {
20
+ margin-top: 0;
21
+ }
22
+
23
+ .contentEditable > :last-child {
24
+ margin-bottom: 0;
25
+ }
@@ -1,3 +1,9 @@
1
- import { ReactNodeViewProps } from '@tiptap/react';
2
- export declare function VariableChip({ node, updateAttributes, }: ReactNodeViewProps<HTMLElement>): import("react/jsx-runtime").JSX.Element;
1
+ import type { NodeKey } from '@payloadcms/richtext-lexical/lexical';
2
+ export interface VariableChipProps {
3
+ name: string;
4
+ label: string;
5
+ icu: string;
6
+ nodeKey: NodeKey;
7
+ }
8
+ export declare function VariableChip({ name, label, icu, nodeKey }: VariableChipProps): import("react/jsx-runtime").JSX.Element;
3
9
  //# sourceMappingURL=VariableChip.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"VariableChip.d.ts","sourceRoot":"","sources":["../../../../src/components/inputs/variables/VariableChip.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AA0BxD,wBAAgB,YAAY,CAAC,EAC3B,IAAI,EACJ,gBAAgB,GACjB,EAAE,kBAAkB,CAAC,WAAW,CAAC,2CAiEjC"}
1
+ {"version":3,"file":"VariableChip.d.ts","sourceRoot":"","sources":["../../../../src/components/inputs/variables/VariableChip.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sCAAsC,CAAC;AAwBpE,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,OAAO,CAAC;CAClB;AAID,wBAAgB,YAAY,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,iBAAiB,2CAkE5E"}