@tduniec/plugin-template-designer 0.1.7

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 (69) hide show
  1. package/README.md +120 -0
  2. package/dist/api/scaffolderActions.esm.js +42 -0
  3. package/dist/api/scaffolderActions.esm.js.map +1 -0
  4. package/dist/components/DesignerFlow/DesignerFlow.esm.js +370 -0
  5. package/dist/components/DesignerFlow/DesignerFlow.esm.js.map +1 -0
  6. package/dist/components/DesignerFlow/flowConfig.esm.js +21 -0
  7. package/dist/components/DesignerFlow/flowConfig.esm.js.map +1 -0
  8. package/dist/components/DesignerFlow/handlers.esm.js +288 -0
  9. package/dist/components/DesignerFlow/handlers.esm.js.map +1 -0
  10. package/dist/components/DesignerFlow/model.esm.js +181 -0
  11. package/dist/components/DesignerFlow/model.esm.js.map +1 -0
  12. package/dist/components/DesignerFlow/nodeLayout.esm.js +138 -0
  13. package/dist/components/DesignerFlow/nodeLayout.esm.js.map +1 -0
  14. package/dist/components/DesignerFlow/parameterTransforms.esm.js +184 -0
  15. package/dist/components/DesignerFlow/parameterTransforms.esm.js.map +1 -0
  16. package/dist/components/Nodes/ActionNode.esm.js +437 -0
  17. package/dist/components/Nodes/ActionNode.esm.js.map +1 -0
  18. package/dist/components/Nodes/OutputNode.esm.js +368 -0
  19. package/dist/components/Nodes/OutputNode.esm.js.map +1 -0
  20. package/dist/components/Nodes/ParameterInputNode.esm.js +310 -0
  21. package/dist/components/Nodes/ParameterInputNode.esm.js.map +1 -0
  22. package/dist/components/Nodes/ParameterTitlesNode.esm.js +251 -0
  23. package/dist/components/Nodes/ParameterTitlesNode.esm.js.map +1 -0
  24. package/dist/components/Nodes/ParametersNode.esm.js +142 -0
  25. package/dist/components/Nodes/ParametersNode.esm.js.map +1 -0
  26. package/dist/components/Nodes/action/schema.esm.js +117 -0
  27. package/dist/components/Nodes/action/schema.esm.js.map +1 -0
  28. package/dist/components/Nodes/action/useActionInputs.esm.js +66 -0
  29. package/dist/components/Nodes/action/useActionInputs.esm.js.map +1 -0
  30. package/dist/components/Nodes/common/AutoWidthPopper.esm.js +22 -0
  31. package/dist/components/Nodes/common/AutoWidthPopper.esm.js.map +1 -0
  32. package/dist/components/Nodes/common/nodeInteraction.esm.js +9 -0
  33. package/dist/components/Nodes/common/nodeInteraction.esm.js.map +1 -0
  34. package/dist/components/Nodes/output/useOutputController.esm.js +191 -0
  35. package/dist/components/Nodes/output/useOutputController.esm.js.map +1 -0
  36. package/dist/components/Nodes/parameters/useParameterSections.esm.js +162 -0
  37. package/dist/components/Nodes/parameters/useParameterSections.esm.js.map +1 -0
  38. package/dist/components/Nodes/types.esm.js +8 -0
  39. package/dist/components/Nodes/types.esm.js.map +1 -0
  40. package/dist/components/TemplateDesigner/TemplateDesigner.esm.js +115 -0
  41. package/dist/components/TemplateDesigner/TemplateDesigner.esm.js.map +1 -0
  42. package/dist/components/TemplateDesigner/components/FieldEditorDialog.esm.js +32 -0
  43. package/dist/components/TemplateDesigner/components/FieldEditorDialog.esm.js.map +1 -0
  44. package/dist/components/TemplateDesigner/components/TemplateLanding.esm.js +102 -0
  45. package/dist/components/TemplateDesigner/components/TemplateLanding.esm.js.map +1 -0
  46. package/dist/components/TemplateDesigner/components/TemplateWorkspace.esm.js +200 -0
  47. package/dist/components/TemplateDesigner/components/TemplateWorkspace.esm.js.map +1 -0
  48. package/dist/components/TemplateDesigner/index.esm.js +2 -0
  49. package/dist/components/TemplateDesigner/index.esm.js.map +1 -0
  50. package/dist/components/TemplateDesigner/useFieldEditor.esm.js +96 -0
  51. package/dist/components/TemplateDesigner/useFieldEditor.esm.js.map +1 -0
  52. package/dist/components/TemplateDesigner/useTemplateState.esm.js +391 -0
  53. package/dist/components/TemplateDesigner/useTemplateState.esm.js.map +1 -0
  54. package/dist/components/TemplateDesigner/utils.esm.js +46 -0
  55. package/dist/components/TemplateDesigner/utils.esm.js.map +1 -0
  56. package/dist/index.d.ts +9 -0
  57. package/dist/index.esm.js +2 -0
  58. package/dist/index.esm.js.map +1 -0
  59. package/dist/plugin.esm.js +19 -0
  60. package/dist/plugin.esm.js.map +1 -0
  61. package/dist/routes.esm.js +8 -0
  62. package/dist/routes.esm.js.map +1 -0
  63. package/dist/utils/createSequentialEdges.esm.js +15 -0
  64. package/dist/utils/createSequentialEdges.esm.js.map +1 -0
  65. package/dist/utils/sampleTemplate.esm.js +40 -0
  66. package/dist/utils/sampleTemplate.esm.js.map +1 -0
  67. package/dist/utils/yamlJsonConversion.esm.js +47 -0
  68. package/dist/utils/yamlJsonConversion.esm.js.map +1 -0
  69. package/package.json +116 -0
@@ -0,0 +1,200 @@
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import { useMemo } from 'react';
3
+ import { Grid, Typography, Button, Paper } from '@material-ui/core';
4
+ import { useTheme } from '@material-ui/core/styles';
5
+ import CodeMirror from '@uiw/react-codemirror';
6
+ import { yaml } from '@codemirror/lang-yaml';
7
+ import App from '../../DesignerFlow/DesignerFlow.esm.js';
8
+
9
+ const TemplateWorkspace = ({
10
+ templateSteps,
11
+ templateParameters,
12
+ templateOutput,
13
+ templateYaml,
14
+ yamlError,
15
+ loadError,
16
+ showYaml,
17
+ onToggleYaml,
18
+ onYamlChange,
19
+ onStepsChange,
20
+ onParametersChange,
21
+ onOutputChange,
22
+ onReload,
23
+ onSave,
24
+ onOpenTemplatePicker,
25
+ activeTemplateLabel,
26
+ reloadButtonLabel,
27
+ saveButtonLabel,
28
+ isReloading,
29
+ isSaving
30
+ }) => {
31
+ const theme = useTheme();
32
+ const paletteMode = theme.palette.mode ?? theme.palette.type ?? "light";
33
+ const yamlExtensions = useMemo(() => [yaml()], []);
34
+ const codeMirrorTheme = useMemo(
35
+ () => paletteMode === "dark" ? "dark" : "light",
36
+ [paletteMode]
37
+ );
38
+ return /* @__PURE__ */ jsx(Grid, { container: true, spacing: 3, direction: "column", children: /* @__PURE__ */ jsx(Grid, { item: true, style: { height: 800 }, children: /* @__PURE__ */ jsxs(
39
+ "div",
40
+ {
41
+ style: {
42
+ height: "100%",
43
+ display: "flex",
44
+ flexDirection: "column",
45
+ gap: 16
46
+ },
47
+ children: [
48
+ /* @__PURE__ */ jsxs(
49
+ "div",
50
+ {
51
+ style: {
52
+ display: "flex",
53
+ justifyContent: "space-between",
54
+ alignItems: "center",
55
+ flexWrap: "wrap",
56
+ gap: 12
57
+ },
58
+ children: [
59
+ /* @__PURE__ */ jsxs(
60
+ "div",
61
+ {
62
+ style: {
63
+ display: "flex",
64
+ alignItems: "center",
65
+ gap: 12,
66
+ flexWrap: "wrap"
67
+ },
68
+ children: [
69
+ activeTemplateLabel && /* @__PURE__ */ jsxs(Typography, { variant: "body2", color: "textSecondary", children: [
70
+ "Active template: ",
71
+ activeTemplateLabel
72
+ ] }),
73
+ /* @__PURE__ */ jsx(
74
+ Button,
75
+ {
76
+ color: "primary",
77
+ variant: "contained",
78
+ size: "small",
79
+ onClick: onReload,
80
+ disabled: isReloading,
81
+ children: reloadButtonLabel
82
+ }
83
+ ),
84
+ /* @__PURE__ */ jsx(
85
+ Button,
86
+ {
87
+ color: "primary",
88
+ variant: "outlined",
89
+ size: "small",
90
+ onClick: onSave,
91
+ disabled: isSaving,
92
+ children: saveButtonLabel
93
+ }
94
+ ),
95
+ /* @__PURE__ */ jsx(
96
+ Button,
97
+ {
98
+ color: "primary",
99
+ variant: "outlined",
100
+ size: "small",
101
+ onClick: onOpenTemplatePicker,
102
+ children: "Load different file"
103
+ }
104
+ )
105
+ ]
106
+ }
107
+ ),
108
+ /* @__PURE__ */ jsx(Button, { variant: "outlined", size: "small", onClick: onToggleYaml, children: showYaml ? "Hide YAML" : "Show YAML" })
109
+ ]
110
+ }
111
+ ),
112
+ loadError && /* @__PURE__ */ jsx(
113
+ Typography,
114
+ {
115
+ variant: "body2",
116
+ style: { color: theme.palette.error.main },
117
+ children: loadError
118
+ }
119
+ ),
120
+ /* @__PURE__ */ jsxs(
121
+ "div",
122
+ {
123
+ style: {
124
+ flex: 1,
125
+ display: "flex",
126
+ gap: 16,
127
+ minHeight: 0
128
+ },
129
+ children: [
130
+ /* @__PURE__ */ jsx("div", { style: { flex: showYaml ? 1.6 : 1, minWidth: 0 }, children: /* @__PURE__ */ jsx("div", { style: { height: "100%" }, children: /* @__PURE__ */ jsx(
131
+ App,
132
+ {
133
+ steps: templateSteps,
134
+ parameters: templateParameters,
135
+ output: templateOutput,
136
+ onStepsChange,
137
+ onParametersChange,
138
+ onOutputChange
139
+ }
140
+ ) }) }),
141
+ showYaml && /* @__PURE__ */ jsxs(
142
+ Paper,
143
+ {
144
+ elevation: 2,
145
+ style: {
146
+ flex: 1,
147
+ display: "flex",
148
+ flexDirection: "column",
149
+ minWidth: 0,
150
+ overflow: "hidden"
151
+ },
152
+ children: [
153
+ /* @__PURE__ */ jsx(
154
+ "div",
155
+ {
156
+ style: {
157
+ padding: "12px 16px",
158
+ borderBottom: "1px solid rgba(0,0,0,0.12)",
159
+ fontWeight: 600,
160
+ fontSize: "0.875rem"
161
+ },
162
+ children: "YAML Preview"
163
+ }
164
+ ),
165
+ yamlError && /* @__PURE__ */ jsx(
166
+ "div",
167
+ {
168
+ style: {
169
+ padding: "8px 16px",
170
+ borderBottom: "1px solid rgba(0,0,0,0.08)",
171
+ color: theme.palette.error.main,
172
+ fontSize: "0.75rem",
173
+ background: paletteMode === "dark" ? "rgba(255, 82, 82, 0.1)" : "rgba(244, 67, 54, 0.08)"
174
+ },
175
+ children: yamlError
176
+ }
177
+ ),
178
+ /* @__PURE__ */ jsx("div", { style: { flex: 1, minHeight: 0, overflow: "auto" }, children: /* @__PURE__ */ jsx(
179
+ CodeMirror,
180
+ {
181
+ value: templateYaml,
182
+ extensions: yamlExtensions,
183
+ theme: codeMirrorTheme,
184
+ height: "100%",
185
+ onChange: (value) => onYamlChange(value)
186
+ }
187
+ ) })
188
+ ]
189
+ }
190
+ )
191
+ ]
192
+ }
193
+ )
194
+ ]
195
+ }
196
+ ) }) });
197
+ };
198
+
199
+ export { TemplateWorkspace };
200
+ //# sourceMappingURL=TemplateWorkspace.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TemplateWorkspace.esm.js","sources":["../../../../src/components/TemplateDesigner/components/TemplateWorkspace.tsx"],"sourcesContent":["import { useMemo } from \"react\";\nimport { Button, Grid, Paper, Typography } from \"@material-ui/core\";\nimport { useTheme } from \"@material-ui/core/styles\";\nimport CodeMirror from \"@uiw/react-codemirror\";\nimport { yaml } from \"@codemirror/lang-yaml\";\nimport type {\n ScaffolderTaskOutput,\n TaskStep,\n} from \"@backstage/plugin-scaffolder-common\";\nimport type { TemplateParametersValue } from \"../../Nodes/types\";\nimport App from \"../../DesignerFlow/DesignerFlow\";\n\ntype TemplateWorkspaceProps = {\n templateSteps: TaskStep[];\n templateParameters: TemplateParametersValue;\n templateOutput?: ScaffolderTaskOutput;\n templateYaml: string;\n yamlError?: string;\n loadError?: string;\n showYaml: boolean;\n onToggleYaml: () => void;\n onYamlChange: (value: string) => void;\n onStepsChange: (steps: TaskStep[]) => void;\n onParametersChange: (parameters: TemplateParametersValue) => void;\n onOutputChange: (output?: ScaffolderTaskOutput) => void;\n onReload: () => void;\n onSave: () => void;\n onOpenTemplatePicker: () => void;\n activeTemplateLabel?: string;\n reloadButtonLabel: string;\n saveButtonLabel: string;\n isReloading: boolean;\n isSaving: boolean;\n};\n\nexport const TemplateWorkspace = ({\n templateSteps,\n templateParameters,\n templateOutput,\n templateYaml,\n yamlError,\n loadError,\n showYaml,\n onToggleYaml,\n onYamlChange,\n onStepsChange,\n onParametersChange,\n onOutputChange,\n onReload,\n onSave,\n onOpenTemplatePicker,\n activeTemplateLabel,\n reloadButtonLabel,\n saveButtonLabel,\n isReloading,\n isSaving,\n}: TemplateWorkspaceProps) => {\n const theme = useTheme();\n const paletteMode =\n (theme.palette as { mode?: \"light\" | \"dark\" }).mode ??\n theme.palette.type ??\n \"light\";\n const yamlExtensions = useMemo(() => [yaml()], []);\n const codeMirrorTheme = useMemo(\n () => (paletteMode === \"dark\" ? \"dark\" : \"light\"),\n [paletteMode]\n );\n\n return (\n <Grid container spacing={3} direction=\"column\">\n <Grid item style={{ height: 800 }}>\n <div\n style={{\n height: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: 16,\n }}\n >\n <div\n style={{\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n flexWrap: \"wrap\",\n gap: 12,\n }}\n >\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 12,\n flexWrap: \"wrap\",\n }}\n >\n {activeTemplateLabel && (\n <Typography variant=\"body2\" color=\"textSecondary\">\n Active template: {activeTemplateLabel}\n </Typography>\n )}\n <Button\n color=\"primary\"\n variant=\"contained\"\n size=\"small\"\n onClick={onReload}\n disabled={isReloading}\n >\n {reloadButtonLabel}\n </Button>\n <Button\n color=\"primary\"\n variant=\"outlined\"\n size=\"small\"\n onClick={onSave}\n disabled={isSaving}\n >\n {saveButtonLabel}\n </Button>\n <Button\n color=\"primary\"\n variant=\"outlined\"\n size=\"small\"\n onClick={onOpenTemplatePicker}\n >\n Load different file\n </Button>\n </div>\n <Button variant=\"outlined\" size=\"small\" onClick={onToggleYaml}>\n {showYaml ? \"Hide YAML\" : \"Show YAML\"}\n </Button>\n </div>\n {loadError && (\n <Typography\n variant=\"body2\"\n style={{ color: theme.palette.error.main }}\n >\n {loadError}\n </Typography>\n )}\n <div\n style={{\n flex: 1,\n display: \"flex\",\n gap: 16,\n minHeight: 0,\n }}\n >\n <div style={{ flex: showYaml ? 1.6 : 1, minWidth: 0 }}>\n <div style={{ height: \"100%\" }}>\n <App\n steps={templateSteps}\n parameters={templateParameters}\n output={templateOutput}\n onStepsChange={onStepsChange}\n onParametersChange={onParametersChange}\n onOutputChange={onOutputChange}\n />\n </div>\n </div>\n {showYaml && (\n <Paper\n elevation={2}\n style={{\n flex: 1,\n display: \"flex\",\n flexDirection: \"column\",\n minWidth: 0,\n overflow: \"hidden\",\n }}\n >\n <div\n style={{\n padding: \"12px 16px\",\n borderBottom: \"1px solid rgba(0,0,0,0.12)\",\n fontWeight: 600,\n fontSize: \"0.875rem\",\n }}\n >\n YAML Preview\n </div>\n {yamlError && (\n <div\n style={{\n padding: \"8px 16px\",\n borderBottom: \"1px solid rgba(0,0,0,0.08)\",\n color: theme.palette.error.main,\n fontSize: \"0.75rem\",\n background:\n paletteMode === \"dark\"\n ? \"rgba(255, 82, 82, 0.1)\"\n : \"rgba(244, 67, 54, 0.08)\",\n }}\n >\n {yamlError}\n </div>\n )}\n <div style={{ flex: 1, minHeight: 0, overflow: \"auto\" }}>\n <CodeMirror\n value={templateYaml}\n extensions={yamlExtensions}\n theme={codeMirrorTheme}\n height=\"100%\"\n onChange={(value) => onYamlChange(value)}\n />\n </div>\n </Paper>\n )}\n </div>\n </div>\n </Grid>\n </Grid>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export { TemplateDesigner } from './TemplateDesigner.esm.js';
2
+ //# sourceMappingURL=index.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,96 @@
1
+ import { useState, useRef, useCallback, useEffect } from 'react';
2
+
3
+ const resolveLabel = (element) => element.getAttribute("aria-label") ?? element.name ?? element.placeholder ?? "Field editor";
4
+ const useFieldEditor = () => {
5
+ const [editorState, setEditorState] = useState(null);
6
+ const [editorValue, setEditorValue] = useState("");
7
+ const interactionRootRef = useRef(null);
8
+ const closeEditor = useCallback(() => {
9
+ setEditorState(null);
10
+ setEditorValue("");
11
+ }, []);
12
+ const applyEditorValue = useCallback(() => {
13
+ const current = editorState;
14
+ if (!current) {
15
+ return;
16
+ }
17
+ const setNativeValue = (element, value) => {
18
+ const valueSetter = Object.getOwnPropertyDescriptor(
19
+ element,
20
+ "value"
21
+ )?.set;
22
+ const prototype = Object.getPrototypeOf(element);
23
+ const prototypeValueSetter = Object.getOwnPropertyDescriptor(
24
+ prototype,
25
+ "value"
26
+ )?.set;
27
+ if (valueSetter && valueSetter !== prototypeValueSetter) {
28
+ prototypeValueSetter?.call(element, value);
29
+ } else if (valueSetter) {
30
+ valueSetter.call(element, value);
31
+ } else {
32
+ element.value = value;
33
+ }
34
+ };
35
+ setNativeValue(current.target, editorValue);
36
+ current.target.dispatchEvent(new Event("input", { bubbles: true }));
37
+ closeEditor();
38
+ }, [closeEditor, editorState, editorValue]);
39
+ const openEditor = useCallback(
40
+ (target) => {
41
+ setEditorState({
42
+ target,
43
+ label: resolveLabel(target)
44
+ });
45
+ setEditorValue(target.value);
46
+ },
47
+ []
48
+ );
49
+ useEffect(() => {
50
+ const root = interactionRootRef.current;
51
+ if (!root) {
52
+ return void 0;
53
+ }
54
+ const handleDoubleClick = (event) => {
55
+ const target = event.target;
56
+ if (target instanceof HTMLInputElement && !target.readOnly && !target.disabled) {
57
+ const type = target.type?.toLowerCase();
58
+ const editableTypes = [
59
+ "text",
60
+ "search",
61
+ "url",
62
+ "tel",
63
+ "email",
64
+ "number",
65
+ "password"
66
+ ];
67
+ const isTextual = !type || editableTypes.includes(type);
68
+ if (!isTextual || !target.value) {
69
+ return;
70
+ }
71
+ event.stopPropagation();
72
+ openEditor(target);
73
+ return;
74
+ }
75
+ if (target instanceof HTMLTextAreaElement && !target.readOnly && !target.disabled && target.value) {
76
+ event.stopPropagation();
77
+ openEditor(target);
78
+ }
79
+ };
80
+ root.addEventListener("dblclick", handleDoubleClick, true);
81
+ return () => {
82
+ root.removeEventListener("dblclick", handleDoubleClick, true);
83
+ };
84
+ }, [openEditor]);
85
+ return {
86
+ editorState,
87
+ editorValue,
88
+ setEditorValue,
89
+ interactionRootRef,
90
+ closeEditor,
91
+ applyEditorValue
92
+ };
93
+ };
94
+
95
+ export { useFieldEditor };
96
+ //# sourceMappingURL=useFieldEditor.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useFieldEditor.esm.js","sources":["../../../src/components/TemplateDesigner/useFieldEditor.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from \"react\";\n\ntype EditorState = null | {\n target: HTMLInputElement | HTMLTextAreaElement;\n label: string;\n};\n\nconst resolveLabel = (element: HTMLInputElement | HTMLTextAreaElement) =>\n element.getAttribute(\"aria-label\") ??\n element.name ??\n element.placeholder ??\n \"Field editor\";\n\n/**\n * Provides a modal-friendly editing experience for readonly-looking inputs\n * by letting users double-click any text field and edit its value centrally.\n */\nexport const useFieldEditor = () => {\n const [editorState, setEditorState] = useState<EditorState>(null);\n const [editorValue, setEditorValue] = useState(\"\");\n const interactionRootRef = useRef<HTMLDivElement | null>(null);\n\n const closeEditor = useCallback(() => {\n setEditorState(null);\n setEditorValue(\"\");\n }, []);\n\n const applyEditorValue = useCallback(() => {\n const current = editorState;\n if (!current) {\n return;\n }\n\n const setNativeValue = (\n element: HTMLInputElement | HTMLTextAreaElement,\n value: string\n ) => {\n const valueSetter = Object.getOwnPropertyDescriptor(\n element,\n \"value\"\n )?.set;\n const prototype = Object.getPrototypeOf(element);\n const prototypeValueSetter = Object.getOwnPropertyDescriptor(\n prototype,\n \"value\"\n )?.set;\n\n if (valueSetter && valueSetter !== prototypeValueSetter) {\n prototypeValueSetter?.call(element, value);\n } else if (valueSetter) {\n valueSetter.call(element, value);\n } else {\n // eslint-disable-next-line no-param-reassign\n element.value = value;\n }\n };\n\n setNativeValue(current.target, editorValue);\n current.target.dispatchEvent(new Event(\"input\", { bubbles: true }));\n closeEditor();\n }, [closeEditor, editorState, editorValue]);\n\n const openEditor = useCallback(\n (target: HTMLInputElement | HTMLTextAreaElement) => {\n setEditorState({\n target,\n label: resolveLabel(target),\n });\n setEditorValue(target.value);\n },\n []\n );\n\n useEffect(() => {\n const root = interactionRootRef.current;\n if (!root) {\n return undefined;\n }\n\n const handleDoubleClick = (event: MouseEvent) => {\n const target = event.target;\n if (\n target instanceof HTMLInputElement &&\n !target.readOnly &&\n !target.disabled\n ) {\n const type = target.type?.toLowerCase();\n const editableTypes = [\n \"text\",\n \"search\",\n \"url\",\n \"tel\",\n \"email\",\n \"number\",\n \"password\",\n ];\n const isTextual = !type || editableTypes.includes(type);\n if (!isTextual || !target.value) {\n return;\n }\n event.stopPropagation();\n openEditor(target);\n return;\n }\n if (\n target instanceof HTMLTextAreaElement &&\n !target.readOnly &&\n !target.disabled &&\n target.value\n ) {\n event.stopPropagation();\n openEditor(target);\n }\n };\n\n root.addEventListener(\"dblclick\", handleDoubleClick, true);\n return () => {\n root.removeEventListener(\"dblclick\", handleDoubleClick, true);\n };\n }, [openEditor]);\n\n return {\n editorState,\n editorValue,\n setEditorValue,\n interactionRootRef,\n closeEditor,\n applyEditorValue,\n };\n};\n"],"names":[],"mappings":"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"}