payload-intl 0.1.0 → 0.2.1

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 (55) hide show
  1. package/dist/components/MessageController.js +11 -11
  2. package/dist/components/MessageController.js.map +1 -1
  3. package/dist/components/MessagesForm.d.ts +2 -3
  4. package/dist/components/MessagesForm.js +100 -93
  5. package/dist/components/MessagesForm.js.map +1 -1
  6. package/dist/components/inputs/InputWrapper.js +13 -13
  7. package/dist/components/inputs/InputWrapper.js.map +1 -1
  8. package/dist/components/inputs/LexicalInput.d.ts +19 -0
  9. package/dist/components/inputs/LexicalInput.js +90 -0
  10. package/dist/components/inputs/LexicalInput.js.map +1 -0
  11. package/dist/components/inputs/variables/editors/PluralVariableEditor.js.map +1 -1
  12. package/dist/components/inputs/variables/editors/SelectVariableEditor.js.map +1 -1
  13. package/dist/components/inputs/variables/editors/TagVariableEditor.js.map +1 -1
  14. package/dist/components/inputs/variables/pickers/NumericVariablePicker.js.map +1 -1
  15. package/dist/components/layout/MessageField.js +21 -18
  16. package/dist/components/layout/MessageField.js.map +1 -1
  17. package/dist/components/layout/MessagesTree.js.map +1 -1
  18. package/dist/context/messages-form.d.ts +2 -4
  19. package/dist/context/messages-form.js +10 -11
  20. package/dist/context/messages-form.js.map +1 -1
  21. package/dist/exports/view.d.ts +2 -3
  22. package/dist/exports/view.js +31 -33
  23. package/dist/exports/view.js.map +1 -1
  24. package/dist/index.d.ts +1 -1
  25. package/dist/index.js +40 -23
  26. package/dist/index.js.map +1 -1
  27. package/dist/requests/fetchMessages.js +22 -19
  28. package/dist/requests/fetchMessages.js.map +1 -1
  29. package/dist/styles.css +1 -1
  30. package/dist/types.d.ts +0 -8
  31. package/dist/utils/error-handling.d.ts +1 -0
  32. package/dist/utils/error-handling.js +13 -0
  33. package/dist/utils/error-handling.js.map +1 -0
  34. package/dist/utils/schema.js.map +1 -1
  35. package/dist/utils/validate.d.ts +1 -1
  36. package/dist/utils/validate.js.map +1 -1
  37. package/package.json +24 -34
  38. package/dist/components/inputs/RichTextInput.d.ts +0 -8
  39. package/dist/components/inputs/RichTextInput.js +0 -85
  40. package/dist/components/inputs/RichTextInput.js.map +0 -1
  41. package/dist/components/inputs/toolbar/AlignmentControls.d.ts +0 -5
  42. package/dist/components/inputs/toolbar/AlignmentControls.js +0 -62
  43. package/dist/components/inputs/toolbar/AlignmentControls.js.map +0 -1
  44. package/dist/components/inputs/toolbar/BlockElementSelect.d.ts +0 -5
  45. package/dist/components/inputs/toolbar/BlockElementSelect.js +0 -135
  46. package/dist/components/inputs/toolbar/BlockElementSelect.js.map +0 -1
  47. package/dist/components/inputs/toolbar/LinkEditor.d.ts +0 -58
  48. package/dist/components/inputs/toolbar/LinkEditor.js +0 -242
  49. package/dist/components/inputs/toolbar/LinkEditor.js.map +0 -1
  50. package/dist/components/inputs/toolbar/MarkControls.d.ts +0 -5
  51. package/dist/components/inputs/toolbar/MarkControls.js +0 -48
  52. package/dist/components/inputs/toolbar/MarkControls.js.map +0 -1
  53. package/dist/components/inputs/toolbar/RichTextToolbar.d.ts +0 -6
  54. package/dist/components/inputs/toolbar/RichTextToolbar.js +0 -35
  55. package/dist/components/inputs/toolbar/RichTextToolbar.js.map +0 -1
@@ -1,22 +1,22 @@
1
1
  import { jsx as o } from "react/jsx-runtime";
2
- import { Controller as m } from "react-hook-form";
2
+ import { Controller as g } from "react-hook-form";
3
3
  import { useMessagesForm as i } from "../context/messages-form.js";
4
+ import { LexicalInput as C } from "./inputs/LexicalInput.js";
4
5
  import { MessageInput as h } from "./inputs/MessageInput.js";
5
- import { RichTextInput as C } from "./inputs/RichTextInput.js";
6
6
  function M({
7
- type: a,
7
+ type: l,
8
8
  name: n,
9
- variables: l,
9
+ variables: m,
10
10
  label: u,
11
11
  locale: t,
12
12
  validate: p,
13
13
  className: s
14
14
  }) {
15
- const { control: g } = i();
16
- return a === "rich" ? /* @__PURE__ */ o(
17
- m,
15
+ const { control: a } = i();
16
+ return l === "rich" ? /* @__PURE__ */ o(
17
+ g,
18
18
  {
19
- control: g,
19
+ control: a,
20
20
  name: n,
21
21
  render: ({ field: r, fieldState: e }) => /* @__PURE__ */ o(
22
22
  C,
@@ -35,9 +35,9 @@ function M({
35
35
  }
36
36
  }
37
37
  ) : /* @__PURE__ */ o(
38
- m,
38
+ g,
39
39
  {
40
- control: g,
40
+ control: a,
41
41
  name: n,
42
42
  render: ({ field: r, fieldState: e }) => /* @__PURE__ */ o(
43
43
  h,
@@ -46,7 +46,7 @@ function M({
46
46
  lang: t,
47
47
  className: s,
48
48
  value: r.value || "",
49
- variables: l,
49
+ variables: m,
50
50
  error: e.error,
51
51
  onChange: r.onChange,
52
52
  onBlur: r.onBlur
@@ -1 +1 @@
1
- {"version":3,"file":"MessageController.js","sources":["../../src/components/MessageController.tsx"],"sourcesContent":["import type { TemplateVariable } from \"@/types\";\nimport type { MessageType } from \"@/utils/schema\";\nimport type { MessageValidator } from \"@/utils/validate\";\nimport { Controller } from \"react-hook-form\";\n\nimport { useMessagesForm } from \"@/context/messages-form\";\n\nimport { MessageInput } from \"./inputs/MessageInput\";\nimport { RichTextInput } from \"./inputs/RichTextInput\";\n\ninterface MessageControllerProps {\n type: MessageType;\n label?: string;\n locale: string;\n name: string;\n className?: string;\n variables: TemplateVariable[];\n validate: MessageValidator;\n}\n\nexport function MessageController({\n type,\n name,\n variables,\n label,\n locale,\n validate,\n className,\n}: MessageControllerProps): React.ReactNode {\n const { control } = useMessagesForm();\n\n if (type === \"rich\") {\n return (\n <Controller\n control={control}\n name={name}\n render={({ field, fieldState }) => (\n <RichTextInput\n className={className}\n error={fieldState.error}\n label={label}\n lang={locale}\n onChange={field.onChange}\n onBlur={field.onBlur}\n value={(field.value as unknown as string) || \"\"}\n />\n )}\n rules={{\n required: true,\n }}\n />\n );\n }\n\n return (\n <Controller\n control={control}\n name={name}\n render={({ field, fieldState }) => (\n <MessageInput\n label={label}\n lang={locale}\n className={className}\n value={(field.value as unknown as string) || \"\"}\n variables={variables}\n error={fieldState.error}\n onChange={field.onChange}\n onBlur={field.onBlur}\n />\n )}\n rules={{\n required: true,\n validate,\n }}\n />\n );\n}\n"],"names":["MessageController","type","name","variables","label","locale","validate","className","control","useMessagesForm","jsx","Controller","field","fieldState","RichTextInput","MessageInput"],"mappings":";;;;;AAoBO,SAASA,EAAkB;AAAA,EAChC,MAAAC;AAAA,EACA,MAAAC;AAAA,EACA,WAAAC;AAAA,EACA,OAAAC;AAAA,EACA,QAAAC;AAAA,EACA,UAAAC;AAAA,EACA,WAAAC;AACF,GAA4C;AAC1C,QAAM,EAAE,SAAAC,EAAA,IAAYC,EAAA;AAEpB,SAAIR,MAAS,SAET,gBAAAS;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,SAAAH;AAAA,MACA,MAAAN;AAAA,MACA,QAAQ,CAAC,EAAE,OAAAU,GAAO,YAAAC,QAChB,gBAAAH;AAAA,QAACI;AAAA,QAAA;AAAA,UACC,WAAAP;AAAA,UACA,OAAOM,EAAW;AAAA,UAClB,OAAAT;AAAA,UACA,MAAMC;AAAA,UACN,UAAUO,EAAM;AAAA,UAChB,QAAQA,EAAM;AAAA,UACd,OAAQA,EAAM,SAA+B;AAAA,QAAA;AAAA,MAAA;AAAA,MAGjD,OAAO;AAAA,QACL,UAAU;AAAA,MAAA;AAAA,IACZ;AAAA,EAAA,IAMJ,gBAAAF;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,SAAAH;AAAA,MACA,MAAAN;AAAA,MACA,QAAQ,CAAC,EAAE,OAAAU,GAAO,YAAAC,QAChB,gBAAAH;AAAA,QAACK;AAAA,QAAA;AAAA,UACC,OAAAX;AAAA,UACA,MAAMC;AAAA,UACN,WAAAE;AAAA,UACA,OAAQK,EAAM,SAA+B;AAAA,UAC7C,WAAAT;AAAA,UACA,OAAOU,EAAW;AAAA,UAClB,UAAUD,EAAM;AAAA,UAChB,QAAQA,EAAM;AAAA,QAAA;AAAA,MAAA;AAAA,MAGlB,OAAO;AAAA,QACL,UAAU;AAAA,QACV,UAAAN;AAAA,MAAA;AAAA,IACF;AAAA,EAAA;AAGN;"}
1
+ {"version":3,"file":"MessageController.js","sources":["../../src/components/MessageController.tsx"],"sourcesContent":["import type { TemplateVariable } from \"@/types\";\nimport type { MessageType } from \"@/utils/schema\";\nimport type { MessageValidator } from \"@/utils/validate\";\nimport { Controller } from \"react-hook-form\";\n\nimport { useMessagesForm } from \"@/context/messages-form\";\n\nimport { LexicalInput } from \"./inputs/LexicalInput\";\nimport { MessageInput } from \"./inputs/MessageInput\";\n\ninterface MessageControllerProps {\n type: MessageType;\n label?: string;\n locale: string;\n name: string;\n className?: string;\n variables: TemplateVariable[];\n validate: MessageValidator;\n}\n\nexport function MessageController({\n type,\n name,\n variables,\n label,\n locale,\n validate,\n className,\n}: MessageControllerProps): React.ReactNode {\n const { control } = useMessagesForm();\n\n if (type === \"rich\") {\n return (\n <Controller\n control={control}\n name={name}\n render={({ field, fieldState }) => (\n <LexicalInput\n className={className}\n error={fieldState.error}\n label={label}\n lang={locale}\n onChange={field.onChange}\n onBlur={field.onBlur}\n value={(field.value as unknown as string) || \"\"}\n />\n )}\n rules={{\n required: true,\n }}\n />\n );\n }\n\n return (\n <Controller\n control={control}\n name={name}\n render={({ field, fieldState }) => (\n <MessageInput\n label={label}\n lang={locale}\n className={className}\n value={(field.value as unknown as string) || \"\"}\n variables={variables}\n error={fieldState.error}\n onChange={field.onChange}\n onBlur={field.onBlur}\n />\n )}\n rules={{\n required: true,\n validate,\n }}\n />\n );\n}\n"],"names":["MessageController","type","name","variables","label","locale","validate","className","control","useMessagesForm","jsx","Controller","field","fieldState","LexicalInput","MessageInput"],"mappings":";;;;;AAoBO,SAASA,EAAkB;AAAA,EAChC,MAAAC;AAAA,EACA,MAAAC;AAAA,EACA,WAAAC;AAAA,EACA,OAAAC;AAAA,EACA,QAAAC;AAAA,EACA,UAAAC;AAAA,EACA,WAAAC;AACF,GAA4C;AAC1C,QAAM,EAAE,SAAAC,EAAA,IAAYC,EAAA;AAEpB,SAAIR,MAAS,SAET,gBAAAS;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,SAAAH;AAAA,MACA,MAAAN;AAAA,MACA,QAAQ,CAAC,EAAE,OAAAU,GAAO,YAAAC,QAChB,gBAAAH;AAAA,QAACI;AAAA,QAAA;AAAA,UACC,WAAAP;AAAA,UACA,OAAOM,EAAW;AAAA,UAClB,OAAAT;AAAA,UACA,MAAMC;AAAA,UACN,UAAUO,EAAM;AAAA,UAChB,QAAQA,EAAM;AAAA,UACd,OAAQA,EAAM,SAA+B;AAAA,QAAA;AAAA,MAAA;AAAA,MAGjD,OAAO;AAAA,QACL,UAAU;AAAA,MAAA;AAAA,IACZ;AAAA,EAAA,IAMJ,gBAAAF;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,SAAAH;AAAA,MACA,MAAAN;AAAA,MACA,QAAQ,CAAC,EAAE,OAAAU,GAAO,YAAAC,QAChB,gBAAAH;AAAA,QAACK;AAAA,QAAA;AAAA,UACC,OAAAX;AAAA,UACA,MAAMC;AAAA,UACN,WAAAE;AAAA,UACA,OAAQK,EAAM,SAA+B;AAAA,UAC7C,WAAAT;AAAA,UACA,OAAOU,EAAW;AAAA,UAClB,UAAUD,EAAM;AAAA,UAChB,QAAQA,EAAM;AAAA,QAAA;AAAA,MAAA;AAAA,MAGlB,OAAO;AAAA,QACL,UAAU;AAAA,QACV,UAAAN;AAAA,MAAA;AAAA,IACF;AAAA,EAAA;AAGN;"}
@@ -1,11 +1,10 @@
1
- import { DeepPartial, Locales, Messages, MessagesSchema, RichTextEditorOptions, Translations } from '../types.ts';
1
+ import { DeepPartial, Locales, Messages, MessagesSchema, Translations } from '../types.ts';
2
2
  interface MessagesFormProps {
3
3
  locales: Locales;
4
4
  schema: MessagesSchema;
5
5
  tabs?: boolean;
6
6
  values: Translations<DeepPartial<Messages>>;
7
7
  endpointUrl: string;
8
- richTextEditorOptions?: RichTextEditorOptions;
9
8
  }
10
- export declare function MessagesForm({ locales, schema, tabs, values, endpointUrl, richTextEditorOptions, }: MessagesFormProps): React.ReactNode;
9
+ export declare function MessagesForm({ locales, schema, tabs, values, endpointUrl, }: MessagesFormProps): React.ReactNode;
11
10
  export {};
@@ -1,112 +1,119 @@
1
1
  "use client";
2
- import { jsx as s, jsxs as r } from "react/jsx-runtime";
3
- import { useStepNav as M, Button as j } from "@payloadcms/ui";
2
+ import { jsx as s, jsxs as o } from "react/jsx-runtime";
3
+ import { useStepNav as x, Button as M } from "@payloadcms/ui";
4
4
  import { isEqual as y } from "lodash-es";
5
- import { useEffect as T, useState as F } from "react";
6
- import { useForm as O } from "react-hook-form";
7
- import { toast as h } from "sonner";
8
- import { MessagesFormProvider as w } from "../context/messages-form.js";
9
- import { cn as p } from "../utils/cn.js";
5
+ import { useEffect as j, useState as w } from "react";
6
+ import { useForm as T } from "react-hook-form";
7
+ import { toast as d } from "sonner";
8
+ import { MessagesFormProvider as E } from "../context/messages-form.js";
9
+ import { cn as h } from "../utils/cn.js";
10
+ import { getErrorMessage as F } from "../utils/error-handling.js";
10
11
  import { JsonImport as C } from "./actions/JsonImport.js";
11
- import { MessageField as I } from "./layout/MessageField.js";
12
- import { MessagesTabs as E } from "./layout/MessagesTabs.js";
12
+ import { MessageField as O } from "./layout/MessageField.js";
13
+ import { MessagesTabs as I } from "./layout/MessagesTabs.js";
13
14
  import { MessagesTree as g } from "./layout/MessagesTree.js";
14
15
  function Q({
15
16
  locales: u,
16
17
  schema: a,
17
- tabs: o = !1,
18
- values: m,
19
- endpointUrl: b,
20
- richTextEditorOptions: v
18
+ tabs: m = !1,
19
+ values: l,
20
+ endpointUrl: b
21
21
  }) {
22
- const { setStepNav: c } = M();
23
- T(() => {
24
- c([{ label: "Intl Messages", url: "/intl" }]);
25
- }, [c]);
26
- const i = O({
27
- defaultValues: m,
22
+ const { setStepNav: f } = x();
23
+ j(() => {
24
+ f([{ label: "Intl Messages", url: "/intl" }]);
25
+ }, [f]);
26
+ const i = T({
27
+ defaultValues: l,
28
28
  reValidateMode: "onChange"
29
- }), [n, N] = F(Object.keys(a)[0]), S = async (e) => {
30
- const t = h.loading("Saving..."), x = Object.entries(e).reduce((d, [l, f]) => y(f, m[l]) ? d : {
31
- ...d,
32
- [l]: f
29
+ }), [c, v] = w(Object.keys(a)[0]), N = async (e) => {
30
+ const r = d.loading("Saving..."), S = Object.entries(e).reduce((t, [n, p]) => y(p, l[n]) ? t : {
31
+ ...t,
32
+ [n]: p
33
33
  }, {});
34
- await fetch(b, {
35
- method: "PUT",
36
- body: JSON.stringify(x)
37
- }), i.reset(e), h.success("Saved", { id: t });
34
+ try {
35
+ const t = await fetch(b, {
36
+ method: "PUT",
37
+ headers: {
38
+ "Content-Type": "application/json"
39
+ },
40
+ body: JSON.stringify(S)
41
+ });
42
+ if (!t.ok) {
43
+ const n = await F(t);
44
+ throw new Error(n);
45
+ }
46
+ i.reset(e), d.success("Saved", { id: r });
47
+ } catch (t) {
48
+ d.error(
49
+ `Failed to save: ${t instanceof Error ? t.message : "Unknown error"}`,
50
+ { id: r }
51
+ );
52
+ }
38
53
  };
39
- return /* @__PURE__ */ s(
40
- w,
54
+ return /* @__PURE__ */ s(E, { form: i, locales: u, children: /* @__PURE__ */ o(
55
+ "form",
41
56
  {
42
- form: i,
43
- locales: u,
44
- richTextEditorOptions: v,
45
- children: /* @__PURE__ */ r(
46
- "form",
47
- {
48
- className: "flex h-[calc(100vh-var(--app-header-height))] flex-col",
49
- onSubmit: i.handleSubmit(S),
50
- children: [
51
- /* @__PURE__ */ r("div", { className: "sticky top-0 z-10 bg-background", children: [
52
- /* @__PURE__ */ r("header", { className: "mb-6 flex items-center justify-between gap-4", children: [
53
- /* @__PURE__ */ s("h1", { className: "text-4xl", children: "Messages" }),
54
- /* @__PURE__ */ r("div", { className: "flex items-center gap-2", children: [
55
- /* @__PURE__ */ s(C, {}),
56
- /* @__PURE__ */ s(
57
- j,
58
- {
59
- className: "my-0",
60
- type: "submit",
61
- disabled: !i.formState.isDirty,
62
- children: "Save"
63
- }
64
- )
65
- ] })
66
- ] }),
67
- o && /* @__PURE__ */ s(
68
- E,
57
+ className: "flex h-[calc(100vh-var(--app-header-height))] flex-col",
58
+ onSubmit: i.handleSubmit(N),
59
+ children: [
60
+ /* @__PURE__ */ o("div", { className: "sticky top-0 z-10 bg-background", children: [
61
+ /* @__PURE__ */ o("header", { className: "mb-6 flex items-center justify-between gap-4", children: [
62
+ /* @__PURE__ */ s("h1", { className: "text-4xl", children: "Messages" }),
63
+ /* @__PURE__ */ o("div", { className: "flex items-center gap-2", children: [
64
+ /* @__PURE__ */ s(C, {}),
65
+ /* @__PURE__ */ s(
66
+ M,
69
67
  {
70
- schema: a,
71
- activeTab: n,
72
- setActiveTab: N
68
+ className: "my-0",
69
+ type: "submit",
70
+ disabled: !i.formState.isDirty,
71
+ children: "Save"
73
72
  }
74
73
  )
75
- ] }),
76
- /* @__PURE__ */ r(
77
- "div",
78
- {
79
- id: "messages-form-content",
80
- className: "min-h-0 overflow-y-auto pt-8 pb-16",
81
- children: [
82
- !o && /* @__PURE__ */ s(g, { path: "", schema: a, nestingLevel: 0 }),
83
- o && Object.entries(a).map(([e, t]) => typeof t == "string" ? /* @__PURE__ */ s(
84
- I,
85
- {
86
- schema: t,
87
- className: p({ hidden: n !== e }),
88
- messageKey: e,
89
- path: e
90
- },
91
- e
92
- ) : /* @__PURE__ */ s(
93
- g,
94
- {
95
- className: p({ hidden: n !== e }),
96
- path: e,
97
- schema: t,
98
- nestingLevel: 0
99
- },
100
- e
101
- ))
102
- ]
103
- }
104
- )
105
- ]
106
- }
107
- )
74
+ ] })
75
+ ] }),
76
+ m && /* @__PURE__ */ s(
77
+ I,
78
+ {
79
+ schema: a,
80
+ activeTab: c,
81
+ setActiveTab: v
82
+ }
83
+ )
84
+ ] }),
85
+ /* @__PURE__ */ o(
86
+ "div",
87
+ {
88
+ id: "messages-form-content",
89
+ className: "min-h-0 overflow-y-auto pt-8 pb-16",
90
+ children: [
91
+ !m && /* @__PURE__ */ s(g, { path: "", schema: a, nestingLevel: 0 }),
92
+ m && Object.entries(a).map(([e, r]) => typeof r == "string" ? /* @__PURE__ */ s(
93
+ O,
94
+ {
95
+ schema: r,
96
+ className: h({ hidden: c !== e }),
97
+ messageKey: e,
98
+ path: e
99
+ },
100
+ e
101
+ ) : /* @__PURE__ */ s(
102
+ g,
103
+ {
104
+ className: h({ hidden: c !== e }),
105
+ path: e,
106
+ schema: r,
107
+ nestingLevel: 0
108
+ },
109
+ e
110
+ ))
111
+ ]
112
+ }
113
+ )
114
+ ]
108
115
  }
109
- );
116
+ ) });
110
117
  }
111
118
  export {
112
119
  Q as MessagesForm
@@ -1 +1 @@
1
- {"version":3,"file":"MessagesForm.js","sources":["../../src/components/MessagesForm.tsx"],"sourcesContent":["\"use client\";\n\nimport type { FormValues } from \"@/context/messages-form\";\nimport type {\n DeepPartial,\n Locales,\n Messages,\n MessagesSchema,\n RichTextEditorOptions,\n Translations,\n} from \"@/types\";\nimport { Button, useStepNav } from \"@payloadcms/ui\";\nimport { isEqual } from \"lodash-es\";\nimport { useEffect, useState } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport { toast } from \"sonner\";\n\nimport { MessagesFormProvider } from \"@/context/messages-form\";\nimport { cn } from \"@/utils/cn\";\n\nimport { JsonImport } from \"./actions/JsonImport\";\nimport { MessageField } from \"./layout/MessageField\";\nimport { MessagesTabs } from \"./layout/MessagesTabs\";\nimport { MessagesTree } from \"./layout/MessagesTree\";\n\ninterface MessagesFormProps {\n locales: Locales;\n schema: MessagesSchema;\n tabs?: boolean;\n values: Translations<DeepPartial<Messages>>;\n endpointUrl: string;\n richTextEditorOptions?: RichTextEditorOptions;\n}\n\nexport function MessagesForm({\n locales,\n schema,\n tabs = false,\n values,\n endpointUrl,\n richTextEditorOptions,\n}: MessagesFormProps): React.ReactNode {\n const { setStepNav } = useStepNav();\n useEffect(() => {\n setStepNav([{ label: \"Intl Messages\", url: \"/intl\" }]);\n }, [setStepNav]);\n\n const form = useForm<FormValues>({\n defaultValues: values,\n reValidateMode: \"onChange\",\n });\n const [activeTab, setActiveTab] = useState(Object.keys(schema)[0]);\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, values[locale]);\n if (!hasChanged) {\n return acc;\n }\n return {\n ...acc,\n [locale]: value,\n };\n }, {});\n\n await fetch(endpointUrl, {\n method: \"PUT\",\n body: JSON.stringify(changes),\n });\n\n form.reset(currentValues);\n toast.success(\"Saved\", { id: toastId });\n };\n\n return (\n <MessagesFormProvider\n form={form}\n locales={locales}\n richTextEditorOptions={richTextEditorOptions}\n >\n <form\n className=\"flex h-[calc(100vh-var(--app-header-height))] flex-col\"\n onSubmit={form.handleSubmit(handleSubmit)}\n >\n <div className=\"sticky top-0 z-10 bg-background\">\n <header className=\"mb-6 flex items-center justify-between gap-4\">\n <h1 className=\"text-4xl\">Messages</h1>\n <div className=\"flex items-center gap-2\">\n <JsonImport />\n <Button\n className=\"my-0\"\n type=\"submit\"\n disabled={!form.formState.isDirty}\n >\n Save\n </Button>\n </div>\n </header>\n {tabs && (\n <MessagesTabs\n schema={schema}\n activeTab={activeTab}\n setActiveTab={setActiveTab}\n />\n )}\n </div>\n\n <div\n id=\"messages-form-content\"\n className=\"min-h-0 overflow-y-auto pt-8 pb-16\"\n >\n {!tabs && <MessagesTree path=\"\" schema={schema} nestingLevel={0} />}\n {tabs &&\n Object.entries(schema).map(([key, value]) => {\n if (typeof value === \"string\") {\n return (\n <MessageField\n schema={value}\n key={key}\n className={cn({ hidden: activeTab !== key })}\n messageKey={key}\n path={key}\n />\n );\n }\n return (\n <MessagesTree\n className={cn({ hidden: activeTab !== key })}\n key={key}\n path={key}\n schema={value}\n nestingLevel={0}\n />\n );\n })}\n </div>\n </form>\n </MessagesFormProvider>\n );\n}\n"],"names":["MessagesForm","locales","schema","tabs","values","endpointUrl","richTextEditorOptions","setStepNav","useStepNav","useEffect","form","useForm","activeTab","setActiveTab","useState","handleSubmit","currentValues","toastId","toast","changes","acc","locale","value","isEqual","jsx","MessagesFormProvider","jsxs","JsonImport","Button","MessagesTabs","MessagesTree","key","MessageField","cn"],"mappings":"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"}
1
+ {"version":3,"file":"MessagesForm.js","sources":["../../src/components/MessagesForm.tsx"],"sourcesContent":["\"use client\";\n\nimport type { FormValues } from \"@/context/messages-form\";\nimport type {\n DeepPartial,\n Locales,\n Messages,\n MessagesSchema,\n Translations,\n} from \"@/types\";\nimport { Button, useStepNav } from \"@payloadcms/ui\";\nimport { isEqual } from \"lodash-es\";\nimport { useEffect, useState } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport { toast } from \"sonner\";\n\nimport { MessagesFormProvider } from \"@/context/messages-form\";\nimport { cn } from \"@/utils/cn\";\nimport { getErrorMessage } from \"@/utils/error-handling\";\n\nimport { JsonImport } from \"./actions/JsonImport\";\nimport { MessageField } from \"./layout/MessageField\";\nimport { MessagesTabs } from \"./layout/MessagesTabs\";\nimport { MessagesTree } from \"./layout/MessagesTree\";\n\ninterface MessagesFormProps {\n locales: Locales;\n schema: MessagesSchema;\n tabs?: boolean;\n values: Translations<DeepPartial<Messages>>;\n endpointUrl: string;\n}\n\nexport function MessagesForm({\n locales,\n schema,\n tabs = false,\n values,\n endpointUrl,\n}: MessagesFormProps): React.ReactNode {\n const { setStepNav } = useStepNav();\n useEffect(() => {\n setStepNav([{ label: \"Intl Messages\", url: \"/intl\" }]);\n }, [setStepNav]);\n\n const form = useForm<FormValues>({\n defaultValues: values,\n reValidateMode: \"onChange\",\n });\n const [activeTab, setActiveTab] = useState(Object.keys(schema)[0]);\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, values[locale]);\n if (!hasChanged) {\n return acc;\n }\n return {\n ...acc,\n [locale]: value,\n };\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 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 (\n <MessagesFormProvider form={form} locales={locales}>\n <form\n className=\"flex h-[calc(100vh-var(--app-header-height))] flex-col\"\n onSubmit={form.handleSubmit(handleSubmit)}\n >\n <div className=\"sticky top-0 z-10 bg-background\">\n <header className=\"mb-6 flex items-center justify-between gap-4\">\n <h1 className=\"text-4xl\">Messages</h1>\n <div className=\"flex items-center gap-2\">\n <JsonImport />\n <Button\n className=\"my-0\"\n type=\"submit\"\n disabled={!form.formState.isDirty}\n >\n Save\n </Button>\n </div>\n </header>\n\n {tabs && (\n <MessagesTabs\n schema={schema}\n activeTab={activeTab}\n setActiveTab={setActiveTab}\n />\n )}\n </div>\n\n <div\n id=\"messages-form-content\"\n className=\"min-h-0 overflow-y-auto pt-8 pb-16\"\n >\n {!tabs && <MessagesTree path=\"\" schema={schema} nestingLevel={0} />}\n {tabs &&\n Object.entries(schema).map(([key, value]) => {\n if (typeof value === \"string\") {\n return (\n <MessageField\n schema={value}\n key={key}\n className={cn({ hidden: activeTab !== key })}\n messageKey={key}\n path={key}\n />\n );\n }\n return (\n <MessagesTree\n className={cn({ hidden: activeTab !== key })}\n key={key}\n path={key}\n schema={value}\n nestingLevel={0}\n />\n );\n })}\n </div>\n </form>\n </MessagesFormProvider>\n );\n}\n"],"names":["MessagesForm","locales","schema","tabs","values","endpointUrl","setStepNav","useStepNav","useEffect","form","useForm","activeTab","setActiveTab","useState","handleSubmit","currentValues","toastId","toast","changes","acc","locale","value","isEqual","response","error","getErrorMessage","jsx","MessagesFormProvider","jsxs","JsonImport","Button","MessagesTabs","MessagesTree","key","MessageField","cn"],"mappings":";;;;;;;;;;;;;;AAiCO,SAASA,EAAa;AAAA,EAC3B,SAAAC;AAAA,EACA,QAAAC;AAAA,EACA,MAAAC,IAAO;AAAA,EACP,QAAAC;AAAA,EACA,aAAAC;AACF,GAAuC;AACrC,QAAM,EAAE,YAAAC,EAAA,IAAeC,EAAA;AACvB,EAAAC,EAAU,MAAM;AACd,IAAAF,EAAW,CAAC,EAAE,OAAO,iBAAiB,KAAK,QAAA,CAAS,CAAC;AAAA,EACvD,GAAG,CAACA,CAAU,CAAC;AAEf,QAAMG,IAAOC,EAAoB;AAAA,IAC/B,eAAeN;AAAA,IACf,gBAAgB;AAAA,EAAA,CACjB,GACK,CAACO,GAAWC,CAAY,IAAIC,EAAS,OAAO,KAAKX,CAAM,EAAE,CAAC,CAAC,GAE3DY,IAAe,OAAOC,MAA8B;AACxD,UAAMC,IAAUC,EAAM,QAAQ,WAAW,GACnCC,IAAU,OAAO,QAAQH,CAAa,EAAE,OAE5C,CAACI,GAAK,CAACC,GAAQC,CAAK,MACAC,EAAQD,GAAOjB,EAAOgB,CAAM,CAAC,IAExCD,IAEF;AAAA,MACL,GAAGA;AAAA,MACH,CAACC,CAAM,GAAGC;AAAA,IAAA,GAEX,CAAA,CAAE;AAEL,QAAI;AACF,YAAME,IAAW,MAAM,MAAMlB,GAAa;AAAA,QACxC,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,QAAA;AAAA,QAElB,MAAM,KAAK,UAAUa,CAAO;AAAA,MAAA,CAC7B;AAED,UAAI,CAACK,EAAS,IAAI;AAChB,cAAMC,IAAQ,MAAMC,EAAgBF,CAAQ;AAC5C,cAAM,IAAI,MAAMC,CAAK;AAAA,MACvB;AAEA,MAAAf,EAAK,MAAMM,CAAa,GACxBE,EAAM,QAAQ,SAAS,EAAE,IAAID,GAAS;AAAA,IACxC,SAASQ,GAAO;AACd,MAAAP,EAAM;AAAA,QACJ,mBAAmBO,aAAiB,QAAQA,EAAM,UAAU,eAAe;AAAA,QAC3E,EAAE,IAAIR,EAAA;AAAA,MAAQ;AAAA,IAElB;AAAA,EACF;AAEA,SACE,gBAAAU,EAACC,GAAA,EAAqB,MAAAlB,GAAY,SAAAR,GAChC,UAAA,gBAAA2B;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAU;AAAA,MACV,UAAUnB,EAAK,aAAaK,CAAY;AAAA,MAExC,UAAA;AAAA,QAAA,gBAAAc,EAAC,OAAA,EAAI,WAAU,mCACb,UAAA;AAAA,UAAA,gBAAAA,EAAC,UAAA,EAAO,WAAU,gDAChB,UAAA;AAAA,YAAA,gBAAAF,EAAC,MAAA,EAAG,WAAU,YAAW,UAAA,YAAQ;AAAA,YACjC,gBAAAE,EAAC,OAAA,EAAI,WAAU,2BACb,UAAA;AAAA,cAAA,gBAAAF,EAACG,GAAA,EAAW;AAAA,cACZ,gBAAAH;AAAA,gBAACI;AAAA,gBAAA;AAAA,kBACC,WAAU;AAAA,kBACV,MAAK;AAAA,kBACL,UAAU,CAACrB,EAAK,UAAU;AAAA,kBAC3B,UAAA;AAAA,gBAAA;AAAA,cAAA;AAAA,YAED,EAAA,CACF;AAAA,UAAA,GACF;AAAA,UAECN,KACC,gBAAAuB;AAAA,YAACK;AAAA,YAAA;AAAA,cACC,QAAA7B;AAAA,cACA,WAAAS;AAAA,cACA,cAAAC;AAAA,YAAA;AAAA,UAAA;AAAA,QACF,GAEJ;AAAA,QAEA,gBAAAgB;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,IAAG;AAAA,YACH,WAAU;AAAA,YAET,UAAA;AAAA,cAAA,CAACzB,KAAQ,gBAAAuB,EAACM,GAAA,EAAa,MAAK,IAAG,QAAA9B,GAAgB,cAAc,GAAG;AAAA,cAChEC,KACC,OAAO,QAAQD,CAAM,EAAE,IAAI,CAAC,CAAC+B,GAAKZ,CAAK,MACjC,OAAOA,KAAU,WAEjB,gBAAAK;AAAA,gBAACQ;AAAA,gBAAA;AAAA,kBACC,QAAQb;AAAA,kBAER,WAAWc,EAAG,EAAE,QAAQxB,MAAcsB,GAAK;AAAA,kBAC3C,YAAYA;AAAA,kBACZ,MAAMA;AAAA,gBAAA;AAAA,gBAHDA;AAAA,cAAA,IAQT,gBAAAP;AAAA,gBAACM;AAAA,gBAAA;AAAA,kBACC,WAAWG,EAAG,EAAE,QAAQxB,MAAcsB,GAAK;AAAA,kBAE3C,MAAMA;AAAA,kBACN,QAAQZ;AAAA,kBACR,cAAc;AAAA,gBAAA;AAAA,gBAHTY;AAAA,cAAA,CAMV;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MACL;AAAA,IAAA;AAAA,EAAA,GAEJ;AAEJ;"}
@@ -1,26 +1,26 @@
1
- import { jsxs as o, jsx as e } from "react/jsx-runtime";
2
- import { FieldLabel as i } from "@payloadcms/ui";
3
- import { cn as t } from "../../utils/cn.js";
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
4
  function c({
5
5
  label: r,
6
- error: s,
7
- className: l,
8
- children: a
6
+ error: l,
7
+ className: t,
8
+ children: i
9
9
  }) {
10
- return /* @__PURE__ */ o("div", { className: t("flex flex-col gap-1", l), children: [
11
- /* @__PURE__ */ o(
10
+ return /* @__PURE__ */ s("div", { className: o("flex flex-col gap-1 h-full min-w-5", t), children: [
11
+ /* @__PURE__ */ s(
12
12
  "fieldset",
13
13
  {
14
- className: t("mx-0 rounded-md focus-within:border-elevation-400", {
15
- "border-error bg-error": s
14
+ className: o("mx-0 rounded-md flex-1 focus-within:border-elevation-400", {
15
+ "border-error bg-error": l
16
16
  }),
17
17
  children: [
18
- r && /* @__PURE__ */ e("legend", { className: "-ml-2 px-1.5 text-base", children: /* @__PURE__ */ e(i, { label: r }) }),
19
- a
18
+ r && /* @__PURE__ */ e("legend", { className: "-ml-2 px-1.5 text-base", children: /* @__PURE__ */ e(m, { label: r }) }),
19
+ i
20
20
  ]
21
21
  }
22
22
  ),
23
- /* @__PURE__ */ e("p", { className: "text-base text-error", children: s?.message })
23
+ /* @__PURE__ */ e("p", { className: "text-base text-error", children: l?.message })
24
24
  ] });
25
25
  }
26
26
  export {
@@ -1 +1 @@
1
- {"version":3,"file":"InputWrapper.js","sources":["../../../src/components/inputs/InputWrapper.tsx"],"sourcesContent":["import type { FieldError } from \"react-hook-form\";\nimport { FieldLabel } from \"@payloadcms/ui\";\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 flex-col gap-1\", className)}>\n <fieldset\n className={cn(\"mx-0 rounded-md focus-within:border-elevation-400\", {\n \"border-error bg-error\": error,\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,uBAAuBF,CAAS,GACjD,UAAA;AAAA,IAAA,gBAAAG;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAWD,EAAG,qDAAqD;AAAA,UACjE,yBAAyBH;AAAA,QAAA,CAC1B;AAAA,QAEA,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,"file":"InputWrapper.js","sources":["../../../src/components/inputs/InputWrapper.tsx"],"sourcesContent":["import type { FieldError } from \"react-hook-form\";\nimport { FieldLabel } from \"@payloadcms/ui\";\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 flex-col gap-1 h-full min-w-5\", className)}>\n <fieldset\n className={cn(\"mx-0 rounded-md flex-1 focus-within:border-elevation-400\", {\n \"border-error bg-error\": error,\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,EAAG,4DAA4D;AAAA,UACxE,yBAAyBH;AAAA,QAAA,CAC1B;AAAA,QAEA,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;"}
@@ -0,0 +1,19 @@
1
+ import { DefaultNodeTypes, TypedEditorState } from '@payloadcms/richtext-lexical';
2
+ import { SerializedEditorState } from '@payloadcms/richtext-lexical/lexical';
3
+ import { InputWrapperProps } from './InputWrapper';
4
+ export interface LexicalInputProps extends InputWrapperProps {
5
+ lang: string;
6
+ value: string;
7
+ onChange: (value: string) => void;
8
+ onBlur: () => void;
9
+ }
10
+ 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 {};
@@ -0,0 +1,90 @@
1
+ import { jsx as l } from "react/jsx-runtime";
2
+ import { $generateNodesFromDOM as p, $generateHtmlFromNodes as f } from "@lexical/html";
3
+ import { defaultEditorFeatures as g, defaultEditorConfig as E } from "@payloadcms/richtext-lexical";
4
+ import { sanitizeClientEditorConfig as S, RenderLexical as h, getEnabledNodes as x } from "@payloadcms/richtext-lexical/client";
5
+ import { $getRoot as v } from "@payloadcms/richtext-lexical/lexical";
6
+ import { createHeadlessEditor as C } from "@payloadcms/richtext-lexical/lexical/headless";
7
+ import { useRef as F, useCallback as c, useMemo as T } from "react";
8
+ import { InputWrapper as b } from "./InputWrapper.js";
9
+ function A({
10
+ error: r,
11
+ label: o,
12
+ value: n,
13
+ onChange: i,
14
+ className: s
15
+ }) {
16
+ const a = M({
17
+ html: n,
18
+ onChange: i
19
+ });
20
+ return /* @__PURE__ */ l(b, { label: o, error: r, className: s, children: /* @__PURE__ */ l(
21
+ h,
22
+ {
23
+ field: {
24
+ name: "myCustomEditor",
25
+ label: !1,
26
+ type: "richText"
27
+ },
28
+ value: a.value,
29
+ setValue: (e) => a.setValue(e),
30
+ schemaPath: "global.intl-plugin.editorTemplate"
31
+ }
32
+ ) });
33
+ }
34
+ const y = {
35
+ root: {
36
+ children: [
37
+ {
38
+ children: [],
39
+ direction: null,
40
+ textFormat: 0,
41
+ format: "left",
42
+ indent: 0,
43
+ type: "paragraph",
44
+ version: 1
45
+ }
46
+ ],
47
+ direction: null,
48
+ format: "",
49
+ indent: 0,
50
+ type: "root",
51
+ version: 1
52
+ }
53
+ }, H = S(
54
+ // @ts-expect-error - it works
55
+ g,
56
+ E
57
+ );
58
+ function M({
59
+ html: r,
60
+ onChange: o
61
+ }) {
62
+ const n = F(
63
+ C({
64
+ nodes: x({
65
+ editorConfig: H
66
+ })
67
+ })
68
+ ), i = c((e) => {
69
+ const t = n.current;
70
+ return t.update(() => {
71
+ const m = new DOMParser().parseFromString(e, "text/html"), u = p(t, m);
72
+ v().clear().append(...u);
73
+ }, { discrete: !0 }), t.getEditorState().toJSON();
74
+ }, []), s = T(() => {
75
+ const e = i(r);
76
+ return e.root.children.length === 0 ? y : e;
77
+ }, [r, i]), a = c((e) => {
78
+ const t = n.current;
79
+ t.setEditorState(t.parseEditorState(e)), t.read(() => {
80
+ const d = f(t);
81
+ d !== r && o(d);
82
+ });
83
+ }, [r, o]);
84
+ return { value: s, setValue: a };
85
+ }
86
+ export {
87
+ A as LexicalInput,
88
+ M as useHtmlLexicalAdapter
89
+ };
90
+ //# sourceMappingURL=LexicalInput.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LexicalInput.js","sources":["../../../src/components/inputs/LexicalInput.tsx"],"sourcesContent":["import type {\n DefaultNodeTypes,\n TypedEditorState,\n} from \"@payloadcms/richtext-lexical\";\nimport { $generateHtmlFromNodes, $generateNodesFromDOM } from \"@lexical/html\";\nimport {\n defaultEditorConfig,\n defaultEditorFeatures,\n} from \"@payloadcms/richtext-lexical\";\nimport {\n getEnabledNodes,\n RenderLexical,\n sanitizeClientEditorConfig,\n} from \"@payloadcms/richtext-lexical/client\";\nimport { $getRoot, type SerializedEditorState } from \"@payloadcms/richtext-lexical/lexical\";\nimport { createHeadlessEditor } from \"@payloadcms/richtext-lexical/lexical/headless\";\nimport { useCallback, useMemo, useRef } from \"react\";\n\nimport type { InputWrapperProps } from \"./InputWrapper\";\nimport { InputWrapper } from \"./InputWrapper\";\n\nexport interface LexicalInputProps extends InputWrapperProps {\n lang: string;\n value: string;\n onChange: (value: string) => void;\n onBlur: () => void;\n}\n\nexport function LexicalInput({\n error,\n label,\n value,\n onChange,\n className,\n}: LexicalInputProps): React.ReactNode {\n const editor = useHtmlLexicalAdapter({\n html:value,\n onChange,\n });\n\n return (\n <InputWrapper label={label} error={error} className={className}>\n <RenderLexical\n field={{\n name: \"myCustomEditor\",\n label: false,\n type: \"richText\",\n }}\n value={editor.value}\n setValue={(val) => editor.setValue(val as SerializedEditorState)}\n schemaPath=\"global.intl-plugin.editorTemplate\"\n />\n </InputWrapper>\n );\n}\n\nconst EMPTY_STATE: TypedEditorState<DefaultNodeTypes> = {\n root: {\n children: [\n {\n children: [],\n direction: null,\n textFormat: 0,\n format: \"left\",\n indent: 0,\n type: \"paragraph\",\n version: 1,\n },\n ],\n direction: null,\n format: \"\",\n indent: 0,\n type: \"root\",\n version: 1,\n },\n};\n\n\nconst editorConfig = sanitizeClientEditorConfig(\n // @ts-expect-error - it works\n defaultEditorFeatures,\n defaultEditorConfig,\n);\n\ninterface UseHtmlLexicalAdapterProps {\n html: string;\n onChange: (html: string) => void;\n}\n\n\nexport function useHtmlLexicalAdapter({ \n html, \n onChange, \n}: UseHtmlLexicalAdapterProps) {\n // 1. Maintain a persistent headless editor for conversion\n const headlessEditor = useRef(\n createHeadlessEditor({\n nodes:getEnabledNodes({\n editorConfig,\n }),\n })\n );\n\n // 2. HTML -> SerializedState\n const getSerializedState = useCallback((htmlString: string): SerializedEditorState => {\n const editor = headlessEditor.current;\n editor.update(() => {\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 }, { discrete: true });\n\n return editor.getEditorState().toJSON();\n }, []);\n\n // 3. Memoize the initial value to prevent unnecessary re-renders\n const value = useMemo(() => {\n\n const serializedState = getSerializedState(html)\n\n if (serializedState.root.children.length === 0) {\n return EMPTY_STATE;\n }\n\n return serializedState;\n\n\n }, [html, getSerializedState]);\n\n // 4. SerializedState -> HTML\n const setValue = useCallback((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 }, [html, onChange]);\n\n return { value: value as TypedEditorState<DefaultNodeTypes>, setValue };\n}\n\n\n\n"],"names":["LexicalInput","error","label","value","onChange","className","editor","useHtmlLexicalAdapter","jsx","InputWrapper","RenderLexical","val","EMPTY_STATE","editorConfig","sanitizeClientEditorConfig","defaultEditorFeatures","defaultEditorConfig","html","headlessEditor","useRef","createHeadlessEditor","getEnabledNodes","getSerializedState","useCallback","htmlString","dom","nodes","$generateNodesFromDOM","$getRoot","useMemo","serializedState","setValue","newHtml","$generateHtmlFromNodes"],"mappings":";;;;;;;;AA4BO,SAASA,EAAa;AAAA,EAC3B,OAAAC;AAAA,EACA,OAAAC;AAAA,EACA,OAAAC;AAAA,EACA,UAAAC;AAAA,EACA,WAAAC;AACF,GAAuC;AACrC,QAAMC,IAASC,EAAsB;AAAA,IACnC,MAAKJ;AAAA,IACL,UAAAC;AAAA,EAAA,CACD;AAED,SACE,gBAAAI,EAACC,GAAA,EAAa,OAAAP,GAAc,OAAAD,GAAc,WAAAI,GACxC,UAAA,gBAAAG;AAAA,IAACE;AAAA,IAAA;AAAA,MACC,OAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO;AAAA,QACP,MAAM;AAAA,MAAA;AAAA,MAER,OAAOJ,EAAO;AAAA,MACd,UAAU,CAACK,MAAQL,EAAO,SAASK,CAA4B;AAAA,MAC/D,YAAW;AAAA,IAAA;AAAA,EAAA,GAEf;AAEJ;AAEA,MAAMC,IAAkD;AAAA,EACtD,MAAM;AAAA,IACJ,UAAU;AAAA,MACR;AAAA,QACE,UAAU,CAAA;AAAA,QACV,WAAW;AAAA,QACX,YAAY;AAAA,QACZ,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,SAAS;AAAA,MAAA;AAAA,IACX;AAAA,IAEF,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,SAAS;AAAA,EAAA;AAEb,GAGMC,IAAeC;AAAA;AAAA,EAEnBC;AAAA,EACAC;AACF;AAQO,SAAST,EAAsB;AAAA,EACpC,MAAAU;AAAA,EACA,UAAAb;AACF,GAA+B;AAE7B,QAAMc,IAAiBC;AAAA,IACrBC,EAAqB;AAAA,MACnB,OAAMC,EAAgB;AAAA,QACpB,cAAAR;AAAA,MAAA,CACD;AAAA,IAAA,CACF;AAAA,EAAA,GAIGS,IAAqBC,EAAY,CAACC,MAA8C;AACpF,UAAMlB,IAASY,EAAe;AAC9B,WAAAZ,EAAO,OAAO,MAAM;AAElB,YAAMmB,IADS,IAAI,UAAA,EACA,gBAAgBD,GAAY,WAAW,GACpDE,IAAQC,EAAsBrB,GAAQmB,CAAG;AAG/C,MADaG,EAAA,EACR,MAAA,EAAQ,OAAO,GAAGF,CAAK;AAAA,IAC9B,GAAG,EAAE,UAAU,IAAM,GAEdpB,EAAO,eAAA,EAAiB,OAAA;AAAA,EACjC,GAAG,CAAA,CAAE,GAGCH,IAAQ0B,EAAQ,MAAM;AAE1B,UAAMC,IAAkBR,EAAmBL,CAAI;AAE/C,WAAIa,EAAgB,KAAK,SAAS,WAAW,IACpClB,IAGFkB;AAAA,EAGT,GAAG,CAACb,GAAMK,CAAkB,CAAC,GAGvBS,IAAWR,EAAY,CAACO,MAA2C;AACvE,UAAMxB,IAASY,EAAe;AAG9B,IAAAZ,EAAO,eAAeA,EAAO,iBAAiBwB,CAAe,CAAC,GAG9DxB,EAAO,KAAK,MAAM;AAChB,YAAM0B,IAAUC,EAAuB3B,CAAM;AAC7C,MAAI0B,MAAYf,KACdb,EAAS4B,CAAO;AAAA,IAEpB,CAAC;AAAA,EACH,GAAG,CAACf,GAAMb,CAAQ,CAAC;AAEnB,SAAO,EAAE,OAAAD,GAAoD,UAAA4B,EAAA;AAC/D;"}
@@ -1 +1 @@
1
- {"version":3,"file":"PluralVariableEditor.js","sources":["../../../../../src/components/inputs/variables/editors/PluralVariableEditor.tsx"],"sourcesContent":["import { TYPE } from \"@formatjs/icu-messageformat-parser\";\nimport { IconX } from \"@tabler/icons-react\";\nimport { Popover } from \"radix-ui\";\nimport { Fragment, useImperativeHandle, useMemo } from \"react\";\nimport { Controller, useFieldArray, useForm } from \"react-hook-form\";\n\nimport type { PluralElement } from \"@/types\";\nimport { cn } from \"@/utils/cn\";\nimport { parseICUMessage, serializeICUMessage } from \"@/utils/icu-tranform\";\n\nconst NAMED_PLURAL_OPTIONS = [\"zero\", \"one\", \"two\", \"few\", \"many\"] as const;\n\nexport interface PluralVariableEditorProps {\n variableName: string;\n element: PluralElement | undefined;\n ref: React.Ref<{ getValue: () => string }>;\n}\n\n// TODO add support for selectordinal (\"pluralType\": \"ordinal\")\n\nexport function PluralVariableEditor({\n variableName,\n element,\n ref,\n}: PluralVariableEditorProps) {\n const config = useMemo<{\n offset: number;\n options: { name: string; content: string }[];\n other: string;\n }>(() => {\n const { other, ...options } = element?.options ?? {};\n return {\n offset: element?.offset ?? 0,\n options: Object.entries(options).map(([name, option]) => ({\n name,\n content: serializeICUMessage(option.value),\n })),\n other: serializeICUMessage(other ? other.value : []),\n };\n }, [element]);\n\n const { control, register, getValues } = useForm<{\n offset: number;\n options: { name: string; content: string }[];\n other: string;\n customValue?: number;\n }>({\n defaultValues: config,\n });\n\n useImperativeHandle(ref, () => ({\n getValue: () => {\n const values = getValues();\n const updatedElement: PluralElement = {\n type: TYPE.plural,\n value: variableName,\n offset: values.offset,\n pluralType: element?.pluralType ?? \"cardinal\",\n options: Object.fromEntries(\n values.options.map(({ name, content }) => [\n name,\n { value: parseICUMessage(content) },\n ]),\n ),\n };\n return serializeICUMessage([updatedElement]);\n },\n }));\n\n const options = useFieldArray({\n control,\n name: \"options\",\n });\n\n return (\n <div className=\"flex flex-col gap-3\">\n <fieldset className=\"mx-0 grid grid-cols-[3rem_8rem_1.5rem] gap-y-2 rounded-md border border-border px-2 pr-0\">\n <legend>Options</legend>\n {options.fields.map((field, index) => (\n <Fragment key={field.id}>\n <label htmlFor={`options.${index}`}>{field.name}</label>\n {/* // TODO add support for variable mentions */}\n <input\n className=\"focus:outline-none\"\n type=\"text\"\n {...register(`options.${index}.content`, { required: true })}\n />\n <button\n className=\"ml-auto flex cursor-pointer items-center justify-center border-none bg-transparent p-0 hover:text-error\"\n type=\"button\"\n onClick={() => options.remove(index)}\n >\n <IconX size={16} />\n </button>\n </Fragment>\n ))}\n\n <>\n <label htmlFor=\"other\">other</label>\n {/* // TODO add support for variable mentions */}\n <input\n type=\"text\"\n className=\"col-span-2 focus:outline-none\"\n {...register(\"other\", { required: true })}\n />\n </>\n </fieldset>\n <div className=\"grid grid-cols-2 items-center gap-2\">\n <label className=\"flex items-center gap-3 pl-2\">\n offset\n <input\n className=\"w-8 text-center\"\n type=\"numeric\"\n placeholder=\"0\"\n {...register(\"offset\")}\n />\n </label>\n <Popover.Root>\n <Popover.Trigger>Add Option</Popover.Trigger>\n <Popover.Portal>\n <Popover.Content\n sideOffset={4}\n className=\"z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border border-border bg-elevation-50 shadow-md data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95\"\n >\n <div className=\"flex flex-col\">\n {NAMED_PLURAL_OPTIONS.filter((option) =>\n options.fields.every((field) => field.name !== option),\n ).map((option) => (\n <Popover.Close\n key={option}\n className={cn(\n \"cursor-pointer border-none bg-transparent px-1 hover:bg-elevation-250\",\n )}\n onClick={() => {\n // TODO ensure the fields are always in the same order as staticPluralOptions\n options.append(\n {\n name: option,\n content: \"\",\n },\n {\n shouldFocus: true,\n },\n );\n }}\n >\n {option}\n </Popover.Close>\n ))}\n </div>\n\n <div className=\"flex items-center justify-between gap-2 border-t border-border p-2\">\n <label htmlFor=\"customValue\">custom</label>\n <Controller\n control={control}\n name=\"customValue\"\n render={({ field }) => (\n // eslint-disable-next-line jsx-a11y/control-has-associated-label\n <input\n type=\"numeric\"\n className=\"w-8 rounded-sm border-transparent text-center focus:border-border focus:outline-none\"\n placeholder=\"=0\"\n min={0}\n value={field.value ?? \"\"}\n onChange={({ currentTarget: { value } }) => {\n const number = Number(value);\n if (isNaN(number)) return;\n if (number < 0) return;\n field.onChange(number);\n }}\n onKeyDown={(e) => {\n if (e.key !== \"Enter\") return;\n if (field.value === undefined) return;\n const isUnique = !options.fields.some(\n (existingField) =>\n existingField.name === `=${field.value}`,\n );\n if (!isUnique) return; // TODO maybe show error?\n options.append(\n {\n name: `=${field.value}`,\n content: \"\",\n },\n {\n shouldFocus: true,\n },\n );\n field.onChange(undefined);\n }}\n />\n )}\n />\n </div>\n </Popover.Content>\n </Popover.Portal>\n </Popover.Root>\n </div>\n </div>\n );\n}\n"],"names":["NAMED_PLURAL_OPTIONS","PluralVariableEditor","variableName","element","ref","config","useMemo","other","options","name","option","serializeICUMessage","control","register","getValues","useForm","useImperativeHandle","values","updatedElement","TYPE","content","parseICUMessage","useFieldArray","jsxs","jsx","field","index","Fragment","IconX","Popover","cn","Controller","value","number","e","existingField"],"mappings":"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"}
1
+ {"version":3,"file":"PluralVariableEditor.js","sources":["../../../../../src/components/inputs/variables/editors/PluralVariableEditor.tsx"],"sourcesContent":["import type { PluralElement } from \"@/types\";\nimport { TYPE } from \"@formatjs/icu-messageformat-parser\";\nimport { IconX } from \"@tabler/icons-react\";\nimport { Popover } from \"radix-ui\";\nimport { Fragment, useImperativeHandle, useMemo } from \"react\";\nimport { Controller, useFieldArray, useForm } from \"react-hook-form\";\n\nimport { cn } from \"@/utils/cn\";\nimport { parseICUMessage, serializeICUMessage } from \"@/utils/icu-tranform\";\n\nconst NAMED_PLURAL_OPTIONS = [\"zero\", \"one\", \"two\", \"few\", \"many\"] as const;\n\nexport interface PluralVariableEditorProps {\n variableName: string;\n element: PluralElement | undefined;\n ref: React.Ref<{ getValue: () => string }>;\n}\n\n// TODO add support for selectordinal (\"pluralType\": \"ordinal\")\n\nexport function PluralVariableEditor({\n variableName,\n element,\n ref,\n}: PluralVariableEditorProps) {\n const config = useMemo<{\n offset: number;\n options: { name: string; content: string }[];\n other: string;\n }>(() => {\n const { other, ...options } = element?.options ?? {};\n return {\n offset: element?.offset ?? 0,\n options: Object.entries(options).map(([name, option]) => ({\n name,\n content: serializeICUMessage(option.value),\n })),\n other: serializeICUMessage(other ? other.value : []),\n };\n }, [element]);\n\n const { control, register, getValues } = useForm<{\n offset: number;\n options: { name: string; content: string }[];\n other: string;\n customValue?: number;\n }>({\n defaultValues: config,\n });\n\n useImperativeHandle(ref, () => ({\n getValue: () => {\n const values = getValues();\n const updatedElement: PluralElement = {\n type: TYPE.plural,\n value: variableName,\n offset: values.offset,\n pluralType: element?.pluralType ?? \"cardinal\",\n options: Object.fromEntries(\n values.options.map(({ name, content }) => [\n name,\n { value: parseICUMessage(content) },\n ]),\n ),\n };\n return serializeICUMessage([updatedElement]);\n },\n }));\n\n const options = useFieldArray({\n control,\n name: \"options\",\n });\n\n return (\n <div className=\"flex flex-col gap-3\">\n <fieldset className=\"mx-0 grid grid-cols-[3rem_8rem_1.5rem] gap-y-2 rounded-md border border-border px-2 pr-0\">\n <legend>Options</legend>\n {options.fields.map((field, index) => (\n <Fragment key={field.id}>\n <label htmlFor={`options.${index}`}>{field.name}</label>\n {/* // TODO add support for variable mentions */}\n <input\n className=\"focus:outline-none\"\n type=\"text\"\n {...register(`options.${index}.content`, { required: true })}\n />\n <button\n className=\"ml-auto flex cursor-pointer items-center justify-center border-none bg-transparent p-0 hover:text-error\"\n type=\"button\"\n onClick={() => options.remove(index)}\n >\n <IconX size={16} />\n </button>\n </Fragment>\n ))}\n\n <>\n <label htmlFor=\"other\">other</label>\n {/* // TODO add support for variable mentions */}\n <input\n type=\"text\"\n className=\"col-span-2 focus:outline-none\"\n {...register(\"other\", { required: true })}\n />\n </>\n </fieldset>\n <div className=\"grid grid-cols-2 items-center gap-2\">\n <label className=\"flex items-center gap-3 pl-2\">\n offset\n <input\n className=\"w-8 text-center\"\n type=\"numeric\"\n placeholder=\"0\"\n {...register(\"offset\")}\n />\n </label>\n <Popover.Root>\n <Popover.Trigger>Add Option</Popover.Trigger>\n <Popover.Portal>\n <Popover.Content\n sideOffset={4}\n className=\"z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border border-border bg-elevation-50 shadow-md data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95\"\n >\n <div className=\"flex flex-col\">\n {NAMED_PLURAL_OPTIONS.filter((option) =>\n options.fields.every((field) => field.name !== option),\n ).map((option) => (\n <Popover.Close\n key={option}\n className={cn(\n \"cursor-pointer border-none bg-transparent px-1 hover:bg-elevation-250\",\n )}\n onClick={() => {\n // TODO ensure the fields are always in the same order as staticPluralOptions\n options.append(\n {\n name: option,\n content: \"\",\n },\n {\n shouldFocus: true,\n },\n );\n }}\n >\n {option}\n </Popover.Close>\n ))}\n </div>\n\n <div className=\"flex items-center justify-between gap-2 border-t border-border p-2\">\n <label htmlFor=\"customValue\">custom</label>\n <Controller\n control={control}\n name=\"customValue\"\n render={({ field }) => (\n // eslint-disable-next-line jsx-a11y/control-has-associated-label\n <input\n type=\"numeric\"\n className=\"w-8 rounded-sm border-transparent text-center focus:border-border focus:outline-none\"\n placeholder=\"=0\"\n min={0}\n value={field.value ?? \"\"}\n onChange={({ currentTarget: { value } }) => {\n const number = Number(value);\n if (isNaN(number)) return;\n if (number < 0) return;\n field.onChange(number);\n }}\n onKeyDown={(e) => {\n if (e.key !== \"Enter\") return;\n if (field.value === undefined) return;\n const isUnique = !options.fields.some(\n (existingField) =>\n existingField.name === `=${field.value}`,\n );\n if (!isUnique) return; // TODO maybe show error?\n options.append(\n {\n name: `=${field.value}`,\n content: \"\",\n },\n {\n shouldFocus: true,\n },\n );\n field.onChange(undefined);\n }}\n />\n )}\n />\n </div>\n </Popover.Content>\n </Popover.Portal>\n </Popover.Root>\n </div>\n </div>\n );\n}\n"],"names":["NAMED_PLURAL_OPTIONS","PluralVariableEditor","variableName","element","ref","config","useMemo","other","options","name","option","serializeICUMessage","control","register","getValues","useForm","useImperativeHandle","values","updatedElement","TYPE","content","parseICUMessage","useFieldArray","jsxs","jsx","field","index","Fragment","IconX","Popover","cn","Controller","value","number","e","existingField"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"SelectVariableEditor.js","sources":["../../../../../src/components/inputs/variables/editors/SelectVariableEditor.tsx"],"sourcesContent":["import { useEffect, useMemo } from \"react\";\nimport { useFieldArray, useForm } from \"react-hook-form\";\n\nimport type { SelectElement } from \"@/types\";\nimport { parseICUMessage, serializeICUMessage } from \"@/utils/icu-tranform\";\n\nexport interface SelectVariableEditorProps {\n element: SelectElement;\n onUpdate: (value: string) => void;\n}\n\nexport function SelectVariableEditor({\n element,\n onUpdate,\n}: SelectVariableEditorProps) {\n const options = useMemo<{ name: string; content: string }[]>(\n () =>\n Object.entries(element.options).map(([name, option]) => ({\n name,\n content: serializeICUMessage(option.value),\n })),\n [element],\n );\n\n const { control, register, getValues } = useForm<{\n options: { name: string; content: string }[];\n }>({\n defaultValues: { options },\n });\n const { fields } = useFieldArray({\n control,\n name: \"options\",\n });\n\n useEffect(() => {\n return () => {\n const values = getValues();\n const updatedElement: SelectElement = {\n ...element,\n options: Object.fromEntries(\n values.options.map(({ name, content }) => [\n name,\n { value: parseICUMessage(content) },\n ]),\n ),\n };\n onUpdate(serializeICUMessage([updatedElement]));\n };\n }, []);\n\n return (\n <div className=\"flex flex-col gap-2 p-3\">\n {fields.map((field, index) => (\n <div key={field.name} className=\"flex flex-col gap-1\">\n <label className=\"text-sm font-medium\">{field.name}</label>\n {/* // TODO add support for variable mentions */}\n <input\n className=\"focus:outline-none\"\n {...register(`options.${index}.content`)}\n />\n </div>\n ))}\n </div>\n );\n}\n"],"names":["SelectVariableEditor","element","onUpdate","options","useMemo","name","option","serializeICUMessage","control","register","getValues","useForm","fields","useFieldArray","useEffect","values","updatedElement","content","parseICUMessage","jsx","field","index","jsxs"],"mappings":";;;;AAWO,SAASA,EAAqB;AAAA,EACnC,SAAAC;AAAA,EACA,UAAAC;AACF,GAA8B;AAC5B,QAAMC,IAAUC;AAAA,IACd,MACE,OAAO,QAAQH,EAAQ,OAAO,EAAE,IAAI,CAAC,CAACI,GAAMC,CAAM,OAAO;AAAA,MACvD,MAAAD;AAAA,MACA,SAASE,EAAoBD,EAAO,KAAK;AAAA,IAAA,EACzC;AAAA,IACJ,CAACL,CAAO;AAAA,EAAA,GAGJ,EAAE,SAAAO,GAAS,UAAAC,GAAU,WAAAC,EAAA,IAAcC,EAEtC;AAAA,IACD,eAAe,EAAE,SAAAR,EAAA;AAAA,EAAQ,CAC1B,GACK,EAAE,QAAAS,EAAA,IAAWC,EAAc;AAAA,IAC/B,SAAAL;AAAA,IACA,MAAM;AAAA,EAAA,CACP;AAED,SAAAM,EAAU,MACD,MAAM;AACX,UAAMC,IAASL,EAAA,GACTM,IAAgC;AAAA,MACpC,GAAGf;AAAA,MACH,SAAS,OAAO;AAAA,QACdc,EAAO,QAAQ,IAAI,CAAC,EAAE,MAAAV,GAAM,SAAAY,QAAc;AAAA,UACxCZ;AAAA,UACA,EAAE,OAAOa,EAAgBD,CAAO,EAAA;AAAA,QAAE,CACnC;AAAA,MAAA;AAAA,IACH;AAEF,IAAAf,EAASK,EAAoB,CAACS,CAAc,CAAC,CAAC;AAAA,EAChD,GACC,CAAA,CAAE,GAGH,gBAAAG,EAAC,OAAA,EAAI,WAAU,2BACZ,UAAAP,EAAO,IAAI,CAACQ,GAAOC,MAClB,gBAAAC,EAAC,OAAA,EAAqB,WAAU,uBAC9B,UAAA;AAAA,IAAA,gBAAAH,EAAC,SAAA,EAAM,WAAU,uBAAuB,UAAAC,EAAM,MAAK;AAAA,IAEnD,gBAAAD;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACT,GAAGV,EAAS,WAAWY,CAAK,UAAU;AAAA,MAAA;AAAA,IAAA;AAAA,EACzC,EAAA,GANQD,EAAM,IAOhB,CACD,GACH;AAEJ;"}
1
+ {"version":3,"file":"SelectVariableEditor.js","sources":["../../../../../src/components/inputs/variables/editors/SelectVariableEditor.tsx"],"sourcesContent":["import type { SelectElement } from \"@/types\";\nimport { useEffect, useMemo } from \"react\";\nimport { useFieldArray, useForm } from \"react-hook-form\";\n\nimport { parseICUMessage, serializeICUMessage } from \"@/utils/icu-tranform\";\n\nexport interface SelectVariableEditorProps {\n element: SelectElement;\n onUpdate: (value: string) => void;\n}\n\nexport function SelectVariableEditor({\n element,\n onUpdate,\n}: SelectVariableEditorProps) {\n const options = useMemo<{ name: string; content: string }[]>(\n () =>\n Object.entries(element.options).map(([name, option]) => ({\n name,\n content: serializeICUMessage(option.value),\n })),\n [element],\n );\n\n const { control, register, getValues } = useForm<{\n options: { name: string; content: string }[];\n }>({\n defaultValues: { options },\n });\n const { fields } = useFieldArray({\n control,\n name: \"options\",\n });\n\n useEffect(() => {\n return () => {\n const values = getValues();\n const updatedElement: SelectElement = {\n ...element,\n options: Object.fromEntries(\n values.options.map(({ name, content }) => [\n name,\n { value: parseICUMessage(content) },\n ]),\n ),\n };\n onUpdate(serializeICUMessage([updatedElement]));\n };\n }, []);\n\n return (\n <div className=\"flex flex-col gap-2 p-3\">\n {fields.map((field, index) => (\n <div key={field.name} className=\"flex flex-col gap-1\">\n <label className=\"text-sm font-medium\">{field.name}</label>\n {/* // TODO add support for variable mentions */}\n <input\n className=\"focus:outline-none\"\n {...register(`options.${index}.content`)}\n />\n </div>\n ))}\n </div>\n );\n}\n"],"names":["SelectVariableEditor","element","onUpdate","options","useMemo","name","option","serializeICUMessage","control","register","getValues","useForm","fields","useFieldArray","useEffect","values","updatedElement","content","parseICUMessage","jsx","field","index","jsxs"],"mappings":";;;;AAWO,SAASA,EAAqB;AAAA,EACnC,SAAAC;AAAA,EACA,UAAAC;AACF,GAA8B;AAC5B,QAAMC,IAAUC;AAAA,IACd,MACE,OAAO,QAAQH,EAAQ,OAAO,EAAE,IAAI,CAAC,CAACI,GAAMC,CAAM,OAAO;AAAA,MACvD,MAAAD;AAAA,MACA,SAASE,EAAoBD,EAAO,KAAK;AAAA,IAAA,EACzC;AAAA,IACJ,CAACL,CAAO;AAAA,EAAA,GAGJ,EAAE,SAAAO,GAAS,UAAAC,GAAU,WAAAC,EAAA,IAAcC,EAEtC;AAAA,IACD,eAAe,EAAE,SAAAR,EAAA;AAAA,EAAQ,CAC1B,GACK,EAAE,QAAAS,EAAA,IAAWC,EAAc;AAAA,IAC/B,SAAAL;AAAA,IACA,MAAM;AAAA,EAAA,CACP;AAED,SAAAM,EAAU,MACD,MAAM;AACX,UAAMC,IAASL,EAAA,GACTM,IAAgC;AAAA,MACpC,GAAGf;AAAA,MACH,SAAS,OAAO;AAAA,QACdc,EAAO,QAAQ,IAAI,CAAC,EAAE,MAAAV,GAAM,SAAAY,QAAc;AAAA,UACxCZ;AAAA,UACA,EAAE,OAAOa,EAAgBD,CAAO,EAAA;AAAA,QAAE,CACnC;AAAA,MAAA;AAAA,IACH;AAEF,IAAAf,EAASK,EAAoB,CAACS,CAAc,CAAC,CAAC;AAAA,EAChD,GACC,CAAA,CAAE,GAGH,gBAAAG,EAAC,OAAA,EAAI,WAAU,2BACZ,UAAAP,EAAO,IAAI,CAACQ,GAAOC,MAClB,gBAAAC,EAAC,OAAA,EAAqB,WAAU,uBAC9B,UAAA;AAAA,IAAA,gBAAAH,EAAC,SAAA,EAAM,WAAU,uBAAuB,UAAAC,EAAM,MAAK;AAAA,IAEnD,gBAAAD;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACT,GAAGV,EAAS,WAAWY,CAAK,UAAU;AAAA,MAAA;AAAA,IAAA;AAAA,EACzC,EAAA,GANQD,EAAM,IAOhB,CACD,GACH;AAEJ;"}
@@ -1 +1 @@
1
- {"version":3,"file":"TagVariableEditor.js","sources":["../../../../../src/components/inputs/variables/editors/TagVariableEditor.tsx"],"sourcesContent":["import { useEffect, useMemo } from \"react\";\nimport { useForm } from \"react-hook-form\";\n\nimport type { TagElement } from \"@/types\";\nimport { parseICUMessage, serializeICUMessage } from \"@/utils/icu-tranform\";\n\nexport interface TagVariableEditorProps {\n element: TagElement;\n onUpdate: (value: string) => void;\n}\n\nexport function TagVariableEditor({\n element,\n onUpdate,\n}: TagVariableEditorProps) {\n const content = useMemo<string>(\n () => serializeICUMessage(element.children),\n [element],\n );\n\n const { register, getValues } = useForm<{ content: string }>({\n defaultValues: { content },\n });\n\n useEffect(() => {\n return () => {\n const { content } = getValues();\n // TODO find better solution for this\n const updatedElement: TagElement = {\n ...element,\n children: parseICUMessage(content),\n };\n onUpdate(serializeICUMessage([updatedElement]));\n };\n }, []);\n\n // TODO add support for variable mentions\n return (\n <textarea\n className=\"p-3 focus:outline-none\"\n {...register(\"content\")}\n rows={1}\n />\n );\n}\n"],"names":["TagVariableEditor","element","onUpdate","content","useMemo","serializeICUMessage","register","getValues","useForm","useEffect","updatedElement","parseICUMessage","jsx"],"mappings":";;;;AAWO,SAASA,EAAkB;AAAA,EAChC,SAAAC;AAAA,EACA,UAAAC;AACF,GAA2B;AACzB,QAAMC,IAAUC;AAAA,IACd,MAAMC,EAAoBJ,EAAQ,QAAQ;AAAA,IAC1C,CAACA,CAAO;AAAA,EAAA,GAGJ,EAAE,UAAAK,GAAU,WAAAC,EAAA,IAAcC,EAA6B;AAAA,IAC3D,eAAe,EAAE,SAAAL,EAAA;AAAA,EAAQ,CAC1B;AAED,SAAAM,EAAU,MACD,MAAM;AACX,UAAM,EAAE,SAAAN,EAAAA,IAAYI,EAAA,GAEdG,IAA6B;AAAA,MACjC,GAAGT;AAAA,MACH,UAAUU,EAAgBR,CAAO;AAAA,IAAA;AAEnC,IAAAD,EAASG,EAAoB,CAACK,CAAc,CAAC,CAAC;AAAA,EAChD,GACC,CAAA,CAAE,GAIH,gBAAAE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAU;AAAA,MACT,GAAGN,EAAS,SAAS;AAAA,MACtB,MAAM;AAAA,IAAA;AAAA,EAAA;AAGZ;"}
1
+ {"version":3,"file":"TagVariableEditor.js","sources":["../../../../../src/components/inputs/variables/editors/TagVariableEditor.tsx"],"sourcesContent":["import type { TagElement } from \"@/types\";\nimport { useEffect, useMemo } from \"react\";\nimport { useForm } from \"react-hook-form\";\n\nimport { parseICUMessage, serializeICUMessage } from \"@/utils/icu-tranform\";\n\nexport interface TagVariableEditorProps {\n element: TagElement;\n onUpdate: (value: string) => void;\n}\n\nexport function TagVariableEditor({\n element,\n onUpdate,\n}: TagVariableEditorProps) {\n const content = useMemo<string>(\n () => serializeICUMessage(element.children),\n [element],\n );\n\n const { register, getValues } = useForm<{ content: string }>({\n defaultValues: { content },\n });\n\n useEffect(() => {\n return () => {\n const { content } = getValues();\n // TODO find better solution for this\n const updatedElement: TagElement = {\n ...element,\n children: parseICUMessage(content),\n };\n onUpdate(serializeICUMessage([updatedElement]));\n };\n }, []);\n\n // TODO add support for variable mentions\n return (\n <textarea\n className=\"p-3 focus:outline-none\"\n {...register(\"content\")}\n rows={1}\n />\n );\n}\n"],"names":["TagVariableEditor","element","onUpdate","content","useMemo","serializeICUMessage","register","getValues","useForm","useEffect","updatedElement","parseICUMessage","jsx"],"mappings":";;;;AAWO,SAASA,EAAkB;AAAA,EAChC,SAAAC;AAAA,EACA,UAAAC;AACF,GAA2B;AACzB,QAAMC,IAAUC;AAAA,IACd,MAAMC,EAAoBJ,EAAQ,QAAQ;AAAA,IAC1C,CAACA,CAAO;AAAA,EAAA,GAGJ,EAAE,UAAAK,GAAU,WAAAC,EAAA,IAAcC,EAA6B;AAAA,IAC3D,eAAe,EAAE,SAAAL,EAAA;AAAA,EAAQ,CAC1B;AAED,SAAAM,EAAU,MACD,MAAM;AACX,UAAM,EAAE,SAAAN,EAAAA,IAAYI,EAAA,GAEdG,IAA6B;AAAA,MACjC,GAAGT;AAAA,MACH,UAAUU,EAAgBR,CAAO;AAAA,IAAA;AAEnC,IAAAD,EAASG,EAAoB,CAACK,CAAc,CAAC,CAAC;AAAA,EAChD,GACC,CAAA,CAAE,GAIH,gBAAAE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAU;AAAA,MACT,GAAGN,EAAS,SAAS;AAAA,MACtB,MAAM;AAAA,IAAA;AAAA,EAAA;AAGZ;"}