@mittwald/flow-react-components 0.2.0-alpha.552 → 0.2.0-alpha.554

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 (156) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/assets/doc-properties.json +14681 -10043
  3. package/dist/css/all.css +1 -1
  4. package/dist/js/_virtual/_.locale.json@bb0db7b5021f874310cbe5b6cc3d9cac.mjs +2 -2
  5. package/dist/js/components/src/components/Action/Action.mjs +1 -0
  6. package/dist/js/components/src/components/Action/Action.mjs.map +1 -1
  7. package/dist/js/components/src/components/Action/models/ActionState.mjs +1 -1
  8. package/dist/js/components/src/components/Action/models/ActionState.mjs.map +1 -1
  9. package/dist/js/components/src/components/Autocomplete/Autocomplete.mjs +1 -1
  10. package/dist/js/components/src/components/Autocomplete/Autocomplete.mjs.map +1 -1
  11. package/dist/js/components/src/components/Button/Button.mjs +1 -1
  12. package/dist/js/components/src/components/Button/Button.mjs.map +1 -1
  13. package/dist/js/components/src/components/Checkbox/Checkbox.mjs +18 -6
  14. package/dist/js/components/src/components/Checkbox/Checkbox.mjs.map +1 -1
  15. package/dist/js/components/src/components/CheckboxButton/CheckboxButton.mjs +15 -3
  16. package/dist/js/components/src/components/CheckboxButton/CheckboxButton.mjs.map +1 -1
  17. package/dist/js/components/src/components/ComboBox/ComboBox.mjs +25 -4
  18. package/dist/js/components/src/components/ComboBox/ComboBox.mjs.map +1 -1
  19. package/dist/js/components/src/components/FileField/FileField.mjs +7 -3
  20. package/dist/js/components/src/components/FileField/FileField.mjs.map +1 -1
  21. package/dist/js/components/src/components/Markdown/Markdown.mjs +2 -1
  22. package/dist/js/components/src/components/Markdown/Markdown.mjs.map +1 -1
  23. package/dist/js/components/src/components/MarkdownEditor/MarkdownEditor.mjs +107 -45
  24. package/dist/js/components/src/components/MarkdownEditor/MarkdownEditor.mjs.map +1 -1
  25. package/dist/js/components/src/components/MarkdownEditor/MarkdownEditor.module.scss.mjs +3 -3
  26. package/dist/js/components/src/components/MarkdownEditor/components/ToolbarButton.mjs +1 -0
  27. package/dist/js/components/src/components/MarkdownEditor/components/ToolbarButton.mjs.map +1 -1
  28. package/dist/js/components/src/components/MarkdownEditor/lib/{handleKeyDown.mjs → modifyValueByMarkdownSyntax.mjs} +20 -29
  29. package/dist/js/components/src/components/MarkdownEditor/lib/modifyValueByMarkdownSyntax.mjs.map +1 -0
  30. package/dist/js/components/src/components/MarkdownEditor/lib/{insertAtCursor.mjs → modifyValueByType.mjs} +17 -11
  31. package/dist/js/components/src/components/MarkdownEditor/lib/modifyValueByType.mjs.map +1 -0
  32. package/dist/js/components/src/components/NumberField/NumberField.mjs +11 -2
  33. package/dist/js/components/src/components/NumberField/NumberField.mjs.map +1 -1
  34. package/dist/js/components/src/components/Popover/Popover.mjs +9 -2
  35. package/dist/js/components/src/components/Popover/Popover.mjs.map +1 -1
  36. package/dist/js/components/src/components/SearchField/SearchField.mjs +1 -1
  37. package/dist/js/components/src/components/SearchField/SearchField.mjs.map +1 -1
  38. package/dist/js/components/src/components/Select/Select.mjs +9 -9
  39. package/dist/js/components/src/components/Select/Select.mjs.map +1 -1
  40. package/dist/js/components/src/components/TextArea/TextArea.mjs +10 -5
  41. package/dist/js/components/src/components/TextArea/TextArea.mjs.map +1 -1
  42. package/dist/js/components/src/components/TextField/TextField.mjs +9 -2
  43. package/dist/js/components/src/components/TextField/TextField.mjs.map +1 -1
  44. package/dist/js/components/src/components/propTypes/index.mjs +2 -0
  45. package/dist/js/components/src/components/propTypes/index.mjs.map +1 -1
  46. package/dist/js/components/src/integrations/react-hook-form/components/Field/Field.mjs +14 -0
  47. package/dist/js/components/src/integrations/react-hook-form/components/Field/Field.mjs.map +1 -1
  48. package/dist/js/components/src/integrations/react-hook-form/components/Form/Form.mjs +22 -11
  49. package/dist/js/components/src/integrations/react-hook-form/components/Form/Form.mjs.map +1 -1
  50. package/dist/js/components/src/integrations/react-hook-form/components/Form/lib/useRegisterActionStateContext.mjs +2 -1
  51. package/dist/js/components/src/integrations/react-hook-form/components/Form/lib/useRegisterActionStateContext.mjs.map +1 -1
  52. package/dist/js/components/src/integrations/react-hook-form/components/ResetButton/ResetButton.mjs +51 -0
  53. package/dist/js/components/src/integrations/react-hook-form/components/ResetButton/ResetButton.mjs.map +1 -0
  54. package/dist/js/components/src/integrations/react-hook-form/components/SubmitButton/SubmitButton.mjs +57 -0
  55. package/dist/js/components/src/integrations/react-hook-form/components/SubmitButton/SubmitButton.mjs.map +1 -0
  56. package/dist/js/components/src/integrations/react-hook-form/components/context/formContext.mjs.map +1 -1
  57. package/dist/js/components/src/lib/react/ReactAriaControlledValueFix.mjs +18 -10
  58. package/dist/js/components/src/lib/react/ReactAriaControlledValueFix.mjs.map +1 -1
  59. package/dist/js/react-hook-form.mjs +2 -0
  60. package/dist/js/react-hook-form.mjs.map +1 -1
  61. package/dist/types/components/Action/Action.d.ts.map +1 -1
  62. package/dist/types/components/Action/models/ActionState.d.ts +5 -0
  63. package/dist/types/components/Action/models/ActionState.d.ts.map +1 -1
  64. package/dist/types/components/Checkbox/Checkbox.d.ts +2 -1
  65. package/dist/types/components/Checkbox/Checkbox.d.ts.map +1 -1
  66. package/dist/types/components/CheckboxButton/CheckboxButton.d.ts +2 -0
  67. package/dist/types/components/CheckboxButton/CheckboxButton.d.ts.map +1 -1
  68. package/dist/types/components/ComboBox/ComboBox.d.ts +2 -1
  69. package/dist/types/components/ComboBox/ComboBox.d.ts.map +1 -1
  70. package/dist/types/components/FileField/FileField.d.ts +2 -1
  71. package/dist/types/components/FileField/FileField.d.ts.map +1 -1
  72. package/dist/types/components/List/typedList.d.ts +1 -1
  73. package/dist/types/components/Markdown/Markdown.d.ts +2 -1
  74. package/dist/types/components/Markdown/Markdown.d.ts.map +1 -1
  75. package/dist/types/components/MarkdownEditor/MarkdownEditor.d.ts +7 -3
  76. package/dist/types/components/MarkdownEditor/MarkdownEditor.d.ts.map +1 -1
  77. package/dist/types/components/MarkdownEditor/MarkdownEditor.test.d.ts +2 -0
  78. package/dist/types/components/MarkdownEditor/MarkdownEditor.test.d.ts.map +1 -0
  79. package/dist/types/components/MarkdownEditor/components/ToolbarButton.d.ts +1 -1
  80. package/dist/types/components/MarkdownEditor/components/ToolbarButton.d.ts.map +1 -1
  81. package/dist/types/components/MarkdownEditor/lib/modifyValueByMarkdownSyntax.d.ts +8 -0
  82. package/dist/types/components/MarkdownEditor/lib/modifyValueByMarkdownSyntax.d.ts.map +1 -0
  83. package/dist/types/components/MarkdownEditor/lib/modifyValueByMarkdownSyntax.test.d.ts +2 -0
  84. package/dist/types/components/MarkdownEditor/lib/modifyValueByMarkdownSyntax.test.d.ts.map +1 -0
  85. package/dist/types/components/MarkdownEditor/lib/modifyValueByType.d.ts +12 -0
  86. package/dist/types/components/MarkdownEditor/lib/modifyValueByType.d.ts.map +1 -0
  87. package/dist/types/components/MarkdownEditor/lib/modifyValueByType.test.d.ts +2 -0
  88. package/dist/types/components/MarkdownEditor/lib/modifyValueByType.test.d.ts.map +1 -0
  89. package/dist/types/components/NumberField/NumberField.d.ts +4 -3
  90. package/dist/types/components/NumberField/NumberField.d.ts.map +1 -1
  91. package/dist/types/components/Popover/Popover.d.ts.map +1 -1
  92. package/dist/types/components/Select/Select.d.ts.map +1 -1
  93. package/dist/types/components/TextArea/TextArea.d.ts +4 -7
  94. package/dist/types/components/TextArea/TextArea.d.ts.map +1 -1
  95. package/dist/types/components/TextField/TextField.d.ts.map +1 -1
  96. package/dist/types/components/propTypes/index.d.ts +4 -0
  97. package/dist/types/components/propTypes/index.d.ts.map +1 -1
  98. package/dist/types/integrations/react-hook-form/components/Field/Field.d.ts.map +1 -1
  99. package/dist/types/integrations/react-hook-form/components/Field/stories/Autocomplete.stories.d.ts.map +1 -1
  100. package/dist/types/integrations/react-hook-form/components/Field/stories/Checkbox.stories.d.ts.map +1 -1
  101. package/dist/types/integrations/react-hook-form/components/Field/stories/CheckboxButton.stories.d.ts.map +1 -1
  102. package/dist/types/integrations/react-hook-form/components/Field/stories/CheckboxGroup.stories.d.ts.map +1 -1
  103. package/dist/types/integrations/react-hook-form/components/Field/stories/ComboBox.stories.d.ts.map +1 -1
  104. package/dist/types/integrations/react-hook-form/components/Field/stories/DatePicker.stories.d.ts.map +1 -1
  105. package/dist/types/integrations/react-hook-form/components/Field/stories/DateRangePicker.stories.d.ts.map +1 -1
  106. package/dist/types/integrations/react-hook-form/components/Field/stories/FileField.stories.d.ts.map +1 -1
  107. package/dist/types/integrations/react-hook-form/components/Field/stories/MarkdownEditor.stories.d.ts.map +1 -1
  108. package/dist/types/integrations/react-hook-form/components/Field/stories/NumberField.stories.d.ts.map +1 -1
  109. package/dist/types/integrations/react-hook-form/components/Field/stories/PasswordCreationField.stories.d.ts.map +1 -1
  110. package/dist/types/integrations/react-hook-form/components/Field/stories/RadioGroup.stories.d.ts.map +1 -1
  111. package/dist/types/integrations/react-hook-form/components/Field/stories/SearchField.stories.d.ts.map +1 -1
  112. package/dist/types/integrations/react-hook-form/components/Field/stories/SegmentedControl.stories.d.ts.map +1 -1
  113. package/dist/types/integrations/react-hook-form/components/Field/stories/Select.stories.d.ts.map +1 -1
  114. package/dist/types/integrations/react-hook-form/components/Field/stories/Slider.stories.d.ts.map +1 -1
  115. package/dist/types/integrations/react-hook-form/components/Field/stories/Switch.stories.d.ts.map +1 -1
  116. package/dist/types/integrations/react-hook-form/components/Field/stories/TextArea.stories.d.ts.map +1 -1
  117. package/dist/types/integrations/react-hook-form/components/Field/stories/TextField.stories.d.ts.map +1 -1
  118. package/dist/types/integrations/react-hook-form/components/Field/stories/TimeField.stories.d.ts.map +1 -1
  119. package/dist/types/integrations/react-hook-form/components/Form/Form.d.ts +4 -3
  120. package/dist/types/integrations/react-hook-form/components/Form/Form.d.ts.map +1 -1
  121. package/dist/types/integrations/react-hook-form/components/Form/lib/useRegisterActionStateContext.d.ts +1 -0
  122. package/dist/types/integrations/react-hook-form/components/Form/lib/useRegisterActionStateContext.d.ts.map +1 -1
  123. package/dist/types/integrations/react-hook-form/components/ResetButton/ResetButton.d.ts +10 -0
  124. package/dist/types/integrations/react-hook-form/components/ResetButton/ResetButton.d.ts.map +1 -0
  125. package/dist/types/integrations/react-hook-form/components/ResetButton/ResetButton.test.d.ts +2 -0
  126. package/dist/types/integrations/react-hook-form/components/ResetButton/ResetButton.test.d.ts.map +1 -0
  127. package/dist/types/integrations/react-hook-form/components/ResetButton/index.d.ts +3 -0
  128. package/dist/types/integrations/react-hook-form/components/ResetButton/index.d.ts.map +1 -0
  129. package/dist/types/integrations/react-hook-form/components/SubmitButton/SubmitButton.d.ts +10 -0
  130. package/dist/types/integrations/react-hook-form/components/SubmitButton/SubmitButton.d.ts.map +1 -0
  131. package/dist/types/integrations/react-hook-form/components/SubmitButton/SubmitButton.test.d.ts +2 -0
  132. package/dist/types/integrations/react-hook-form/components/SubmitButton/SubmitButton.test.d.ts.map +1 -0
  133. package/dist/types/integrations/react-hook-form/components/SubmitButton/index.d.ts +3 -0
  134. package/dist/types/integrations/react-hook-form/components/SubmitButton/index.d.ts.map +1 -0
  135. package/dist/types/integrations/react-hook-form/components/context/formContext.d.ts +6 -2
  136. package/dist/types/integrations/react-hook-form/components/context/formContext.d.ts.map +1 -1
  137. package/dist/types/integrations/react-hook-form/index.d.ts +2 -0
  138. package/dist/types/integrations/react-hook-form/index.d.ts.map +1 -1
  139. package/dist/types/lib/dev/vitest.d.ts +3 -0
  140. package/dist/types/lib/dev/vitest.d.ts.map +1 -0
  141. package/dist/types/lib/propsContext/nestedPropsContext/lib.d.ts +2 -0
  142. package/dist/types/lib/propsContext/nestedPropsContext/lib.d.ts.map +1 -1
  143. package/dist/types/lib/react/ReactAriaControlledValueFix.d.ts.map +1 -1
  144. package/package.json +5 -4
  145. package/dist/js/components/src/components/MarkdownEditor/lib/handleKeyDown.mjs.map +0 -1
  146. package/dist/js/components/src/components/MarkdownEditor/lib/insertAtCursor.mjs.map +0 -1
  147. package/dist/types/components/MarkdownEditor/lib/handleKeyDown.d.ts +0 -3
  148. package/dist/types/components/MarkdownEditor/lib/handleKeyDown.d.ts.map +0 -1
  149. package/dist/types/components/MarkdownEditor/lib/handleKeyDown.test.d.ts +0 -2
  150. package/dist/types/components/MarkdownEditor/lib/handleKeyDown.test.d.ts.map +0 -1
  151. package/dist/types/components/MarkdownEditor/lib/insertAtCursor.d.ts +0 -4
  152. package/dist/types/components/MarkdownEditor/lib/insertAtCursor.d.ts.map +0 -1
  153. package/dist/types/components/MarkdownEditor/lib/insertAtCursor.test.d.ts +0 -2
  154. package/dist/types/components/MarkdownEditor/lib/insertAtCursor.test.d.ts.map +0 -1
  155. package/dist/types/lib/dev/vitestUserEvent.d.ts +0 -3
  156. package/dist/types/lib/dev/vitestUserEvent.d.ts.map +0 -1
@@ -1,17 +1,20 @@
1
1
  "use client"
2
2
  /* */
3
- import { jsxs, jsx } from 'react/jsx-runtime';
4
- import { useState } from 'react';
3
+ import { jsx, jsxs } from 'react/jsx-runtime';
4
+ import { useState, useRef, useEffect } from 'react';
5
5
  import styles from './MarkdownEditor.module.scss.mjs';
6
6
  import { Markdown } from '../Markdown/Markdown.mjs';
7
7
  import { TextArea } from '../TextArea/TextArea.mjs';
8
8
  import { Toolbar } from './components/Toolbar.mjs';
9
9
  import clsx from 'clsx';
10
10
  import { flowComponent } from '../../lib/componentFactory/flowComponent.mjs';
11
- import { handleKeyDown } from './lib/handleKeyDown.mjs';
12
11
  import { useObjectRef } from '@react-aria/utils';
13
12
  import { useManagedValue } from '../../lib/hooks/useManagedValue.mjs';
14
- import { insertAtCursor } from './lib/insertAtCursor.mjs';
13
+ import '../../lib/propsContext/propsContext.mjs';
14
+ import { PropsContextProvider } from '../../lib/propsContext/components/PropsContextProvider.mjs';
15
+ import { TunnelProvider, TunnelExit } from '@mittwald/react-tunnel';
16
+ import { scrollToCursor, modifyValueByMarkdownSyntax } from './lib/modifyValueByMarkdownSyntax.mjs';
17
+ import { modifyValueByType } from './lib/modifyValueByType.mjs';
15
18
 
16
19
  const MarkdownEditor = flowComponent("MarkdownEditor", (props) => {
17
20
  const {
@@ -23,58 +26,117 @@ const MarkdownEditor = flowComponent("MarkdownEditor", (props) => {
23
26
  autoResizeMaxRows,
24
27
  headingOffset,
25
28
  ref,
29
+ inputRef,
26
30
  ...rest
27
31
  } = props;
32
+ const localRef = useObjectRef(ref);
33
+ const localInputRef = useObjectRef(inputRef);
28
34
  const [mode, setMode] = useState("editor");
29
35
  const { value, handleOnChange } = useManagedValue(props);
30
- const textAreaRef = useObjectRef(ref);
36
+ const selectionPresent = useRef(null);
37
+ useEffect(() => {
38
+ const inputRef2 = localInputRef.current;
39
+ const present = selectionPresent.current;
40
+ if (!present || !inputRef2) {
41
+ return;
42
+ }
43
+ setTimeout(() => {
44
+ requestAnimationFrame(() => {
45
+ requestAnimationFrame(() => {
46
+ inputRef2.setSelectionRange(
47
+ present.selectionStart,
48
+ present.selectionEnd
49
+ );
50
+ if (present.shouldScrollToCursor) {
51
+ scrollToCursor(value, inputRef2);
52
+ }
53
+ });
54
+ });
55
+ selectionPresent.current = null;
56
+ }, 0);
57
+ }, [selectionPresent.current, localInputRef.current, value]);
31
58
  const rootClassName = clsx(
32
59
  styles.markdownEditor,
33
60
  className,
34
61
  styles[`mode-${mode}`]
35
62
  );
36
- return /* @__PURE__ */ jsxs(
37
- TextArea,
38
- {
39
- ...rest,
40
- isReadOnly: isReadOnly || mode === "preview",
41
- isDisabled,
42
- className: rootClassName,
43
- ref: textAreaRef,
63
+ const handleKeyDown = (event) => {
64
+ if (event.key !== "Enter") {
65
+ return;
66
+ }
67
+ const modifyParams = modifyValueByMarkdownSyntax(value, localInputRef);
68
+ if (!modifyParams) {
69
+ return;
70
+ }
71
+ const { newValue, newSelectionStart, newSelectionEnd } = modifyParams;
72
+ event.preventDefault();
73
+ localInputRef.current?.blur();
74
+ selectionPresent.current = {
75
+ shouldScrollToCursor: true,
76
+ selectionStart: newSelectionStart,
77
+ selectionEnd: newSelectionEnd
78
+ };
79
+ handleOnChange(newValue);
80
+ };
81
+ const handleToolButtonPressed = (type) => {
82
+ const { newValue, newSelectionStart, newSelectionEnd } = modifyValueByType(
44
83
  value,
45
- rows,
46
- autoResizeMaxRows,
47
- onChange: (v) => {
48
- handleOnChange(v);
49
- },
50
- onKeyDown: (e) => handleKeyDown(e, textAreaRef, handleOnChange),
51
- children: [
52
- /* @__PURE__ */ jsx(
53
- Toolbar,
54
- {
55
- currentMode: mode,
56
- isDisabled,
57
- onModeChange: (newMode) => setMode(newMode),
58
- onToolPressed: (type) => {
59
- insertAtCursor(value, handleOnChange, textAreaRef, type);
60
- }
61
- }
62
- ),
63
- /* @__PURE__ */ jsx(
64
- Markdown,
65
- {
66
- headingOffset,
67
- className: styles.markdown,
68
- style: {
69
- height: textAreaRef.current?.offsetHeight
70
- },
71
- children: value
72
- }
73
- ),
74
- children
75
- ]
84
+ type,
85
+ localInputRef
86
+ );
87
+ selectionPresent.current = {
88
+ shouldScrollToCursor: false,
89
+ selectionStart: newSelectionStart,
90
+ selectionEnd: newSelectionEnd
91
+ };
92
+ handleOnChange(newValue);
93
+ };
94
+ const propsContext = {
95
+ Label: {
96
+ tunnelId: "label"
76
97
  }
77
- );
98
+ };
99
+ return /* @__PURE__ */ jsx("div", { ref: localRef, className: rootClassName, children: /* @__PURE__ */ jsxs(TunnelProvider, { children: [
100
+ /* @__PURE__ */ jsx(TunnelExit, { id: "label" }),
101
+ /* @__PURE__ */ jsx(
102
+ Toolbar,
103
+ {
104
+ currentMode: mode,
105
+ isDisabled,
106
+ onModeChange: setMode,
107
+ onToolPressed: handleToolButtonPressed
108
+ }
109
+ ),
110
+ /* @__PURE__ */ jsxs(
111
+ TextArea,
112
+ {
113
+ ...rest,
114
+ "aria-hidden": mode === "preview",
115
+ isReadOnly: isReadOnly || mode === "preview",
116
+ isDisabled,
117
+ ref: localInputRef,
118
+ value,
119
+ rows,
120
+ autoResizeMaxRows,
121
+ onChange: handleOnChange,
122
+ onKeyDown: handleKeyDown,
123
+ children: [
124
+ /* @__PURE__ */ jsx(
125
+ Markdown,
126
+ {
127
+ headingOffset,
128
+ className: styles.markdown,
129
+ style: {
130
+ height: localInputRef.current?.offsetHeight
131
+ },
132
+ children: value
133
+ }
134
+ ),
135
+ /* @__PURE__ */ jsx(PropsContextProvider, { props: propsContext, children })
136
+ ]
137
+ }
138
+ )
139
+ ] }) });
78
140
  });
79
141
 
80
142
  export { MarkdownEditor, MarkdownEditor as default };
@@ -1 +1 @@
1
- {"version":3,"file":"MarkdownEditor.mjs","sources":["../../../../../../src/components/MarkdownEditor/MarkdownEditor.tsx"],"sourcesContent":["import React, { useState } from \"react\";\nimport styles from \"./MarkdownEditor.module.scss\";\nimport { Markdown, type MarkdownProps } from \"@/components/Markdown\";\nimport { TextArea, type TextAreaProps } from \"@/components/TextArea\";\nimport { Toolbar } from \"@/components/MarkdownEditor/components/Toolbar\";\nimport clsx from \"clsx\";\nimport { flowComponent } from \"@/lib/componentFactory/flowComponent\";\nimport { handleKeyDown } from \"@/components/MarkdownEditor/lib/handleKeyDown\";\nimport { useObjectRef } from \"@react-aria/utils\";\nimport { useManagedValue } from \"@/lib/hooks/useManagedValue\";\nimport { insertAtCursor } from \"@/components/MarkdownEditor/lib/insertAtCursor\";\n\nexport type MarkdownEditorMode = \"editor\" | \"preview\";\n\nexport type MarkdownEditorProps = TextAreaProps &\n Pick<MarkdownProps, \"headingOffset\">;\n\n/** @flr-generate all */\nexport const MarkdownEditor = flowComponent(\"MarkdownEditor\", (props) => {\n const {\n isDisabled,\n isReadOnly,\n children,\n className,\n rows = 5,\n autoResizeMaxRows,\n headingOffset,\n ref,\n ...rest\n } = props;\n\n const [mode, setMode] = useState<MarkdownEditorMode>(\"editor\");\n const { value, handleOnChange } = useManagedValue(props);\n const textAreaRef = useObjectRef<HTMLTextAreaElement>(ref);\n\n const rootClassName = clsx(\n styles.markdownEditor,\n className,\n styles[`mode-${mode}`],\n );\n\n return (\n <TextArea\n {...rest}\n isReadOnly={isReadOnly || mode === \"preview\"}\n isDisabled={isDisabled}\n className={rootClassName}\n ref={textAreaRef}\n value={value}\n rows={rows}\n autoResizeMaxRows={autoResizeMaxRows}\n onChange={(v) => {\n handleOnChange(v);\n }}\n onKeyDown={(e) => handleKeyDown(e, textAreaRef, handleOnChange)}\n >\n <Toolbar\n currentMode={mode}\n isDisabled={isDisabled}\n onModeChange={(newMode) => setMode(newMode)}\n onToolPressed={(type) => {\n insertAtCursor(value, handleOnChange, textAreaRef, type);\n }}\n />\n\n <Markdown\n headingOffset={headingOffset}\n className={styles.markdown}\n style={{\n height: textAreaRef.current?.offsetHeight,\n }}\n >\n {value}\n </Markdown>\n\n {children}\n </TextArea>\n );\n});\n\nexport default MarkdownEditor;\n"],"names":[],"mappings":";;;;;;;;;;;;;AAkBO,MAAM,cAAA,GAAiB,aAAA,CAAc,gBAAA,EAAkB,CAAC,KAAA,KAAU;AACvE,EAAA,MAAM;AAAA,IACJ,UAAA;AAAA,IACA,UAAA;AAAA,IACA,QAAA;AAAA,IACA,SAAA;AAAA,IACA,IAAA,GAAO,CAAA;AAAA,IACP,iBAAA;AAAA,IACA,aAAA;AAAA,IACA,GAAA;AAAA,IACA,GAAG;AAAA,GACL,GAAI,KAAA;AAEJ,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAI,SAA6B,QAAQ,CAAA;AAC7D,EAAA,MAAM,EAAE,KAAA,EAAO,cAAA,EAAe,GAAI,gBAAgB,KAAK,CAAA;AACvD,EAAA,MAAM,WAAA,GAAc,aAAkC,GAAG,CAAA;AAEzD,EAAA,MAAM,aAAA,GAAgB,IAAA;AAAA,IACpB,MAAA,CAAO,cAAA;AAAA,IACP,SAAA;AAAA,IACA,MAAA,CAAO,CAAA,KAAA,EAAQ,IAAI,CAAA,CAAE;AAAA,GACvB;AAEA,EAAA,uBACE,IAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACE,GAAG,IAAA;AAAA,MACJ,UAAA,EAAY,cAAc,IAAA,KAAS,SAAA;AAAA,MACnC,UAAA;AAAA,MACA,SAAA,EAAW,aAAA;AAAA,MACX,GAAA,EAAK,WAAA;AAAA,MACL,KAAA;AAAA,MACA,IAAA;AAAA,MACA,iBAAA;AAAA,MACA,QAAA,EAAU,CAAC,CAAA,KAAM;AACf,QAAA,cAAA,CAAe,CAAC,CAAA;AAAA,MAClB,CAAA;AAAA,MACA,WAAW,CAAC,CAAA,KAAM,aAAA,CAAc,CAAA,EAAG,aAAa,cAAc,CAAA;AAAA,MAE9D,QAAA,EAAA;AAAA,wBAAA,GAAA;AAAA,UAAC,OAAA;AAAA,UAAA;AAAA,YACC,WAAA,EAAa,IAAA;AAAA,YACb,UAAA;AAAA,YACA,YAAA,EAAc,CAAC,OAAA,KAAY,OAAA,CAAQ,OAAO,CAAA;AAAA,YAC1C,aAAA,EAAe,CAAC,IAAA,KAAS;AACvB,cAAA,cAAA,CAAe,KAAA,EAAO,cAAA,EAAgB,WAAA,EAAa,IAAI,CAAA;AAAA,YACzD;AAAA;AAAA,SACF;AAAA,wBAEA,GAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,aAAA;AAAA,YACA,WAAW,MAAA,CAAO,QAAA;AAAA,YAClB,KAAA,EAAO;AAAA,cACL,MAAA,EAAQ,YAAY,OAAA,EAAS;AAAA,aAC/B;AAAA,YAEC,QAAA,EAAA;AAAA;AAAA,SACH;AAAA,QAEC;AAAA;AAAA;AAAA,GACH;AAEJ,CAAC;;;;"}
1
+ {"version":3,"file":"MarkdownEditor.mjs","sources":["../../../../../../src/components/MarkdownEditor/MarkdownEditor.tsx"],"sourcesContent":["import React, {\n type KeyboardEventHandler,\n type RefObject,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport styles from \"./MarkdownEditor.module.scss\";\nimport { Markdown, type MarkdownProps } from \"@/components/Markdown\";\nimport { TextArea, type TextAreaProps } from \"@/components/TextArea\";\nimport { Toolbar } from \"@/components/MarkdownEditor/components/Toolbar\";\nimport clsx from \"clsx\";\nimport { flowComponent } from \"@/lib/componentFactory/flowComponent\";\nimport { useObjectRef } from \"@react-aria/utils\";\nimport { useManagedValue } from \"@/lib/hooks/useManagedValue\";\nimport { type PropsContext, PropsContextProvider } from \"@/lib/propsContext\";\nimport { TunnelProvider, TunnelExit } from \"@mittwald/react-tunnel\";\nimport {\n modifyValueByMarkdownSyntax,\n scrollToCursor,\n} from \"@/components/MarkdownEditor/lib/modifyValueByMarkdownSyntax\";\nimport {\n type InsertType,\n modifyValueByType,\n} from \"@/components/MarkdownEditor/lib/modifyValueByType\";\n\nexport type MarkdownEditorMode = \"editor\" | \"preview\";\n\nexport type MarkdownEditorProps = Omit<TextAreaProps, \"ref\"> &\n Pick<MarkdownProps, \"headingOffset\" | \"ref\"> & {\n inputRef?: RefObject<HTMLTextAreaElement | null>;\n };\n\n/** @flr-generate all */\nexport const MarkdownEditor = flowComponent(\"MarkdownEditor\", (props) => {\n const {\n isDisabled,\n isReadOnly,\n children,\n className,\n rows = 5,\n autoResizeMaxRows,\n headingOffset,\n ref,\n inputRef,\n ...rest\n } = props;\n\n const localRef = useObjectRef(ref);\n const localInputRef = useObjectRef(inputRef);\n\n const [mode, setMode] = useState<MarkdownEditorMode>(\"editor\");\n const { value, handleOnChange } = useManagedValue(props);\n\n const selectionPresent = useRef<{\n shouldScrollToCursor: boolean;\n selectionStart: number | null;\n selectionEnd: number | null;\n } | null>(null);\n\n useEffect(() => {\n const inputRef = localInputRef.current;\n const present = selectionPresent.current;\n\n if (!present || !inputRef) {\n return;\n }\n\n setTimeout(() => {\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n inputRef.setSelectionRange(\n present.selectionStart,\n present.selectionEnd,\n );\n\n if (present.shouldScrollToCursor) {\n scrollToCursor(value, inputRef);\n }\n });\n });\n\n selectionPresent.current = null;\n }, 0);\n }, [selectionPresent.current, localInputRef.current, value]);\n\n const rootClassName = clsx(\n styles.markdownEditor,\n className,\n styles[`mode-${mode}`],\n );\n\n const handleKeyDown: KeyboardEventHandler = (event) => {\n if (event.key !== \"Enter\") {\n return;\n }\n\n const modifyParams = modifyValueByMarkdownSyntax(value, localInputRef);\n\n if (!modifyParams) {\n return;\n }\n\n const { newValue, newSelectionStart, newSelectionEnd } = modifyParams;\n\n event.preventDefault();\n localInputRef.current?.blur();\n\n selectionPresent.current = {\n shouldScrollToCursor: true,\n selectionStart: newSelectionStart,\n selectionEnd: newSelectionEnd,\n };\n\n handleOnChange(newValue);\n };\n\n const handleToolButtonPressed = (type: InsertType) => {\n const { newValue, newSelectionStart, newSelectionEnd } = modifyValueByType(\n value,\n type,\n localInputRef,\n );\n\n selectionPresent.current = {\n shouldScrollToCursor: false,\n selectionStart: newSelectionStart,\n selectionEnd: newSelectionEnd,\n };\n\n handleOnChange(newValue);\n };\n\n const propsContext: PropsContext = {\n Label: {\n tunnelId: \"label\",\n },\n };\n\n return (\n <div ref={localRef} className={rootClassName}>\n <TunnelProvider>\n <TunnelExit id=\"label\" />\n <Toolbar\n currentMode={mode}\n isDisabled={isDisabled}\n onModeChange={setMode}\n onToolPressed={handleToolButtonPressed}\n />\n <TextArea\n {...rest}\n aria-hidden={mode === \"preview\"}\n isReadOnly={isReadOnly || mode === \"preview\"}\n isDisabled={isDisabled}\n ref={localInputRef}\n value={value}\n rows={rows}\n autoResizeMaxRows={autoResizeMaxRows}\n onChange={handleOnChange}\n onKeyDown={handleKeyDown}\n >\n <Markdown\n headingOffset={headingOffset}\n className={styles.markdown}\n style={{\n height: localInputRef.current?.offsetHeight,\n }}\n >\n {value}\n </Markdown>\n <PropsContextProvider props={propsContext}>\n {children}\n </PropsContextProvider>\n </TextArea>\n </TunnelProvider>\n </div>\n );\n});\n\nexport default MarkdownEditor;\n"],"names":["inputRef"],"mappings":"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"}
@@ -7,12 +7,12 @@ const modeButton = "flow--markdown-editor--mode-button";
7
7
  const markdown = "flow--markdown-editor--markdown";
8
8
  const styles = {
9
9
  markdownEditor: markdownEditor,
10
- "mode-editor": "flow--markdown-editor--mode-editor",
11
- "mode-preview": "flow--markdown-editor--mode-preview",
12
10
  toolbar: toolbar,
13
11
  toolbarButtons: toolbarButtons,
14
12
  modeButton: modeButton,
15
- markdown: markdown
13
+ markdown: markdown,
14
+ "mode-editor": "flow--markdown-editor--mode-editor",
15
+ "mode-preview": "flow--markdown-editor--mode-preview"
16
16
  };
17
17
 
18
18
  export { styles as default, markdown, markdownEditor, modeButton, toolbar, toolbarButtons };
@@ -13,6 +13,7 @@ const ToolbarButton = (props) => {
13
13
  Button,
14
14
  {
15
15
  ...rest,
16
+ "data-button-type": type,
16
17
  "aria-label": stringFormatter.format(`toolbar.${type}`),
17
18
  size: "s",
18
19
  variant: "plain",
@@ -1 +1 @@
1
- {"version":3,"file":"ToolbarButton.mjs","sources":["../../../../../../../src/components/MarkdownEditor/components/ToolbarButton.tsx"],"sourcesContent":["import React, { type FC } from \"react\";\nimport { type InsertType } from \"@/components/MarkdownEditor/lib/insertAtCursor\";\nimport { Button, type ButtonProps } from \"@/components/Button\";\nimport { useLocalizedStringFormatter } from \"react-aria\";\nimport locales from \"../locales/*.locale.json\";\n\nexport interface ToolBarButtonProps\n extends Pick<ButtonProps, \"isDisabled\" | \"children\"> {\n type: InsertType;\n onPress?: (type: InsertType) => void;\n}\n\nexport const ToolbarButton: FC<ToolBarButtonProps> = (props) => {\n const { children, type, onPress, ...rest } = props;\n\n const stringFormatter = useLocalizedStringFormatter(locales);\n\n return (\n <Button\n {...rest}\n aria-label={stringFormatter.format(`toolbar.${type}`)}\n size=\"s\"\n variant=\"plain\"\n color=\"dark\"\n onPress={() => onPress?.(type)}\n >\n {children}\n </Button>\n );\n};\n"],"names":[],"mappings":";;;;;;AAYO,MAAM,aAAA,GAAwC,CAAC,KAAA,KAAU;AAC9D,EAAA,MAAM,EAAE,QAAA,EAAU,IAAA,EAAM,OAAA,EAAS,GAAG,MAAK,GAAI,KAAA;AAE7C,EAAA,MAAM,eAAA,GAAkB,4BAA4B,OAAO,CAAA;AAE3D,EAAA,uBACE,GAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACE,GAAG,IAAA;AAAA,MACJ,YAAA,EAAY,eAAA,CAAgB,MAAA,CAAO,CAAA,QAAA,EAAW,IAAI,CAAA,CAAE,CAAA;AAAA,MACpD,IAAA,EAAK,GAAA;AAAA,MACL,OAAA,EAAQ,OAAA;AAAA,MACR,KAAA,EAAM,MAAA;AAAA,MACN,OAAA,EAAS,MAAM,OAAA,GAAU,IAAI,CAAA;AAAA,MAE5B;AAAA;AAAA,GACH;AAEJ;;;;"}
1
+ {"version":3,"file":"ToolbarButton.mjs","sources":["../../../../../../../src/components/MarkdownEditor/components/ToolbarButton.tsx"],"sourcesContent":["import React, { type FC } from \"react\";\nimport { type InsertType } from \"@/components/MarkdownEditor/lib/modifyValueByType\";\nimport { Button, type ButtonProps } from \"@/components/Button\";\nimport { useLocalizedStringFormatter } from \"react-aria\";\nimport locales from \"../locales/*.locale.json\";\n\nexport interface ToolBarButtonProps\n extends Pick<ButtonProps, \"isDisabled\" | \"children\"> {\n type: InsertType;\n onPress?: (type: InsertType) => void;\n}\n\nexport const ToolbarButton: FC<ToolBarButtonProps> = (props) => {\n const { children, type, onPress, ...rest } = props;\n\n const stringFormatter = useLocalizedStringFormatter(locales);\n\n return (\n <Button\n {...rest}\n data-button-type={type}\n aria-label={stringFormatter.format(`toolbar.${type}`)}\n size=\"s\"\n variant=\"plain\"\n color=\"dark\"\n onPress={() => onPress?.(type)}\n >\n {children}\n </Button>\n );\n};\n"],"names":[],"mappings":";;;;;;AAYO,MAAM,aAAA,GAAwC,CAAC,KAAA,KAAU;AAC9D,EAAA,MAAM,EAAE,QAAA,EAAU,IAAA,EAAM,OAAA,EAAS,GAAG,MAAK,GAAI,KAAA;AAE7C,EAAA,MAAM,eAAA,GAAkB,4BAA4B,OAAO,CAAA;AAE3D,EAAA,uBACE,GAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACE,GAAG,IAAA;AAAA,MACJ,kBAAA,EAAkB,IAAA;AAAA,MAClB,YAAA,EAAY,eAAA,CAAgB,MAAA,CAAO,CAAA,QAAA,EAAW,IAAI,CAAA,CAAE,CAAA;AAAA,MACpD,IAAA,EAAK,GAAA;AAAA,MACL,OAAA,EAAQ,OAAA;AAAA,MACR,KAAA,EAAM,MAAA;AAAA,MACN,OAAA,EAAS,MAAM,OAAA,GAAU,IAAI,CAAA;AAAA,MAE5B;AAAA;AAAA,GACH;AAEJ;;;;"}
@@ -1,25 +1,21 @@
1
1
  "use client"
2
2
  /* */
3
- const scrollToCursor = (textarea) => {
3
+ const scrollToCursor = (value, textarea) => {
4
4
  const { selectionStart } = textarea;
5
5
  const lineHeight = parseInt(
6
6
  getComputedStyle(textarea).lineHeight || "20",
7
7
  10
8
8
  );
9
- const lines = textarea.value.slice(0, selectionStart).split("\n").length;
9
+ const lines = value.slice(0, selectionStart).split("\n").length;
10
10
  textarea.scrollTop = (lines - 1) * lineHeight;
11
11
  };
12
- const handleKeyDown = (e, textAreaRef, setMarkdown) => {
13
- if (e.key !== "Enter") {
14
- return;
15
- }
12
+ const modifyValueByMarkdownSyntax = (value, textAreaRef) => {
16
13
  const textarea = textAreaRef.current;
17
14
  if (!textarea) {
18
15
  return;
19
16
  }
20
17
  const start = textarea.selectionStart;
21
18
  const end = textarea.selectionEnd;
22
- const value = textarea.value;
23
19
  const before = value.slice(0, start);
24
20
  const after = value.slice(end);
25
21
  const lineStart = before.lastIndexOf("\n") + 1;
@@ -27,41 +23,36 @@ const handleKeyDown = (e, textAreaRef, setMarkdown) => {
27
23
  const orderedMatch = currentLine.match(/^(\s*)(\d+)\.\s+/);
28
24
  const unorderedMatch = currentLine.match(/^(\s*)([-*+])\s+/);
29
25
  if ((orderedMatch || unorderedMatch) && currentLine.trim().match(/^([-*+]|\d+\.)$/)) {
30
- e.preventDefault();
31
26
  const newText = value.slice(0, lineStart) + "\n" + after;
32
- setMarkdown(newText);
33
- requestAnimationFrame(() => {
34
- textarea.selectionStart = textarea.selectionEnd = lineStart + 1;
35
- scrollToCursor(textarea);
36
- });
37
- return;
27
+ return {
28
+ newValue: newText,
29
+ newSelectionStart: lineStart + 1,
30
+ newSelectionEnd: lineStart + 1
31
+ };
38
32
  }
39
33
  if (orderedMatch) {
40
- e.preventDefault();
41
34
  const indent = orderedMatch[1];
42
35
  const nextNum = parseInt(orderedMatch[2] ?? "", 10) + 1;
43
36
  const insert = `
44
37
  ${indent}${nextNum}. `;
45
- const newText = before + insert + after;
46
- setMarkdown(newText);
47
- requestAnimationFrame(() => {
48
- textarea.selectionStart = textarea.selectionEnd = start + insert.length;
49
- scrollToCursor(textarea);
50
- });
38
+ return {
39
+ newValue: before + insert + after,
40
+ newSelectionStart: start + insert.length,
41
+ newSelectionEnd: start + insert.length
42
+ };
51
43
  } else if (unorderedMatch) {
52
- e.preventDefault();
53
44
  const indent = unorderedMatch[1];
54
45
  const bullet = unorderedMatch[2];
55
46
  const insert = `
56
47
  ${indent}${bullet} `;
57
48
  const newText = before + insert + after;
58
- setMarkdown(newText);
59
- requestAnimationFrame(() => {
60
- textarea.selectionStart = textarea.selectionEnd = start + insert.length;
61
- scrollToCursor(textarea);
62
- });
49
+ return {
50
+ newValue: newText,
51
+ newSelectionStart: start + insert.length,
52
+ newSelectionEnd: start + insert.length
53
+ };
63
54
  }
64
55
  };
65
56
 
66
- export { handleKeyDown };
67
- //# sourceMappingURL=handleKeyDown.mjs.map
57
+ export { modifyValueByMarkdownSyntax, scrollToCursor };
58
+ //# sourceMappingURL=modifyValueByMarkdownSyntax.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modifyValueByMarkdownSyntax.mjs","sources":["../../../../../../../src/components/MarkdownEditor/lib/modifyValueByMarkdownSyntax.ts"],"sourcesContent":["import type { RefObject } from \"react\";\n\nexport const scrollToCursor = (\n value: string,\n textarea: HTMLTextAreaElement,\n) => {\n const { selectionStart } = textarea;\n const lineHeight = parseInt(\n getComputedStyle(textarea).lineHeight || \"20\",\n 10,\n );\n const lines = value.slice(0, selectionStart).split(\"\\n\").length;\n textarea.scrollTop = (lines - 1) * lineHeight;\n};\n\nexport const modifyValueByMarkdownSyntax = (\n value: string,\n textAreaRef: RefObject<HTMLTextAreaElement | null>,\n) => {\n const textarea = textAreaRef.current;\n if (!textarea) {\n return;\n }\n\n const start = textarea.selectionStart;\n const end = textarea.selectionEnd;\n\n const before = value.slice(0, start);\n const after = value.slice(end);\n const lineStart = before.lastIndexOf(\"\\n\") + 1;\n const currentLine = before.slice(lineStart);\n\n const orderedMatch = currentLine.match(/^(\\s*)(\\d+)\\.\\s+/);\n const unorderedMatch = currentLine.match(/^(\\s*)([-*+])\\s+/);\n\n if (\n (orderedMatch || unorderedMatch) &&\n currentLine.trim().match(/^([-*+]|\\d+\\.)$/)\n ) {\n const newText = value.slice(0, lineStart) + \"\\n\" + after;\n\n return {\n newValue: newText,\n newSelectionStart: lineStart + 1,\n newSelectionEnd: lineStart + 1,\n } as const;\n }\n\n if (orderedMatch) {\n const indent = orderedMatch[1];\n const nextNum = parseInt(orderedMatch[2] ?? \"\", 10) + 1;\n const insert = `\\n${indent}${nextNum}. `;\n\n return {\n newValue: before + insert + after,\n newSelectionStart: start + insert.length,\n newSelectionEnd: start + insert.length,\n } as const;\n } else if (unorderedMatch) {\n const indent = unorderedMatch[1];\n const bullet = unorderedMatch[2];\n const insert = `\\n${indent}${bullet} `;\n\n const newText = before + insert + after;\n return {\n newValue: newText,\n newSelectionStart: start + insert.length,\n newSelectionEnd: start + insert.length,\n } as const;\n }\n};\n"],"names":[],"mappings":"AAEO,MAAM,cAAA,GAAiB,CAC5B,KAAA,EACA,QAAA,KACG;AACH,EAAA,MAAM,EAAE,gBAAe,GAAI,QAAA;AAC3B,EAAA,MAAM,UAAA,GAAa,QAAA;AAAA,IACjB,gBAAA,CAAiB,QAAQ,CAAA,CAAE,UAAA,IAAc,IAAA;AAAA,IACzC;AAAA,GACF;AACA,EAAA,MAAM,KAAA,GAAQ,MAAM,KAAA,CAAM,CAAA,EAAG,cAAc,CAAA,CAAE,KAAA,CAAM,IAAI,CAAA,CAAE,MAAA;AACzD,EAAA,QAAA,CAAS,SAAA,GAAA,CAAa,QAAQ,CAAA,IAAK,UAAA;AACrC;AAEO,MAAM,2BAAA,GAA8B,CACzC,KAAA,EACA,WAAA,KACG;AACH,EAAA,MAAM,WAAW,WAAA,CAAY,OAAA;AAC7B,EAAA,IAAI,CAAC,QAAA,EAAU;AACb,IAAA;AAAA,EACF;AAEA,EAAA,MAAM,QAAQ,QAAA,CAAS,cAAA;AACvB,EAAA,MAAM,MAAM,QAAA,CAAS,YAAA;AAErB,EAAA,MAAM,MAAA,GAAS,KAAA,CAAM,KAAA,CAAM,CAAA,EAAG,KAAK,CAAA;AACnC,EAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,KAAA,CAAM,GAAG,CAAA;AAC7B,EAAA,MAAM,SAAA,GAAY,MAAA,CAAO,WAAA,CAAY,IAAI,CAAA,GAAI,CAAA;AAC7C,EAAA,MAAM,WAAA,GAAc,MAAA,CAAO,KAAA,CAAM,SAAS,CAAA;AAE1C,EAAA,MAAM,YAAA,GAAe,WAAA,CAAY,KAAA,CAAM,kBAAkB,CAAA;AACzD,EAAA,MAAM,cAAA,GAAiB,WAAA,CAAY,KAAA,CAAM,kBAAkB,CAAA;AAE3D,EAAA,IAAA,CACG,gBAAgB,cAAA,KACjB,WAAA,CAAY,MAAK,CAAE,KAAA,CAAM,iBAAiB,CAAA,EAC1C;AACA,IAAA,MAAM,UAAU,KAAA,CAAM,KAAA,CAAM,CAAA,EAAG,SAAS,IAAI,IAAA,GAAO,KAAA;AAEnD,IAAA,OAAO;AAAA,MACL,QAAA,EAAU,OAAA;AAAA,MACV,mBAAmB,SAAA,GAAY,CAAA;AAAA,MAC/B,iBAAiB,SAAA,GAAY;AAAA,KAC/B;AAAA,EACF;AAEA,EAAA,IAAI,YAAA,EAAc;AAChB,IAAA,MAAM,MAAA,GAAS,aAAa,CAAC,CAAA;AAC7B,IAAA,MAAM,UAAU,QAAA,CAAS,YAAA,CAAa,CAAC,CAAA,IAAK,EAAA,EAAI,EAAE,CAAA,GAAI,CAAA;AACtD,IAAA,MAAM,MAAA,GAAS;AAAA,EAAK,MAAM,GAAG,OAAO,CAAA,EAAA,CAAA;AAEpC,IAAA,OAAO;AAAA,MACL,QAAA,EAAU,SAAS,MAAA,GAAS,KAAA;AAAA,MAC5B,iBAAA,EAAmB,QAAQ,MAAA,CAAO,MAAA;AAAA,MAClC,eAAA,EAAiB,QAAQ,MAAA,CAAO;AAAA,KAClC;AAAA,EACF,WAAW,cAAA,EAAgB;AACzB,IAAA,MAAM,MAAA,GAAS,eAAe,CAAC,CAAA;AAC/B,IAAA,MAAM,MAAA,GAAS,eAAe,CAAC,CAAA;AAC/B,IAAA,MAAM,MAAA,GAAS;AAAA,EAAK,MAAM,GAAG,MAAM,CAAA,CAAA,CAAA;AAEnC,IAAA,MAAM,OAAA,GAAU,SAAS,MAAA,GAAS,KAAA;AAClC,IAAA,OAAO;AAAA,MACL,QAAA,EAAU,OAAA;AAAA,MACV,iBAAA,EAAmB,QAAQ,MAAA,CAAO,MAAA;AAAA,MAClC,eAAA,EAAiB,QAAQ,MAAA,CAAO;AAAA,KAClC;AAAA,EACF;AACF;;;;"}
@@ -1,5 +1,7 @@
1
1
  "use client"
2
2
  /* */
3
+ import 'react';
4
+
3
5
  const markdownSyntax = {
4
6
  bold: { before: "**", after: "**", toggleable: true },
5
7
  italic: { before: "_", after: "_", toggleable: true },
@@ -18,11 +20,15 @@ const getLineEnd = (text, pos) => {
18
20
  const nextNewline = text.indexOf("\n", pos);
19
21
  return nextNewline === -1 ? text.length : nextNewline;
20
22
  };
21
- const insertAtCursor = (markdown, setMarkdown, textAreaRef, type) => {
22
- const textarea = textAreaRef.current;
23
- if (!textarea) {
24
- return;
23
+ const modifyValueByType = (markdown, type, textAreaRef) => {
24
+ if (!textAreaRef.current) {
25
+ return {
26
+ newValue: markdown,
27
+ newSelectionStart: null,
28
+ newSelectionEnd: null
29
+ };
25
30
  }
31
+ const textarea = textAreaRef.current;
26
32
  const { before, after = "", toggleable = false } = markdownSyntax[type];
27
33
  const start = textarea.selectionStart;
28
34
  const end = textarea.selectionEnd;
@@ -142,12 +148,12 @@ ${before} `;
142
148
  selectionEnd = selectionStart + selectedText.length;
143
149
  }
144
150
  }
145
- setMarkdown(newText);
146
- requestAnimationFrame(() => {
147
- textarea.setSelectionRange(selectionStart, selectionEnd);
148
- textarea.focus();
149
- });
151
+ return {
152
+ newValue: newText,
153
+ newSelectionStart: selectionStart,
154
+ newSelectionEnd: selectionEnd
155
+ };
150
156
  };
151
157
 
152
- export { insertAtCursor };
153
- //# sourceMappingURL=insertAtCursor.mjs.map
158
+ export { modifyValueByType };
159
+ //# sourceMappingURL=modifyValueByType.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modifyValueByType.mjs","sources":["../../../../../../../src/components/MarkdownEditor/lib/modifyValueByType.ts"],"sourcesContent":["import { type RefObject } from \"react\";\n\nexport type InsertType =\n | \"bold\"\n | \"italic\"\n | \"strikeThrough\"\n | \"quote\"\n | \"code\"\n | \"link\"\n | \"unorderedList\"\n | \"orderedList\";\n\nconst markdownSyntax: Record<\n InsertType,\n { before: string; after?: string; toggleable?: boolean }\n> = {\n bold: { before: \"**\", after: \"**\", toggleable: true },\n italic: { before: \"_\", after: \"_\", toggleable: true },\n strikeThrough: { before: \"~~\", after: \"~~\", toggleable: true },\n quote: { before: \"> \" },\n code: { before: \"`\", after: \"`\", toggleable: true },\n link: { before: \"[\", after: \"](https://)\" },\n unorderedList: { before: \"- \" },\n orderedList: { before: \"1. \" },\n};\n\nconst getLineStart = (text: string, pos: number) => {\n const lastNewline = text.lastIndexOf(\"\\n\", pos - 1);\n return lastNewline === -1 ? 0 : lastNewline + 1;\n};\n\nconst getLineEnd = (text: string, pos: number) => {\n const nextNewline = text.indexOf(\"\\n\", pos);\n return nextNewline === -1 ? text.length : nextNewline;\n};\n\nexport const modifyValueByType = (\n markdown: string,\n type: InsertType,\n textAreaRef: RefObject<HTMLTextAreaElement | null>,\n) => {\n if (!textAreaRef.current) {\n return {\n newValue: markdown,\n newSelectionStart: null,\n newSelectionEnd: null,\n } as const;\n }\n\n const textarea = textAreaRef.current;\n const { before, after = \"\", toggleable = false } = markdownSyntax[type];\n const start = textarea.selectionStart;\n const end = textarea.selectionEnd;\n const selectedText = markdown.substring(start, end);\n const lines = selectedText.split(\"\\n\");\n\n let newText = markdown;\n let selectionStart = start;\n let selectionEnd = end;\n\n if (type === \"code\" && selectedText.includes(\"\\n\")) {\n newText =\n markdown.substring(0, start) +\n \"```\\n\" +\n selectedText +\n \"\\n```\\n\" +\n markdown.substring(end);\n selectionStart = start + 4;\n selectionEnd = selectionStart + selectedText.length;\n } else if (type === \"orderedList\") {\n if (selectedText) {\n const numbered = lines.map((line, i) => `${i + 1}. ${line}`).join(\"\\n\");\n newText =\n markdown.substring(0, start) + numbered + markdown.substring(end);\n selectionStart = start;\n selectionEnd = start + numbered.length;\n } else {\n const lineStart = getLineStart(markdown, start);\n const lineEnd = getLineEnd(markdown, start);\n const numberedLine = `1. ${markdown.substring(lineStart, lineEnd)}`;\n\n newText =\n markdown.substring(0, lineStart) +\n before +\n markdown.substring(lineStart);\n selectionStart = lineStart + numberedLine.length;\n selectionEnd = selectionStart;\n }\n } else if (type === \"unorderedList\") {\n if (selectedText) {\n const bulleted = lines.map((line) => `${before}${line}`).join(\"\\n\");\n newText =\n markdown.substring(0, start) + bulleted + markdown.substring(end);\n selectionStart = start;\n selectionEnd = start + bulleted.length;\n } else {\n const lineStart = getLineStart(markdown, start);\n const lineEnd = getLineEnd(markdown, start);\n const bulletedLine = `- ${markdown.substring(lineStart, lineEnd)}`;\n\n newText =\n markdown.substring(0, lineStart) +\n before +\n markdown.substring(lineStart);\n selectionStart = lineStart + bulletedLine.length;\n selectionEnd = selectionStart;\n }\n } else if (type === \"quote\") {\n if (selectedText) {\n const quoted = lines.map((line) => `${before}${line}`).join(\"\\n\");\n newText = markdown.substring(0, start) + quoted + markdown.substring(end);\n selectionStart = start;\n selectionEnd = start + quoted.length;\n } else {\n const quoteLine = `\\n${before} `;\n newText =\n markdown.substring(0, start) + quoteLine + markdown.substring(end);\n selectionStart = start + quoteLine.length;\n selectionEnd = selectionStart;\n }\n } else if (toggleable) {\n const prefix = markdown.substring(start - before.length, start);\n const suffix = markdown.substring(end, end + after.length);\n const isSurrounded = prefix === before && suffix === after;\n const isWrappedInside =\n selectedText.startsWith(before) && selectedText.endsWith(after);\n\n if (isSurrounded) {\n // Remove external wrapping (not selected)\n newText =\n markdown.substring(0, start - before.length) +\n selectedText +\n markdown.substring(end + after.length);\n selectionStart = start - before.length;\n selectionEnd = selectionStart + selectedText.length;\n } else if (isWrappedInside) {\n // Remove internal wrapping (selected)\n const unwrapped = selectedText.slice(\n before.length,\n selectedText.length - after.length,\n );\n newText =\n markdown.substring(0, start) + unwrapped + markdown.substring(end);\n selectionStart = start;\n selectionEnd = start + unwrapped.length;\n } else {\n // Add wrapping\n newText =\n markdown.substring(0, start) +\n before +\n selectedText +\n after +\n markdown.substring(end);\n\n if (selectedText.length === 0) {\n selectionStart = start + before.length;\n selectionEnd = selectionStart;\n } else {\n selectionStart = start + before.length;\n selectionEnd = selectionStart + selectedText.length;\n }\n }\n } else if (type === \"link\") {\n let linkText = \"\";\n let linkUrl = \"\";\n let inserted = \"\";\n let cursorOffsetStart = 0;\n\n const isValidUrl = (str: string): boolean => {\n try {\n new URL(str);\n return true;\n } catch {\n return false;\n }\n };\n\n if (selectedText) {\n if (isValidUrl(selectedText)) {\n linkUrl = selectedText;\n inserted = `[](${linkUrl})`;\n cursorOffsetStart = start + 1;\n } else {\n linkText = selectedText;\n inserted = `[${linkText}]()`;\n cursorOffsetStart = start + inserted.indexOf(\"](\") + 2;\n }\n } else {\n inserted = `[](https://)`;\n cursorOffsetStart = start + 1;\n }\n\n newText = markdown.substring(0, start) + inserted + markdown.substring(end);\n selectionStart = selectionEnd = cursorOffsetStart;\n } else {\n // Fallback for non-toggleable, inline syntax\n newText =\n markdown.substring(0, start) +\n before +\n selectedText +\n after +\n markdown.substring(end);\n\n if (selectedText.length === 0) {\n // No text selected – place cursor between syntax\n selectionStart = start + before.length;\n selectionEnd = selectionStart;\n } else {\n // Keep selection\n selectionStart = start + before.length;\n selectionEnd = selectionStart + selectedText.length;\n }\n }\n\n return {\n newValue: newText,\n newSelectionStart: selectionStart,\n newSelectionEnd: selectionEnd,\n } as const;\n};\n"],"names":[],"mappings":"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"}
@@ -19,12 +19,15 @@ import { IconPlus } from '../Icon/components/icons/IconPlus.mjs';
19
19
  import { flowComponent } from '../../lib/componentFactory/flowComponent.mjs';
20
20
  import { ReactAriaControlledValueFix } from '../../lib/react/ReactAriaControlledValueFix.mjs';
21
21
  import { useFieldComponent } from '../../lib/hooks/useFieldComponent.mjs';
22
+ import { useMakeFocusable } from '../../lib/hooks/dom/useMakeFocusable.mjs';
23
+ import { useObjectRef } from '@react-aria/utils';
22
24
 
23
25
  const NumberField = flowComponent("NumberField", (props) => {
24
26
  const {
25
27
  children,
26
28
  className,
27
29
  ref,
30
+ inputRef,
28
31
  defaultValue,
29
32
  isWheelDisabled = true,
30
33
  ...rest
@@ -36,10 +39,16 @@ const NumberField = flowComponent("NumberField", (props) => {
36
39
  fieldPropsContext
37
40
  } = useFieldComponent(props);
38
41
  const rootClassName = clsx(formFieldStyles.formField, className);
42
+ const localNumberFieldRef = useObjectRef(ref);
43
+ const localNumberFieldInputRef = useObjectRef(inputRef);
44
+ useMakeFocusable(localNumberFieldRef, () => {
45
+ localNumberFieldInputRef?.current?.focus();
46
+ });
39
47
  return /* @__PURE__ */ jsxs(
40
48
  Aria.NumberField,
41
49
  {
42
50
  ...rest,
51
+ ref: localNumberFieldRef,
43
52
  isWheelDisabled,
44
53
  defaultValue,
45
54
  className: clsx(rootClassName, fieldProps.className),
@@ -66,9 +75,9 @@ const NumberField = flowComponent("NumberField", (props) => {
66
75
  /* @__PURE__ */ jsx(
67
76
  ReactAriaControlledValueFix,
68
77
  {
69
- inputContext: Aria.InputContext,
78
+ inputContext: Aria.NumberFieldContext,
70
79
  props,
71
- children: /* @__PURE__ */ jsx(Aria.Input, { className: styles.input, ref })
80
+ children: /* @__PURE__ */ jsx(Aria.Input, { className: styles.input, ref: localNumberFieldInputRef })
72
81
  }
73
82
  ),
74
83
  /* @__PURE__ */ jsxs(
@@ -1 +1 @@
1
- {"version":3,"file":"NumberField.mjs","sources":["../../../../../../src/components/NumberField/NumberField.tsx"],"sourcesContent":["import React, { type PropsWithChildren } from \"react\";\nimport * as Aria from \"react-aria-components\";\nimport formFieldStyles from \"../FormField/FormField.module.scss\";\nimport styles from \"./NumberField.module.scss\";\nimport clsx from \"clsx\";\nimport { PropsContextProvider } from \"@/lib/propsContext\";\nimport { Button } from \"@/components/Button\";\nimport {\n IconChevronDown,\n IconChevronUp,\n IconMinus,\n IconPlus,\n} from \"@/components/Icon/components/icons\";\nimport type { FlowComponentProps } from \"@/lib/componentFactory/flowComponent\";\nimport { flowComponent } from \"@/lib/componentFactory/flowComponent\";\nimport { ReactAriaControlledValueFix } from \"@/lib/react/ReactAriaControlledValueFix\";\nimport { useFieldComponent } from \"@/lib/hooks/useFieldComponent\";\n\nexport interface NumberFieldProps\n extends PropsWithChildren<Omit<Aria.NumberFieldProps, \"children\">>,\n FlowComponentProps<HTMLInputElement> {}\n\n/** @flr-generate all */\nexport const NumberField = flowComponent(\"NumberField\", (props) => {\n const {\n children,\n className,\n ref,\n defaultValue,\n isWheelDisabled = true,\n ...rest\n } = props;\n\n const {\n FieldErrorView,\n FieldErrorCaptureContext,\n fieldProps,\n fieldPropsContext,\n } = useFieldComponent(props);\n\n const rootClassName = clsx(formFieldStyles.formField, className);\n\n return (\n <Aria.NumberField\n {...rest}\n isWheelDisabled={isWheelDisabled}\n defaultValue={defaultValue}\n className={clsx(rootClassName, fieldProps.className)}\n >\n <PropsContextProvider props={fieldPropsContext}>\n <FieldErrorCaptureContext>{children}</FieldErrorCaptureContext>\n <FieldErrorView />\n </PropsContextProvider>\n <Aria.Group className={styles.group}>\n <Button\n ariaSlot=\"decrement\"\n className={styles.decrementButton}\n size=\"s\"\n variant=\"plain\"\n color=\"secondary\"\n >\n <IconChevronDown />\n <IconMinus className={styles.coarsePointerIcon} />\n </Button>\n <ReactAriaControlledValueFix\n inputContext={Aria.InputContext}\n props={props}\n >\n <Aria.Input className={styles.input} ref={ref} />\n </ReactAriaControlledValueFix>\n <Button\n ariaSlot=\"increment\"\n className={styles.incrementButton}\n size=\"s\"\n variant=\"plain\"\n color=\"secondary\"\n >\n <IconChevronUp />\n <IconPlus className={styles.coarsePointerIcon} />\n </Button>\n </Aria.Group>\n </Aria.NumberField>\n );\n});\n\nexport default NumberField;\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AAuBO,MAAM,WAAA,GAAc,aAAA,CAAc,aAAA,EAAe,CAAC,KAAA,KAAU;AACjE,EAAA,MAAM;AAAA,IACJ,QAAA;AAAA,IACA,SAAA;AAAA,IACA,GAAA;AAAA,IACA,YAAA;AAAA,IACA,eAAA,GAAkB,IAAA;AAAA,IAClB,GAAG;AAAA,GACL,GAAI,KAAA;AAEJ,EAAA,MAAM;AAAA,IACJ,cAAA;AAAA,IACA,wBAAA;AAAA,IACA,UAAA;AAAA,IACA;AAAA,GACF,GAAI,kBAAkB,KAAK,CAAA;AAE3B,EAAA,MAAM,aAAA,GAAgB,IAAA,CAAK,eAAA,CAAgB,SAAA,EAAW,SAAS,CAAA;AAE/D,EAAA,uBACE,IAAA;AAAA,IAAC,IAAA,CAAK,WAAA;AAAA,IAAL;AAAA,MACE,GAAG,IAAA;AAAA,MACJ,eAAA;AAAA,MACA,YAAA;AAAA,MACA,SAAA,EAAW,IAAA,CAAK,aAAA,EAAe,UAAA,CAAW,SAAS,CAAA;AAAA,MAEnD,QAAA,EAAA;AAAA,wBAAA,IAAA,CAAC,oBAAA,EAAA,EAAqB,OAAO,iBAAA,EAC3B,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,4BAA0B,QAAA,EAAS,CAAA;AAAA,8BACnC,cAAA,EAAA,EAAe;AAAA,SAAA,EAClB,CAAA;AAAA,6BACC,IAAA,CAAK,KAAA,EAAL,EAAW,SAAA,EAAW,OAAO,KAAA,EAC5B,QAAA,EAAA;AAAA,0BAAA,IAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,QAAA,EAAS,WAAA;AAAA,cACT,WAAW,MAAA,CAAO,eAAA;AAAA,cAClB,IAAA,EAAK,GAAA;AAAA,cACL,OAAA,EAAQ,OAAA;AAAA,cACR,KAAA,EAAM,WAAA;AAAA,cAEN,QAAA,EAAA;AAAA,gCAAA,GAAA,CAAC,eAAA,EAAA,EAAgB,CAAA;AAAA,gCACjB,GAAA,CAAC,SAAA,EAAA,EAAU,SAAA,EAAW,MAAA,CAAO,iBAAA,EAAmB;AAAA;AAAA;AAAA,WAClD;AAAA,0BACA,GAAA;AAAA,YAAC,2BAAA;AAAA,YAAA;AAAA,cACC,cAAc,IAAA,CAAK,YAAA;AAAA,cACnB,KAAA;AAAA,cAEA,8BAAC,IAAA,CAAK,KAAA,EAAL,EAAW,SAAA,EAAW,MAAA,CAAO,OAAO,GAAA,EAAU;AAAA;AAAA,WACjD;AAAA,0BACA,IAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,QAAA,EAAS,WAAA;AAAA,cACT,WAAW,MAAA,CAAO,eAAA;AAAA,cAClB,IAAA,EAAK,GAAA;AAAA,cACL,OAAA,EAAQ,OAAA;AAAA,cACR,KAAA,EAAM,WAAA;AAAA,cAEN,QAAA,EAAA;AAAA,gCAAA,GAAA,CAAC,aAAA,EAAA,EAAc,CAAA;AAAA,gCACf,GAAA,CAAC,QAAA,EAAA,EAAS,SAAA,EAAW,MAAA,CAAO,iBAAA,EAAmB;AAAA;AAAA;AAAA;AACjD,SAAA,EACF;AAAA;AAAA;AAAA,GACF;AAEJ,CAAC;;;;"}
1
+ {"version":3,"file":"NumberField.mjs","sources":["../../../../../../src/components/NumberField/NumberField.tsx"],"sourcesContent":["import React, { type PropsWithChildren, type RefObject } from \"react\";\nimport * as Aria from \"react-aria-components\";\nimport formFieldStyles from \"../FormField/FormField.module.scss\";\nimport styles from \"./NumberField.module.scss\";\nimport clsx from \"clsx\";\nimport { PropsContextProvider } from \"@/lib/propsContext\";\nimport { Button } from \"@/components/Button\";\nimport {\n IconChevronDown,\n IconChevronUp,\n IconMinus,\n IconPlus,\n} from \"@/components/Icon/components/icons\";\nimport type { FlowComponentProps } from \"@/lib/componentFactory/flowComponent\";\nimport { flowComponent } from \"@/lib/componentFactory/flowComponent\";\nimport { ReactAriaControlledValueFix } from \"@/lib/react/ReactAriaControlledValueFix\";\nimport { useFieldComponent } from \"@/lib/hooks/useFieldComponent\";\nimport { useMakeFocusable } from \"@/lib/hooks/dom/useMakeFocusable\";\nimport { useObjectRef } from \"@react-aria/utils\";\n\nexport interface NumberFieldProps\n extends PropsWithChildren<Omit<Aria.NumberFieldProps, \"children\">>,\n FlowComponentProps {\n inputRef?: RefObject<HTMLInputElement | null>;\n}\n\n/** @flr-generate all */\nexport const NumberField = flowComponent(\"NumberField\", (props) => {\n const {\n children,\n className,\n ref,\n inputRef,\n defaultValue,\n isWheelDisabled = true,\n ...rest\n } = props;\n\n const {\n FieldErrorView,\n FieldErrorCaptureContext,\n fieldProps,\n fieldPropsContext,\n } = useFieldComponent(props);\n\n const rootClassName = clsx(formFieldStyles.formField, className);\n\n const localNumberFieldRef = useObjectRef(ref);\n const localNumberFieldInputRef = useObjectRef(inputRef);\n\n useMakeFocusable(localNumberFieldRef, () => {\n localNumberFieldInputRef?.current?.focus();\n });\n\n return (\n <Aria.NumberField\n {...rest}\n ref={localNumberFieldRef}\n isWheelDisabled={isWheelDisabled}\n defaultValue={defaultValue}\n className={clsx(rootClassName, fieldProps.className)}\n >\n <PropsContextProvider props={fieldPropsContext}>\n <FieldErrorCaptureContext>{children}</FieldErrorCaptureContext>\n <FieldErrorView />\n </PropsContextProvider>\n <Aria.Group className={styles.group}>\n <Button\n ariaSlot=\"decrement\"\n className={styles.decrementButton}\n size=\"s\"\n variant=\"plain\"\n color=\"secondary\"\n >\n <IconChevronDown />\n <IconMinus className={styles.coarsePointerIcon} />\n </Button>\n <ReactAriaControlledValueFix\n inputContext={Aria.NumberFieldContext}\n props={props}\n >\n <Aria.Input className={styles.input} ref={localNumberFieldInputRef} />\n </ReactAriaControlledValueFix>\n <Button\n ariaSlot=\"increment\"\n className={styles.incrementButton}\n size=\"s\"\n variant=\"plain\"\n color=\"secondary\"\n >\n <IconChevronUp />\n <IconPlus className={styles.coarsePointerIcon} />\n </Button>\n </Aria.Group>\n </Aria.NumberField>\n );\n});\n\nexport default NumberField;\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AA2BO,MAAM,WAAA,GAAc,aAAA,CAAc,aAAA,EAAe,CAAC,KAAA,KAAU;AACjE,EAAA,MAAM;AAAA,IACJ,QAAA;AAAA,IACA,SAAA;AAAA,IACA,GAAA;AAAA,IACA,QAAA;AAAA,IACA,YAAA;AAAA,IACA,eAAA,GAAkB,IAAA;AAAA,IAClB,GAAG;AAAA,GACL,GAAI,KAAA;AAEJ,EAAA,MAAM;AAAA,IACJ,cAAA;AAAA,IACA,wBAAA;AAAA,IACA,UAAA;AAAA,IACA;AAAA,GACF,GAAI,kBAAkB,KAAK,CAAA;AAE3B,EAAA,MAAM,aAAA,GAAgB,IAAA,CAAK,eAAA,CAAgB,SAAA,EAAW,SAAS,CAAA;AAE/D,EAAA,MAAM,mBAAA,GAAsB,aAAa,GAAG,CAAA;AAC5C,EAAA,MAAM,wBAAA,GAA2B,aAAa,QAAQ,CAAA;AAEtD,EAAA,gBAAA,CAAiB,qBAAqB,MAAM;AAC1C,IAAA,wBAAA,EAA0B,SAAS,KAAA,EAAM;AAAA,EAC3C,CAAC,CAAA;AAED,EAAA,uBACE,IAAA;AAAA,IAAC,IAAA,CAAK,WAAA;AAAA,IAAL;AAAA,MACE,GAAG,IAAA;AAAA,MACJ,GAAA,EAAK,mBAAA;AAAA,MACL,eAAA;AAAA,MACA,YAAA;AAAA,MACA,SAAA,EAAW,IAAA,CAAK,aAAA,EAAe,UAAA,CAAW,SAAS,CAAA;AAAA,MAEnD,QAAA,EAAA;AAAA,wBAAA,IAAA,CAAC,oBAAA,EAAA,EAAqB,OAAO,iBAAA,EAC3B,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,4BAA0B,QAAA,EAAS,CAAA;AAAA,8BACnC,cAAA,EAAA,EAAe;AAAA,SAAA,EAClB,CAAA;AAAA,6BACC,IAAA,CAAK,KAAA,EAAL,EAAW,SAAA,EAAW,OAAO,KAAA,EAC5B,QAAA,EAAA;AAAA,0BAAA,IAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,QAAA,EAAS,WAAA;AAAA,cACT,WAAW,MAAA,CAAO,eAAA;AAAA,cAClB,IAAA,EAAK,GAAA;AAAA,cACL,OAAA,EAAQ,OAAA;AAAA,cACR,KAAA,EAAM,WAAA;AAAA,cAEN,QAAA,EAAA;AAAA,gCAAA,GAAA,CAAC,eAAA,EAAA,EAAgB,CAAA;AAAA,gCACjB,GAAA,CAAC,SAAA,EAAA,EAAU,SAAA,EAAW,MAAA,CAAO,iBAAA,EAAmB;AAAA;AAAA;AAAA,WAClD;AAAA,0BACA,GAAA;AAAA,YAAC,2BAAA;AAAA,YAAA;AAAA,cACC,cAAc,IAAA,CAAK,kBAAA;AAAA,cACnB,KAAA;AAAA,cAEA,QAAA,kBAAA,GAAA,CAAC,KAAK,KAAA,EAAL,EAAW,WAAW,MAAA,CAAO,KAAA,EAAO,KAAK,wBAAA,EAA0B;AAAA;AAAA,WACtE;AAAA,0BACA,IAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,QAAA,EAAS,WAAA;AAAA,cACT,WAAW,MAAA,CAAO,eAAA;AAAA,cAClB,IAAA,EAAK,GAAA;AAAA,cACL,OAAA,EAAQ,OAAA;AAAA,cACR,KAAA,EAAM,WAAA;AAAA,cAEN,QAAA,EAAA;AAAA,gCAAA,GAAA,CAAC,aAAA,EAAA,EAAc,CAAA;AAAA,gCACf,GAAA,CAAC,QAAA,EAAA,EAAS,SAAA,EAAW,MAAA,CAAO,iBAAA,EAAmB;AAAA;AAAA;AAAA;AACjD,SAAA,EACF;AAAA;AAAA;AAAA,GACF;AAEJ,CAAC;;;;"}
@@ -1,9 +1,9 @@
1
1
  "use client"
2
2
  /* */
3
3
  import { jsx } from 'react/jsx-runtime';
4
+ import 'react';
4
5
  import clsx from 'clsx';
5
6
  import 'mobx';
6
- import 'react';
7
7
  import { useOverlayController } from '../../lib/controller/overlay/useOverlayController.mjs';
8
8
  import { flowComponent } from '../../lib/componentFactory/flowComponent.mjs';
9
9
  import { OverlayContextProvider } from '../../lib/controller/overlay/OverlayContextProvider.mjs';
@@ -16,6 +16,7 @@ const Popover = flowComponent("Popover", (props) => {
16
16
  children,
17
17
  className,
18
18
  controller: controllerFromProps,
19
+ onOpenChange: onOpenChangeFromProps,
19
20
  defaultOpen = false,
20
21
  ref,
21
22
  ...contentProps
@@ -33,7 +34,13 @@ const Popover = flowComponent("Popover", (props) => {
33
34
  ...contentProps,
34
35
  className: rootClassName,
35
36
  isOpen,
36
- onOpenChange: (isOpen2) => controller.setOpen(isOpen2),
37
+ onOpenChange: (isOpen2) => {
38
+ if (!onOpenChangeFromProps) {
39
+ controller.setOpen(isOpen2);
40
+ } else {
41
+ onOpenChangeFromProps(isOpen2);
42
+ }
43
+ },
37
44
  ref,
38
45
  children: /* @__PURE__ */ jsx(OverlayContextProvider, { type: "Popover", controller, children })
39
46
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Popover.mjs","sources":["../../../../../../src/components/Popover/Popover.tsx"],"sourcesContent":["import type { PropsWithChildren } from \"react\";\nimport type * as Aria from \"react-aria-components\";\nimport clsx from \"clsx\";\nimport { type OverlayController, useOverlayController } from \"@/lib/controller\";\nimport {\n flowComponent,\n type FlowComponentProps,\n} from \"@/lib/componentFactory/flowComponent\";\nimport OverlayContextProvider from \"@/lib/controller/overlay/OverlayContextProvider\";\nimport styles from \"./Popover.module.scss\";\nimport PopoverContentView from \"@/views/PopoverContentView\";\nimport ClearPropsContextView from \"@/views/ClearPropsContextView\";\n\nexport interface PopoverProps\n extends PropsWithChildren<Omit<Aria.PopoverProps, \"children\">>,\n FlowComponentProps {\n /**\n * Whether the popover should display a tip, pointing towards the trigger\n * element.\n */\n withTip?: boolean;\n /** Whether the popover contains a dialog. */\n isDialogContent?: boolean;\n /** An overlay controller to control the popover state. */\n controller?: OverlayController;\n /** A fixed width for the popover. */\n width?: string | number;\n}\n\nexport const Popover = flowComponent(\"Popover\", (props) => {\n const {\n children,\n className,\n controller: controllerFromProps,\n defaultOpen = false,\n ref,\n ...contentProps\n } = props;\n\n const controllerFromContext = useOverlayController(\"Popover\", {\n reuseControllerFromContext: true,\n isDefaultOpen: defaultOpen,\n });\n\n const controller = controllerFromProps ?? controllerFromContext;\n const isOpen = controller.useIsOpen();\n\n const rootClassName = clsx(styles.popover, className);\n\n return (\n <ClearPropsContextView>\n <PopoverContentView\n {...contentProps}\n className={rootClassName}\n isOpen={isOpen}\n onOpenChange={(isOpen) => controller.setOpen(isOpen)}\n ref={ref}\n >\n <OverlayContextProvider type=\"Popover\" controller={controller}>\n {children}\n </OverlayContextProvider>\n </PopoverContentView>\n </ClearPropsContextView>\n );\n});\n\nexport default Popover;\n"],"names":["isOpen"],"mappings":";;;;;;;;;;;AA6BO,MAAM,OAAA,GAAU,aAAA,CAAc,SAAA,EAAW,CAAC,KAAA,KAAU;AACzD,EAAA,MAAM;AAAA,IACJ,QAAA;AAAA,IACA,SAAA;AAAA,IACA,UAAA,EAAY,mBAAA;AAAA,IACZ,WAAA,GAAc,KAAA;AAAA,IACd,GAAA;AAAA,IACA,GAAG;AAAA,GACL,GAAI,KAAA;AAEJ,EAAA,MAAM,qBAAA,GAAwB,qBAAqB,SAAA,EAAW;AAAA,IAC5D,0BAAA,EAA4B,IAAA;AAAA,IAC5B,aAAA,EAAe;AAAA,GAChB,CAAA;AAED,EAAA,MAAM,aAAa,mBAAA,IAAuB,qBAAA;AAC1C,EAAA,MAAM,MAAA,GAAS,WAAW,SAAA,EAAU;AAEpC,EAAA,MAAM,aAAA,GAAgB,IAAA,CAAK,MAAA,CAAO,OAAA,EAAS,SAAS,CAAA;AAEpD,EAAA,2BACG,qBAAA,EAAA,EACC,QAAA,kBAAA,GAAA;AAAA,IAAC,kBAAA;AAAA,IAAA;AAAA,MACE,GAAG,YAAA;AAAA,MACJ,SAAA,EAAW,aAAA;AAAA,MACX,MAAA;AAAA,MACA,YAAA,EAAc,CAACA,OAAAA,KAAW,UAAA,CAAW,QAAQA,OAAM,CAAA;AAAA,MACnD,GAAA;AAAA,MAEA,QAAA,kBAAA,GAAA,CAAC,sBAAA,EAAA,EAAuB,IAAA,EAAK,SAAA,EAAU,YACpC,QAAA,EACH;AAAA;AAAA,GACF,EACF,CAAA;AAEJ,CAAC;;;;"}
1
+ {"version":3,"file":"Popover.mjs","sources":["../../../../../../src/components/Popover/Popover.tsx"],"sourcesContent":["import { type PropsWithChildren } from \"react\";\nimport type * as Aria from \"react-aria-components\";\nimport clsx from \"clsx\";\nimport { type OverlayController, useOverlayController } from \"@/lib/controller\";\nimport {\n flowComponent,\n type FlowComponentProps,\n} from \"@/lib/componentFactory/flowComponent\";\nimport OverlayContextProvider from \"@/lib/controller/overlay/OverlayContextProvider\";\nimport styles from \"./Popover.module.scss\";\nimport PopoverContentView from \"@/views/PopoverContentView\";\nimport ClearPropsContextView from \"@/views/ClearPropsContextView\";\n\nexport interface PopoverProps\n extends PropsWithChildren<Omit<Aria.PopoverProps, \"children\">>,\n FlowComponentProps {\n /**\n * Whether the popover should display a tip, pointing towards the trigger\n * element.\n */\n withTip?: boolean;\n /** Whether the popover contains a dialog. */\n isDialogContent?: boolean;\n /** An overlay controller to control the popover state. */\n controller?: OverlayController;\n /** A fixed width for the popover. */\n width?: string | number;\n}\n\nexport const Popover = flowComponent(\"Popover\", (props) => {\n const {\n children,\n className,\n controller: controllerFromProps,\n onOpenChange: onOpenChangeFromProps,\n defaultOpen = false,\n ref,\n ...contentProps\n } = props;\n\n const controllerFromContext = useOverlayController(\"Popover\", {\n reuseControllerFromContext: true,\n isDefaultOpen: defaultOpen,\n });\n\n const controller = controllerFromProps ?? controllerFromContext;\n const isOpen = controller.useIsOpen();\n\n const rootClassName = clsx(styles.popover, className);\n\n return (\n <ClearPropsContextView>\n <PopoverContentView\n {...contentProps}\n className={rootClassName}\n isOpen={isOpen}\n onOpenChange={(isOpen) => {\n if (!onOpenChangeFromProps) {\n controller.setOpen(isOpen);\n } else {\n onOpenChangeFromProps(isOpen);\n }\n }}\n ref={ref}\n >\n <OverlayContextProvider type=\"Popover\" controller={controller}>\n {children}\n </OverlayContextProvider>\n </PopoverContentView>\n </ClearPropsContextView>\n );\n});\n\nexport default Popover;\n"],"names":["isOpen"],"mappings":";;;;;;;;;;;AA6BO,MAAM,OAAA,GAAU,aAAA,CAAc,SAAA,EAAW,CAAC,KAAA,KAAU;AACzD,EAAA,MAAM;AAAA,IACJ,QAAA;AAAA,IACA,SAAA;AAAA,IACA,UAAA,EAAY,mBAAA;AAAA,IACZ,YAAA,EAAc,qBAAA;AAAA,IACd,WAAA,GAAc,KAAA;AAAA,IACd,GAAA;AAAA,IACA,GAAG;AAAA,GACL,GAAI,KAAA;AAEJ,EAAA,MAAM,qBAAA,GAAwB,qBAAqB,SAAA,EAAW;AAAA,IAC5D,0BAAA,EAA4B,IAAA;AAAA,IAC5B,aAAA,EAAe;AAAA,GAChB,CAAA;AAED,EAAA,MAAM,aAAa,mBAAA,IAAuB,qBAAA;AAC1C,EAAA,MAAM,MAAA,GAAS,WAAW,SAAA,EAAU;AAEpC,EAAA,MAAM,aAAA,GAAgB,IAAA,CAAK,MAAA,CAAO,OAAA,EAAS,SAAS,CAAA;AAEpD,EAAA,2BACG,qBAAA,EAAA,EACC,QAAA,kBAAA,GAAA;AAAA,IAAC,kBAAA;AAAA,IAAA;AAAA,MACE,GAAG,YAAA;AAAA,MACJ,SAAA,EAAW,aAAA;AAAA,MACX,MAAA;AAAA,MACA,YAAA,EAAc,CAACA,OAAAA,KAAW;AACxB,QAAA,IAAI,CAAC,qBAAA,EAAuB;AAC1B,UAAA,UAAA,CAAW,QAAQA,OAAM,CAAA;AAAA,QAC3B,CAAA,MAAO;AACL,UAAA,qBAAA,CAAsBA,OAAM,CAAA;AAAA,QAC9B;AAAA,MACF,CAAA;AAAA,MACA,GAAA;AAAA,MAEA,QAAA,kBAAA,GAAA,CAAC,sBAAA,EAAA,EAAuB,IAAA,EAAK,SAAA,EAAU,YACpC,QAAA,EACH;AAAA;AAAA,GACF,EACF,CAAA;AAEJ,CAAC;;;;"}
@@ -49,7 +49,7 @@ const SearchField = flowComponent("SearchField", (props) => {
49
49
  /* @__PURE__ */ jsx(
50
50
  ReactAriaControlledValueFix,
51
51
  {
52
- inputContext: Aria.InputContext,
52
+ inputContext: Aria.SearchFieldContext,
53
53
  props,
54
54
  children: /* @__PURE__ */ jsx(
55
55
  Aria.Input,
@@ -1 +1 @@
1
- {"version":3,"file":"SearchField.mjs","sources":["../../../../../../src/components/SearchField/SearchField.tsx"],"sourcesContent":["import type { PropsWithChildren } from \"react\";\nimport * as Aria from \"react-aria-components\";\nimport formFieldStyles from \"../FormField/FormField.module.scss\";\nimport styles from \"./SearchField.module.scss\";\nimport clsx from \"clsx\";\nimport { PropsContextProvider } from \"@/lib/propsContext\";\nimport type { FlowComponentProps } from \"@/lib/componentFactory/flowComponent\";\nimport { flowComponent } from \"@/lib/componentFactory/flowComponent\";\nimport { Button } from \"@/components/Button\";\nimport { IconClose, IconSearch } from \"@/components/Icon/components/icons\";\nimport locales from \"./locales/*.locale.json\";\nimport { useLocalizedStringFormatter } from \"react-aria\";\nimport { ReactAriaControlledValueFix } from \"@/lib/react/ReactAriaControlledValueFix\";\nimport { useFieldComponent } from \"@/lib/hooks/useFieldComponent\";\n\nexport interface SearchFieldProps\n extends PropsWithChildren<Omit<Aria.SearchFieldProps, \"children\">>,\n FlowComponentProps<HTMLInputElement> {}\n\n/** @flr-generate all */\nexport const SearchField = flowComponent(\"SearchField\", (props) => {\n const { children, className, ref, ...rest } = props;\n\n const {\n FieldErrorView,\n FieldErrorCaptureContext,\n fieldProps,\n fieldPropsContext,\n } = useFieldComponent(props);\n\n const rootClassName = clsx(\n formFieldStyles.formField,\n styles.searchField,\n className,\n );\n\n const stringFormatter = useLocalizedStringFormatter(locales);\n const searchText = stringFormatter.format(`searchField.search`);\n\n return (\n <Aria.SearchField\n {...rest}\n {...fieldProps}\n aria-label={searchText}\n className={clsx(rootClassName, fieldProps.className)}\n >\n <PropsContextProvider props={fieldPropsContext}>\n <FieldErrorCaptureContext>{children}</FieldErrorCaptureContext>\n </PropsContextProvider>\n <div className={styles.inputContainer}>\n <IconSearch className={styles.searchIcon} />\n <ReactAriaControlledValueFix\n inputContext={Aria.InputContext}\n props={props}\n >\n <Aria.Input\n placeholder={searchText}\n className={styles.input}\n ref={ref}\n />\n </ReactAriaControlledValueFix>\n <Button\n className={styles.clearButton}\n variant=\"plain\"\n color=\"secondary\"\n >\n <IconClose />\n </Button>\n </div>\n <FieldErrorView />\n </Aria.SearchField>\n );\n});\n\nexport default SearchField;\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AAoBO,MAAM,WAAA,GAAc,aAAA,CAAc,aAAA,EAAe,CAAC,KAAA,KAAU;AACjE,EAAA,MAAM,EAAE,QAAA,EAAU,SAAA,EAAW,GAAA,EAAK,GAAG,MAAK,GAAI,KAAA;AAE9C,EAAA,MAAM;AAAA,IACJ,cAAA;AAAA,IACA,wBAAA;AAAA,IACA,UAAA;AAAA,IACA;AAAA,GACF,GAAI,kBAAkB,KAAK,CAAA;AAE3B,EAAA,MAAM,aAAA,GAAgB,IAAA;AAAA,IACpB,eAAA,CAAgB,SAAA;AAAA,IAChB,MAAA,CAAO,WAAA;AAAA,IACP;AAAA,GACF;AAEA,EAAA,MAAM,eAAA,GAAkB,4BAA4B,OAAO,CAAA;AAC3D,EAAA,MAAM,UAAA,GAAa,eAAA,CAAgB,MAAA,CAAO,CAAA,kBAAA,CAAoB,CAAA;AAE9D,EAAA,uBACE,IAAA;AAAA,IAAC,IAAA,CAAK,WAAA;AAAA,IAAL;AAAA,MACE,GAAG,IAAA;AAAA,MACH,GAAG,UAAA;AAAA,MACJ,YAAA,EAAY,UAAA;AAAA,MACZ,SAAA,EAAW,IAAA,CAAK,aAAA,EAAe,UAAA,CAAW,SAAS,CAAA;AAAA,MAEnD,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,wBAAqB,KAAA,EAAO,iBAAA,EAC3B,QAAA,kBAAA,GAAA,CAAC,wBAAA,EAAA,EAA0B,UAAS,CAAA,EACtC,CAAA;AAAA,wBACA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,MAAA,CAAO,cAAA,EACrB,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,UAAA,EAAA,EAAW,SAAA,EAAW,MAAA,CAAO,UAAA,EAAY,CAAA;AAAA,0BAC1C,GAAA;AAAA,YAAC,2BAAA;AAAA,YAAA;AAAA,cACC,cAAc,IAAA,CAAK,YAAA;AAAA,cACnB,KAAA;AAAA,cAEA,QAAA,kBAAA,GAAA;AAAA,gBAAC,IAAA,CAAK,KAAA;AAAA,gBAAL;AAAA,kBACC,WAAA,EAAa,UAAA;AAAA,kBACb,WAAW,MAAA,CAAO,KAAA;AAAA,kBAClB;AAAA;AAAA;AACF;AAAA,WACF;AAAA,0BACA,GAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,WAAW,MAAA,CAAO,WAAA;AAAA,cAClB,OAAA,EAAQ,OAAA;AAAA,cACR,KAAA,EAAM,WAAA;AAAA,cAEN,8BAAC,SAAA,EAAA,EAAU;AAAA;AAAA;AACb,SAAA,EACF,CAAA;AAAA,4BACC,cAAA,EAAA,EAAe;AAAA;AAAA;AAAA,GAClB;AAEJ,CAAC;;;;"}
1
+ {"version":3,"file":"SearchField.mjs","sources":["../../../../../../src/components/SearchField/SearchField.tsx"],"sourcesContent":["import type { PropsWithChildren } from \"react\";\nimport * as Aria from \"react-aria-components\";\nimport formFieldStyles from \"../FormField/FormField.module.scss\";\nimport styles from \"./SearchField.module.scss\";\nimport clsx from \"clsx\";\nimport { PropsContextProvider } from \"@/lib/propsContext\";\nimport type { FlowComponentProps } from \"@/lib/componentFactory/flowComponent\";\nimport { flowComponent } from \"@/lib/componentFactory/flowComponent\";\nimport { Button } from \"@/components/Button\";\nimport { IconClose, IconSearch } from \"@/components/Icon/components/icons\";\nimport locales from \"./locales/*.locale.json\";\nimport { useLocalizedStringFormatter } from \"react-aria\";\nimport { ReactAriaControlledValueFix } from \"@/lib/react/ReactAriaControlledValueFix\";\nimport { useFieldComponent } from \"@/lib/hooks/useFieldComponent\";\n\nexport interface SearchFieldProps\n extends PropsWithChildren<Omit<Aria.SearchFieldProps, \"children\">>,\n FlowComponentProps<HTMLInputElement> {}\n\n/** @flr-generate all */\nexport const SearchField = flowComponent(\"SearchField\", (props) => {\n const { children, className, ref, ...rest } = props;\n\n const {\n FieldErrorView,\n FieldErrorCaptureContext,\n fieldProps,\n fieldPropsContext,\n } = useFieldComponent(props);\n\n const rootClassName = clsx(\n formFieldStyles.formField,\n styles.searchField,\n className,\n );\n\n const stringFormatter = useLocalizedStringFormatter(locales);\n const searchText = stringFormatter.format(`searchField.search`);\n\n return (\n <Aria.SearchField\n {...rest}\n {...fieldProps}\n aria-label={searchText}\n className={clsx(rootClassName, fieldProps.className)}\n >\n <PropsContextProvider props={fieldPropsContext}>\n <FieldErrorCaptureContext>{children}</FieldErrorCaptureContext>\n </PropsContextProvider>\n <div className={styles.inputContainer}>\n <IconSearch className={styles.searchIcon} />\n <ReactAriaControlledValueFix\n inputContext={Aria.SearchFieldContext}\n props={props}\n >\n <Aria.Input\n placeholder={searchText}\n className={styles.input}\n ref={ref}\n />\n </ReactAriaControlledValueFix>\n <Button\n className={styles.clearButton}\n variant=\"plain\"\n color=\"secondary\"\n >\n <IconClose />\n </Button>\n </div>\n <FieldErrorView />\n </Aria.SearchField>\n );\n});\n\nexport default SearchField;\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AAoBO,MAAM,WAAA,GAAc,aAAA,CAAc,aAAA,EAAe,CAAC,KAAA,KAAU;AACjE,EAAA,MAAM,EAAE,QAAA,EAAU,SAAA,EAAW,GAAA,EAAK,GAAG,MAAK,GAAI,KAAA;AAE9C,EAAA,MAAM;AAAA,IACJ,cAAA;AAAA,IACA,wBAAA;AAAA,IACA,UAAA;AAAA,IACA;AAAA,GACF,GAAI,kBAAkB,KAAK,CAAA;AAE3B,EAAA,MAAM,aAAA,GAAgB,IAAA;AAAA,IACpB,eAAA,CAAgB,SAAA;AAAA,IAChB,MAAA,CAAO,WAAA;AAAA,IACP;AAAA,GACF;AAEA,EAAA,MAAM,eAAA,GAAkB,4BAA4B,OAAO,CAAA;AAC3D,EAAA,MAAM,UAAA,GAAa,eAAA,CAAgB,MAAA,CAAO,CAAA,kBAAA,CAAoB,CAAA;AAE9D,EAAA,uBACE,IAAA;AAAA,IAAC,IAAA,CAAK,WAAA;AAAA,IAAL;AAAA,MACE,GAAG,IAAA;AAAA,MACH,GAAG,UAAA;AAAA,MACJ,YAAA,EAAY,UAAA;AAAA,MACZ,SAAA,EAAW,IAAA,CAAK,aAAA,EAAe,UAAA,CAAW,SAAS,CAAA;AAAA,MAEnD,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,wBAAqB,KAAA,EAAO,iBAAA,EAC3B,QAAA,kBAAA,GAAA,CAAC,wBAAA,EAAA,EAA0B,UAAS,CAAA,EACtC,CAAA;AAAA,wBACA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,MAAA,CAAO,cAAA,EACrB,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,UAAA,EAAA,EAAW,SAAA,EAAW,MAAA,CAAO,UAAA,EAAY,CAAA;AAAA,0BAC1C,GAAA;AAAA,YAAC,2BAAA;AAAA,YAAA;AAAA,cACC,cAAc,IAAA,CAAK,kBAAA;AAAA,cACnB,KAAA;AAAA,cAEA,QAAA,kBAAA,GAAA;AAAA,gBAAC,IAAA,CAAK,KAAA;AAAA,gBAAL;AAAA,kBACC,WAAA,EAAa,UAAA;AAAA,kBACb,WAAW,MAAA,CAAO,KAAA;AAAA,kBAClB;AAAA;AAAA;AACF;AAAA,WACF;AAAA,0BACA,GAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,WAAW,MAAA,CAAO,WAAA;AAAA,cAClB,OAAA,EAAQ,OAAA;AAAA,cACR,KAAA,EAAM,WAAA;AAAA,cAEN,8BAAC,SAAA,EAAA,EAAU;AAAA;AAAA;AACb,SAAA,EACF,CAAA;AAAA,4BACC,cAAA,EAAA,EAAe;AAAA;AAAA;AAAA,GAClB;AAEJ,CAAC;;;;"}