@mittwald/flow-react-components 0.2.0-alpha.551 → 0.2.0-alpha.553
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.
- package/CHANGELOG.md +8 -0
- package/dist/assets/doc-properties.json +37652 -32936
- package/dist/css/all.css +1 -1
- package/dist/js/_virtual/_.locale.json@bb0db7b5021f874310cbe5b6cc3d9cac.mjs +2 -2
- package/dist/js/components/src/components/Action/Action.mjs +1 -0
- package/dist/js/components/src/components/Action/Action.mjs.map +1 -1
- package/dist/js/components/src/components/Action/models/ActionState.mjs +1 -1
- package/dist/js/components/src/components/Action/models/ActionState.mjs.map +1 -1
- package/dist/js/components/src/components/Autocomplete/Autocomplete.mjs +1 -1
- package/dist/js/components/src/components/Autocomplete/Autocomplete.mjs.map +1 -1
- package/dist/js/components/src/components/Button/Button.mjs +1 -1
- package/dist/js/components/src/components/Button/Button.mjs.map +1 -1
- package/dist/js/components/src/components/CartesianChart/CartesianChart.mjs +120 -25
- package/dist/js/components/src/components/CartesianChart/CartesianChart.mjs.map +1 -1
- package/dist/js/components/src/components/CartesianChart/components/Area/Area.mjs +5 -11
- package/dist/js/components/src/components/CartesianChart/components/Area/Area.mjs.map +1 -1
- package/dist/js/components/src/components/CartesianChart/components/YAxis/YAxis.mjs +1 -1
- package/dist/js/components/src/components/CartesianChart/components/YAxis/YAxis.mjs.map +1 -1
- package/dist/js/components/src/components/Checkbox/Checkbox.mjs +18 -6
- package/dist/js/components/src/components/Checkbox/Checkbox.mjs.map +1 -1
- package/dist/js/components/src/components/CheckboxButton/CheckboxButton.mjs +15 -3
- package/dist/js/components/src/components/CheckboxButton/CheckboxButton.mjs.map +1 -1
- package/dist/js/components/src/components/ComboBox/ComboBox.mjs +25 -4
- package/dist/js/components/src/components/ComboBox/ComboBox.mjs.map +1 -1
- package/dist/js/components/src/components/FileField/FileField.mjs +7 -3
- package/dist/js/components/src/components/FileField/FileField.mjs.map +1 -1
- package/dist/js/components/src/components/Markdown/Markdown.mjs +2 -1
- package/dist/js/components/src/components/Markdown/Markdown.mjs.map +1 -1
- package/dist/js/components/src/components/MarkdownEditor/MarkdownEditor.mjs +107 -45
- package/dist/js/components/src/components/MarkdownEditor/MarkdownEditor.mjs.map +1 -1
- package/dist/js/components/src/components/MarkdownEditor/MarkdownEditor.module.scss.mjs +3 -3
- package/dist/js/components/src/components/MarkdownEditor/components/ToolbarButton.mjs +1 -0
- package/dist/js/components/src/components/MarkdownEditor/components/ToolbarButton.mjs.map +1 -1
- package/dist/js/components/src/components/MarkdownEditor/lib/{handleKeyDown.mjs → modifyValueByMarkdownSyntax.mjs} +20 -29
- package/dist/js/components/src/components/MarkdownEditor/lib/modifyValueByMarkdownSyntax.mjs.map +1 -0
- package/dist/js/components/src/components/MarkdownEditor/lib/{insertAtCursor.mjs → modifyValueByType.mjs} +17 -11
- package/dist/js/components/src/components/MarkdownEditor/lib/modifyValueByType.mjs.map +1 -0
- package/dist/js/components/src/components/NumberField/NumberField.mjs +11 -2
- package/dist/js/components/src/components/NumberField/NumberField.mjs.map +1 -1
- package/dist/js/components/src/components/Popover/Popover.mjs +9 -2
- package/dist/js/components/src/components/Popover/Popover.mjs.map +1 -1
- package/dist/js/components/src/components/SearchField/SearchField.mjs +1 -1
- package/dist/js/components/src/components/SearchField/SearchField.mjs.map +1 -1
- package/dist/js/components/src/components/Select/Select.mjs +9 -9
- package/dist/js/components/src/components/Select/Select.mjs.map +1 -1
- package/dist/js/components/src/components/TextArea/TextArea.mjs +10 -5
- package/dist/js/components/src/components/TextArea/TextArea.mjs.map +1 -1
- package/dist/js/components/src/components/TextField/TextField.mjs +9 -2
- package/dist/js/components/src/components/TextField/TextField.mjs.map +1 -1
- package/dist/js/components/src/components/propTypes/index.mjs +2 -0
- package/dist/js/components/src/components/propTypes/index.mjs.map +1 -1
- package/dist/js/components/src/integrations/react-hook-form/components/Field/Field.mjs +14 -0
- package/dist/js/components/src/integrations/react-hook-form/components/Field/Field.mjs.map +1 -1
- package/dist/js/components/src/integrations/react-hook-form/components/Form/Form.mjs +22 -11
- package/dist/js/components/src/integrations/react-hook-form/components/Form/Form.mjs.map +1 -1
- package/dist/js/components/src/integrations/react-hook-form/components/Form/lib/useRegisterActionStateContext.mjs +2 -1
- package/dist/js/components/src/integrations/react-hook-form/components/Form/lib/useRegisterActionStateContext.mjs.map +1 -1
- package/dist/js/components/src/integrations/react-hook-form/components/ResetButton/ResetButton.mjs +51 -0
- package/dist/js/components/src/integrations/react-hook-form/components/ResetButton/ResetButton.mjs.map +1 -0
- package/dist/js/components/src/integrations/react-hook-form/components/SubmitButton/SubmitButton.mjs +57 -0
- package/dist/js/components/src/integrations/react-hook-form/components/SubmitButton/SubmitButton.mjs.map +1 -0
- package/dist/js/components/src/integrations/react-hook-form/components/context/formContext.mjs.map +1 -1
- package/dist/js/components/src/lib/react/ReactAriaControlledValueFix.mjs +18 -10
- package/dist/js/components/src/lib/react/ReactAriaControlledValueFix.mjs.map +1 -1
- package/dist/js/react-hook-form.mjs +2 -0
- package/dist/js/react-hook-form.mjs.map +1 -1
- package/dist/types/components/Action/Action.d.ts.map +1 -1
- package/dist/types/components/Action/models/ActionState.d.ts +5 -0
- package/dist/types/components/Action/models/ActionState.d.ts.map +1 -1
- package/dist/types/components/CartesianChart/CartesianChart.d.ts +4 -4
- package/dist/types/components/CartesianChart/CartesianChart.d.ts.map +1 -1
- package/dist/types/components/CartesianChart/components/Area/Area.d.ts.map +1 -1
- package/dist/types/components/Checkbox/Checkbox.d.ts +2 -1
- package/dist/types/components/Checkbox/Checkbox.d.ts.map +1 -1
- package/dist/types/components/CheckboxButton/CheckboxButton.d.ts +2 -0
- package/dist/types/components/CheckboxButton/CheckboxButton.d.ts.map +1 -1
- package/dist/types/components/ComboBox/ComboBox.d.ts +2 -1
- package/dist/types/components/ComboBox/ComboBox.d.ts.map +1 -1
- package/dist/types/components/FileField/FileField.d.ts +2 -1
- package/dist/types/components/FileField/FileField.d.ts.map +1 -1
- package/dist/types/components/List/typedList.d.ts +1 -1
- package/dist/types/components/Markdown/Markdown.d.ts +2 -1
- package/dist/types/components/Markdown/Markdown.d.ts.map +1 -1
- package/dist/types/components/MarkdownEditor/MarkdownEditor.d.ts +7 -3
- package/dist/types/components/MarkdownEditor/MarkdownEditor.d.ts.map +1 -1
- package/dist/types/components/MarkdownEditor/MarkdownEditor.test.d.ts +2 -0
- package/dist/types/components/MarkdownEditor/MarkdownEditor.test.d.ts.map +1 -0
- package/dist/types/components/MarkdownEditor/components/ToolbarButton.d.ts +1 -1
- package/dist/types/components/MarkdownEditor/components/ToolbarButton.d.ts.map +1 -1
- package/dist/types/components/MarkdownEditor/lib/modifyValueByMarkdownSyntax.d.ts +8 -0
- package/dist/types/components/MarkdownEditor/lib/modifyValueByMarkdownSyntax.d.ts.map +1 -0
- package/dist/types/components/MarkdownEditor/lib/modifyValueByMarkdownSyntax.test.d.ts +2 -0
- package/dist/types/components/MarkdownEditor/lib/modifyValueByMarkdownSyntax.test.d.ts.map +1 -0
- package/dist/types/components/MarkdownEditor/lib/modifyValueByType.d.ts +12 -0
- package/dist/types/components/MarkdownEditor/lib/modifyValueByType.d.ts.map +1 -0
- package/dist/types/components/MarkdownEditor/lib/modifyValueByType.test.d.ts +2 -0
- package/dist/types/components/MarkdownEditor/lib/modifyValueByType.test.d.ts.map +1 -0
- package/dist/types/components/NumberField/NumberField.d.ts +4 -3
- package/dist/types/components/NumberField/NumberField.d.ts.map +1 -1
- package/dist/types/components/Popover/Popover.d.ts.map +1 -1
- package/dist/types/components/Select/Select.d.ts.map +1 -1
- package/dist/types/components/TextArea/TextArea.d.ts +4 -7
- package/dist/types/components/TextArea/TextArea.d.ts.map +1 -1
- package/dist/types/components/TextField/TextField.d.ts.map +1 -1
- package/dist/types/components/propTypes/index.d.ts +4 -0
- package/dist/types/components/propTypes/index.d.ts.map +1 -1
- package/dist/types/integrations/react-hook-form/components/Field/Field.d.ts.map +1 -1
- package/dist/types/integrations/react-hook-form/components/Field/stories/Autocomplete.stories.d.ts.map +1 -1
- package/dist/types/integrations/react-hook-form/components/Field/stories/Checkbox.stories.d.ts.map +1 -1
- package/dist/types/integrations/react-hook-form/components/Field/stories/CheckboxButton.stories.d.ts.map +1 -1
- package/dist/types/integrations/react-hook-form/components/Field/stories/CheckboxGroup.stories.d.ts.map +1 -1
- package/dist/types/integrations/react-hook-form/components/Field/stories/ComboBox.stories.d.ts.map +1 -1
- package/dist/types/integrations/react-hook-form/components/Field/stories/DatePicker.stories.d.ts.map +1 -1
- package/dist/types/integrations/react-hook-form/components/Field/stories/DateRangePicker.stories.d.ts.map +1 -1
- package/dist/types/integrations/react-hook-form/components/Field/stories/FileField.stories.d.ts.map +1 -1
- package/dist/types/integrations/react-hook-form/components/Field/stories/MarkdownEditor.stories.d.ts.map +1 -1
- package/dist/types/integrations/react-hook-form/components/Field/stories/NumberField.stories.d.ts.map +1 -1
- package/dist/types/integrations/react-hook-form/components/Field/stories/PasswordCreationField.stories.d.ts.map +1 -1
- package/dist/types/integrations/react-hook-form/components/Field/stories/RadioGroup.stories.d.ts.map +1 -1
- package/dist/types/integrations/react-hook-form/components/Field/stories/SearchField.stories.d.ts.map +1 -1
- package/dist/types/integrations/react-hook-form/components/Field/stories/SegmentedControl.stories.d.ts.map +1 -1
- package/dist/types/integrations/react-hook-form/components/Field/stories/Select.stories.d.ts.map +1 -1
- package/dist/types/integrations/react-hook-form/components/Field/stories/Slider.stories.d.ts.map +1 -1
- package/dist/types/integrations/react-hook-form/components/Field/stories/Switch.stories.d.ts.map +1 -1
- package/dist/types/integrations/react-hook-form/components/Field/stories/TextArea.stories.d.ts.map +1 -1
- package/dist/types/integrations/react-hook-form/components/Field/stories/TextField.stories.d.ts.map +1 -1
- package/dist/types/integrations/react-hook-form/components/Field/stories/TimeField.stories.d.ts.map +1 -1
- package/dist/types/integrations/react-hook-form/components/Form/Form.d.ts +4 -3
- package/dist/types/integrations/react-hook-form/components/Form/Form.d.ts.map +1 -1
- package/dist/types/integrations/react-hook-form/components/Form/lib/useRegisterActionStateContext.d.ts +1 -0
- package/dist/types/integrations/react-hook-form/components/Form/lib/useRegisterActionStateContext.d.ts.map +1 -1
- package/dist/types/integrations/react-hook-form/components/ResetButton/ResetButton.d.ts +10 -0
- package/dist/types/integrations/react-hook-form/components/ResetButton/ResetButton.d.ts.map +1 -0
- package/dist/types/integrations/react-hook-form/components/ResetButton/ResetButton.test.d.ts +2 -0
- package/dist/types/integrations/react-hook-form/components/ResetButton/ResetButton.test.d.ts.map +1 -0
- package/dist/types/integrations/react-hook-form/components/ResetButton/index.d.ts +3 -0
- package/dist/types/integrations/react-hook-form/components/ResetButton/index.d.ts.map +1 -0
- package/dist/types/integrations/react-hook-form/components/SubmitButton/SubmitButton.d.ts +10 -0
- package/dist/types/integrations/react-hook-form/components/SubmitButton/SubmitButton.d.ts.map +1 -0
- package/dist/types/integrations/react-hook-form/components/SubmitButton/SubmitButton.test.d.ts +2 -0
- package/dist/types/integrations/react-hook-form/components/SubmitButton/SubmitButton.test.d.ts.map +1 -0
- package/dist/types/integrations/react-hook-form/components/SubmitButton/index.d.ts +3 -0
- package/dist/types/integrations/react-hook-form/components/SubmitButton/index.d.ts.map +1 -0
- package/dist/types/integrations/react-hook-form/components/context/formContext.d.ts +6 -2
- package/dist/types/integrations/react-hook-form/components/context/formContext.d.ts.map +1 -1
- package/dist/types/integrations/react-hook-form/index.d.ts +2 -0
- package/dist/types/integrations/react-hook-form/index.d.ts.map +1 -1
- package/dist/types/lib/dev/vitest.d.ts +3 -0
- package/dist/types/lib/dev/vitest.d.ts.map +1 -0
- package/dist/types/lib/propsContext/nestedPropsContext/lib.d.ts +2 -0
- package/dist/types/lib/propsContext/nestedPropsContext/lib.d.ts.map +1 -1
- package/dist/types/lib/react/ReactAriaControlledValueFix.d.ts.map +1 -1
- package/package.json +6 -5
- package/dist/js/components/src/components/MarkdownEditor/lib/handleKeyDown.mjs.map +0 -1
- package/dist/js/components/src/components/MarkdownEditor/lib/insertAtCursor.mjs.map +0 -1
- package/dist/types/components/MarkdownEditor/lib/handleKeyDown.d.ts +0 -3
- package/dist/types/components/MarkdownEditor/lib/handleKeyDown.d.ts.map +0 -1
- package/dist/types/components/MarkdownEditor/lib/handleKeyDown.test.d.ts +0 -2
- package/dist/types/components/MarkdownEditor/lib/handleKeyDown.test.d.ts.map +0 -1
- package/dist/types/components/MarkdownEditor/lib/insertAtCursor.d.ts +0 -4
- package/dist/types/components/MarkdownEditor/lib/insertAtCursor.d.ts.map +0 -1
- package/dist/types/components/MarkdownEditor/lib/insertAtCursor.test.d.ts +0 -2
- package/dist/types/components/MarkdownEditor/lib/insertAtCursor.test.d.ts.map +0 -1
- package/dist/types/lib/dev/vitestUserEvent.d.ts +0 -3
- package/dist/types/lib/dev/vitestUserEvent.d.ts.map +0 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use client"
|
|
2
2
|
/* */
|
|
3
3
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
4
|
+
import 'react';
|
|
4
5
|
import * as Aria from 'react-aria-components';
|
|
5
6
|
import { TunnelProvider, TunnelExit } from '@mittwald/react-tunnel';
|
|
6
7
|
import { Button } from '../Button/Button.mjs';
|
|
7
|
-
import 'react';
|
|
8
8
|
import '@tabler/icons-react';
|
|
9
9
|
import '../Icon/Icon.mjs';
|
|
10
10
|
import '../../views/IconView.mjs';
|
|
@@ -22,6 +22,7 @@ import { useOverlayController } from '../../lib/controller/overlay/useOverlayCon
|
|
|
22
22
|
import { useObjectRef } from '@react-aria/utils';
|
|
23
23
|
import { useMakeFocusable } from '../../lib/hooks/dom/useMakeFocusable.mjs';
|
|
24
24
|
import { useFieldComponent } from '../../lib/hooks/useFieldComponent.mjs';
|
|
25
|
+
import { ReactAriaControlledValueFix } from '../../lib/react/ReactAriaControlledValueFix.mjs';
|
|
25
26
|
|
|
26
27
|
const ComboBox = flowComponent("ComboBox", (props) => {
|
|
27
28
|
const {
|
|
@@ -35,6 +36,7 @@ const ComboBox = flowComponent("ComboBox", (props) => {
|
|
|
35
36
|
controller: controllerFromProps,
|
|
36
37
|
placeholder,
|
|
37
38
|
ref,
|
|
39
|
+
inputRef,
|
|
38
40
|
renderEmptyState,
|
|
39
41
|
...rest
|
|
40
42
|
} = props;
|
|
@@ -64,7 +66,10 @@ const ComboBox = flowComponent("ComboBox", (props) => {
|
|
|
64
66
|
});
|
|
65
67
|
const controller = controllerFromProps ?? controllerFromContext;
|
|
66
68
|
const localComboBoxRef = useObjectRef(ref);
|
|
67
|
-
|
|
69
|
+
const localInputComboBoxRef = useObjectRef(inputRef);
|
|
70
|
+
useMakeFocusable(localComboBoxRef, () => {
|
|
71
|
+
localInputComboBoxRef.current?.focus();
|
|
72
|
+
});
|
|
68
73
|
return /* @__PURE__ */ jsx(
|
|
69
74
|
Aria.ComboBox,
|
|
70
75
|
{
|
|
@@ -74,11 +79,26 @@ const ComboBox = flowComponent("ComboBox", (props) => {
|
|
|
74
79
|
...rest,
|
|
75
80
|
ref: localComboBoxRef,
|
|
76
81
|
onSelectionChange: handleOnSelectionChange,
|
|
77
|
-
onOpenChange: (isOpen) =>
|
|
82
|
+
onOpenChange: (isOpen) => {
|
|
83
|
+
controller.setOpen(isOpen);
|
|
84
|
+
},
|
|
78
85
|
children: /* @__PURE__ */ jsx(PropsContextProvider, { props: propsContext, children: /* @__PURE__ */ jsxs(TunnelProvider, { children: [
|
|
79
86
|
/* @__PURE__ */ jsxs(FieldErrorCaptureContext, { children: [
|
|
80
87
|
/* @__PURE__ */ jsxs("div", { className: styles.input, children: [
|
|
81
|
-
/* @__PURE__ */ jsx(
|
|
88
|
+
/* @__PURE__ */ jsx(
|
|
89
|
+
ReactAriaControlledValueFix,
|
|
90
|
+
{
|
|
91
|
+
inputContext: Aria.ComboBoxContext,
|
|
92
|
+
props,
|
|
93
|
+
children: /* @__PURE__ */ jsx(
|
|
94
|
+
Aria.Input,
|
|
95
|
+
{
|
|
96
|
+
placeholder,
|
|
97
|
+
ref: localInputComboBoxRef
|
|
98
|
+
}
|
|
99
|
+
)
|
|
100
|
+
}
|
|
101
|
+
),
|
|
82
102
|
/* @__PURE__ */ jsx(
|
|
83
103
|
Button,
|
|
84
104
|
{
|
|
@@ -95,6 +115,7 @@ const ComboBox = flowComponent("ComboBox", (props) => {
|
|
|
95
115
|
Options,
|
|
96
116
|
{
|
|
97
117
|
controller,
|
|
118
|
+
onOpenChange: () => null,
|
|
98
119
|
renderEmptyState,
|
|
99
120
|
children: /* @__PURE__ */ jsx(TunnelExit, { id: "options" })
|
|
100
121
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ComboBox.mjs","sources":["../../../../../../src/components/ComboBox/ComboBox.tsx"],"sourcesContent":["import type
|
|
1
|
+
{"version":3,"file":"ComboBox.mjs","sources":["../../../../../../src/components/ComboBox/ComboBox.tsx"],"sourcesContent":["import { type PropsWithChildren, type RefObject } from \"react\";\nimport type { Key } from \"react-aria-components\";\nimport * as Aria from \"react-aria-components\";\nimport { TunnelExit, TunnelProvider } from \"@mittwald/react-tunnel\";\nimport { Button } from \"@/components/Button\";\nimport { IconChevronDown } from \"@/components/Icon/components/icons\";\nimport { Options } from \"@/components/Options\";\nimport type { PropsContext } from \"@/lib/propsContext\";\nimport { PropsContextProvider } from \"@/lib/propsContext\";\nimport clsx from \"clsx\";\nimport styles from \"./ComboBox.module.scss\";\nimport locales from \"./locales/*.locale.json\";\nimport { useLocalizedStringFormatter } from \"react-aria\";\nimport type { FlowComponentProps } from \"@/lib/componentFactory/flowComponent\";\nimport { flowComponent } from \"@/lib/componentFactory/flowComponent\";\nimport { type OverlayController, useOverlayController } from \"@/lib/controller\";\nimport type { OptionsProps } from \"@/components/Options/Options\";\nimport { useObjectRef } from \"@react-aria/utils\";\nimport { useMakeFocusable } from \"@/lib/hooks/dom/useMakeFocusable\";\nimport { useFieldComponent } from \"@/lib/hooks/useFieldComponent\";\nimport { ReactAriaControlledValueFix } from \"@/lib/react/ReactAriaControlledValueFix\";\n\nexport interface ComboBoxProps\n extends Omit<Aria.ComboBoxProps<never>, \"children\">,\n Pick<Aria.InputProps, \"placeholder\">,\n Pick<OptionsProps, \"renderEmptyState\">,\n PropsWithChildren,\n FlowComponentProps {\n onChange?: (value: string) => void;\n controller?: OverlayController;\n inputRef?: RefObject<HTMLInputElement | null>;\n}\n\n/** @flr-generate all */\nexport const ComboBox = flowComponent(\"ComboBox\", (props) => {\n const {\n children,\n className,\n menuTrigger = \"focus\",\n onChange = () => {\n // default: do nothing\n },\n onSelectionChange = () => {\n // default: do nothing\n },\n controller: controllerFromProps,\n placeholder,\n ref,\n inputRef,\n renderEmptyState,\n\n ...rest\n } = props;\n\n const {\n FieldErrorView,\n FieldErrorCaptureContext,\n fieldProps,\n fieldPropsContext,\n } = useFieldComponent(props);\n\n const stringFormatter = useLocalizedStringFormatter(locales);\n\n const rootClassName = clsx(fieldProps.className, styles.comboBox, className);\n\n const propsContext: PropsContext = {\n Option: {\n tunnelId: \"options\",\n },\n ...fieldPropsContext,\n };\n\n const handleOnSelectionChange = (key: Key | null) => {\n if (key === null) {\n return;\n }\n onChange(String(key));\n onSelectionChange(key);\n };\n\n const controllerFromContext = useOverlayController(\"ComboBox\", {\n reuseControllerFromContext: true,\n });\n\n const controller = controllerFromProps ?? controllerFromContext;\n\n const localComboBoxRef = useObjectRef(ref);\n const localInputComboBoxRef = useObjectRef(inputRef);\n\n useMakeFocusable(localComboBoxRef, () => {\n localInputComboBoxRef.current?.focus();\n });\n\n return (\n <Aria.ComboBox\n {...fieldProps}\n menuTrigger={menuTrigger}\n className={rootClassName}\n {...rest}\n ref={localComboBoxRef}\n onSelectionChange={handleOnSelectionChange}\n onOpenChange={(isOpen) => {\n controller.setOpen(isOpen);\n }}\n >\n <PropsContextProvider props={propsContext}>\n <TunnelProvider>\n <FieldErrorCaptureContext>\n <div className={styles.input}>\n <ReactAriaControlledValueFix\n inputContext={Aria.ComboBoxContext}\n props={props}\n >\n <Aria.Input\n placeholder={placeholder}\n ref={localInputComboBoxRef}\n />\n </ReactAriaControlledValueFix>\n <Button\n className={styles.toggle}\n aria-label={stringFormatter.format(\"comboBox.showOptions\")}\n variant=\"plain\"\n color=\"secondary\"\n >\n <IconChevronDown />\n </Button>\n </div>\n\n {children}\n\n <Options\n controller={controller}\n onOpenChange={() => null}\n renderEmptyState={renderEmptyState}\n >\n <TunnelExit id=\"options\" />\n </Options>\n </FieldErrorCaptureContext>\n <FieldErrorView />\n </TunnelProvider>\n </PropsContextProvider>\n </Aria.ComboBox>\n );\n});\n\nexport default ComboBox;\n"],"names":[],"mappings":"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"}
|
|
@@ -50,8 +50,12 @@ const FileField = flowComponent("FileField", (props) => {
|
|
|
50
50
|
);
|
|
51
51
|
}
|
|
52
52
|
};
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
const localRef = useObjectRef(ref);
|
|
54
|
+
const localInputRef = useObjectRef(inputRef);
|
|
55
|
+
useMakeFocusable(localRef, () => {
|
|
56
|
+
localInputRef.current?.focus();
|
|
57
|
+
});
|
|
58
|
+
return /* @__PURE__ */ jsx("div", { ...fieldProps, ref: localRef, children: /* @__PURE__ */ jsx(InputContext.Provider, { value: inputProps, children: /* @__PURE__ */ jsxs(
|
|
55
59
|
FieldErrorContext.Provider,
|
|
56
60
|
{
|
|
57
61
|
value: formValidationState.displayValidation,
|
|
@@ -65,7 +69,7 @@ const FileField = flowComponent("FileField", (props) => {
|
|
|
65
69
|
children: /* @__PURE__ */ jsx(
|
|
66
70
|
FileInput,
|
|
67
71
|
{
|
|
68
|
-
ref:
|
|
72
|
+
ref: localInputRef,
|
|
69
73
|
isReadOnly,
|
|
70
74
|
onChange: isReadOnly ? void 0 : handleOnChange,
|
|
71
75
|
isDisabled,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileField.mjs","sources":["../../../../../../src/components/FileField/FileField.tsx"],"sourcesContent":["import { useFormValidation } from \"@react-aria/form\";\nimport { useFormValidationState } from \"@react-stately/form\";\nimport type { PropsWithChildren } from \"react\";\nimport type * as Aria from \"react-aria-components\";\nimport { FieldErrorContext, InputContext } from \"react-aria-components\";\nimport type { FileInputOnChangeHandler } from \"@/components/FileField/components/FileInput\";\nimport { FileInput } from \"@/components/FileField/components/FileInput\";\nimport type { FlowComponentProps } from \"@/lib/componentFactory/flowComponent\";\nimport { flowComponent } from \"@/lib/componentFactory/flowComponent\";\nimport { PropsContextProvider } from \"@/lib/propsContext\";\nimport { useObjectRef } from \"@react-aria/utils\";\nimport { addAwaitedArrayBuffer } from \"@mittwald/flow-core\";\nimport { useMakeFocusable } from \"@/lib/hooks/dom/useMakeFocusable\";\nimport { useFieldComponent } from \"@/lib/hooks/useFieldComponent\";\n\nexport interface FileFieldProps\n extends PropsWithChildren,\n FlowComponentProps<HTMLInputElement>,\n Pick<Aria.InputProps, \"accept\" | \"multiple\" | \"name\">,\n Pick<\n Aria.TextFieldProps,\n \"isRequired\" | \"isInvalid\" | \"validationBehavior\" | \"isDisabled\"\n > {\n /** Handler that is called when the file input changes. */\n onChange?: FileInputOnChangeHandler;\n /** Whether the component is read only. */\n isReadOnly?: boolean;\n}\n\n/** @flr-generate all */\nexport const FileField = flowComponent(\"FileField\", (props) => {\n const {\n children,\n ref,\n isRequired,\n isInvalid,\n isDisabled,\n validationBehavior,\n onChange,\n isReadOnly,\n ...restInputProps\n } = props;\n\n const {\n FieldErrorView,\n FieldErrorCaptureContext,\n fieldProps,\n fieldPropsContext,\n } = useFieldComponent(props);\n\n const inputRef = useObjectRef(ref);\n\n const formValidationState = useFormValidationState({\n value: undefined,\n validationBehavior,\n isInvalid,\n });\n\n useFormValidation({ validationBehavior }, formValidationState, inputRef);\n\n const inputProps = {\n ...restInputProps,\n \"aria-invalid\": formValidationState.displayValidation.isInvalid,\n value: undefined,\n };\n\n const handleOnChange: FileInputOnChangeHandler = (fileList) => {\n if (fileList && onChange) {\n Promise.all(Array.from(fileList).map(addAwaitedArrayBuffer)).then(() =>\n onChange(fileList),\n );\n }\n };\n\n
|
|
1
|
+
{"version":3,"file":"FileField.mjs","sources":["../../../../../../src/components/FileField/FileField.tsx"],"sourcesContent":["import { useFormValidation } from \"@react-aria/form\";\nimport { useFormValidationState } from \"@react-stately/form\";\nimport type { PropsWithChildren, RefObject } from \"react\";\nimport type * as Aria from \"react-aria-components\";\nimport { FieldErrorContext, InputContext } from \"react-aria-components\";\nimport type { FileInputOnChangeHandler } from \"@/components/FileField/components/FileInput\";\nimport { FileInput } from \"@/components/FileField/components/FileInput\";\nimport type { FlowComponentProps } from \"@/lib/componentFactory/flowComponent\";\nimport { flowComponent } from \"@/lib/componentFactory/flowComponent\";\nimport { PropsContextProvider } from \"@/lib/propsContext\";\nimport { useObjectRef } from \"@react-aria/utils\";\nimport { addAwaitedArrayBuffer } from \"@mittwald/flow-core\";\nimport { useMakeFocusable } from \"@/lib/hooks/dom/useMakeFocusable\";\nimport { useFieldComponent } from \"@/lib/hooks/useFieldComponent\";\n\nexport interface FileFieldProps\n extends PropsWithChildren,\n FlowComponentProps<HTMLInputElement>,\n Pick<Aria.InputProps, \"accept\" | \"multiple\" | \"name\">,\n Pick<\n Aria.TextFieldProps,\n \"isRequired\" | \"isInvalid\" | \"validationBehavior\" | \"isDisabled\"\n > {\n /** Handler that is called when the file input changes. */\n onChange?: FileInputOnChangeHandler;\n /** Whether the component is read only. */\n isReadOnly?: boolean;\n inputRef?: RefObject<HTMLInputElement>;\n}\n\n/** @flr-generate all */\nexport const FileField = flowComponent(\"FileField\", (props) => {\n const {\n children,\n ref,\n isRequired,\n isInvalid,\n isDisabled,\n validationBehavior,\n onChange,\n isReadOnly,\n ...restInputProps\n } = props;\n\n const {\n FieldErrorView,\n FieldErrorCaptureContext,\n fieldProps,\n fieldPropsContext,\n } = useFieldComponent(props);\n\n const inputRef = useObjectRef(ref);\n\n const formValidationState = useFormValidationState({\n value: undefined,\n validationBehavior,\n isInvalid,\n });\n\n useFormValidation({ validationBehavior }, formValidationState, inputRef);\n\n const inputProps = {\n ...restInputProps,\n \"aria-invalid\": formValidationState.displayValidation.isInvalid,\n value: undefined,\n };\n\n const handleOnChange: FileInputOnChangeHandler = (fileList) => {\n if (fileList && onChange) {\n Promise.all(Array.from(fileList).map(addAwaitedArrayBuffer)).then(() =>\n onChange(fileList),\n );\n }\n };\n\n const localRef = useObjectRef(ref);\n const localInputRef = useObjectRef(inputRef);\n\n useMakeFocusable(localRef, () => {\n localInputRef.current?.focus();\n });\n\n return (\n <div {...fieldProps} ref={localRef}>\n <InputContext.Provider value={inputProps}>\n <FieldErrorContext.Provider\n value={formValidationState.displayValidation}\n >\n <FieldErrorCaptureContext>\n <PropsContextProvider props={fieldPropsContext}>\n <div\n data-readonly={isReadOnly}\n data-required={!!isRequired || undefined}\n data-invalid={\n formValidationState.displayValidation.isInvalid || undefined\n }\n >\n <FileInput\n ref={localInputRef}\n isReadOnly={isReadOnly}\n onChange={isReadOnly ? undefined : handleOnChange}\n isDisabled={isDisabled}\n >\n {children}\n </FileInput>\n </div>\n </PropsContextProvider>\n </FieldErrorCaptureContext>\n <FieldErrorView />\n </FieldErrorContext.Provider>\n </InputContext.Provider>\n </div>\n );\n});\nexport default FileField;\n"],"names":[],"mappings":";;;;;;;;;;;;;AA+BO,MAAM,SAAA,GAAY,aAAA,CAAc,WAAA,EAAa,CAAC,KAAA,KAAU;AAC7D,EAAA,MAAM;AAAA,IACJ,QAAA;AAAA,IACA,GAAA;AAAA,IACA,UAAA;AAAA,IACA,SAAA;AAAA,IACA,UAAA;AAAA,IACA,kBAAA;AAAA,IACA,QAAA;AAAA,IACA,UAAA;AAAA,IACA,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,QAAA,GAAW,aAAa,GAAG,CAAA;AAEjC,EAAA,MAAM,sBAAsB,sBAAA,CAAuB;AAAA,IACjD,KAAA,EAAO,MAAA;AAAA,IACP,kBAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAA,iBAAA,CAAkB,EAAE,kBAAA,EAAmB,EAAG,mBAAA,EAAqB,QAAQ,CAAA;AAEvE,EAAA,MAAM,UAAA,GAAa;AAAA,IACjB,GAAG,cAAA;AAAA,IACH,cAAA,EAAgB,oBAAoB,iBAAA,CAAkB,SAAA;AAAA,IACtD,KAAA,EAAO;AAAA,GACT;AAEA,EAAA,MAAM,cAAA,GAA2C,CAAC,QAAA,KAAa;AAC7D,IAAA,IAAI,YAAY,QAAA,EAAU;AACxB,MAAA,OAAA,CAAQ,GAAA,CAAI,MAAM,IAAA,CAAK,QAAQ,EAAE,GAAA,CAAI,qBAAqB,CAAC,CAAA,CAAE,IAAA;AAAA,QAAK,MAChE,SAAS,QAAQ;AAAA,OACnB;AAAA,IACF;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,QAAA,GAAW,aAAa,GAAG,CAAA;AACjC,EAAA,MAAM,aAAA,GAAgB,aAAa,QAAQ,CAAA;AAE3C,EAAA,gBAAA,CAAiB,UAAU,MAAM;AAC/B,IAAA,aAAA,CAAc,SAAS,KAAA,EAAM;AAAA,EAC/B,CAAC,CAAA;AAED,EAAA,uBACE,GAAA,CAAC,KAAA,EAAA,EAAK,GAAG,UAAA,EAAY,GAAA,EAAK,QAAA,EACxB,QAAA,kBAAA,GAAA,CAAC,YAAA,CAAa,QAAA,EAAb,EAAsB,KAAA,EAAO,UAAA,EAC5B,QAAA,kBAAA,IAAA;AAAA,IAAC,iBAAA,CAAkB,QAAA;AAAA,IAAlB;AAAA,MACC,OAAO,mBAAA,CAAoB,iBAAA;AAAA,MAE3B,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,wBAAA,EAAA,EACC,QAAA,kBAAA,GAAA,CAAC,oBAAA,EAAA,EAAqB,KAAA,EAAO,iBAAA,EAC3B,QAAA,kBAAA,GAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,eAAA,EAAe,UAAA;AAAA,YACf,eAAA,EAAe,CAAC,CAAC,UAAA,IAAc,MAAA;AAAA,YAC/B,cAAA,EACE,mBAAA,CAAoB,iBAAA,CAAkB,SAAA,IAAa,MAAA;AAAA,YAGrD,QAAA,kBAAA,GAAA;AAAA,cAAC,SAAA;AAAA,cAAA;AAAA,gBACC,GAAA,EAAK,aAAA;AAAA,gBACL,UAAA;AAAA,gBACA,QAAA,EAAU,aAAa,MAAA,GAAY,cAAA;AAAA,gBACnC,UAAA;AAAA,gBAEC;AAAA;AAAA;AACH;AAAA,WAEJ,CAAA,EACF,CAAA;AAAA,4BACC,cAAA,EAAA,EAAe;AAAA;AAAA;AAAA,KAEpB,CAAA,EACF,CAAA;AAEJ,CAAC;;;;"}
|
|
@@ -21,6 +21,7 @@ const Markdown = (props) => {
|
|
|
21
21
|
color = "default",
|
|
22
22
|
className,
|
|
23
23
|
headingOffset = 0,
|
|
24
|
+
ref,
|
|
24
25
|
...rest
|
|
25
26
|
} = props;
|
|
26
27
|
const headingAndLinkColor = color === "default" ? "primary" : color;
|
|
@@ -97,7 +98,7 @@ const Markdown = (props) => {
|
|
|
97
98
|
blockquote: (props2) => /* @__PURE__ */ jsx(Text, { color: textColor, children: /* @__PURE__ */ jsx("blockquote", { children: props2.children }) })
|
|
98
99
|
};
|
|
99
100
|
const textContent = extractTextFromFirstChild(children);
|
|
100
|
-
return /* @__PURE__ */ jsx("div", { className: clsx(styles.markdown, className), ...rest, children: /* @__PURE__ */ jsx(ReactMarkdown, { remarkPlugins: [remarkGfm], components, children: textContent }) });
|
|
101
|
+
return /* @__PURE__ */ jsx("div", { className: clsx(styles.markdown, className), ...rest, ref, children: /* @__PURE__ */ jsx(ReactMarkdown, { remarkPlugins: [remarkGfm], components, children: textContent }) });
|
|
101
102
|
};
|
|
102
103
|
|
|
103
104
|
export { Markdown, Markdown as default };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Markdown.mjs","sources":["../../../../../../src/components/Markdown/Markdown.tsx"],"sourcesContent":["import { CodeBlock } from \"@/components/CodeBlock\";\nimport { Heading } from \"@/components/Heading\";\nimport { InlineCode } from \"@/components/InlineCode\";\nimport { Link } from \"@/components/Link\";\nimport { Separator } from \"@/components/Separator\";\nimport { Text } from \"@/components/Text\";\nimport type { CSSProperties, FC, ReactNode } from \"react\";\nimport React, { Children, isValidElement } from \"react\";\nimport type { Components, Options } from \"react-markdown\";\nimport ReactMarkdown from \"react-markdown\";\nimport styles from \"./Markdown.module.scss\";\nimport { extractTextFromFirstChild } from \"@/lib/react/remote\";\nimport type { PropsWithClassName } from \"@/lib/types/props\";\nimport clsx from \"clsx\";\nimport remarkGfm from \"remark-gfm\";\nimport { getHeadingLevelWithOffset } from \"@/components/Markdown/lib/getHeadingLevelWithOffset\";\n\nexport interface MarkdownProps\n extends PropsWithClassName,\n Omit<Options, \"components\"> {\n /** The color schema of the markdown component. */\n color?: \"dark\" | \"light\" | \"default\";\n /** Shifts all heading levels by the given offset. @default 0 */\n headingOffset?: number;\n /** @internal */\n style?: CSSProperties;\n}\n\n/** @flr-generate all */\nexport const Markdown: FC<MarkdownProps> = (props) => {\n const {\n children,\n color = \"default\",\n className,\n headingOffset = 0,\n ...rest\n } = props;\n\n const headingAndLinkColor = color === \"default\" ? \"primary\" : color;\n const textColor = color === \"default\" ? undefined : color;\n\n const components: Components = {\n a: (props) => (\n <Link target=\"_blank\" color={headingAndLinkColor} href={props.href}>\n {props.children}\n </Link>\n ),\n p: (props) => (\n <Text elementType=\"p\" color={textColor}>\n {props.children}\n </Text>\n ),\n code: (props) => <InlineCode color={color}>{props.children}</InlineCode>,\n h1: (props) => (\n <Heading\n level={getHeadingLevelWithOffset(1, headingOffset)}\n color={headingAndLinkColor}\n >\n {props.children}\n </Heading>\n ),\n h2: (props) => (\n <Heading\n level={getHeadingLevelWithOffset(2, headingOffset)}\n color={headingAndLinkColor}\n >\n {props.children}\n </Heading>\n ),\n h3: (props) => (\n <Heading\n level={getHeadingLevelWithOffset(3, headingOffset)}\n color={headingAndLinkColor}\n >\n {props.children}\n </Heading>\n ),\n h4: (props) => (\n <Heading\n level={getHeadingLevelWithOffset(4, headingOffset)}\n color={headingAndLinkColor}\n >\n {props.children}\n </Heading>\n ),\n h5: (props) => (\n <Heading\n level={getHeadingLevelWithOffset(5, headingOffset)}\n color={headingAndLinkColor}\n >\n {props.children}\n </Heading>\n ),\n h6: (props) => (\n <Heading\n level={getHeadingLevelWithOffset(6, headingOffset)}\n color={headingAndLinkColor}\n >\n {props.children}\n </Heading>\n ),\n hr: () => <Separator />,\n pre: (props) => {\n const preElementContent = Children.toArray(props.children)[0];\n\n return (\n <CodeBlock\n copyable={false}\n color=\"dark\"\n language={\n isValidElement<{ className?: string }>(preElementContent) &&\n preElementContent.props.className\n ? preElementContent.props.className.replace(\"language-\", \"\")\n : undefined\n }\n code={String(\n isValidElement<{ children: string }>(preElementContent)\n ? preElementContent.props.children\n : preElementContent,\n )}\n />\n );\n },\n ul: (props) => (\n <Text color={textColor}>\n <ul>{props.children as ReactNode}</ul>\n </Text>\n ),\n ol: (props) => (\n <Text color={textColor}>\n <ol>{props.children as ReactNode}</ol>\n </Text>\n ),\n blockquote: (props) => (\n <Text color={textColor}>\n <blockquote>{props.children}</blockquote>\n </Text>\n ),\n };\n\n const textContent = extractTextFromFirstChild(children);\n\n return (\n <div className={clsx(styles.markdown, className)} {...rest}>\n <ReactMarkdown remarkPlugins={[remarkGfm]} components={components}>\n {textContent}\n </ReactMarkdown>\n </div>\n );\n};\n\nexport default Markdown;\n"],"names":["props"],"mappings":";;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"Markdown.mjs","sources":["../../../../../../src/components/Markdown/Markdown.tsx"],"sourcesContent":["import { CodeBlock } from \"@/components/CodeBlock\";\nimport { Heading } from \"@/components/Heading\";\nimport { InlineCode } from \"@/components/InlineCode\";\nimport { Link } from \"@/components/Link\";\nimport { Separator } from \"@/components/Separator\";\nimport { Text } from \"@/components/Text\";\nimport type { CSSProperties, FC, ReactNode, RefObject } from \"react\";\nimport React, { Children, isValidElement } from \"react\";\nimport type { Components, Options } from \"react-markdown\";\nimport ReactMarkdown from \"react-markdown\";\nimport styles from \"./Markdown.module.scss\";\nimport { extractTextFromFirstChild } from \"@/lib/react/remote\";\nimport type { PropsWithClassName } from \"@/lib/types/props\";\nimport clsx from \"clsx\";\nimport remarkGfm from \"remark-gfm\";\nimport { getHeadingLevelWithOffset } from \"@/components/Markdown/lib/getHeadingLevelWithOffset\";\n\nexport interface MarkdownProps\n extends PropsWithClassName,\n Omit<Options, \"components\"> {\n /** The color schema of the markdown component. */\n color?: \"dark\" | \"light\" | \"default\";\n /** Shifts all heading levels by the given offset. @default 0 */\n headingOffset?: number;\n /** @internal */\n style?: CSSProperties;\n ref?: RefObject<HTMLDivElement>;\n}\n\n/** @flr-generate all */\nexport const Markdown: FC<MarkdownProps> = (props) => {\n const {\n children,\n color = \"default\",\n className,\n headingOffset = 0,\n ref,\n ...rest\n } = props;\n\n const headingAndLinkColor = color === \"default\" ? \"primary\" : color;\n const textColor = color === \"default\" ? undefined : color;\n\n const components: Components = {\n a: (props) => (\n <Link target=\"_blank\" color={headingAndLinkColor} href={props.href}>\n {props.children}\n </Link>\n ),\n p: (props) => (\n <Text elementType=\"p\" color={textColor}>\n {props.children}\n </Text>\n ),\n code: (props) => <InlineCode color={color}>{props.children}</InlineCode>,\n h1: (props) => (\n <Heading\n level={getHeadingLevelWithOffset(1, headingOffset)}\n color={headingAndLinkColor}\n >\n {props.children}\n </Heading>\n ),\n h2: (props) => (\n <Heading\n level={getHeadingLevelWithOffset(2, headingOffset)}\n color={headingAndLinkColor}\n >\n {props.children}\n </Heading>\n ),\n h3: (props) => (\n <Heading\n level={getHeadingLevelWithOffset(3, headingOffset)}\n color={headingAndLinkColor}\n >\n {props.children}\n </Heading>\n ),\n h4: (props) => (\n <Heading\n level={getHeadingLevelWithOffset(4, headingOffset)}\n color={headingAndLinkColor}\n >\n {props.children}\n </Heading>\n ),\n h5: (props) => (\n <Heading\n level={getHeadingLevelWithOffset(5, headingOffset)}\n color={headingAndLinkColor}\n >\n {props.children}\n </Heading>\n ),\n h6: (props) => (\n <Heading\n level={getHeadingLevelWithOffset(6, headingOffset)}\n color={headingAndLinkColor}\n >\n {props.children}\n </Heading>\n ),\n hr: () => <Separator />,\n pre: (props) => {\n const preElementContent = Children.toArray(props.children)[0];\n\n return (\n <CodeBlock\n copyable={false}\n color=\"dark\"\n language={\n isValidElement<{ className?: string }>(preElementContent) &&\n preElementContent.props.className\n ? preElementContent.props.className.replace(\"language-\", \"\")\n : undefined\n }\n code={String(\n isValidElement<{ children: string }>(preElementContent)\n ? preElementContent.props.children\n : preElementContent,\n )}\n />\n );\n },\n ul: (props) => (\n <Text color={textColor}>\n <ul>{props.children as ReactNode}</ul>\n </Text>\n ),\n ol: (props) => (\n <Text color={textColor}>\n <ol>{props.children as ReactNode}</ol>\n </Text>\n ),\n blockquote: (props) => (\n <Text color={textColor}>\n <blockquote>{props.children}</blockquote>\n </Text>\n ),\n };\n\n const textContent = extractTextFromFirstChild(children);\n\n return (\n <div className={clsx(styles.markdown, className)} {...rest} ref={ref}>\n <ReactMarkdown remarkPlugins={[remarkGfm]} components={components}>\n {textContent}\n </ReactMarkdown>\n </div>\n );\n};\n\nexport default Markdown;\n"],"names":["props"],"mappings":"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"}
|
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
"use client"
|
|
2
2
|
/* */
|
|
3
|
-
import {
|
|
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
|
|
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
|
|
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
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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
|
|
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 };
|
|
@@ -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/
|
|
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 =
|
|
9
|
+
const lines = value.slice(0, selectionStart).split("\n").length;
|
|
10
10
|
textarea.scrollTop = (lines - 1) * lineHeight;
|
|
11
11
|
};
|
|
12
|
-
const
|
|
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
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
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 {
|
|
67
|
-
//# sourceMappingURL=
|
|
57
|
+
export { modifyValueByMarkdownSyntax, scrollToCursor };
|
|
58
|
+
//# sourceMappingURL=modifyValueByMarkdownSyntax.mjs.map
|
package/dist/js/components/src/components/MarkdownEditor/lib/modifyValueByMarkdownSyntax.mjs.map
ADDED
|
@@ -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;;;;"}
|