@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.
- package/README.md +120 -0
- package/dist/api/scaffolderActions.esm.js +42 -0
- package/dist/api/scaffolderActions.esm.js.map +1 -0
- package/dist/components/DesignerFlow/DesignerFlow.esm.js +370 -0
- package/dist/components/DesignerFlow/DesignerFlow.esm.js.map +1 -0
- package/dist/components/DesignerFlow/flowConfig.esm.js +21 -0
- package/dist/components/DesignerFlow/flowConfig.esm.js.map +1 -0
- package/dist/components/DesignerFlow/handlers.esm.js +288 -0
- package/dist/components/DesignerFlow/handlers.esm.js.map +1 -0
- package/dist/components/DesignerFlow/model.esm.js +181 -0
- package/dist/components/DesignerFlow/model.esm.js.map +1 -0
- package/dist/components/DesignerFlow/nodeLayout.esm.js +138 -0
- package/dist/components/DesignerFlow/nodeLayout.esm.js.map +1 -0
- package/dist/components/DesignerFlow/parameterTransforms.esm.js +184 -0
- package/dist/components/DesignerFlow/parameterTransforms.esm.js.map +1 -0
- package/dist/components/Nodes/ActionNode.esm.js +437 -0
- package/dist/components/Nodes/ActionNode.esm.js.map +1 -0
- package/dist/components/Nodes/OutputNode.esm.js +368 -0
- package/dist/components/Nodes/OutputNode.esm.js.map +1 -0
- package/dist/components/Nodes/ParameterInputNode.esm.js +310 -0
- package/dist/components/Nodes/ParameterInputNode.esm.js.map +1 -0
- package/dist/components/Nodes/ParameterTitlesNode.esm.js +251 -0
- package/dist/components/Nodes/ParameterTitlesNode.esm.js.map +1 -0
- package/dist/components/Nodes/ParametersNode.esm.js +142 -0
- package/dist/components/Nodes/ParametersNode.esm.js.map +1 -0
- package/dist/components/Nodes/action/schema.esm.js +117 -0
- package/dist/components/Nodes/action/schema.esm.js.map +1 -0
- package/dist/components/Nodes/action/useActionInputs.esm.js +66 -0
- package/dist/components/Nodes/action/useActionInputs.esm.js.map +1 -0
- package/dist/components/Nodes/common/AutoWidthPopper.esm.js +22 -0
- package/dist/components/Nodes/common/AutoWidthPopper.esm.js.map +1 -0
- package/dist/components/Nodes/common/nodeInteraction.esm.js +9 -0
- package/dist/components/Nodes/common/nodeInteraction.esm.js.map +1 -0
- package/dist/components/Nodes/output/useOutputController.esm.js +191 -0
- package/dist/components/Nodes/output/useOutputController.esm.js.map +1 -0
- package/dist/components/Nodes/parameters/useParameterSections.esm.js +162 -0
- package/dist/components/Nodes/parameters/useParameterSections.esm.js.map +1 -0
- package/dist/components/Nodes/types.esm.js +8 -0
- package/dist/components/Nodes/types.esm.js.map +1 -0
- package/dist/components/TemplateDesigner/TemplateDesigner.esm.js +115 -0
- package/dist/components/TemplateDesigner/TemplateDesigner.esm.js.map +1 -0
- package/dist/components/TemplateDesigner/components/FieldEditorDialog.esm.js +32 -0
- package/dist/components/TemplateDesigner/components/FieldEditorDialog.esm.js.map +1 -0
- package/dist/components/TemplateDesigner/components/TemplateLanding.esm.js +102 -0
- package/dist/components/TemplateDesigner/components/TemplateLanding.esm.js.map +1 -0
- package/dist/components/TemplateDesigner/components/TemplateWorkspace.esm.js +200 -0
- package/dist/components/TemplateDesigner/components/TemplateWorkspace.esm.js.map +1 -0
- package/dist/components/TemplateDesigner/index.esm.js +2 -0
- package/dist/components/TemplateDesigner/index.esm.js.map +1 -0
- package/dist/components/TemplateDesigner/useFieldEditor.esm.js +96 -0
- package/dist/components/TemplateDesigner/useFieldEditor.esm.js.map +1 -0
- package/dist/components/TemplateDesigner/useTemplateState.esm.js +391 -0
- package/dist/components/TemplateDesigner/useTemplateState.esm.js.map +1 -0
- package/dist/components/TemplateDesigner/utils.esm.js +46 -0
- package/dist/components/TemplateDesigner/utils.esm.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.esm.js +2 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/plugin.esm.js +19 -0
- package/dist/plugin.esm.js.map +1 -0
- package/dist/routes.esm.js +8 -0
- package/dist/routes.esm.js.map +1 -0
- package/dist/utils/createSequentialEdges.esm.js +15 -0
- package/dist/utils/createSequentialEdges.esm.js.map +1 -0
- package/dist/utils/sampleTemplate.esm.js +40 -0
- package/dist/utils/sampleTemplate.esm.js.map +1 -0
- package/dist/utils/yamlJsonConversion.esm.js +47 -0
- package/dist/utils/yamlJsonConversion.esm.js.map +1 -0
- 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 @@
|
|
|
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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"}
|