payload-intl 0.0.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 (101) hide show
  1. package/README.md +67 -0
  2. package/dist/components/MessageController.d.ts +14 -0
  3. package/dist/components/MessageController.js +64 -0
  4. package/dist/components/MessageController.js.map +1 -0
  5. package/dist/components/MessagesForm.d.ts +11 -0
  6. package/dist/components/MessagesForm.js +91 -0
  7. package/dist/components/MessagesForm.js.map +1 -0
  8. package/dist/components/actions/JsonImport.d.ts +1 -0
  9. package/dist/components/actions/Move.d.ts +3 -0
  10. package/dist/components/inputs/InputWrapper.d.ts +7 -0
  11. package/dist/components/inputs/InputWrapper.js +23 -0
  12. package/dist/components/inputs/InputWrapper.js.map +1 -0
  13. package/dist/components/inputs/MessageInput.d.ts +10 -0
  14. package/dist/components/inputs/MessageInput.js +52 -0
  15. package/dist/components/inputs/MessageInput.js.map +1 -0
  16. package/dist/components/inputs/RichTextInput.d.ts +8 -0
  17. package/dist/components/inputs/RichTextInput.js +81 -0
  18. package/dist/components/inputs/RichTextInput.js.map +1 -0
  19. package/dist/components/inputs/toolbar/AlignmentControls.d.ts +5 -0
  20. package/dist/components/inputs/toolbar/AlignmentControls.js +59 -0
  21. package/dist/components/inputs/toolbar/AlignmentControls.js.map +1 -0
  22. package/dist/components/inputs/toolbar/BlockElementSelect.d.ts +5 -0
  23. package/dist/components/inputs/toolbar/BlockElementSelect.js +129 -0
  24. package/dist/components/inputs/toolbar/BlockElementSelect.js.map +1 -0
  25. package/dist/components/inputs/toolbar/LinkEditor.d.ts +58 -0
  26. package/dist/components/inputs/toolbar/LinkEditor.js +230 -0
  27. package/dist/components/inputs/toolbar/LinkEditor.js.map +1 -0
  28. package/dist/components/inputs/toolbar/MarkControls.d.ts +5 -0
  29. package/dist/components/inputs/toolbar/MarkControls.js +47 -0
  30. package/dist/components/inputs/toolbar/MarkControls.js.map +1 -0
  31. package/dist/components/inputs/toolbar/RichTextToolbar.d.ts +6 -0
  32. package/dist/components/inputs/toolbar/RichTextToolbar.js +32 -0
  33. package/dist/components/inputs/toolbar/RichTextToolbar.js.map +1 -0
  34. package/dist/components/inputs/variables/VariableChip.d.ts +2 -0
  35. package/dist/components/inputs/variables/VariableChip.js +60 -0
  36. package/dist/components/inputs/variables/VariableChip.js.map +1 -0
  37. package/dist/components/inputs/variables/VariableSuggestion.d.ts +8 -0
  38. package/dist/components/inputs/variables/VariableSuggestion.js +40 -0
  39. package/dist/components/inputs/variables/VariableSuggestion.js.map +1 -0
  40. package/dist/components/inputs/variables/editors/DateVariableEditor.d.ts +9 -0
  41. package/dist/components/inputs/variables/editors/PluralVariableEditor.d.ts +9 -0
  42. package/dist/components/inputs/variables/editors/PluralVariableEditor.js +149 -0
  43. package/dist/components/inputs/variables/editors/PluralVariableEditor.js.map +1 -0
  44. package/dist/components/inputs/variables/editors/SelectVariableEditor.d.ts +6 -0
  45. package/dist/components/inputs/variables/editors/SelectVariableEditor.js +42 -0
  46. package/dist/components/inputs/variables/editors/SelectVariableEditor.js.map +1 -0
  47. package/dist/components/inputs/variables/editors/TagVariableEditor.d.ts +6 -0
  48. package/dist/components/inputs/variables/editors/TagVariableEditor.js +32 -0
  49. package/dist/components/inputs/variables/editors/TagVariableEditor.js.map +1 -0
  50. package/dist/components/inputs/variables/editors/TimeVariableEditor.d.ts +9 -0
  51. package/dist/components/inputs/variables/extension.d.ts +3 -0
  52. package/dist/components/inputs/variables/extension.js +93 -0
  53. package/dist/components/inputs/variables/extension.js.map +1 -0
  54. package/dist/components/inputs/variables/pickers/NumericVariablePicker.d.ts +6 -0
  55. package/dist/components/inputs/variables/pickers/NumericVariablePicker.js +49 -0
  56. package/dist/components/inputs/variables/pickers/NumericVariablePicker.js.map +1 -0
  57. package/dist/components/inputs/variables/pickers/TemporalElementEditor.d.ts +6 -0
  58. package/dist/components/layout/MessageField.d.ts +9 -0
  59. package/dist/components/layout/MessageField.js +46 -0
  60. package/dist/components/layout/MessageField.js.map +1 -0
  61. package/dist/components/layout/MessagesTabs.d.ts +8 -0
  62. package/dist/components/layout/MessagesTabs.js +43 -0
  63. package/dist/components/layout/MessagesTabs.js.map +1 -0
  64. package/dist/components/layout/MessagesTree.d.ts +9 -0
  65. package/dist/components/layout/MessagesTree.js +67 -0
  66. package/dist/components/layout/MessagesTree.js.map +1 -0
  67. package/dist/context/messages-form.d.ts +30 -0
  68. package/dist/endpoints/get-messages.d.ts +2 -0
  69. package/dist/endpoints/get-messages.js +13 -0
  70. package/dist/endpoints/get-messages.js.map +1 -0
  71. package/dist/endpoints/set-messages.d.ts +2 -0
  72. package/dist/endpoints/set-messages.js +47 -0
  73. package/dist/endpoints/set-messages.js.map +1 -0
  74. package/dist/exports/link.d.ts +7 -0
  75. package/dist/exports/link.js +20 -0
  76. package/dist/exports/link.js.map +1 -0
  77. package/dist/exports/rsc.d.ts +2 -0
  78. package/dist/exports/rsc.js +7 -0
  79. package/dist/exports/rsc.js.map +1 -0
  80. package/dist/exports/view.d.ts +10 -0
  81. package/dist/exports/view.js +56 -0
  82. package/dist/exports/view.js.map +1 -0
  83. package/dist/index.d.ts +5 -0
  84. package/dist/index.js +76 -0
  85. package/dist/index.js.map +1 -0
  86. package/dist/requests/fetchMessages.d.ts +3 -0
  87. package/dist/requests/fetchMessages.js +29 -0
  88. package/dist/requests/fetchMessages.js.map +1 -0
  89. package/dist/styles.css +1 -0
  90. package/dist/types.d.ts +48 -0
  91. package/dist/utils/cn.d.ts +2 -0
  92. package/dist/utils/config.d.ts +11 -0
  93. package/dist/utils/config.js +19 -0
  94. package/dist/utils/config.js.map +1 -0
  95. package/dist/utils/format.d.ts +3 -0
  96. package/dist/utils/guards.d.ts +4 -0
  97. package/dist/utils/icu-tranform.d.ts +30 -0
  98. package/dist/utils/sanitize.d.ts +15 -0
  99. package/dist/utils/schema.d.ts +9 -0
  100. package/dist/utils/validate.d.ts +5 -0
  101. package/package.json +131 -0
@@ -0,0 +1,60 @@
1
+ import { NodeViewWrapper as l } from "@tiptap/react";
2
+ import { Popover as r } from "radix-ui";
3
+ import { useMemo as m } from "react";
4
+ import { cn as s } from "@/utils/cn";
5
+ import { isArgumentElement as c, isTemporalElement as p, isNumericElement as f, isSelectElement as u, isTagElement as E } from "@/utils/guards";
6
+ import { parseICUMessage as b } from "@/utils/icu-tranform";
7
+ import { SelectVariableEditor as g } from "./editors/SelectVariableEditor.js";
8
+ import { TagVariableEditor as h } from "./editors/TagVariableEditor.js";
9
+ import { NumericVariablePicker as v } from "./pickers/NumericVariablePicker.js";
10
+ const i = !1;
11
+ function M({
12
+ node: n,
13
+ updateAttributes: d
14
+ }) {
15
+ const a = n.attrs, o = (t) => d({
16
+ icu: t
17
+ }), e = m(() => {
18
+ try {
19
+ const [t] = b(a.icu);
20
+ if (!t) throw new Error("No part found");
21
+ return t;
22
+ } catch (t) {
23
+ throw console.error(t), new Error(`Invalid ICU: ${a.icu}`, { cause: t });
24
+ }
25
+ }, [a.icu]);
26
+ return /* @__PURE__ */ React.createElement(r.Root, null, /* @__PURE__ */ React.createElement(r.Trigger, { asChild: !0 }, /* @__PURE__ */ React.createElement(
27
+ l,
28
+ {
29
+ as: "span",
30
+ className: s(
31
+ "inline-flex cursor-pointer items-center rounded-md bg-elevation-250 px-1 hover:bg-elevation-400",
32
+ {
33
+ "pointer-events-none": c(e) || p(e) && !i
34
+ }
35
+ ),
36
+ contentEditable: !1,
37
+ "data-variable": a.name,
38
+ "data-icu": a.icu,
39
+ role: "button",
40
+ tabIndex: 0
41
+ },
42
+ a.label
43
+ )), /* @__PURE__ */ React.createElement(r.Portal, null, /* @__PURE__ */ React.createElement(
44
+ r.Content,
45
+ {
46
+ side: "bottom",
47
+ sideOffset: 5,
48
+ align: "start",
49
+ className: "z-50 grid origin-(--radix-hover-card-content-transform-origin) overflow-clip rounded-md border border-border bg-elevation-50 shadow-md outline-hidden empty:hidden 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"
50
+ },
51
+ f(e) && /* @__PURE__ */ React.createElement(v, { element: e, onUpdate: o }),
52
+ u(e) && /* @__PURE__ */ React.createElement(g, { element: e, onUpdate: o }),
53
+ i,
54
+ E(e) && /* @__PURE__ */ React.createElement(h, { element: e, onUpdate: o })
55
+ )));
56
+ }
57
+ export {
58
+ M as VariableChip
59
+ };
60
+ //# sourceMappingURL=VariableChip.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VariableChip.js","sources":["../../../../src/components/inputs/variables/VariableChip.tsx"],"sourcesContent":["import type { VariableMentionNodeAttrs } from \"@/types\";\nimport type { ReactNodeViewProps } from \"@tiptap/react\";\nimport { NodeViewWrapper } from \"@tiptap/react\";\nimport { Popover } from \"radix-ui\";\nimport { useMemo } from \"react\";\n\nimport { cn } from \"@/utils/cn\";\nimport {\n isArgumentElement,\n isNumericElement,\n isSelectElement,\n isTagElement,\n isTemporalElement,\n} from \"@/utils/guards\";\nimport { parseICUMessage } from \"@/utils/icu-tranform\";\n\nimport { SelectVariableEditor } from \"./editors/SelectVariableEditor\";\nimport { TagVariableEditor } from \"./editors/TagVariableEditor\";\nimport { NumericVariablePicker } from \"./pickers/NumericVariablePicker\";\nimport { TemporalElementEditor } from \"./pickers/TemporalElementEditor\";\n\nconst TEMPORAL_ELEMENTS_FLAG = false;\n\n// TODO replace popover with portal below input field\n\nexport function VariableChip({\n node,\n updateAttributes,\n}: ReactNodeViewProps<HTMLElement>) {\n const attrs = node.attrs as VariableMentionNodeAttrs;\n const handleUpdate = (value: string) =>\n updateAttributes({\n icu: value,\n });\n\n const element = useMemo(() => {\n try {\n const [part] = parseICUMessage(attrs.icu);\n if (!part) throw new Error(\"No part found\");\n return part;\n } catch (error) {\n console.error(error);\n throw new Error(`Invalid ICU: ${attrs.icu}`, { cause: error });\n }\n }, [attrs.icu]);\n\n return (\n <Popover.Root>\n <Popover.Trigger asChild>\n <NodeViewWrapper\n as=\"span\"\n className={cn(\n \"inline-flex cursor-pointer items-center rounded-md bg-elevation-250 px-1 hover:bg-elevation-400\",\n {\n \"pointer-events-none\":\n isArgumentElement(element) ||\n (isTemporalElement(element) && !TEMPORAL_ELEMENTS_FLAG),\n },\n )}\n contentEditable={false}\n data-variable={attrs.name}\n data-icu={attrs.icu}\n role=\"button\"\n tabIndex={0}\n >\n {attrs.label}\n </NodeViewWrapper>\n </Popover.Trigger>\n <Popover.Portal>\n <Popover.Content\n side=\"bottom\"\n sideOffset={5}\n align=\"start\"\n className=\"z-50 grid origin-(--radix-hover-card-content-transform-origin) overflow-clip rounded-md border border-border bg-elevation-50 shadow-md outline-hidden empty:hidden 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 {isNumericElement(element) && (\n <NumericVariablePicker element={element} onUpdate={handleUpdate} />\n )}\n {isSelectElement(element) && (\n <SelectVariableEditor element={element} onUpdate={handleUpdate} />\n )}\n {TEMPORAL_ELEMENTS_FLAG && isTemporalElement(element) && (\n <TemporalElementEditor element={element} onUpdate={handleUpdate} />\n )}\n\n {isTagElement(element) && (\n <TagVariableEditor element={element} onUpdate={handleUpdate} />\n )}\n </Popover.Content>\n </Popover.Portal>\n </Popover.Root>\n );\n}\n"],"names":["TEMPORAL_ELEMENTS_FLAG","VariableChip","node","updateAttributes","attrs","handleUpdate","value","element","useMemo","part","parseICUMessage","error","Popover","NodeViewWrapper","cn","isArgumentElement","isTemporalElement","isNumericElement","NumericVariablePicker","isSelectElement","SelectVariableEditor","isTagElement","TagVariableEditor"],"mappings":";;;;;;;;;AAqBA,MAAMA,IAAyB;AAIxB,SAASC,EAAa;AAAA,EAC3B,MAAAC;AAAA,EACA,kBAAAC;AACF,GAAoC;AAClC,QAAMC,IAAQF,EAAK,OACbG,IAAe,CAACC,MACpBH,EAAiB;AAAA,IACf,KAAKG;AAAA,EAAA,CACN,GAEGC,IAAUC,EAAQ,MAAM;AAC5B,QAAI;AACF,YAAM,CAACC,CAAI,IAAIC,EAAgBN,EAAM,GAAG;AACxC,UAAI,CAACK,EAAM,OAAM,IAAI,MAAM,eAAe;AAC1C,aAAOA;AAAA,IACT,SAASE,GAAO;AACd,oBAAQ,MAAMA,CAAK,GACb,IAAI,MAAM,gBAAgBP,EAAM,GAAG,IAAI,EAAE,OAAOO,GAAO;AAAA,IAC/D;AAAA,EACF,GAAG,CAACP,EAAM,GAAG,CAAC;AAEd,SACE,sBAAA,cAACQ,EAAQ,MAAR,0CACEA,EAAQ,SAAR,EAAgB,SAAO,GAAA,GACtB,sBAAA;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,IAAG;AAAA,MACH,WAAWC;AAAA,QACT;AAAA,QACA;AAAA,UACE,uBACEC,EAAkBR,CAAO,KACxBS,EAAkBT,CAAO,KAAK,CAACP;AAAA,QAAA;AAAA,MACpC;AAAA,MAEF,iBAAiB;AAAA,MACjB,iBAAeI,EAAM;AAAA,MACrB,YAAUA,EAAM;AAAA,MAChB,MAAK;AAAA,MACL,UAAU;AAAA,IAAA;AAAA,IAETA,EAAM;AAAA,EAAA,CAEX,GACA,sBAAA,cAACQ,EAAQ,QAAR,MACC,sBAAA;AAAA,IAACA,EAAQ;AAAA,IAAR;AAAA,MACC,MAAK;AAAA,MACL,YAAY;AAAA,MACZ,OAAM;AAAA,MACN,WAAU;AAAA,IAAA;AAAA,IAETK,EAAiBV,CAAO,yCACtBW,GAAA,EAAsB,SAAAX,GAAkB,UAAUF,GAAc;AAAA,IAElEc,EAAgBZ,CAAO,yCACrBa,GAAA,EAAqB,SAAAb,GAAkB,UAAUF,GAAc;AAAA,IAEjEL;AAAA,IAIAqB,EAAad,CAAO,yCAClBe,GAAA,EAAkB,SAAAf,GAAkB,UAAUF,EAAA,CAAc;AAAA,EAAA,CAGnE,CACF;AAEJ;"}
@@ -0,0 +1,8 @@
1
+ import { VariableMentionNodeAttrs } from '../../../types.ts';
2
+ import { SuggestionKeyDownProps, SuggestionProps } from '@tiptap/suggestion';
3
+ export interface VariableSuggestionProps extends SuggestionProps<VariableMentionNodeAttrs, VariableMentionNodeAttrs> {
4
+ ref: React.RefObject<{
5
+ onKeyDown: (props: SuggestionKeyDownProps) => boolean;
6
+ }>;
7
+ }
8
+ export declare function VariableSuggestion({ items, command, ref, }: VariableSuggestionProps): import("react").JSX.Element;
@@ -0,0 +1,40 @@
1
+ import { useState as p, useEffect as f, useImperativeHandle as i } from "react";
2
+ import { cn as g } from "@/utils/cn";
3
+ function v({
4
+ items: e,
5
+ command: a,
6
+ ref: c
7
+ }) {
8
+ const [r, o] = p(0), l = (t) => {
9
+ const n = e[t];
10
+ n && a(n);
11
+ }, u = () => {
12
+ o((r + e.length - 1) % e.length);
13
+ }, s = () => {
14
+ o((r + 1) % e.length);
15
+ }, d = () => {
16
+ l(r);
17
+ };
18
+ return f(() => o(0), [e]), i(c, () => ({
19
+ onKeyDown: ({ event: t }) => t.key === "ArrowUp" ? (u(), !0) : t.key === "ArrowDown" ? (s(), !0) : t.key === "Enter" ? (d(), !0) : !1
20
+ })), /* @__PURE__ */ React.createElement("div", { className: "flex flex-col overflow-clip rounded-md bg-elevation-100" }, e.length ? e.map((t, n) => /* @__PURE__ */ React.createElement(
21
+ "button",
22
+ {
23
+ key: n,
24
+ type: "button",
25
+ className: g(
26
+ "cursor-pointer rounded-none border-none bg-transparent px-3 py-1 text-lg text-nowrap",
27
+ {
28
+ "bg-elevation-800 text-elevation-0": n === r,
29
+ "hover:bg-elevation-250": n !== r
30
+ }
31
+ ),
32
+ onClick: () => l(n)
33
+ },
34
+ t.label
35
+ )) : /* @__PURE__ */ React.createElement("div", { className: "item" }, "No result"));
36
+ }
37
+ export {
38
+ v as VariableSuggestion
39
+ };
40
+ //# sourceMappingURL=VariableSuggestion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VariableSuggestion.js","sources":["../../../../src/components/inputs/variables/VariableSuggestion.tsx"],"sourcesContent":["import type { VariableMentionNodeAttrs } from \"@/types\";\nimport type {\n SuggestionKeyDownProps,\n SuggestionProps,\n} from \"@tiptap/suggestion\";\nimport { useEffect, useImperativeHandle, useState } from \"react\";\n\nimport { cn } from \"@/utils/cn\";\n\nexport interface VariableSuggestionProps\n extends SuggestionProps<VariableMentionNodeAttrs, VariableMentionNodeAttrs> {\n ref: React.RefObject<{\n onKeyDown: (props: SuggestionKeyDownProps) => boolean;\n }>;\n}\n\nexport function VariableSuggestion({\n items,\n command,\n ref,\n}: VariableSuggestionProps) {\n const [selectedIndex, setSelectedIndex] = useState(0);\n\n const selectItem = (index: number) => {\n const item = items[index];\n\n if (item) command(item);\n };\n\n const upHandler = () => {\n setSelectedIndex((selectedIndex + items.length - 1) % items.length);\n };\n\n const downHandler = () => {\n setSelectedIndex((selectedIndex + 1) % items.length);\n };\n\n const enterHandler = () => {\n selectItem(selectedIndex);\n };\n\n useEffect(() => setSelectedIndex(0), [items]);\n\n useImperativeHandle(ref, () => ({\n onKeyDown: ({ event }) => {\n if (event.key === \"ArrowUp\") {\n upHandler();\n return true;\n }\n\n if (event.key === \"ArrowDown\") {\n downHandler();\n return true;\n }\n\n if (event.key === \"Enter\") {\n enterHandler();\n return true;\n }\n\n return false;\n },\n }));\n\n return (\n <div className=\"flex flex-col overflow-clip rounded-md bg-elevation-100\">\n {items.length ? (\n items.map((item, index) => (\n <button\n key={index}\n type=\"button\"\n className={cn(\n \"cursor-pointer rounded-none border-none bg-transparent px-3 py-1 text-lg text-nowrap\",\n {\n \"bg-elevation-800 text-elevation-0\": index === selectedIndex,\n \"hover:bg-elevation-250\": index !== selectedIndex,\n },\n )}\n onClick={() => selectItem(index)}\n >\n {item.label}\n </button>\n ))\n ) : (\n <div className=\"item\">No result</div>\n )}\n </div>\n );\n}\n"],"names":["VariableSuggestion","items","command","ref","selectedIndex","setSelectedIndex","useState","selectItem","index","item","upHandler","downHandler","enterHandler","useEffect","useImperativeHandle","event","cn"],"mappings":";;AAgBO,SAASA,EAAmB;AAAA,EACjC,OAAAC;AAAA,EACA,SAAAC;AAAA,EACA,KAAAC;AACF,GAA4B;AAC1B,QAAM,CAACC,GAAeC,CAAgB,IAAIC,EAAS,CAAC,GAE9CC,IAAa,CAACC,MAAkB;AACpC,UAAMC,IAAOR,EAAMO,CAAK;AAExB,IAAIC,OAAcA,CAAI;AAAA,EACxB,GAEMC,IAAY,MAAM;AACtB,IAAAL,GAAkBD,IAAgBH,EAAM,SAAS,KAAKA,EAAM,MAAM;AAAA,EACpE,GAEMU,IAAc,MAAM;AACxB,IAAAN,GAAkBD,IAAgB,KAAKH,EAAM,MAAM;AAAA,EACrD,GAEMW,IAAe,MAAM;AACzB,IAAAL,EAAWH,CAAa;AAAA,EAC1B;AAEA,SAAAS,EAAU,MAAMR,EAAiB,CAAC,GAAG,CAACJ,CAAK,CAAC,GAE5Ca,EAAoBX,GAAK,OAAO;AAAA,IAC9B,WAAW,CAAC,EAAE,OAAAY,QACRA,EAAM,QAAQ,aAChBL,EAAA,GACO,MAGLK,EAAM,QAAQ,eAChBJ,EAAA,GACO,MAGLI,EAAM,QAAQ,WAChBH,EAAA,GACO,MAGF;AAAA,EACT,EACA,GAGA,sBAAA,cAAC,OAAA,EAAI,WAAU,0DAAA,GACZX,EAAM,SACLA,EAAM,IAAI,CAACQ,GAAMD,MACf,sBAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAKA;AAAA,MACL,MAAK;AAAA,MACL,WAAWQ;AAAA,QACT;AAAA,QACA;AAAA,UACE,qCAAqCR,MAAUJ;AAAA,UAC/C,0BAA0BI,MAAUJ;AAAA,QAAA;AAAA,MACtC;AAAA,MAEF,SAAS,MAAMG,EAAWC,CAAK;AAAA,IAAA;AAAA,IAE9BC,EAAK;AAAA,EAAA,CAET,IAED,sBAAA,cAAC,SAAI,WAAU,OAAA,GAAO,WAAS,CAEnC;AAEJ;"}
@@ -0,0 +1,9 @@
1
+ import { DateElement } from '../../../../types.ts';
2
+ export interface DateVariableEditorProps {
3
+ name: string;
4
+ element: DateElement | undefined;
5
+ ref: React.Ref<{
6
+ getValue: () => string;
7
+ }>;
8
+ }
9
+ export declare function DateVariableEditor({ name, element, ref, }: DateVariableEditorProps): import("react").JSX.Element;
@@ -0,0 +1,9 @@
1
+ import { PluralElement } from '../../../../types.ts';
2
+ export interface PluralVariableEditorProps {
3
+ variableName: string;
4
+ element: PluralElement | undefined;
5
+ ref: React.Ref<{
6
+ getValue: () => string;
7
+ }>;
8
+ }
9
+ export declare function PluralVariableEditor({ variableName, element, ref, }: PluralVariableEditorProps): import("react").JSX.Element;
@@ -0,0 +1,149 @@
1
+ import { TYPE as f } from "@formatjs/icu-messageformat-parser";
2
+ import { IconX as b } from "@tabler/icons-react";
3
+ import { Popover as n } from "radix-ui";
4
+ import { useMemo as g, useImperativeHandle as E, Fragment as v } from "react";
5
+ import { useForm as R, useFieldArray as h, Controller as y } from "react-hook-form";
6
+ import { cn as x } from "@/utils/cn";
7
+ import { serializeICUMessage as c, parseICUMessage as N } from "@/utils/icu-tranform";
8
+ const w = ["zero", "one", "two", "few", "many"];
9
+ function k({
10
+ variableName: i,
11
+ element: l,
12
+ ref: u
13
+ }) {
14
+ const d = g(() => {
15
+ const { other: e, ...t } = l?.options ?? {};
16
+ return {
17
+ offset: l?.offset ?? 0,
18
+ options: Object.entries(t).map(([r, o]) => ({
19
+ name: r,
20
+ content: c(o.value)
21
+ })),
22
+ other: c(e ? e.value : [])
23
+ };
24
+ }, [l]), { control: m, register: s, getValues: p } = R({
25
+ defaultValues: d
26
+ });
27
+ E(u, () => ({
28
+ getValue: () => {
29
+ const e = p(), t = {
30
+ type: f.plural,
31
+ value: i,
32
+ offset: e.offset,
33
+ pluralType: l?.pluralType ?? "cardinal",
34
+ options: Object.fromEntries(
35
+ e.options.map(({ name: r, content: o }) => [
36
+ r,
37
+ { value: N(o) }
38
+ ])
39
+ )
40
+ };
41
+ return c([t]);
42
+ }
43
+ }));
44
+ const a = h({
45
+ control: m,
46
+ name: "options"
47
+ });
48
+ return /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-3" }, /* @__PURE__ */ React.createElement("fieldset", { className: "mx-0 grid grid-cols-[3rem_8rem_1.5rem] gap-y-2 rounded-md border border-border px-2 pr-0" }, /* @__PURE__ */ React.createElement("legend", null, "Options"), a.fields.map((e, t) => /* @__PURE__ */ React.createElement(v, { key: e.id }, /* @__PURE__ */ React.createElement("label", { htmlFor: `options.${t}` }, e.name), /* @__PURE__ */ React.createElement(
49
+ "input",
50
+ {
51
+ className: "focus:outline-none",
52
+ type: "text",
53
+ ...s(`options.${t}.content`, { required: !0 })
54
+ }
55
+ ), /* @__PURE__ */ React.createElement(
56
+ "button",
57
+ {
58
+ className: "ml-auto flex cursor-pointer items-center justify-center border-none bg-transparent p-0 hover:text-error",
59
+ type: "button",
60
+ onClick: () => a.remove(t)
61
+ },
62
+ /* @__PURE__ */ React.createElement(b, { size: 16 })
63
+ ))), /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("label", { htmlFor: "other" }, "other"), /* @__PURE__ */ React.createElement(
64
+ "input",
65
+ {
66
+ type: "text",
67
+ className: "col-span-2 focus:outline-none",
68
+ ...s("other", { required: !0 })
69
+ }
70
+ ))), /* @__PURE__ */ React.createElement("div", { className: "grid grid-cols-2 items-center gap-2" }, /* @__PURE__ */ React.createElement("label", { className: "flex items-center gap-3 pl-2" }, "offset", /* @__PURE__ */ React.createElement(
71
+ "input",
72
+ {
73
+ className: "w-8 text-center",
74
+ type: "numeric",
75
+ placeholder: "0",
76
+ ...s("offset")
77
+ }
78
+ )), /* @__PURE__ */ React.createElement(n.Root, null, /* @__PURE__ */ React.createElement(n.Trigger, null, "Add Option"), /* @__PURE__ */ React.createElement(n.Portal, null, /* @__PURE__ */ React.createElement(
79
+ n.Content,
80
+ {
81
+ sideOffset: 4,
82
+ 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"
83
+ },
84
+ /* @__PURE__ */ React.createElement("div", { className: "flex flex-col" }, w.filter(
85
+ (e) => a.fields.every((t) => t.name !== e)
86
+ ).map((e) => /* @__PURE__ */ React.createElement(
87
+ n.Close,
88
+ {
89
+ key: e,
90
+ className: x(
91
+ "cursor-pointer border-none bg-transparent px-1 hover:bg-elevation-250"
92
+ ),
93
+ onClick: () => {
94
+ a.append(
95
+ {
96
+ name: e,
97
+ content: ""
98
+ },
99
+ {
100
+ shouldFocus: !0
101
+ }
102
+ );
103
+ }
104
+ },
105
+ e
106
+ ))),
107
+ /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-2 border-t border-border p-2" }, /* @__PURE__ */ React.createElement("label", { htmlFor: "customValue" }, "custom"), /* @__PURE__ */ React.createElement(
108
+ y,
109
+ {
110
+ control: m,
111
+ name: "customValue",
112
+ render: ({ field: e }) => (
113
+ // eslint-disable-next-line jsx-a11y/control-has-associated-label
114
+ /* @__PURE__ */ React.createElement(
115
+ "input",
116
+ {
117
+ type: "numeric",
118
+ className: "w-8 rounded-sm border-transparent text-center focus:border-border focus:outline-none",
119
+ placeholder: "=0",
120
+ min: 0,
121
+ value: e.value ?? "",
122
+ onChange: ({ currentTarget: { value: t } }) => {
123
+ const r = Number(t);
124
+ isNaN(r) || r < 0 || e.onChange(r);
125
+ },
126
+ onKeyDown: (t) => {
127
+ t.key !== "Enter" || e.value === void 0 || a.fields.some(
128
+ (o) => o.name === `=${e.value}`
129
+ ) || (a.append(
130
+ {
131
+ name: `=${e.value}`,
132
+ content: ""
133
+ },
134
+ {
135
+ shouldFocus: !0
136
+ }
137
+ ), e.onChange(void 0));
138
+ }
139
+ }
140
+ )
141
+ )
142
+ }
143
+ ))
144
+ )))));
145
+ }
146
+ export {
147
+ k as PluralVariableEditor
148
+ };
149
+ //# sourceMappingURL=PluralVariableEditor.js.map
@@ -0,0 +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","field","index","Fragment","IconX","Popover","cn","Controller","value","number","e","existingField"],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { SelectElement } from '../../../../types.ts';
2
+ export interface SelectVariableEditorProps {
3
+ element: SelectElement;
4
+ onUpdate: (value: string) => void;
5
+ }
6
+ export declare function SelectVariableEditor({ element, onUpdate, }: SelectVariableEditorProps): import("react").JSX.Element;
@@ -0,0 +1,42 @@
1
+ import { useMemo as u, useEffect as f } from "react";
2
+ import { useForm as d, useFieldArray as E } from "react-hook-form";
3
+ import { serializeICUMessage as o, parseICUMessage as g } from "@/utils/icu-tranform";
4
+ function N({
5
+ element: a,
6
+ onUpdate: s
7
+ }) {
8
+ const n = u(
9
+ () => Object.entries(a.options).map(([e, t]) => ({
10
+ name: e,
11
+ content: o(t.value)
12
+ })),
13
+ [a]
14
+ ), { control: c, register: r, getValues: l } = d({
15
+ defaultValues: { options: n }
16
+ }), { fields: m } = E({
17
+ control: c,
18
+ name: "options"
19
+ });
20
+ return f(() => () => {
21
+ const e = l(), t = {
22
+ ...a,
23
+ options: Object.fromEntries(
24
+ e.options.map(({ name: i, content: p }) => [
25
+ i,
26
+ { value: g(p) }
27
+ ])
28
+ )
29
+ };
30
+ s(o([t]));
31
+ }, []), /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-2 p-3" }, m.map((e, t) => /* @__PURE__ */ React.createElement("div", { key: e.name, className: "flex flex-col gap-1" }, /* @__PURE__ */ React.createElement("label", { className: "text-sm font-medium" }, e.name), /* @__PURE__ */ React.createElement(
32
+ "input",
33
+ {
34
+ className: "focus:outline-none",
35
+ ...r(`options.${t}.content`)
36
+ }
37
+ ))));
38
+ }
39
+ export {
40
+ N as SelectVariableEditor
41
+ };
42
+ //# sourceMappingURL=SelectVariableEditor.js.map
@@ -0,0 +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","field","index"],"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,sBAAA,cAAC,SAAI,WAAU,0BAAA,GACZJ,EAAO,IAAI,CAACO,GAAOC,MAClB,sBAAA,cAAC,OAAA,EAAI,KAAKD,EAAM,MAAM,WAAU,sBAAA,GAC9B,sBAAA,cAAC,WAAM,WAAU,sBAAA,GAAuBA,EAAM,IAAK,GAEnD,sBAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAU;AAAA,MACT,GAAGV,EAAS,WAAWW,CAAK,UAAU;AAAA,IAAA;AAAA,EAAA,CAE3C,CACD,CACH;AAEJ;"}
@@ -0,0 +1,6 @@
1
+ import { TagElement } from '../../../../types.ts';
2
+ export interface TagVariableEditorProps {
3
+ element: TagElement;
4
+ onUpdate: (value: string) => void;
5
+ }
6
+ export declare function TagVariableEditor({ element, onUpdate, }: TagVariableEditorProps): import("react").JSX.Element;
@@ -0,0 +1,32 @@
1
+ import { useMemo as i, useEffect as u } from "react";
2
+ import { useForm as l } from "react-hook-form";
3
+ import { serializeICUMessage as t, parseICUMessage as m } from "@/utils/icu-tranform";
4
+ function g({
5
+ element: e,
6
+ onUpdate: o
7
+ }) {
8
+ const r = i(
9
+ () => t(e.children),
10
+ [e]
11
+ ), { register: n, getValues: s } = l({
12
+ defaultValues: { content: r }
13
+ });
14
+ return u(() => () => {
15
+ const { content: a } = s(), c = {
16
+ ...e,
17
+ children: m(a)
18
+ };
19
+ o(t([c]));
20
+ }, []), /* @__PURE__ */ React.createElement(
21
+ "textarea",
22
+ {
23
+ className: "p-3 focus:outline-none",
24
+ ...n("content"),
25
+ rows: 1
26
+ }
27
+ );
28
+ }
29
+ export {
30
+ g as TagVariableEditor
31
+ };
32
+ //# sourceMappingURL=TagVariableEditor.js.map
@@ -0,0 +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"],"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,sBAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAU;AAAA,MACT,GAAGJ,EAAS,SAAS;AAAA,MACtB,MAAM;AAAA,IAAA;AAAA,EAAA;AAGZ;"}
@@ -0,0 +1,9 @@
1
+ import { TimeElement } from '../../../../types.ts';
2
+ export interface TimeElementEditorProps {
3
+ name: string;
4
+ element: TimeElement | undefined;
5
+ ref: React.Ref<{
6
+ getValue: () => string;
7
+ }>;
8
+ }
9
+ export declare function TimeElementEditor({ name, element, ref, }: TimeElementEditorProps): import("react").JSX.Element;
@@ -0,0 +1,3 @@
1
+ import { TemplateVariable, VariableMentionNodeAttrs } from '../../../types.ts';
2
+ import { MentionOptions } from '@tiptap/extension-mention';
3
+ export declare function VariableMention(variables: TemplateVariable[]): import('@tiptap/core').Node<MentionOptions<VariableMentionNodeAttrs, VariableMentionNodeAttrs>, any>;
@@ -0,0 +1,93 @@
1
+ import { computePosition as f, shift as c, flip as p } from "@floating-ui/dom";
2
+ import y from "@tiptap/extension-mention";
3
+ import { ReactNodeViewRenderer as g, ReactRenderer as b, posToDOMRect as w } from "@tiptap/react";
4
+ import { formatVariableLabel as R } from "@/utils/format";
5
+ import { isTagElement as s } from "@/utils/guards";
6
+ import { serializeICUMessage as h } from "@/utils/icu-tranform";
7
+ import { VariableChip as v } from "./VariableChip.js";
8
+ import { VariableSuggestion as x } from "./VariableSuggestion.js";
9
+ function S(r) {
10
+ return y.extend({
11
+ name: "variable",
12
+ addNodeView: () => g(v),
13
+ addAttributes: () => ({
14
+ name: { default: null },
15
+ icu: { default: null },
16
+ label: { default: null }
17
+ }),
18
+ renderText: ({ node: n }) => n.attrs.icu
19
+ }).configure({
20
+ HTMLAttributes: {
21
+ class: "variable"
22
+ },
23
+ suggestions: [
24
+ l("@", r),
25
+ l(
26
+ "{",
27
+ r.filter((n) => !s(n))
28
+ ),
29
+ l(
30
+ "<",
31
+ r.filter((n) => s(n))
32
+ )
33
+ ]
34
+ });
35
+ }
36
+ function l(r, n) {
37
+ const m = n.map((e) => ({
38
+ name: e.value,
39
+ label: R(e),
40
+ icu: h([e])
41
+ }));
42
+ function a(e, o) {
43
+ f({
44
+ getBoundingClientRect: () => w(
45
+ e.view,
46
+ e.state.selection.from,
47
+ e.state.selection.to
48
+ )
49
+ }, o, {
50
+ placement: "bottom-start",
51
+ strategy: "absolute",
52
+ middleware: [c(), p()]
53
+ }).then(({ x: i, y: u, strategy: d }) => {
54
+ o.style.width = "max-content", o.style.position = d, o.style.left = `${i}px`, o.style.top = `${u}px`;
55
+ });
56
+ }
57
+ return {
58
+ char: r,
59
+ items: ({ query: e }) => m.filter(
60
+ (o) => o.name.toLowerCase().startsWith(e.toLowerCase())
61
+ ),
62
+ render: () => {
63
+ let e;
64
+ const o = document.getElementById(
65
+ "messages-form-content"
66
+ );
67
+ return {
68
+ onStart: (t) => {
69
+ if (e = new b(x, {
70
+ props: t,
71
+ editor: t.editor
72
+ }), !t.clientRect) return;
73
+ o.style.overflow = "hidden";
74
+ const i = e.element;
75
+ i.style.position = "absolute", document.body.appendChild(i), a(t.editor, i);
76
+ },
77
+ onUpdate(t) {
78
+ e.updateProps(t), t.clientRect && a(t.editor, e.element);
79
+ },
80
+ onKeyDown(t) {
81
+ return t.event.key === "Escape" ? (e.destroy(), !0) : e.ref ? e.ref.onKeyDown(t) : !1;
82
+ },
83
+ onExit() {
84
+ e.element.remove(), e.destroy(), o.style.overflow = "";
85
+ }
86
+ };
87
+ }
88
+ };
89
+ }
90
+ export {
91
+ S as VariableMention
92
+ };
93
+ //# sourceMappingURL=extension.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension.js","sources":["../../../../src/components/inputs/variables/extension.ts"],"sourcesContent":["import type { TemplateVariable, VariableMentionNodeAttrs } from \"@/types\";\nimport type { VirtualElement } from \"@floating-ui/dom\";\nimport type { MentionOptions } from \"@tiptap/extension-mention\";\nimport type { Attribute, Editor } from \"@tiptap/react\";\nimport type { SuggestionKeyDownProps } from \"@tiptap/suggestion\";\nimport { computePosition, flip, shift } from \"@floating-ui/dom\";\nimport Mention from \"@tiptap/extension-mention\";\nimport {\n posToDOMRect,\n ReactNodeViewRenderer,\n ReactRenderer,\n} from \"@tiptap/react\";\n\nimport { formatVariableLabel } from \"@/utils/format\";\nimport { isTagElement, isTemporalElement } from \"@/utils/guards\";\nimport { serializeICUMessage } from \"@/utils/icu-tranform\";\n\nimport type { VariableSuggestionProps } from \"./VariableSuggestion\";\nimport { VariableChip } from \"./VariableChip\";\nimport { VariableSuggestion } from \"./VariableSuggestion\";\n\nexport function VariableMention(variables: TemplateVariable[]) {\n return Mention.extend<\n MentionOptions<VariableMentionNodeAttrs, VariableMentionNodeAttrs>\n >({\n name: \"variable\",\n addNodeView: () => ReactNodeViewRenderer(VariableChip),\n addAttributes: () =>\n ({\n name: { default: null },\n icu: { default: null },\n label: { default: null },\n }) satisfies Record<keyof VariableMentionNodeAttrs, Attribute>,\n renderText: ({ node }) => node.attrs.icu,\n }).configure({\n HTMLAttributes: {\n class: \"variable\",\n },\n suggestions: [\n createSuggestion(\"@\", variables),\n createSuggestion(\n \"{\",\n variables.filter((variable) => !isTagElement(variable)),\n ),\n createSuggestion(\n \"<\",\n variables.filter((variable) => isTagElement(variable)),\n ),\n ],\n });\n}\n\nfunction createSuggestion(\n char: string,\n variables: TemplateVariable[],\n): MentionOptions<\n VariableMentionNodeAttrs,\n VariableMentionNodeAttrs\n>[\"suggestion\"] {\n const items = variables.map((variable) => ({\n name: variable.value,\n label: formatVariableLabel(variable),\n icu: serializeICUMessage([variable]),\n }));\n\n function updatePosition(editor: Editor, element: HTMLElement): void {\n const virtualElement: VirtualElement = {\n getBoundingClientRect: () =>\n posToDOMRect(\n editor.view,\n editor.state.selection.from,\n editor.state.selection.to,\n ),\n };\n\n void computePosition(virtualElement, element, {\n placement: \"bottom-start\",\n strategy: \"absolute\",\n middleware: [shift(), flip()],\n }).then(({ x, y, strategy }) => {\n element.style.width = \"max-content\";\n element.style.position = strategy;\n element.style.left = `${x}px`;\n element.style.top = `${y}px`;\n });\n }\n\n return {\n char,\n items: ({ query }) =>\n items.filter((item) =>\n item.name.toLowerCase().startsWith(query.toLowerCase()),\n ),\n render: () => {\n let component: ReactRenderer<\n { onKeyDown(props: SuggestionKeyDownProps): boolean },\n VariableSuggestionProps\n >;\n\n const scrollableElement = document.getElementById(\n \"messages-form-content\",\n );\n\n return {\n onStart: (props) => {\n component = new ReactRenderer<\n { onKeyDown(props: SuggestionKeyDownProps): boolean },\n VariableSuggestionProps\n >(VariableSuggestion, {\n props,\n editor: props.editor,\n });\n\n if (!props.clientRect) return;\n\n scrollableElement!.style.overflow = \"hidden\";\n\n const element = component.element as HTMLElement;\n element.style.position = \"absolute\";\n document.body.appendChild(element);\n\n updatePosition(props.editor, element);\n },\n\n onUpdate(props) {\n component.updateProps(props);\n\n if (!props.clientRect) return;\n\n updatePosition(props.editor, component.element as HTMLElement);\n },\n\n onKeyDown(props) {\n if (props.event.key === \"Escape\") {\n component.destroy();\n return true;\n }\n if (!component.ref) return false;\n\n return component.ref.onKeyDown(props);\n },\n\n onExit() {\n component.element.remove();\n component.destroy();\n scrollableElement!.style.overflow = \"\";\n },\n };\n },\n };\n}\n"],"names":["VariableMention","variables","Mention","ReactNodeViewRenderer","VariableChip","node","createSuggestion","variable","isTagElement","char","items","formatVariableLabel","serializeICUMessage","updatePosition","editor","element","computePosition","posToDOMRect","shift","flip","x","y","strategy","query","item","component","scrollableElement","props","ReactRenderer","VariableSuggestion"],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { NumberElement, PluralElement } from '../../../../types.ts';
2
+ export interface NumericVariablePickerProps {
3
+ element: NumberElement | PluralElement;
4
+ onUpdate: (value: string) => void;
5
+ }
6
+ export declare function NumericVariablePicker({ element, onUpdate, }: NumericVariablePickerProps): import("react").JSX.Element;
@@ -0,0 +1,49 @@
1
+ import { ToggleGroup as l } from "radix-ui";
2
+ import { useState as i, useRef as c, useEffect as s } from "react";
3
+ import { isNumberElement as m, isPluralElement as o } from "@/utils/guards";
4
+ import { PluralVariableEditor as f } from "../editors/PluralVariableEditor.js";
5
+ const p = [
6
+ "number",
7
+ "plural"
8
+ // "selectordinal"
9
+ ];
10
+ function R({
11
+ element: e,
12
+ onUpdate: n
13
+ }) {
14
+ const [r, u] = i(() => {
15
+ if (m(e)) return "number";
16
+ if (o(e)) return "plural";
17
+ }), a = c(null);
18
+ return s(() => () => {
19
+ a.current && n(a.current.getValue());
20
+ }, []), /* @__PURE__ */ React.createElement("div", { className: "" }, /* @__PURE__ */ React.createElement(
21
+ l.Root,
22
+ {
23
+ type: "single",
24
+ className: "flex bg-elevation-100",
25
+ onValueChange: (t) => u(t),
26
+ value: r
27
+ },
28
+ p.map((t) => /* @__PURE__ */ React.createElement(
29
+ l.Item,
30
+ {
31
+ key: t,
32
+ value: t,
33
+ className: "flex-1 border-none data-[state=off]:cursor-pointer data-[state=off]:opacity-50 data-[state=off]:hover:opacity-100 data-[state=on]:bg-elevation-800 data-[state=on]:text-elevation-0"
34
+ },
35
+ t
36
+ ))
37
+ ), /* @__PURE__ */ React.createElement("div", { className: "p-3" }, r === "plural" && /* @__PURE__ */ React.createElement(
38
+ f,
39
+ {
40
+ variableName: e.value,
41
+ element: o(e) ? e : void 0,
42
+ ref: a
43
+ }
44
+ )));
45
+ }
46
+ export {
47
+ R as NumericVariablePicker
48
+ };
49
+ //# sourceMappingURL=NumericVariablePicker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NumericVariablePicker.js","sources":["../../../../../src/components/inputs/variables/pickers/NumericVariablePicker.tsx"],"sourcesContent":["import { ToggleGroup } from \"radix-ui\";\nimport { useEffect, useRef, useState } from \"react\";\n\nimport type { NumberElement, PluralElement } from \"@/types\";\nimport { isNumberElement, isPluralElement } from \"@/utils/guards\";\n\nimport { PluralVariableEditor } from \"../editors/PluralVariableEditor\";\n\nconst NUMERIC_TYPES = [\n \"number\",\n \"plural\",\n // \"selectordinal\"\n] as const;\n\ntype NumericType = (typeof NUMERIC_TYPES)[number];\n\nexport interface NumericVariablePickerProps {\n element: NumberElement | PluralElement;\n onUpdate: (value: string) => void;\n}\n\nexport function NumericVariablePicker({\n element,\n onUpdate,\n}: NumericVariablePickerProps) {\n const [type, setType] = useState<NumericType | undefined>(() => {\n if (isNumberElement(element)) return \"number\";\n if (isPluralElement(element)) return \"plural\";\n return undefined;\n });\n const getValueRef = useRef<{ getValue: () => string }>(null);\n\n useEffect(() => {\n return () => {\n if (!getValueRef.current) return;\n onUpdate(getValueRef.current.getValue());\n };\n }, []);\n\n return (\n <div className=\"\">\n <ToggleGroup.Root\n type=\"single\"\n className=\"flex bg-elevation-100\"\n onValueChange={(value) => setType(value as NumericType)}\n value={type}\n >\n {NUMERIC_TYPES.map((type) => (\n <ToggleGroup.Item\n key={type}\n value={type}\n className=\"flex-1 border-none data-[state=off]:cursor-pointer data-[state=off]:opacity-50 data-[state=off]:hover:opacity-100 data-[state=on]:bg-elevation-800 data-[state=on]:text-elevation-0\"\n >\n {type}\n </ToggleGroup.Item>\n ))}\n </ToggleGroup.Root>\n\n <div className=\"p-3\">\n {type === \"plural\" && (\n <PluralVariableEditor\n variableName={element.value}\n element={isPluralElement(element) ? element : undefined}\n ref={getValueRef}\n />\n )}\n </div>\n </div>\n );\n}\n"],"names":["NUMERIC_TYPES","NumericVariablePicker","element","onUpdate","type","setType","useState","isNumberElement","isPluralElement","getValueRef","useRef","useEffect","ToggleGroup","value","PluralVariableEditor"],"mappings":";;;;AAQA,MAAMA,IAAgB;AAAA,EACpB;AAAA,EACA;AAAA;AAEF;AASO,SAASC,EAAsB;AAAA,EACpC,SAAAC;AAAA,EACA,UAAAC;AACF,GAA+B;AAC7B,QAAM,CAACC,GAAMC,CAAO,IAAIC,EAAkC,MAAM;AAC9D,QAAIC,EAAgBL,CAAO,EAAG,QAAO;AACrC,QAAIM,EAAgBN,CAAO,EAAG,QAAO;AAAA,EAEvC,CAAC,GACKO,IAAcC,EAAmC,IAAI;AAE3D,SAAAC,EAAU,MACD,MAAM;AACX,IAAKF,EAAY,WACjBN,EAASM,EAAY,QAAQ,UAAU;AAAA,EACzC,GACC,CAAA,CAAE,GAGH,sBAAA,cAAC,OAAA,EAAI,WAAU,GAAA,GACb,sBAAA;AAAA,IAACG,EAAY;AAAA,IAAZ;AAAA,MACC,MAAK;AAAA,MACL,WAAU;AAAA,MACV,eAAe,CAACC,MAAUR,EAAQQ,CAAoB;AAAA,MACtD,OAAOT;AAAA,IAAA;AAAA,IAENJ,EAAc,IAAI,CAACI,MAClB,sBAAA;AAAA,MAACQ,EAAY;AAAA,MAAZ;AAAA,QACC,KAAKR;AAAAA,QACL,OAAOA;AAAAA,QACP,WAAU;AAAA,MAAA;AAAA,MAETA;AAAAA,IAAA,CAEJ;AAAA,EAAA,GAGH,sBAAA,cAAC,OAAA,EAAI,WAAU,MAAA,GACZA,MAAS,YACR,sBAAA;AAAA,IAACU;AAAA,IAAA;AAAA,MACC,cAAcZ,EAAQ;AAAA,MACtB,SAASM,EAAgBN,CAAO,IAAIA,IAAU;AAAA,MAC9C,KAAKO;AAAA,IAAA;AAAA,EAAA,CAGX,CACF;AAEJ;"}