@panneau/forms 4.1.1 → 5.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +71 -0
- package/dist/ConflictDialog.css +55 -0
- package/dist/ConflictDialog.d.ts +23 -0
- package/dist/ConflictDialog.d.ts.map +1 -0
- package/dist/ConflictDialog.js +122 -0
- package/dist/ConflictDialog.js.map +1 -0
- package/dist/ConflictDialog.module.js +24 -0
- package/dist/ConflictDialog.module.js.map +1 -0
- package/dist/ErrorSummary.d.ts +18 -0
- package/dist/ErrorSummary.d.ts.map +1 -0
- package/dist/ErrorSummary.js +122 -0
- package/dist/ErrorSummary.js.map +1 -0
- package/dist/FieldErrorBoundary.d.ts +19 -0
- package/dist/FieldErrorBoundary.d.ts.map +1 -0
- package/dist/FieldErrorBoundary.js +20 -0
- package/dist/FieldErrorBoundary.js.map +1 -0
- package/dist/Form.css +151 -0
- package/dist/Form.d.ts +20 -0
- package/dist/Form.d.ts.map +1 -0
- package/dist/Form.js +41 -0
- package/dist/Form.js.map +1 -0
- package/dist/Form.module.js +44 -0
- package/dist/Form.module.js.map +1 -0
- package/dist/FormBinding.d.ts +8 -0
- package/dist/FormBinding.d.ts.map +1 -0
- package/dist/FormBinding.js +122 -0
- package/dist/FormBinding.js.map +1 -0
- package/dist/FormView.d.ts +48 -0
- package/dist/FormView.d.ts.map +1 -0
- package/dist/FormView.js +203 -0
- package/dist/FormView.js.map +1 -0
- package/dist/context.d.ts +15 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +32 -0
- package/dist/context.js.map +1 -0
- package/dist/cx.d.ts +3 -0
- package/dist/cx.d.ts.map +1 -0
- package/dist/cx.js +9 -0
- package/dist/cx.js.map +1 -0
- package/dist/describe.d.ts +7 -0
- package/dist/describe.d.ts.map +1 -0
- package/dist/describe.js +17 -0
- package/dist/describe.js.map +1 -0
- package/dist/formatError.d.ts +8 -0
- package/dist/formatError.d.ts.map +1 -0
- package/dist/formatError.js +46 -0
- package/dist/formatError.js.map +1 -0
- package/dist/index.d.ts +10 -12
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -90
- package/dist/layout/Layout.d.ts +9 -0
- package/dist/layout/Layout.d.ts.map +1 -0
- package/dist/layout/Layout.js +442 -0
- package/dist/layout/Layout.js.map +1 -0
- package/dist/locales/index.d.ts +15 -0
- package/dist/locales/index.d.ts.map +1 -0
- package/dist/locales/index.js +21 -0
- package/dist/locales/index.js.map +1 -0
- package/dist/messages.d.ts +2 -0
- package/dist/messages.d.ts.map +1 -0
- package/dist/messages.js +1 -0
- package/dist/paths.d.ts +15 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +34 -0
- package/dist/paths.js.map +1 -0
- package/dist/unsaved.d.ts +22 -0
- package/dist/unsaved.d.ts.map +1 -0
- package/dist/unsaved.js +169 -0
- package/dist/unsaved.js.map +1 -0
- package/package.json +30 -60
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
import { messages } from "../messages.js";
|
|
2
|
+
import Form_module_default from "../Form.module.js";
|
|
3
|
+
import { RevealContext, useFormContext, useFormState } from "../context.js";
|
|
4
|
+
import { c } from "react/compiler-runtime";
|
|
5
|
+
import { getLayoutFieldNames, selectErrorCount, selectVisible, usePlugins } from "@panneau/core";
|
|
6
|
+
import { Badge, Disclosure, Tab, TabList, TabPanel, Tabs, usePanneauIntl } from "@panneau/ui";
|
|
7
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
import { createElement, use, useEffect, useId, useState } from "react";
|
|
9
|
+
import { NestedField } from "@panneau/fields";
|
|
10
|
+
//#region src/layout/Layout.tsx
|
|
11
|
+
/** Whether a path belongs to one of the field names (`title.fr` to `title`). */
|
|
12
|
+
function containsPath(names, path) {
|
|
13
|
+
const name = path.split(".")[0];
|
|
14
|
+
return name !== void 0 && names.includes(name);
|
|
15
|
+
}
|
|
16
|
+
function ErrorBadge(t0) {
|
|
17
|
+
const $ = c(4);
|
|
18
|
+
const { form, names } = t0;
|
|
19
|
+
const intl = usePanneauIntl();
|
|
20
|
+
const count = selectErrorCount(useFormState(form), names);
|
|
21
|
+
if (count === 0) return null;
|
|
22
|
+
const T0 = Badge;
|
|
23
|
+
const t1 = "danger";
|
|
24
|
+
const t2 = intl.formatMessage(messages.errorCount, { count });
|
|
25
|
+
let t3;
|
|
26
|
+
if ($[0] !== T0 || $[1] !== count || $[2] !== t2) {
|
|
27
|
+
t3 = /* @__PURE__ */ jsx(T0, {
|
|
28
|
+
tone: t1,
|
|
29
|
+
label: t2,
|
|
30
|
+
children: count
|
|
31
|
+
});
|
|
32
|
+
$[0] = T0;
|
|
33
|
+
$[1] = count;
|
|
34
|
+
$[2] = t2;
|
|
35
|
+
$[3] = t3;
|
|
36
|
+
} else t3 = $[3];
|
|
37
|
+
return t3;
|
|
38
|
+
}
|
|
39
|
+
function TabsNode(t0) {
|
|
40
|
+
const $ = c(6);
|
|
41
|
+
const { node, fields } = t0;
|
|
42
|
+
const form = useFormContext();
|
|
43
|
+
const state = useFormState(form);
|
|
44
|
+
const registry = use(RevealContext);
|
|
45
|
+
const id = useId();
|
|
46
|
+
let t1;
|
|
47
|
+
if ($[0] !== state) {
|
|
48
|
+
t1 = (child) => child.type === "tab" && selectVisible(state, child);
|
|
49
|
+
$[0] = state;
|
|
50
|
+
$[1] = t1;
|
|
51
|
+
} else t1 = $[1];
|
|
52
|
+
const tabs = (node.children ?? []).filter(t1);
|
|
53
|
+
const names = tabs.map(_temp);
|
|
54
|
+
const [selected, setSelected] = useState(`${id}-0`);
|
|
55
|
+
useEffect(() => registry.add((path) => {
|
|
56
|
+
const index = names.findIndex((tabNames) => containsPath(tabNames, path));
|
|
57
|
+
if (index !== -1) setSelected(`${id}-${index}`);
|
|
58
|
+
}), [
|
|
59
|
+
registry,
|
|
60
|
+
names,
|
|
61
|
+
id
|
|
62
|
+
]);
|
|
63
|
+
let t2;
|
|
64
|
+
if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
|
|
65
|
+
t2 = (key) => setSelected(String(key));
|
|
66
|
+
$[2] = t2;
|
|
67
|
+
} else t2 = $[2];
|
|
68
|
+
let t3;
|
|
69
|
+
if ($[3] !== fields || $[4] !== id) {
|
|
70
|
+
t3 = (tab_2, index_1) => /* @__PURE__ */ jsx(TabPanel, {
|
|
71
|
+
id: `${id}-${index_1}`,
|
|
72
|
+
shouldForceMount: true,
|
|
73
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
74
|
+
className: Form_module_default.stack,
|
|
75
|
+
children: /* @__PURE__ */ jsx(LayoutNodes, {
|
|
76
|
+
nodes: tab_2.children ?? [],
|
|
77
|
+
fields
|
|
78
|
+
})
|
|
79
|
+
})
|
|
80
|
+
}, index_1);
|
|
81
|
+
$[3] = fields;
|
|
82
|
+
$[4] = id;
|
|
83
|
+
$[5] = t3;
|
|
84
|
+
} else t3 = $[5];
|
|
85
|
+
return /* @__PURE__ */ jsxs(Tabs, {
|
|
86
|
+
selectedKey: selected,
|
|
87
|
+
onSelectionChange: t2,
|
|
88
|
+
children: [/* @__PURE__ */ jsx(TabList, {
|
|
89
|
+
"aria-label": node.label ?? tabs.map(_temp2).join(", "),
|
|
90
|
+
children: tabs.map((tab_1, index_0) => /* @__PURE__ */ jsxs(Tab, {
|
|
91
|
+
id: `${id}-${index_0}`,
|
|
92
|
+
children: [
|
|
93
|
+
tab_1.label,
|
|
94
|
+
" ",
|
|
95
|
+
/* @__PURE__ */ jsx(ErrorBadge, {
|
|
96
|
+
form,
|
|
97
|
+
names: names[index_0] ?? []
|
|
98
|
+
})
|
|
99
|
+
]
|
|
100
|
+
}, index_0))
|
|
101
|
+
}), tabs.map(t3)]
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
function _temp2(tab_0) {
|
|
105
|
+
return tab_0.label ?? "";
|
|
106
|
+
}
|
|
107
|
+
function _temp(tab) {
|
|
108
|
+
return getLayoutFieldNames(tab.children ?? []);
|
|
109
|
+
}
|
|
110
|
+
function SectionNode(t0) {
|
|
111
|
+
const $ = c(37);
|
|
112
|
+
const { node, fields } = t0;
|
|
113
|
+
const form = useFormContext();
|
|
114
|
+
const registry = use(RevealContext);
|
|
115
|
+
const titleId = useId();
|
|
116
|
+
let t1;
|
|
117
|
+
if ($[0] !== node.children) {
|
|
118
|
+
t1 = node.children ?? [];
|
|
119
|
+
$[0] = node.children;
|
|
120
|
+
$[1] = t1;
|
|
121
|
+
} else t1 = $[1];
|
|
122
|
+
let t2;
|
|
123
|
+
if ($[2] !== t1) {
|
|
124
|
+
t2 = getLayoutFieldNames(t1);
|
|
125
|
+
$[2] = t1;
|
|
126
|
+
$[3] = t2;
|
|
127
|
+
} else t2 = $[3];
|
|
128
|
+
const names = t2;
|
|
129
|
+
const [expanded, setExpanded] = useState(node.collapsed !== true);
|
|
130
|
+
let t3;
|
|
131
|
+
let t4;
|
|
132
|
+
if ($[4] !== names || $[5] !== registry) {
|
|
133
|
+
t3 = () => registry.add((path) => {
|
|
134
|
+
if (containsPath(names, path)) setExpanded(true);
|
|
135
|
+
});
|
|
136
|
+
t4 = [registry, names];
|
|
137
|
+
$[4] = names;
|
|
138
|
+
$[5] = registry;
|
|
139
|
+
$[6] = t3;
|
|
140
|
+
$[7] = t4;
|
|
141
|
+
} else {
|
|
142
|
+
t3 = $[6];
|
|
143
|
+
t4 = $[7];
|
|
144
|
+
}
|
|
145
|
+
useEffect(t3, t4);
|
|
146
|
+
let t5;
|
|
147
|
+
if ($[8] !== node.description) {
|
|
148
|
+
t5 = node.description !== void 0 ? /* @__PURE__ */ jsx("p", {
|
|
149
|
+
className: Form_module_default.sectionDescription,
|
|
150
|
+
children: node.description
|
|
151
|
+
}) : null;
|
|
152
|
+
$[8] = node.description;
|
|
153
|
+
$[9] = t5;
|
|
154
|
+
} else t5 = $[9];
|
|
155
|
+
let t6;
|
|
156
|
+
if ($[10] !== node.children) {
|
|
157
|
+
t6 = node.children ?? [];
|
|
158
|
+
$[10] = node.children;
|
|
159
|
+
$[11] = t6;
|
|
160
|
+
} else t6 = $[11];
|
|
161
|
+
let t7;
|
|
162
|
+
if ($[12] !== fields || $[13] !== t6) {
|
|
163
|
+
t7 = /* @__PURE__ */ jsx("div", {
|
|
164
|
+
className: Form_module_default.stack,
|
|
165
|
+
children: /* @__PURE__ */ jsx(LayoutNodes, {
|
|
166
|
+
nodes: t6,
|
|
167
|
+
fields
|
|
168
|
+
})
|
|
169
|
+
});
|
|
170
|
+
$[12] = fields;
|
|
171
|
+
$[13] = t6;
|
|
172
|
+
$[14] = t7;
|
|
173
|
+
} else t7 = $[14];
|
|
174
|
+
let t8;
|
|
175
|
+
if ($[15] !== t5 || $[16] !== t7) {
|
|
176
|
+
t8 = /* @__PURE__ */ jsxs(Fragment, { children: [t5, t7] });
|
|
177
|
+
$[15] = t5;
|
|
178
|
+
$[16] = t7;
|
|
179
|
+
$[17] = t8;
|
|
180
|
+
} else t8 = $[17];
|
|
181
|
+
const content = t8;
|
|
182
|
+
if (node.collapsible === true) {
|
|
183
|
+
let t9;
|
|
184
|
+
if ($[18] !== form || $[19] !== names) {
|
|
185
|
+
t9 = /* @__PURE__ */ jsx(ErrorBadge, {
|
|
186
|
+
form,
|
|
187
|
+
names
|
|
188
|
+
});
|
|
189
|
+
$[18] = form;
|
|
190
|
+
$[19] = names;
|
|
191
|
+
$[20] = t9;
|
|
192
|
+
} else t9 = $[20];
|
|
193
|
+
let t10;
|
|
194
|
+
if ($[21] !== content) {
|
|
195
|
+
t10 = /* @__PURE__ */ jsx("div", {
|
|
196
|
+
className: Form_module_default.stack,
|
|
197
|
+
children: content
|
|
198
|
+
});
|
|
199
|
+
$[21] = content;
|
|
200
|
+
$[22] = t10;
|
|
201
|
+
} else t10 = $[22];
|
|
202
|
+
let t11;
|
|
203
|
+
if ($[23] !== expanded || $[24] !== node.label || $[25] !== t10 || $[26] !== t9) {
|
|
204
|
+
t11 = /* @__PURE__ */ jsx("div", {
|
|
205
|
+
className: Form_module_default.section,
|
|
206
|
+
children: /* @__PURE__ */ jsx(Disclosure, {
|
|
207
|
+
title: node.label,
|
|
208
|
+
titleEnd: t9,
|
|
209
|
+
isExpanded: expanded,
|
|
210
|
+
onExpandedChange: setExpanded,
|
|
211
|
+
children: t10
|
|
212
|
+
})
|
|
213
|
+
});
|
|
214
|
+
$[23] = expanded;
|
|
215
|
+
$[24] = node.label;
|
|
216
|
+
$[25] = t10;
|
|
217
|
+
$[26] = t9;
|
|
218
|
+
$[27] = t11;
|
|
219
|
+
} else t11 = $[27];
|
|
220
|
+
return t11;
|
|
221
|
+
}
|
|
222
|
+
const t9 = node.label !== void 0 ? titleId : void 0;
|
|
223
|
+
let t10;
|
|
224
|
+
if ($[28] !== form || $[29] !== names || $[30] !== node.label || $[31] !== titleId) {
|
|
225
|
+
t10 = node.label !== void 0 ? /* @__PURE__ */ jsx("div", {
|
|
226
|
+
className: Form_module_default.sectionHeader,
|
|
227
|
+
children: /* @__PURE__ */ jsxs("h3", {
|
|
228
|
+
id: titleId,
|
|
229
|
+
className: Form_module_default.sectionTitle,
|
|
230
|
+
children: [
|
|
231
|
+
node.label,
|
|
232
|
+
" ",
|
|
233
|
+
/* @__PURE__ */ jsx(ErrorBadge, {
|
|
234
|
+
form,
|
|
235
|
+
names
|
|
236
|
+
})
|
|
237
|
+
]
|
|
238
|
+
})
|
|
239
|
+
}) : null;
|
|
240
|
+
$[28] = form;
|
|
241
|
+
$[29] = names;
|
|
242
|
+
$[30] = node.label;
|
|
243
|
+
$[31] = titleId;
|
|
244
|
+
$[32] = t10;
|
|
245
|
+
} else t10 = $[32];
|
|
246
|
+
let t11;
|
|
247
|
+
if ($[33] !== content || $[34] !== t10 || $[35] !== t9) {
|
|
248
|
+
t11 = /* @__PURE__ */ jsxs("section", {
|
|
249
|
+
className: Form_module_default.section,
|
|
250
|
+
"aria-labelledby": t9,
|
|
251
|
+
children: [t10, content]
|
|
252
|
+
});
|
|
253
|
+
$[33] = content;
|
|
254
|
+
$[34] = t10;
|
|
255
|
+
$[35] = t9;
|
|
256
|
+
$[36] = t11;
|
|
257
|
+
} else t11 = $[36];
|
|
258
|
+
return t11;
|
|
259
|
+
}
|
|
260
|
+
function ComponentNode(t0) {
|
|
261
|
+
const $ = c(5);
|
|
262
|
+
const { node } = t0;
|
|
263
|
+
const form = useFormContext();
|
|
264
|
+
const { components } = usePlugins();
|
|
265
|
+
let t1;
|
|
266
|
+
let t2;
|
|
267
|
+
if ($[0] !== components || $[1] !== form || $[2] !== node) {
|
|
268
|
+
t2 = Symbol.for("react.early_return_sentinel");
|
|
269
|
+
bb0: {
|
|
270
|
+
const Component = node.component !== void 0 ? components.get(node.component) : void 0;
|
|
271
|
+
if (Component === void 0) {
|
|
272
|
+
t2 = null;
|
|
273
|
+
break bb0;
|
|
274
|
+
}
|
|
275
|
+
t1 = createElement(Component, {
|
|
276
|
+
...node.props,
|
|
277
|
+
node,
|
|
278
|
+
form
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
$[0] = components;
|
|
282
|
+
$[1] = form;
|
|
283
|
+
$[2] = node;
|
|
284
|
+
$[3] = t1;
|
|
285
|
+
$[4] = t2;
|
|
286
|
+
} else {
|
|
287
|
+
t1 = $[3];
|
|
288
|
+
t2 = $[4];
|
|
289
|
+
}
|
|
290
|
+
if (t2 !== Symbol.for("react.early_return_sentinel")) return t2;
|
|
291
|
+
return t1;
|
|
292
|
+
}
|
|
293
|
+
function LayoutNodeView(t0) {
|
|
294
|
+
const $ = c(30);
|
|
295
|
+
const { node, fields } = t0;
|
|
296
|
+
const form = useFormContext();
|
|
297
|
+
const state = useFormState(form);
|
|
298
|
+
if (!selectVisible(state, node)) return null;
|
|
299
|
+
switch (node.type) {
|
|
300
|
+
case "field": {
|
|
301
|
+
let t1;
|
|
302
|
+
if ($[0] !== fields || $[1] !== node.name) {
|
|
303
|
+
t1 = node.name !== void 0 ? fields.get(node.name) : void 0;
|
|
304
|
+
$[0] = fields;
|
|
305
|
+
$[1] = node.name;
|
|
306
|
+
$[2] = t1;
|
|
307
|
+
} else t1 = $[2];
|
|
308
|
+
const field = t1;
|
|
309
|
+
let t2;
|
|
310
|
+
if ($[3] !== field || $[4] !== state) {
|
|
311
|
+
t2 = field !== void 0 ? /* @__PURE__ */ jsx(NestedField, {
|
|
312
|
+
field,
|
|
313
|
+
path: field.name,
|
|
314
|
+
parentValue: state.values
|
|
315
|
+
}) : null;
|
|
316
|
+
$[3] = field;
|
|
317
|
+
$[4] = state;
|
|
318
|
+
$[5] = t2;
|
|
319
|
+
} else t2 = $[5];
|
|
320
|
+
return t2;
|
|
321
|
+
}
|
|
322
|
+
case "row": {
|
|
323
|
+
let t1;
|
|
324
|
+
if ($[6] !== node.children) {
|
|
325
|
+
t1 = node.children ?? [];
|
|
326
|
+
$[6] = node.children;
|
|
327
|
+
$[7] = t1;
|
|
328
|
+
} else t1 = $[7];
|
|
329
|
+
let t2;
|
|
330
|
+
if ($[8] !== fields || $[9] !== t1) {
|
|
331
|
+
let t3;
|
|
332
|
+
if ($[11] !== fields) {
|
|
333
|
+
t3 = (child, index) => /* @__PURE__ */ jsx("div", {
|
|
334
|
+
className: Form_module_default.cell,
|
|
335
|
+
style: { "--panneau-span": child.width ?? 12 },
|
|
336
|
+
children: /* @__PURE__ */ jsx(LayoutNodeView, {
|
|
337
|
+
node: child,
|
|
338
|
+
fields
|
|
339
|
+
})
|
|
340
|
+
}, index);
|
|
341
|
+
$[11] = fields;
|
|
342
|
+
$[12] = t3;
|
|
343
|
+
} else t3 = $[12];
|
|
344
|
+
t2 = t1.map(t3);
|
|
345
|
+
$[8] = fields;
|
|
346
|
+
$[9] = t1;
|
|
347
|
+
$[10] = t2;
|
|
348
|
+
} else t2 = $[10];
|
|
349
|
+
let t3;
|
|
350
|
+
if ($[13] !== t2) {
|
|
351
|
+
t3 = /* @__PURE__ */ jsx("div", {
|
|
352
|
+
className: Form_module_default.row,
|
|
353
|
+
children: t2
|
|
354
|
+
});
|
|
355
|
+
$[13] = t2;
|
|
356
|
+
$[14] = t3;
|
|
357
|
+
} else t3 = $[14];
|
|
358
|
+
return t3;
|
|
359
|
+
}
|
|
360
|
+
case "tabs": {
|
|
361
|
+
let t1;
|
|
362
|
+
if ($[15] !== fields || $[16] !== node) {
|
|
363
|
+
t1 = /* @__PURE__ */ jsx(TabsNode, {
|
|
364
|
+
node,
|
|
365
|
+
fields
|
|
366
|
+
});
|
|
367
|
+
$[15] = fields;
|
|
368
|
+
$[16] = node;
|
|
369
|
+
$[17] = t1;
|
|
370
|
+
} else t1 = $[17];
|
|
371
|
+
return t1;
|
|
372
|
+
}
|
|
373
|
+
case "section": {
|
|
374
|
+
let t1;
|
|
375
|
+
if ($[18] !== fields || $[19] !== node) {
|
|
376
|
+
t1 = /* @__PURE__ */ jsx(SectionNode, {
|
|
377
|
+
node,
|
|
378
|
+
fields
|
|
379
|
+
});
|
|
380
|
+
$[18] = fields;
|
|
381
|
+
$[19] = node;
|
|
382
|
+
$[20] = t1;
|
|
383
|
+
} else t1 = $[20];
|
|
384
|
+
return t1;
|
|
385
|
+
}
|
|
386
|
+
case "text": {
|
|
387
|
+
const t1 = node.text ?? node.label;
|
|
388
|
+
let t2;
|
|
389
|
+
if ($[21] !== t1) {
|
|
390
|
+
t2 = /* @__PURE__ */ jsx("p", {
|
|
391
|
+
className: Form_module_default.text,
|
|
392
|
+
children: t1
|
|
393
|
+
});
|
|
394
|
+
$[21] = t1;
|
|
395
|
+
$[22] = t2;
|
|
396
|
+
} else t2 = $[22];
|
|
397
|
+
return t2;
|
|
398
|
+
}
|
|
399
|
+
case "component": {
|
|
400
|
+
let t1;
|
|
401
|
+
if ($[23] !== node) {
|
|
402
|
+
t1 = /* @__PURE__ */ jsx(ComponentNode, { node });
|
|
403
|
+
$[23] = node;
|
|
404
|
+
$[24] = t1;
|
|
405
|
+
} else t1 = $[24];
|
|
406
|
+
return t1;
|
|
407
|
+
}
|
|
408
|
+
default: {
|
|
409
|
+
let t1;
|
|
410
|
+
if ($[25] !== node.children) {
|
|
411
|
+
t1 = node.children ?? [];
|
|
412
|
+
$[25] = node.children;
|
|
413
|
+
$[26] = t1;
|
|
414
|
+
} else t1 = $[26];
|
|
415
|
+
let t2;
|
|
416
|
+
if ($[27] !== fields || $[28] !== t1) {
|
|
417
|
+
t2 = /* @__PURE__ */ jsx("div", {
|
|
418
|
+
className: Form_module_default.stack,
|
|
419
|
+
children: /* @__PURE__ */ jsx(LayoutNodes, {
|
|
420
|
+
nodes: t1,
|
|
421
|
+
fields
|
|
422
|
+
})
|
|
423
|
+
});
|
|
424
|
+
$[27] = fields;
|
|
425
|
+
$[28] = t1;
|
|
426
|
+
$[29] = t2;
|
|
427
|
+
} else t2 = $[29];
|
|
428
|
+
return t2;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
/** Renders layout nodes in order. */
|
|
433
|
+
function LayoutNodes({ nodes, fields }) {
|
|
434
|
+
return nodes.map((node, index) => /* @__PURE__ */ jsx(LayoutNodeView, {
|
|
435
|
+
node,
|
|
436
|
+
fields
|
|
437
|
+
}, index));
|
|
438
|
+
}
|
|
439
|
+
//#endregion
|
|
440
|
+
export { LayoutNodes };
|
|
441
|
+
|
|
442
|
+
//# sourceMappingURL=Layout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Layout.js","names":["count","index","tab","fields","selected","form","names","content","expanded","setExpanded","titleId","field","child","node","_c","styles","_Fragment"],"sources":["../../src/layout/Layout.tsx"],"sourcesContent":["import {\n type CSSProperties,\n type ReactNode,\n createElement,\n use,\n useEffect,\n useId,\n useState,\n} from 'react';\n\nimport {\n type Form,\n getLayoutFieldNames,\n selectErrorCount,\n selectVisible,\n usePlugins,\n} from '@panneau/core';\nimport { NestedField } from '@panneau/fields';\nimport type { Field, LayoutNode } from '@panneau/protocol';\nimport { Badge, Disclosure, Tab, TabList, TabPanel, Tabs, usePanneauIntl } from '@panneau/ui';\n\nimport styles from '../Form.module.css';\nimport { RevealContext, useFormContext, useFormState } from '../context';\nimport { messages } from '../messages';\n\nexport interface LayoutProps {\n nodes: readonly LayoutNode[];\n fields: ReadonlyMap<string, Field>;\n}\n\n/** Whether a path belongs to one of the field names (`title.fr` to `title`). */\nfunction containsPath(names: readonly string[], path: string): boolean {\n const name = path.split('.')[0];\n return name !== undefined && names.includes(name);\n}\n\nfunction ErrorBadge({ form, names }: { form: Form; names: readonly string[] }) {\n const intl = usePanneauIntl();\n const count = selectErrorCount(useFormState(form), names);\n if (count === 0) {\n return null;\n }\n return (\n <Badge tone=\"danger\" label={intl.formatMessage(messages.errorCount, { count })}>\n {count}\n </Badge>\n );\n}\n\nfunction TabsNode({ node, fields }: { node: LayoutNode; fields: ReadonlyMap<string, Field> }) {\n const form = useFormContext();\n const state = useFormState(form);\n const registry = use(RevealContext);\n const id = useId();\n const tabs = (node.children ?? []).filter(\n (child) => child.type === 'tab' && selectVisible(state, child),\n );\n const names = tabs.map((tab) => getLayoutFieldNames(tab.children ?? []));\n const [selected, setSelected] = useState<string>(`${id}-0`);\n\n useEffect(\n () =>\n registry.add((path) => {\n const index = names.findIndex((tabNames) => containsPath(tabNames, path));\n if (index !== -1) {\n setSelected(`${id}-${index}`);\n }\n }),\n [registry, names, id],\n );\n\n return (\n <Tabs selectedKey={selected} onSelectionChange={(key) => setSelected(String(key))}>\n <TabList aria-label={node.label ?? tabs.map((tab) => tab.label ?? '').join(', ')}>\n {tabs.map((tab, index) => (\n <Tab key={index} id={`${id}-${index}`}>\n {tab.label} <ErrorBadge form={form} names={names[index] ?? []} />\n </Tab>\n ))}\n </TabList>\n {tabs.map((tab, index) => (\n // Panels stay mounted: fields keep their state, and errors can be revealed.\n <TabPanel key={index} id={`${id}-${index}`} shouldForceMount>\n <div className={styles.stack}>\n <LayoutNodes nodes={tab.children ?? []} fields={fields} />\n </div>\n </TabPanel>\n ))}\n </Tabs>\n );\n}\n\nfunction SectionNode({ node, fields }: { node: LayoutNode; fields: ReadonlyMap<string, Field> }) {\n const form = useFormContext();\n const registry = use(RevealContext);\n const titleId = useId();\n const names = getLayoutFieldNames(node.children ?? []);\n const [expanded, setExpanded] = useState(node.collapsed !== true);\n\n useEffect(\n () =>\n registry.add((path) => {\n if (containsPath(names, path)) {\n setExpanded(true);\n }\n }),\n [registry, names],\n );\n\n const content = (\n <>\n {node.description !== undefined ? (\n <p className={styles.sectionDescription}>{node.description}</p>\n ) : null}\n <div className={styles.stack}>\n <LayoutNodes nodes={node.children ?? []} fields={fields} />\n </div>\n </>\n );\n if (node.collapsible === true) {\n return (\n <div className={styles.section}>\n <Disclosure\n title={node.label}\n titleEnd={<ErrorBadge form={form} names={names} />}\n isExpanded={expanded}\n onExpandedChange={setExpanded}\n >\n <div className={styles.stack}>{content}</div>\n </Disclosure>\n </div>\n );\n }\n return (\n <section\n className={styles.section}\n aria-labelledby={node.label !== undefined ? titleId : undefined}\n >\n {node.label !== undefined ? (\n <div className={styles.sectionHeader}>\n <h3 id={titleId} className={styles.sectionTitle}>\n {node.label} <ErrorBadge form={form} names={names} />\n </h3>\n </div>\n ) : null}\n {content}\n </section>\n );\n}\n\nfunction ComponentNode({ node }: { node: LayoutNode }) {\n const form = useFormContext();\n const { components } = usePlugins();\n const Component = node.component !== undefined ? components.get(node.component) : undefined;\n if (Component === undefined) {\n return null;\n }\n // A component of the plugin registry, looked up by name: not created during render.\n return createElement(Component, { ...node.props, node, form });\n}\n\nfunction LayoutNodeView({\n node,\n fields,\n}: {\n node: LayoutNode;\n fields: ReadonlyMap<string, Field>;\n}) {\n const form = useFormContext();\n const state = useFormState(form);\n if (!selectVisible(state, node)) {\n return null;\n }\n switch (node.type) {\n case 'field': {\n const field = node.name !== undefined ? fields.get(node.name) : undefined;\n return field !== undefined ? (\n <NestedField field={field} path={field.name} parentValue={state.values} />\n ) : null;\n }\n case 'row':\n return (\n <div className={styles.row}>\n {(node.children ?? []).map((child, index) => (\n <div\n key={index}\n className={styles.cell}\n style={{ '--panneau-span': child.width ?? 12 } as CSSProperties}\n >\n <LayoutNodeView node={child} fields={fields} />\n </div>\n ))}\n </div>\n );\n case 'tabs':\n return <TabsNode node={node} fields={fields} />;\n case 'section':\n return <SectionNode node={node} fields={fields} />;\n case 'text':\n return <p className={styles.text}>{node.text ?? node.label}</p>;\n case 'component':\n return <ComponentNode node={node} />;\n default:\n // `column`, a `tab` or a `sidebar` out of place, and unknown containers.\n return (\n <div className={styles.stack}>\n <LayoutNodes nodes={node.children ?? []} fields={fields} />\n </div>\n );\n }\n}\n\n/** Renders layout nodes in order. */\nexport function LayoutNodes({ nodes, fields }: LayoutProps): ReactNode {\n return nodes.map((node, index) => <LayoutNodeView key={index} node={node} fields={fields} />);\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The English messages of `@panneau/forms`, by id. They are also the default messages.
|
|
3
|
+
*
|
|
4
|
+
* @deprecated Use `en`, or `withPanneauMessages()`, from `@panneau/intl`: they have the messages
|
|
5
|
+
* of every package.
|
|
6
|
+
*/
|
|
7
|
+
export declare const en: Record<string, string>;
|
|
8
|
+
/**
|
|
9
|
+
* The French messages of `@panneau/forms`, by id.
|
|
10
|
+
*
|
|
11
|
+
* @deprecated Use `fr`, or `withPanneauMessages()`, from `@panneau/intl`: they have the messages
|
|
12
|
+
* of every package.
|
|
13
|
+
*/
|
|
14
|
+
export declare const fr: Record<string, string>;
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/locales/index.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH,eAAO,MAAM,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAgC,CAAC;AAEvE;;;;;GAKG;AACH,eAAO,MAAM,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAErC,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { messages } from "../messages.js";
|
|
2
|
+
import { fr as fr$1, getDefaultMessages } from "@panneau/intl";
|
|
3
|
+
//#region src/locales/index.ts
|
|
4
|
+
/**
|
|
5
|
+
* The English messages of `@panneau/forms`, by id. They are also the default messages.
|
|
6
|
+
*
|
|
7
|
+
* @deprecated Use `en`, or `withPanneauMessages()`, from `@panneau/intl`: they have the messages
|
|
8
|
+
* of every package.
|
|
9
|
+
*/
|
|
10
|
+
var en = getDefaultMessages(messages);
|
|
11
|
+
/**
|
|
12
|
+
* The French messages of `@panneau/forms`, by id.
|
|
13
|
+
*
|
|
14
|
+
* @deprecated Use `fr`, or `withPanneauMessages()`, from `@panneau/intl`: they have the messages
|
|
15
|
+
* of every package.
|
|
16
|
+
*/
|
|
17
|
+
var fr = Object.fromEntries(Object.entries(fr$1).filter(([id]) => id in en));
|
|
18
|
+
//#endregion
|
|
19
|
+
export { en, fr };
|
|
20
|
+
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["allFr"],"sources":["../../src/locales/index.ts"],"sourcesContent":["import { fr as allFr, getDefaultMessages } from '@panneau/intl';\n\nimport { messages } from '../messages';\n\n/**\n * The English messages of `@panneau/forms`, by id. They are also the default messages.\n *\n * @deprecated Use `en`, or `withPanneauMessages()`, from `@panneau/intl`: they have the messages\n * of every package.\n */\nexport const en: Record<string, string> = getDefaultMessages(messages);\n\n/**\n * The French messages of `@panneau/forms`, by id.\n *\n * @deprecated Use `fr`, or `withPanneauMessages()`, from `@panneau/intl`: they have the messages\n * of every package.\n */\nexport const fr: Record<string, string> = Object.fromEntries(\n Object.entries(allFr).filter(([id]) => id in en),\n);\n"],"mappings":";;;;;;;;;AAUA,IAAa,KAA6B,mBAAmB,QAAQ;;;;;;;AAQrE,IAAa,KAA6B,OAAO,YAC7C,OAAO,QAAQA,IAAK,CAAC,CAAC,QAAQ,CAAC,QAAQ,MAAM,EAAE,CACnD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,IAAI,QAAQ,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/messages.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { formsMessages as messages } from "@panneau/intl";
|
package/dist/paths.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Field } from '@panneau/protocol';
|
|
2
|
+
/** A step from a field to the value at a path: the field, and a locale or an item index. */
|
|
3
|
+
export interface PathStep {
|
|
4
|
+
field: Field;
|
|
5
|
+
locale?: string;
|
|
6
|
+
index?: number;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* The fields that a dot path goes through (`blocks.2.body.fr`: `blocks`, item 3, `body` in
|
|
10
|
+
* French). Typed blocks are searched in all their types. Returns `[]` for an unknown path.
|
|
11
|
+
*/
|
|
12
|
+
export declare function getPathSteps(fields: readonly Field[], path: string): PathStep[];
|
|
13
|
+
/** The field a path ends on, if the path is known. */
|
|
14
|
+
export declare function getFieldAtPath(fields: readonly Field[], path: string): Field | undefined;
|
|
15
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE/C,4FAA4F;AAC5F,MAAM,WAAW,QAAQ;IACrB,KAAK,EAAE,KAAK,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAMD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,QAAQ,EAAE,CA2B/E;AAED,sDAAsD;AACtD,wBAAgB,cAAc,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAExF"}
|
package/dist/paths.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
//#region src/paths.ts
|
|
2
|
+
function nested(field) {
|
|
3
|
+
return [...field.fields ?? [], ...(field.types ?? []).flatMap((type) => type.fields)];
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* The fields that a dot path goes through (`blocks.2.body.fr`: `blocks`, item 3, `body` in
|
|
7
|
+
* French). Typed blocks are searched in all their types. Returns `[]` for an unknown path.
|
|
8
|
+
*/
|
|
9
|
+
function getPathSteps(fields, path) {
|
|
10
|
+
const steps = [];
|
|
11
|
+
const segments = path.split(".");
|
|
12
|
+
let candidates = fields;
|
|
13
|
+
for (let index = 0; index < segments.length; index += 1) {
|
|
14
|
+
const field = candidates.find((candidate) => candidate.name === segments[index]);
|
|
15
|
+
if (field === void 0) return [];
|
|
16
|
+
const step = { field };
|
|
17
|
+
steps.push(step);
|
|
18
|
+
const next = segments[index + 1];
|
|
19
|
+
if (field.localized === true && next !== void 0) {
|
|
20
|
+
step.locale = next;
|
|
21
|
+
index += 1;
|
|
22
|
+
}
|
|
23
|
+
if (field.type === "repeater" && next !== void 0 && /^\d+$/.test(segments[index + 1] ?? "")) {
|
|
24
|
+
step.index = Number(segments[index + 1]);
|
|
25
|
+
index += 1;
|
|
26
|
+
}
|
|
27
|
+
candidates = nested(field);
|
|
28
|
+
}
|
|
29
|
+
return steps;
|
|
30
|
+
}
|
|
31
|
+
//#endregion
|
|
32
|
+
export { getPathSteps };
|
|
33
|
+
|
|
34
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","names":[],"sources":["../src/paths.ts"],"sourcesContent":["import type { Field } from '@panneau/protocol';\n\n/** A step from a field to the value at a path: the field, and a locale or an item index. */\nexport interface PathStep {\n field: Field;\n locale?: string;\n index?: number;\n}\n\nfunction nested(field: Field): Field[] {\n return [...(field.fields ?? []), ...(field.types ?? []).flatMap((type) => type.fields)];\n}\n\n/**\n * The fields that a dot path goes through (`blocks.2.body.fr`: `blocks`, item 3, `body` in\n * French). Typed blocks are searched in all their types. Returns `[]` for an unknown path.\n */\nexport function getPathSteps(fields: readonly Field[], path: string): PathStep[] {\n const steps: PathStep[] = [];\n const segments = path.split('.');\n let candidates: readonly Field[] = fields;\n for (let index = 0; index < segments.length; index += 1) {\n const field = candidates.find((candidate) => candidate.name === segments[index]);\n if (field === undefined) {\n return [];\n }\n const step: PathStep = { field };\n steps.push(step);\n const next = segments[index + 1];\n if (field.localized === true && next !== undefined) {\n step.locale = next;\n index += 1;\n }\n if (\n field.type === 'repeater' &&\n next !== undefined &&\n /^\\d+$/.test(segments[index + 1] ?? '')\n ) {\n step.index = Number(segments[index + 1]);\n index += 1;\n }\n candidates = nested(field);\n }\n return steps;\n}\n\n/** The field a path ends on, if the path is known. */\nexport function getFieldAtPath(fields: readonly Field[], path: string): Field | undefined {\n return getPathSteps(fields, path).at(-1)?.field;\n}\n"],"mappings":";AASA,SAAS,OAAO,OAAuB;CACnC,OAAO,CAAC,GAAI,MAAM,UAAU,CAAA,GAAK,IAAI,MAAM,SAAS,CAAA,EAAA,CAAI,SAAS,SAAS,KAAK,MAAM,CAAC;AAC1F;;;;;AAMA,SAAgB,aAAa,QAA0B,MAA0B;CAC7E,MAAM,QAAoB,CAAA;CAC1B,MAAM,WAAW,KAAK,MAAM,GAAG;CAC/B,IAAI,aAA+B;CACnC,KAAK,IAAI,QAAQ,GAAG,QAAQ,SAAS,QAAQ,SAAS,GAAG;EACrD,MAAM,QAAQ,WAAW,MAAM,cAAc,UAAU,SAAS,SAAS,MAAM;EAC/E,IAAI,UAAU,KAAA,GACV,OAAO,CAAA;EAEX,MAAM,OAAiB,EAAE,MAAM;EAC/B,MAAM,KAAK,IAAI;EACf,MAAM,OAAO,SAAS,QAAQ;EAC9B,IAAI,MAAM,cAAc,QAAQ,SAAS,KAAA,GAAW;GAChD,KAAK,SAAS;GACd,SAAS;EACb;EACA,IACI,MAAM,SAAS,cACf,SAAS,KAAA,KACT,QAAQ,KAAK,SAAS,QAAQ,MAAM,EAAE,GACxC;GACE,KAAK,QAAQ,OAAO,SAAS,QAAQ,EAAE;GACvC,SAAS;EACb;EACA,aAAa,OAAO,KAAK;CAC7B;CACA,OAAO;AACX"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Asks the browser to confirm before the page is closed or reloaded while `dirty` is true. Forms
|
|
4
|
+
* use it by default.
|
|
5
|
+
*/
|
|
6
|
+
export declare function useBeforeUnloadGuard(dirty: boolean): void;
|
|
7
|
+
export interface LeaveConfirmation {
|
|
8
|
+
/**
|
|
9
|
+
* Resolves `true` when leaving is fine: right away without unsaved changes, or once the user
|
|
10
|
+
* chose to leave in the dialog.
|
|
11
|
+
*/
|
|
12
|
+
confirmLeave: () => Promise<boolean>;
|
|
13
|
+
/** The dialog to render, while it is open. */
|
|
14
|
+
dialog: ReactNode;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Guards in-app navigation while a form has unsaved changes. Call `confirmLeave()` from the
|
|
18
|
+
* router's navigation guard (or before closing a panel), and render `dialog`. The page itself is
|
|
19
|
+
* guarded by `useBeforeUnloadGuard()`.
|
|
20
|
+
*/
|
|
21
|
+
export declare function useLeaveConfirmation(dirty: boolean): LeaveConfirmation;
|
|
22
|
+
//# sourceMappingURL=unsaved.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unsaved.d.ts","sourceRoot":"","sources":["../src/unsaved.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAA+B,MAAM,OAAO,CAAC;AAMpE;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAazD;AAED,MAAM,WAAW,iBAAiB;IAC9B;;;OAGG;IACH,YAAY,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IACrC,8CAA8C;IAC9C,MAAM,EAAE,SAAS,CAAC;CACrB;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,iBAAiB,CA8CtE"}
|