@embedpdf/viewer-chrome 3.0.0-next.13 → 3.0.0-next.15
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 +175 -132
- package/dist/annotation-fonts-BqoLZ4Mp.js +80 -0
- package/dist/annotation-fonts-BqoLZ4Mp.js.map +1 -0
- package/dist/annotation-fonts-Dt0IQXhz.cjs +91 -0
- package/dist/annotation-fonts-Dt0IQXhz.cjs.map +1 -0
- package/dist/annotation-style--rPIZsuP.js +879 -0
- package/dist/annotation-style--rPIZsuP.js.map +1 -0
- package/dist/annotation-style-Bzvvp8-N.cjs +879 -0
- package/dist/annotation-style-Bzvvp8-N.cjs.map +1 -0
- package/dist/ar-D9XKAmDx.js +567 -0
- package/dist/ar-D9XKAmDx.js.map +1 -0
- package/dist/ar-DnEj5vbP.cjs +567 -0
- package/dist/ar-DnEj5vbP.cjs.map +1 -0
- package/dist/chrome.cjs +378 -221
- package/dist/chrome.cjs.map +1 -1
- package/dist/chrome.d.cts +5 -34
- package/dist/chrome.d.ts +5 -34
- package/dist/chrome.js +377 -218
- package/dist/chrome.js.map +1 -1
- package/dist/commands-BmgxhJ8B.js +953 -0
- package/dist/commands-BmgxhJ8B.js.map +1 -0
- package/dist/commands-CYt4SFUX.cjs +1060 -0
- package/dist/commands-CYt4SFUX.cjs.map +1 -0
- package/dist/commands.cjs +12 -595
- package/dist/commands.d.cts +29 -4
- package/dist/commands.d.ts +29 -4
- package/dist/commands.js +2 -593
- package/dist/comments-panel-MUVgLCBI.js +514 -0
- package/dist/comments-panel-MUVgLCBI.js.map +1 -0
- package/dist/comments-panel-pEcQg4Vs.cjs +514 -0
- package/dist/comments-panel-pEcQg4Vs.cjs.map +1 -0
- package/dist/de-Bdr4aWzm.js +566 -0
- package/dist/de-Bdr4aWzm.js.map +1 -0
- package/dist/de-Dv6zvbnd.cjs +566 -0
- package/dist/de-Dv6zvbnd.cjs.map +1 -0
- package/dist/dialog-B5GBisKv.js +55 -0
- package/dist/dialog-B5GBisKv.js.map +1 -0
- package/dist/dialog-t8F13BL_.cjs +60 -0
- package/dist/dialog-t8F13BL_.cjs.map +1 -0
- package/dist/es-BP09DR9w.cjs +566 -0
- package/dist/es-BP09DR9w.cjs.map +1 -0
- package/dist/es-BSXz5tBv.js +566 -0
- package/dist/es-BSXz5tBv.js.map +1 -0
- package/dist/form-design-panel-B5MXTZ96.cjs +418 -0
- package/dist/form-design-panel-B5MXTZ96.cjs.map +1 -0
- package/dist/form-design-panel-vWWU9uB-.js +418 -0
- package/dist/form-design-panel-vWWU9uB-.js.map +1 -0
- package/dist/fr-BBQQn7tJ.cjs +566 -0
- package/dist/fr-BBQQn7tJ.cjs.map +1 -0
- package/dist/fr-Ckn3K9v1.js +566 -0
- package/dist/fr-Ckn3K9v1.js.map +1 -0
- package/dist/he-DRsG7bH7.cjs +567 -0
- package/dist/he-DRsG7bH7.cjs.map +1 -0
- package/dist/he-wdGU5PkU.js +567 -0
- package/dist/he-wdGU5PkU.js.map +1 -0
- package/dist/icons-BrK5iVL8.js +856 -0
- package/dist/icons-BrK5iVL8.js.map +1 -0
- package/dist/icons-x0Tc05bs.cjs +1010 -0
- package/dist/icons-x0Tc05bs.cjs.map +1 -0
- package/dist/index.cjs +3162 -5106
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +636 -143
- package/dist/index.d.ts +636 -143
- package/dist/index.js +3083 -4975
- package/dist/index.js.map +1 -1
- package/dist/it-BuP4o0xQ.cjs +566 -0
- package/dist/it-BuP4o0xQ.cjs.map +1 -0
- package/dist/it-Us-VmvIu.js +566 -0
- package/dist/it-Us-VmvIu.js.map +1 -0
- package/dist/ja-Cizj0-5O.js +566 -0
- package/dist/ja-Cizj0-5O.js.map +1 -0
- package/dist/ja-DovEd6ts.cjs +566 -0
- package/dist/ja-DovEd6ts.cjs.map +1 -0
- package/dist/ko-B-qJEol2.cjs +566 -0
- package/dist/ko-B-qJEol2.cjs.map +1 -0
- package/dist/ko-DlrXliE1.js +566 -0
- package/dist/ko-DlrXliE1.js.map +1 -0
- package/dist/labels-BiM9wp9K.cjs +21 -0
- package/dist/labels-BiM9wp9K.cjs.map +1 -0
- package/dist/labels-C6_i87Oj.js +16 -0
- package/dist/labels-C6_i87Oj.js.map +1 -0
- package/dist/link-editor-CSjqPnj1.cjs +125 -0
- package/dist/link-editor-CSjqPnj1.cjs.map +1 -0
- package/dist/link-editor-SxM1nnJU.js +125 -0
- package/dist/link-editor-SxM1nnJU.js.map +1 -0
- package/dist/measurement-Bs61XWbJ.js +325 -0
- package/dist/measurement-Bs61XWbJ.js.map +1 -0
- package/dist/measurement-CcCsHPOX.cjs +326 -0
- package/dist/measurement-CcCsHPOX.cjs.map +1 -0
- package/dist/nl-0aF7M_0h.js +566 -0
- package/dist/nl-0aF7M_0h.js.map +1 -0
- package/dist/nl-D3KZDDiJ.cjs +566 -0
- package/dist/nl-D3KZDDiJ.cjs.map +1 -0
- package/dist/pl-BW--AaCI.js +566 -0
- package/dist/pl-BW--AaCI.js.map +1 -0
- package/dist/pl-DSFhAUqx.cjs +566 -0
- package/dist/pl-DSFhAUqx.cjs.map +1 -0
- package/dist/pt-C5S-8MC5.cjs +566 -0
- package/dist/pt-C5S-8MC5.cjs.map +1 -0
- package/dist/pt-DIhpU5pT.js +566 -0
- package/dist/pt-DIhpU5pT.js.map +1 -0
- package/dist/redact-confirm-B6j36TPw.js +83 -0
- package/dist/redact-confirm-B6j36TPw.js.map +1 -0
- package/dist/redact-confirm-CX_SY2ZN.cjs +83 -0
- package/dist/redact-confirm-CX_SY2ZN.cjs.map +1 -0
- package/dist/redaction-panel-BmoIl-Ll.cjs +96 -0
- package/dist/redaction-panel-BmoIl-Ll.cjs.map +1 -0
- package/dist/redaction-panel-IJDshSJI.js +96 -0
- package/dist/redaction-panel-IJDshSJI.js.map +1 -0
- package/dist/search-panel-HfIhJm1M.js +249 -0
- package/dist/search-panel-HfIhJm1M.js.map +1 -0
- package/dist/search-panel-s9IoiOtv.cjs +249 -0
- package/dist/search-panel-s9IoiOtv.cjs.map +1 -0
- package/dist/sheet-BDsa_Sup.cjs +442 -0
- package/dist/sheet-BDsa_Sup.cjs.map +1 -0
- package/dist/sheet-R6XDgyEf.js +365 -0
- package/dist/sheet-R6XDgyEf.js.map +1 -0
- package/dist/sign-dialog-CgnR7akj.cjs +155 -0
- package/dist/sign-dialog-CgnR7akj.cjs.map +1 -0
- package/dist/sign-dialog-GDqCoQhA.js +155 -0
- package/dist/sign-dialog-GDqCoQhA.js.map +1 -0
- package/dist/signature-inspector-DyO313Qf.cjs +166 -0
- package/dist/signature-inspector-DyO313Qf.cjs.map +1 -0
- package/dist/signature-inspector-okFz8do6.js +166 -0
- package/dist/signature-inspector-okFz8do6.js.map +1 -0
- package/dist/signature-maker-BhCmYyHD.js +393 -0
- package/dist/signature-maker-BhCmYyHD.js.map +1 -0
- package/dist/signature-maker-BoYa8vgA.cjs +393 -0
- package/dist/signature-maker-BoYa8vgA.cjs.map +1 -0
- package/dist/signatures-panel-B56PC6d9.cjs +300 -0
- package/dist/signatures-panel-B56PC6d9.cjs.map +1 -0
- package/dist/signatures-panel-CgnFfhFm.js +300 -0
- package/dist/signatures-panel-CgnFfhFm.js.map +1 -0
- package/dist/stamp-store-BHvRs-Do.cjs +147 -0
- package/dist/stamp-store-BHvRs-Do.cjs.map +1 -0
- package/dist/stamp-store-WuF-L3Jj.js +112 -0
- package/dist/stamp-store-WuF-L3Jj.js.map +1 -0
- package/dist/stamps-panel-B9NYGayn.cjs +231 -0
- package/dist/stamps-panel-B9NYGayn.cjs.map +1 -0
- package/dist/stamps-panel-CDO0FPyK.js +231 -0
- package/dist/stamps-panel-CDO0FPyK.js.map +1 -0
- package/dist/toolbar-CJu2wKTU.cjs +1659 -0
- package/dist/toolbar-CJu2wKTU.cjs.map +1 -0
- package/dist/toolbar-z9od3tKl.js +1564 -0
- package/dist/toolbar-z9od3tKl.js.map +1 -0
- package/dist/zh-cn-3tmMeHqv.cjs +566 -0
- package/dist/zh-cn-3tmMeHqv.cjs.map +1 -0
- package/dist/zh-cn-CxkUUBct.js +566 -0
- package/dist/zh-cn-CxkUUBct.js.map +1 -0
- package/package.json +6 -4
- package/src/styles.css +153 -89
- package/dist/commands.cjs.map +0 -1
- package/dist/commands.js.map +0 -1
- package/dist/es-DYwzfxyt.cjs +0 -293
- package/dist/es-DYwzfxyt.cjs.map +0 -1
- package/dist/es-sN6uqBgD.js +0 -293
- package/dist/es-sN6uqBgD.js.map +0 -1
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
const require_icons = require("./icons-x0Tc05bs.cjs");
|
|
2
|
+
const require_commands = require("./commands-CYt4SFUX.cjs");
|
|
3
|
+
const require_labels = require("./labels-BiM9wp9K.cjs");
|
|
4
|
+
let react = require("react");
|
|
5
|
+
let _embedpdf_react_runtime = require("@embedpdf/react/runtime");
|
|
6
|
+
let _embedpdf_react_stage = require("@embedpdf/react/stage");
|
|
7
|
+
let _embedpdf_react_interaction = require("@embedpdf/react/interaction");
|
|
8
|
+
let _embedpdf_react_annotation = require("@embedpdf/react/annotation");
|
|
9
|
+
let _embedpdf_react_form = require("@embedpdf/react/form");
|
|
10
|
+
let _embedpdf_react_i18n = require("@embedpdf/react/i18n");
|
|
11
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
12
|
+
//#region src/ui/field-settings.tsx
|
|
13
|
+
/**
|
|
14
|
+
* A field's settings, as the form plugin describes them (`getFieldSettings`),
|
|
15
|
+
* written with `form.update()`: the form designer's sidebar shows them for the
|
|
16
|
+
* selected field. Nothing here knows a field family: the description says what
|
|
17
|
+
* to draw.
|
|
18
|
+
*/
|
|
19
|
+
const inputClass = "border-border bg-surface text-fg w-full rounded-md border px-2 py-1.5 text-sm";
|
|
20
|
+
/** The field's settings, each with the control its description names. */
|
|
21
|
+
function FieldSettings({ field }) {
|
|
22
|
+
const form = (0, _embedpdf_react_runtime.useOptionalCapability)(_embedpdf_react_form.FormToken);
|
|
23
|
+
const settings = (0, _embedpdf_react_runtime.useOptionalSelector)(_embedpdf_react_form.FormToken, (capability) => capability.getFieldSettings(field.ref), null);
|
|
24
|
+
if (!form || !settings || !form.canDesign()) return null;
|
|
25
|
+
const write = (patch) => void form.update(field.ref, patch).catch(() => void 0);
|
|
26
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: settings.properties.map((spec) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SettingControl, {
|
|
27
|
+
fieldKey: JSON.stringify(field.ref),
|
|
28
|
+
spec,
|
|
29
|
+
value: settings.values[spec.key],
|
|
30
|
+
onChange: (value) => write({ [spec.key]: value })
|
|
31
|
+
}, `${spec.key}:${spec.control}`)) });
|
|
32
|
+
}
|
|
33
|
+
function SettingControl({ fieldKey, spec, value, onChange }) {
|
|
34
|
+
const t = (0, _embedpdf_react_i18n.useT)();
|
|
35
|
+
const label = require_labels.useLabel();
|
|
36
|
+
switch (spec.control) {
|
|
37
|
+
case "flag": return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
38
|
+
className: "text-fg mb-2 flex items-center gap-2 text-sm",
|
|
39
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
40
|
+
type: "checkbox",
|
|
41
|
+
checked: value === true,
|
|
42
|
+
onChange: (event) => onChange(event.target.checked)
|
|
43
|
+
}), label(spec)]
|
|
44
|
+
});
|
|
45
|
+
case "text": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Setting, {
|
|
46
|
+
label: label(spec),
|
|
47
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CommittedInput, {
|
|
48
|
+
value: typeof value === "string" ? value : "",
|
|
49
|
+
onCommit: onChange
|
|
50
|
+
}, fieldKey)
|
|
51
|
+
});
|
|
52
|
+
case "number": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Setting, {
|
|
53
|
+
label: label(spec),
|
|
54
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CommittedInput, {
|
|
55
|
+
type: "number",
|
|
56
|
+
min: spec.min,
|
|
57
|
+
placeholder: t("demo.fieldNone"),
|
|
58
|
+
value: typeof value === "number" ? String(value) : "",
|
|
59
|
+
onCommit: (text) => onChange(text === "" ? null : Math.max(spec.min, Number(text)))
|
|
60
|
+
}, fieldKey)
|
|
61
|
+
});
|
|
62
|
+
case "choice": return spec.free ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Setting, {
|
|
63
|
+
label: label(spec),
|
|
64
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(CommittedInput, {
|
|
65
|
+
list: `${fieldKey}-choices`,
|
|
66
|
+
value: typeof value === "string" ? value : "",
|
|
67
|
+
onCommit: onChange
|
|
68
|
+
}, fieldKey), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("datalist", {
|
|
69
|
+
id: `${fieldKey}-choices`,
|
|
70
|
+
children: spec.options.map((option) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", { value: option }, option))
|
|
71
|
+
})]
|
|
72
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Setting, {
|
|
73
|
+
label: label(spec),
|
|
74
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
75
|
+
className: inputClass,
|
|
76
|
+
value: typeof value === "string" ? value : "",
|
|
77
|
+
onChange: (event) => onChange(event.target.value === "" ? null : event.target.value),
|
|
78
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
79
|
+
value: "",
|
|
80
|
+
children: t("demo.fieldNone")
|
|
81
|
+
}), spec.options.map((option) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
82
|
+
value: option,
|
|
83
|
+
children: option
|
|
84
|
+
}, option))]
|
|
85
|
+
})
|
|
86
|
+
});
|
|
87
|
+
case "choices": {
|
|
88
|
+
const chosen = new Set(Array.isArray(value) ? value : []);
|
|
89
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Setting, {
|
|
90
|
+
label: label(spec),
|
|
91
|
+
children: spec.options.map((option) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
92
|
+
className: "text-fg mb-1 flex items-center gap-2 text-sm",
|
|
93
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
94
|
+
type: "checkbox",
|
|
95
|
+
checked: chosen.has(option),
|
|
96
|
+
onChange: (event) => onChange(spec.options.filter((each) => each === option ? event.target.checked : chosen.has(each)))
|
|
97
|
+
}), option]
|
|
98
|
+
}, option))
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
case "options": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Setting, {
|
|
102
|
+
label: label(spec),
|
|
103
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(OptionsEditor, {
|
|
104
|
+
options: Array.isArray(value) ? value : [],
|
|
105
|
+
onCommit: onChange
|
|
106
|
+
}, fieldKey)
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
function Setting({ label, children }) {
|
|
111
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
112
|
+
className: "mb-3",
|
|
113
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
114
|
+
className: "text-fg mb-1 block text-sm font-medium",
|
|
115
|
+
children: label
|
|
116
|
+
}), children]
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
/** A text input that writes on blur or Enter, and keeps what's typed until then. */
|
|
120
|
+
function CommittedInput({ value, onCommit, ...input }) {
|
|
121
|
+
const [draft, setDraft] = (0, react.useState)(null);
|
|
122
|
+
(0, react.useEffect)(() => setDraft(null), [value]);
|
|
123
|
+
const commit = () => {
|
|
124
|
+
if (draft === null || draft === value) return;
|
|
125
|
+
onCommit(draft);
|
|
126
|
+
};
|
|
127
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
128
|
+
...input,
|
|
129
|
+
className: inputClass,
|
|
130
|
+
value: draft ?? value,
|
|
131
|
+
onChange: (event) => setDraft(event.target.value),
|
|
132
|
+
onBlur: commit,
|
|
133
|
+
onKeyDown: (event) => event.key === "Enter" && commit()
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
/** A dropdown's or list's options, each a label and a value; written as a whole on each edit. */
|
|
137
|
+
function OptionsEditor({ options, onCommit }) {
|
|
138
|
+
const t = (0, _embedpdf_react_i18n.useT)();
|
|
139
|
+
const rows = options.map((option) => ({
|
|
140
|
+
label: option.label,
|
|
141
|
+
value: option.value
|
|
142
|
+
}));
|
|
143
|
+
const replace = (at, row) => onCommit(row === null ? rows.filter((_, index) => index !== at) : rows.map((each, index) => index === at ? row : each));
|
|
144
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [rows.map((row, at) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
145
|
+
className: "mb-1 flex gap-1",
|
|
146
|
+
children: [
|
|
147
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(CommittedInput, {
|
|
148
|
+
"aria-label": t("demo.fieldOptionLabel"),
|
|
149
|
+
value: row.label,
|
|
150
|
+
onCommit: (label) => replace(at, {
|
|
151
|
+
...row,
|
|
152
|
+
label
|
|
153
|
+
})
|
|
154
|
+
}),
|
|
155
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(CommittedInput, {
|
|
156
|
+
"aria-label": t("demo.fieldOptionValue"),
|
|
157
|
+
value: row.value,
|
|
158
|
+
onCommit: (value) => replace(at, {
|
|
159
|
+
...row,
|
|
160
|
+
value
|
|
161
|
+
})
|
|
162
|
+
}),
|
|
163
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
164
|
+
type: "button",
|
|
165
|
+
title: t("demo.fieldOptionRemove"),
|
|
166
|
+
className: "text-fg-muted hover:text-fg px-1",
|
|
167
|
+
onClick: () => replace(at, null),
|
|
168
|
+
children: "×"
|
|
169
|
+
})
|
|
170
|
+
]
|
|
171
|
+
}, `${at}:${row.value}`)), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
172
|
+
type: "button",
|
|
173
|
+
className: "text-accent text-sm",
|
|
174
|
+
onClick: () => {
|
|
175
|
+
const label = `Option ${rows.length + 1}`;
|
|
176
|
+
onCommit([...rows, {
|
|
177
|
+
label,
|
|
178
|
+
value: label
|
|
179
|
+
}]);
|
|
180
|
+
},
|
|
181
|
+
children: t("demo.fieldOptionAdd")
|
|
182
|
+
})] });
|
|
183
|
+
}
|
|
184
|
+
//#endregion
|
|
185
|
+
//#region src/ui/form-design-panel.tsx
|
|
186
|
+
/**
|
|
187
|
+
* The form designer's sidebar (`form-design`, which `form:design` opens): what the form's
|
|
188
|
+
* fields are. With no field selected it lists them by page, and a click selects one and
|
|
189
|
+
* scrolls to it; with one selected it shows its settings and, for a radio group or a checkbox,
|
|
190
|
+
* its buttons, with a + that adds one next in line (`form.addWidget`). How a field looks is the
|
|
191
|
+
* style panel's.
|
|
192
|
+
*/
|
|
193
|
+
/** Each family's icon and name, as its field tool shows them. */
|
|
194
|
+
const FAMILIES = {
|
|
195
|
+
text: {
|
|
196
|
+
icon: "formTextfield",
|
|
197
|
+
labelKey: "commands.form.textfield"
|
|
198
|
+
},
|
|
199
|
+
checkbox: {
|
|
200
|
+
icon: "formCheckbox",
|
|
201
|
+
labelKey: "commands.form.checkbox"
|
|
202
|
+
},
|
|
203
|
+
radio: {
|
|
204
|
+
icon: "formRadio",
|
|
205
|
+
labelKey: "commands.form.radio"
|
|
206
|
+
},
|
|
207
|
+
combobox: {
|
|
208
|
+
icon: "formSelect",
|
|
209
|
+
labelKey: "commands.form.select"
|
|
210
|
+
},
|
|
211
|
+
listbox: {
|
|
212
|
+
icon: "formListbox",
|
|
213
|
+
labelKey: "commands.form.listbox"
|
|
214
|
+
},
|
|
215
|
+
pushbutton: {
|
|
216
|
+
icon: "formButton",
|
|
217
|
+
labelKey: "commands.form.button"
|
|
218
|
+
},
|
|
219
|
+
signature: {
|
|
220
|
+
icon: "signature",
|
|
221
|
+
labelKey: "commands.form.signature"
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
const NO_FIELDS = [];
|
|
225
|
+
const NO_WIDGETS = [];
|
|
226
|
+
/** A widget's object number, the key its rows and its selection share. */
|
|
227
|
+
const numberOf = (widget) => widget.ref.kind === "objectNumber" ? widget.ref.objectNumber : -1;
|
|
228
|
+
/** The form's own actions: select a widget and show it, design on first if it was off. */
|
|
229
|
+
function useFormDesign() {
|
|
230
|
+
const annotation = (0, _embedpdf_react_runtime.useOptionalCapability)(_embedpdf_react_annotation.AnnotationToken);
|
|
231
|
+
const interaction = (0, _embedpdf_react_runtime.useOptionalCapability)(_embedpdf_react_interaction.InteractionToken);
|
|
232
|
+
const stage = (0, _embedpdf_react_stage.useStage)();
|
|
233
|
+
const activeTool = (0, _embedpdf_react_runtime.useOptionalSelector)(_embedpdf_react_interaction.InteractionToken, (tools) => tools.getActiveToolId(), null);
|
|
234
|
+
return {
|
|
235
|
+
select(widget) {
|
|
236
|
+
if (!require_commands.isFormDesignTool(activeTool)) interaction?.activateTool(require_commands.FORM_DESIGN_TOOL);
|
|
237
|
+
annotation?.selection.set([widget.ref]);
|
|
238
|
+
stage.reveal(widget.page, { rect: widget.box });
|
|
239
|
+
},
|
|
240
|
+
clear() {
|
|
241
|
+
annotation?.selection.set([]);
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
function FormDesignPanel() {
|
|
246
|
+
const form = (0, _embedpdf_react_runtime.useOptionalCapability)(_embedpdf_react_form.FormToken);
|
|
247
|
+
const selected = (0, _embedpdf_react_runtime.useOptionalSelector)(_embedpdf_react_form.FormToken, (capability) => capability.getSelectedField(), null);
|
|
248
|
+
if (!form) return null;
|
|
249
|
+
return selected ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SelectedField, { field: selected }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FieldList, {});
|
|
250
|
+
}
|
|
251
|
+
/** Every field of the form, by page, in reading order. */
|
|
252
|
+
function FieldList() {
|
|
253
|
+
const t = (0, _embedpdf_react_i18n.useT)();
|
|
254
|
+
const design = useFormDesign();
|
|
255
|
+
const pages = (0, _embedpdf_react_runtime.usePageList)();
|
|
256
|
+
const form = (0, _embedpdf_react_runtime.useOptionalCapability)(_embedpdf_react_form.FormToken);
|
|
257
|
+
const fields = (0, _embedpdf_react_runtime.useOptionalSelector)(_embedpdf_react_form.FormToken, (capability) => capability.list(), NO_FIELDS);
|
|
258
|
+
const groups = (0, react.useMemo)(() => {
|
|
259
|
+
const indexOf = new Map(pages.map((page) => [page.ref.objectNumber, page.index]));
|
|
260
|
+
const rows = fields.flatMap((field) => {
|
|
261
|
+
const place = form?.getWidgets(field.ref)[0];
|
|
262
|
+
const index = place ? indexOf.get(place.page.objectNumber) : void 0;
|
|
263
|
+
return place && index !== void 0 ? [{
|
|
264
|
+
field,
|
|
265
|
+
place,
|
|
266
|
+
index
|
|
267
|
+
}] : [];
|
|
268
|
+
});
|
|
269
|
+
rows.sort((left, right) => left.index - right.index || left.place.box.y - right.place.box.y || left.place.box.x - right.place.box.x);
|
|
270
|
+
const byPage = /* @__PURE__ */ new Map();
|
|
271
|
+
for (const row of rows) byPage.set(row.index, [...byPage.get(row.index) ?? [], row]);
|
|
272
|
+
return [...byPage];
|
|
273
|
+
}, [
|
|
274
|
+
fields,
|
|
275
|
+
form,
|
|
276
|
+
pages
|
|
277
|
+
]);
|
|
278
|
+
if (groups.length === 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
279
|
+
className: "flex flex-col items-center gap-3 px-4 py-10 text-center",
|
|
280
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_icons.Icon, {
|
|
281
|
+
name: "formDesign",
|
|
282
|
+
size: 32,
|
|
283
|
+
className: "text-fg-muted"
|
|
284
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
285
|
+
className: "text-fg-muted text-sm",
|
|
286
|
+
children: t("formDesign.empty")
|
|
287
|
+
})]
|
|
288
|
+
});
|
|
289
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
290
|
+
className: "min-h-0 flex-1 overflow-y-auto p-2",
|
|
291
|
+
children: groups.map(([index, rows]) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
292
|
+
className: "mb-3",
|
|
293
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
|
|
294
|
+
className: "text-fg-muted px-2 pb-1 text-[11px] font-semibold uppercase tracking-wide",
|
|
295
|
+
children: t("formDesign.page", { params: { page: index + 1 } })
|
|
296
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
|
|
297
|
+
className: "flex flex-col",
|
|
298
|
+
children: rows.map(({ field, place }) => {
|
|
299
|
+
const family = FAMILIES[field.family];
|
|
300
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
301
|
+
type: "button",
|
|
302
|
+
onClick: () => design.select(place),
|
|
303
|
+
className: "hover:bg-hover flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-start",
|
|
304
|
+
children: [
|
|
305
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_icons.Icon, {
|
|
306
|
+
name: family?.icon ?? "formTextfield",
|
|
307
|
+
size: 16,
|
|
308
|
+
className: "text-fg-muted shrink-0"
|
|
309
|
+
}),
|
|
310
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
311
|
+
className: "text-fg min-w-0 flex-1 truncate text-sm",
|
|
312
|
+
children: field.name
|
|
313
|
+
}),
|
|
314
|
+
family && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
315
|
+
className: "sr-only",
|
|
316
|
+
children: t(family.labelKey)
|
|
317
|
+
})
|
|
318
|
+
]
|
|
319
|
+
}) }, field.name);
|
|
320
|
+
})
|
|
321
|
+
})]
|
|
322
|
+
}, index))
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
/** The selected field: its settings and, for a radio group or a checkbox, its buttons. */
|
|
326
|
+
function SelectedField({ field }) {
|
|
327
|
+
const t = (0, _embedpdf_react_i18n.useT)();
|
|
328
|
+
const design = useFormDesign();
|
|
329
|
+
const family = FAMILIES[field.family];
|
|
330
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
331
|
+
className: "min-h-0 flex-1 overflow-y-auto p-4",
|
|
332
|
+
children: [
|
|
333
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
334
|
+
type: "button",
|
|
335
|
+
onClick: design.clear,
|
|
336
|
+
className: "text-accent mb-3 flex items-center gap-1 text-sm",
|
|
337
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_icons.Icon, {
|
|
338
|
+
name: "chevronLeft",
|
|
339
|
+
size: 14
|
|
340
|
+
}), t("formDesign.allFields")]
|
|
341
|
+
}),
|
|
342
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
|
|
343
|
+
className: "text-fg mb-4 flex items-center gap-2 text-sm font-semibold",
|
|
344
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_icons.Icon, {
|
|
345
|
+
name: family?.icon ?? "formTextfield",
|
|
346
|
+
size: 16,
|
|
347
|
+
className: "text-fg-muted shrink-0"
|
|
348
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
349
|
+
className: "min-w-0 truncate",
|
|
350
|
+
children: field.name
|
|
351
|
+
})]
|
|
352
|
+
}),
|
|
353
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
354
|
+
className: "text-fg-muted mb-3 text-[11px] font-semibold uppercase tracking-wide",
|
|
355
|
+
children: t("demo.fieldSettingsTitle")
|
|
356
|
+
}),
|
|
357
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(FieldSettings, { field }),
|
|
358
|
+
(field.family === "radio" || field.family === "checkbox") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Buttons, { field })
|
|
359
|
+
]
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
/** A radio group's or a checkbox's buttons, each selectable, and a + for one more. */
|
|
363
|
+
function Buttons({ field }) {
|
|
364
|
+
const t = (0, _embedpdf_react_i18n.useT)();
|
|
365
|
+
const design = useFormDesign();
|
|
366
|
+
const form = (0, _embedpdf_react_runtime.useOptionalCapability)(_embedpdf_react_form.FormToken);
|
|
367
|
+
const places = (0, _embedpdf_react_runtime.useOptionalSelector)(_embedpdf_react_form.FormToken, (capability) => capability.getWidgets(field.ref), NO_WIDGETS);
|
|
368
|
+
const chosen = (0, _embedpdf_react_annotation.useAnnotationState)((state) => state.selected);
|
|
369
|
+
const isChosen = (place) => chosen.some((record) => record.ref.kind === "objectNumber" && record.ref.objectNumber === numberOf(place));
|
|
370
|
+
const radio = field.family === "radio";
|
|
371
|
+
const add = async () => {
|
|
372
|
+
if (!form) return;
|
|
373
|
+
const { widget } = await form.addWidget(field.ref);
|
|
374
|
+
design.select(widget);
|
|
375
|
+
};
|
|
376
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
377
|
+
className: "border-border-subtle mt-4 border-t pt-4",
|
|
378
|
+
children: [
|
|
379
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
380
|
+
className: "text-fg-muted mb-2 text-[11px] font-semibold uppercase tracking-wide",
|
|
381
|
+
children: t(radio ? "formDesign.buttons" : "formDesign.boxes")
|
|
382
|
+
}),
|
|
383
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
|
|
384
|
+
className: "mb-2 flex flex-col",
|
|
385
|
+
children: places.map((place, at) => {
|
|
386
|
+
const widget = field.widgets.find((each) => each.objectNumber === numberOf(place));
|
|
387
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
388
|
+
type: "button",
|
|
389
|
+
"aria-pressed": isChosen(place),
|
|
390
|
+
onClick: () => design.select(place),
|
|
391
|
+
className: `hover:bg-hover flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-start text-sm ${isChosen(place) ? "bg-selected text-accent" : "text-fg"}`,
|
|
392
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_icons.Icon, {
|
|
393
|
+
name: radio ? "formRadio" : "formCheckbox",
|
|
394
|
+
size: 14,
|
|
395
|
+
className: "shrink-0"
|
|
396
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
397
|
+
className: "min-w-0 flex-1 truncate",
|
|
398
|
+
children: radio && widget && "exportValue" in widget ? widget.exportValue : t("formDesign.box", { params: { number: at + 1 } })
|
|
399
|
+
})]
|
|
400
|
+
}) }, numberOf(place));
|
|
401
|
+
})
|
|
402
|
+
}),
|
|
403
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
404
|
+
type: "button",
|
|
405
|
+
onClick: () => void add().catch(() => void 0),
|
|
406
|
+
className: "text-accent flex items-center gap-1 text-sm",
|
|
407
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_icons.Icon, {
|
|
408
|
+
name: "plus",
|
|
409
|
+
size: 14
|
|
410
|
+
}), t(radio ? "formDesign.addButton" : "formDesign.addBox")]
|
|
411
|
+
})
|
|
412
|
+
]
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
//#endregion
|
|
416
|
+
exports.FormDesignPanel = FormDesignPanel;
|
|
417
|
+
|
|
418
|
+
//# sourceMappingURL=form-design-panel-B5MXTZ96.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"form-design-panel-B5MXTZ96.cjs","names":["FormToken","useLabel","AnnotationToken","InteractionToken","isFormDesignTool","FORM_DESIGN_TOOL","FormToken","Icon"],"sources":["../src/ui/field-settings.tsx","../src/ui/form-design-panel.tsx"],"sourcesContent":["/**\n * A field's settings, as the form plugin describes them (`getFieldSettings`),\n * written with `form.update()`: the form designer's sidebar shows them for the\n * selected field. Nothing here knows a field family: the description says what\n * to draw.\n */\nimport {\n FormToken,\n type FormFieldDTO,\n type FormFieldPatch,\n type FormFieldSetting,\n} from '@embedpdf/react/form';\nimport { useT } from '@embedpdf/react/i18n';\nimport { useOptionalCapability, useOptionalSelector } from '@embedpdf/react/runtime';\nimport { useEffect, useState } from 'react';\n\nimport { useLabel } from './labels';\n\nconst inputClass = 'border-border bg-surface text-fg w-full rounded-md border px-2 py-1.5 text-sm';\n\n/** One option of a dropdown or a list, as its settings hold it. */\ninterface Option {\n readonly label: string;\n readonly value: string;\n}\n\n/** The field's settings, each with the control its description names. */\nexport function FieldSettings({ field }: { field: FormFieldDTO }) {\n const form = useOptionalCapability(FormToken);\n const settings = useOptionalSelector(\n FormToken,\n (capability) => capability.getFieldSettings(field.ref),\n null,\n );\n if (!form || !settings || !form.canDesign()) return null;\n const write = (patch: Record<string, unknown>) =>\n void form.update(field.ref, patch as FormFieldPatch).catch(() => undefined);\n\n return (\n <div>\n {settings.properties.map((spec) => (\n <SettingControl\n key={`${spec.key}:${spec.control}`}\n fieldKey={JSON.stringify(field.ref)}\n spec={spec}\n value={settings.values[spec.key]}\n onChange={(value) => write({ [spec.key]: value })}\n />\n ))}\n </div>\n );\n}\n\nfunction SettingControl({\n fieldKey,\n spec,\n value,\n onChange,\n}: {\n /** The field it edits: a draft starts over when the selection moves to another field. */\n fieldKey: string;\n spec: FormFieldSetting;\n value: unknown;\n onChange: (value: unknown) => void;\n}) {\n const t = useT();\n const label = useLabel();\n switch (spec.control) {\n case 'flag':\n return (\n <label className=\"text-fg mb-2 flex items-center gap-2 text-sm\">\n <input\n type=\"checkbox\"\n checked={value === true}\n onChange={(event) => onChange(event.target.checked)}\n />\n {label(spec)}\n </label>\n );\n case 'text':\n return (\n <Setting label={label(spec)}>\n <CommittedInput\n key={fieldKey}\n value={typeof value === 'string' ? value : ''}\n onCommit={onChange}\n />\n </Setting>\n );\n case 'number':\n return (\n <Setting label={label(spec)}>\n <CommittedInput\n key={fieldKey}\n type=\"number\"\n min={spec.min}\n placeholder={t('demo.fieldNone')}\n value={typeof value === 'number' ? String(value) : ''}\n onCommit={(text) => onChange(text === '' ? null : Math.max(spec.min, Number(text)))}\n />\n </Setting>\n );\n case 'choice':\n return spec.free ? (\n <Setting label={label(spec)}>\n <CommittedInput\n key={fieldKey}\n list={`${fieldKey}-choices`}\n value={typeof value === 'string' ? value : ''}\n onCommit={onChange}\n />\n <datalist id={`${fieldKey}-choices`}>\n {spec.options.map((option) => (\n <option key={option} value={option} />\n ))}\n </datalist>\n </Setting>\n ) : (\n <Setting label={label(spec)}>\n <select\n className={inputClass}\n value={typeof value === 'string' ? value : ''}\n onChange={(event) => onChange(event.target.value === '' ? null : event.target.value)}\n >\n <option value=\"\">{t('demo.fieldNone')}</option>\n {spec.options.map((option) => (\n <option key={option} value={option}>\n {option}\n </option>\n ))}\n </select>\n </Setting>\n );\n case 'choices': {\n const chosen = new Set(Array.isArray(value) ? (value as string[]) : []);\n return (\n <Setting label={label(spec)}>\n {spec.options.map((option) => (\n <label key={option} className=\"text-fg mb-1 flex items-center gap-2 text-sm\">\n <input\n type=\"checkbox\"\n checked={chosen.has(option)}\n onChange={(event) =>\n onChange(\n spec.options.filter((each) =>\n each === option ? event.target.checked : chosen.has(each),\n ),\n )\n }\n />\n {option}\n </label>\n ))}\n </Setting>\n );\n }\n case 'options':\n return (\n <Setting label={label(spec)}>\n <OptionsEditor\n key={fieldKey}\n options={Array.isArray(value) ? (value as Option[]) : []}\n onCommit={onChange}\n />\n </Setting>\n );\n }\n}\n\nfunction Setting({ label, children }: { label: string; children: React.ReactNode }) {\n return (\n <section className=\"mb-3\">\n <span className=\"text-fg mb-1 block text-sm font-medium\">{label}</span>\n {children}\n </section>\n );\n}\n\n/** A text input that writes on blur or Enter, and keeps what's typed until then. */\nfunction CommittedInput({\n value,\n onCommit,\n ...input\n}: {\n value: string;\n onCommit: (value: string) => void;\n} & Omit<React.InputHTMLAttributes<HTMLInputElement>, 'value' | 'onChange'>) {\n const [draft, setDraft] = useState<string | null>(null);\n useEffect(() => setDraft(null), [value]);\n const commit = () => {\n if (draft === null || draft === value) return;\n onCommit(draft);\n };\n return (\n <input\n {...input}\n className={inputClass}\n value={draft ?? value}\n onChange={(event) => setDraft(event.target.value)}\n onBlur={commit}\n onKeyDown={(event) => event.key === 'Enter' && commit()}\n />\n );\n}\n\n/** A dropdown's or list's options, each a label and a value; written as a whole on each edit. */\nfunction OptionsEditor({\n options,\n onCommit,\n}: {\n options: readonly Option[];\n onCommit: (options: Option[]) => void;\n}) {\n const t = useT();\n const rows = options.map((option) => ({ label: option.label, value: option.value }));\n const replace = (at: number, row: Option | null) =>\n onCommit(\n row === null\n ? rows.filter((_, index) => index !== at)\n : rows.map((each, index) => (index === at ? row : each)),\n );\n return (\n <div>\n {rows.map((row, at) => (\n <div key={`${at}:${row.value}`} className=\"mb-1 flex gap-1\">\n <CommittedInput\n aria-label={t('demo.fieldOptionLabel')}\n value={row.label}\n onCommit={(label) => replace(at, { ...row, label })}\n />\n <CommittedInput\n aria-label={t('demo.fieldOptionValue')}\n value={row.value}\n onCommit={(value) => replace(at, { ...row, value })}\n />\n <button\n type=\"button\"\n title={t('demo.fieldOptionRemove')}\n className=\"text-fg-muted hover:text-fg px-1\"\n onClick={() => replace(at, null)}\n >\n ×\n </button>\n </div>\n ))}\n <button\n type=\"button\"\n className=\"text-accent text-sm\"\n onClick={() => {\n const label = `Option ${rows.length + 1}`;\n onCommit([...rows, { label, value: label }]);\n }}\n >\n {t('demo.fieldOptionAdd')}\n </button>\n </div>\n );\n}\n","/**\n * The form designer's sidebar (`form-design`, which `form:design` opens): what the form's\n * fields are. With no field selected it lists them by page, and a click selects one and\n * scrolls to it; with one selected it shows its settings and, for a radio group or a checkbox,\n * its buttons, with a + that adds one next in line (`form.addWidget`). How a field looks is the\n * style panel's.\n */\nimport { AnnotationToken, useAnnotationState } from '@embedpdf/react/annotation';\nimport {\n FormToken,\n type FormFieldDTO,\n type FormFieldFamily,\n type WidgetAnnotation,\n} from '@embedpdf/react/form';\nimport { useT } from '@embedpdf/react/i18n';\nimport { InteractionToken } from '@embedpdf/react/interaction';\nimport { useOptionalCapability, useOptionalSelector, usePageList } from '@embedpdf/react/runtime';\nimport { useStage } from '@embedpdf/react/stage';\nimport { useMemo } from 'react';\n\nimport { FORM_DESIGN_TOOL, isFormDesignTool } from '../config/commands';\nimport { FieldSettings } from './field-settings';\nimport { Icon } from './icons';\n\n/** Each family's icon and name, as its field tool shows them. */\nconst FAMILIES: Readonly<Partial<Record<FormFieldFamily, { icon: string; labelKey: string }>>> = {\n text: { icon: 'formTextfield', labelKey: 'commands.form.textfield' },\n checkbox: { icon: 'formCheckbox', labelKey: 'commands.form.checkbox' },\n radio: { icon: 'formRadio', labelKey: 'commands.form.radio' },\n combobox: { icon: 'formSelect', labelKey: 'commands.form.select' },\n listbox: { icon: 'formListbox', labelKey: 'commands.form.listbox' },\n pushbutton: { icon: 'formButton', labelKey: 'commands.form.button' },\n signature: { icon: 'signature', labelKey: 'commands.form.signature' },\n};\n\nconst NO_FIELDS: readonly FormFieldDTO[] = [];\nconst NO_WIDGETS: readonly WidgetAnnotation[] = [];\n\n/** A widget's object number, the key its rows and its selection share. */\nconst numberOf = (widget: WidgetAnnotation): number =>\n widget.ref.kind === 'objectNumber' ? widget.ref.objectNumber : -1;\n\n/** The form's own actions: select a widget and show it, design on first if it was off. */\nfunction useFormDesign() {\n const annotation = useOptionalCapability(AnnotationToken);\n const interaction = useOptionalCapability(InteractionToken);\n const stage = useStage();\n const activeTool = useOptionalSelector(\n InteractionToken,\n (tools) => tools.getActiveToolId(),\n null,\n );\n return {\n select(widget: WidgetAnnotation) {\n // The widgets are lent only while a form is designed.\n if (!isFormDesignTool(activeTool)) interaction?.activateTool(FORM_DESIGN_TOOL);\n annotation?.selection.set([widget.ref]);\n stage.reveal(widget.page, { rect: widget.box });\n },\n clear() {\n annotation?.selection.set([]);\n },\n };\n}\n\nexport function FormDesignPanel() {\n const form = useOptionalCapability(FormToken);\n const selected = useOptionalSelector(\n FormToken,\n (capability) => capability.getSelectedField(),\n null,\n );\n if (!form) return null;\n return selected ? <SelectedField field={selected} /> : <FieldList />;\n}\n\n/** Every field of the form, by page, in reading order. */\nfunction FieldList() {\n const t = useT();\n const design = useFormDesign();\n const pages = usePageList();\n const form = useOptionalCapability(FormToken);\n const fields = useOptionalSelector(FormToken, (capability) => capability.list(), NO_FIELDS);\n const groups = useMemo(() => {\n const indexOf = new Map(pages.map((page) => [page.ref.objectNumber, page.index]));\n const rows = fields.flatMap((field) => {\n const place = form?.getWidgets(field.ref)[0];\n const index = place ? indexOf.get(place.page.objectNumber) : undefined;\n return place && index !== undefined ? [{ field, place, index }] : [];\n });\n rows.sort(\n (left, right) =>\n left.index - right.index ||\n left.place.box.y - right.place.box.y ||\n left.place.box.x - right.place.box.x,\n );\n const byPage = new Map<number, typeof rows>();\n for (const row of rows) byPage.set(row.index, [...(byPage.get(row.index) ?? []), row]);\n return [...byPage];\n }, [fields, form, pages]);\n\n if (groups.length === 0) {\n return (\n <div className=\"flex flex-col items-center gap-3 px-4 py-10 text-center\">\n <Icon name=\"formDesign\" size={32} className=\"text-fg-muted\" />\n <p className=\"text-fg-muted text-sm\">{t('formDesign.empty')}</p>\n </div>\n );\n }\n return (\n <div className=\"min-h-0 flex-1 overflow-y-auto p-2\">\n {groups.map(([index, rows]) => (\n <section key={index} className=\"mb-3\">\n <h3 className=\"text-fg-muted px-2 pb-1 text-[11px] font-semibold uppercase tracking-wide\">\n {t('formDesign.page', { params: { page: index + 1 } })}\n </h3>\n <ul className=\"flex flex-col\">\n {rows.map(({ field, place }) => {\n const family = FAMILIES[field.family];\n return (\n <li key={field.name}>\n <button\n type=\"button\"\n onClick={() => design.select(place)}\n className=\"hover:bg-hover flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-start\"\n >\n <Icon\n name={family?.icon ?? 'formTextfield'}\n size={16}\n className=\"text-fg-muted shrink-0\"\n />\n <span className=\"text-fg min-w-0 flex-1 truncate text-sm\">{field.name}</span>\n {family && <span className=\"sr-only\">{t(family.labelKey)}</span>}\n </button>\n </li>\n );\n })}\n </ul>\n </section>\n ))}\n </div>\n );\n}\n\n/** The selected field: its settings and, for a radio group or a checkbox, its buttons. */\nfunction SelectedField({ field }: { field: FormFieldDTO }) {\n const t = useT();\n const design = useFormDesign();\n const family = FAMILIES[field.family];\n return (\n <div className=\"min-h-0 flex-1 overflow-y-auto p-4\">\n <button\n type=\"button\"\n onClick={design.clear}\n className=\"text-accent mb-3 flex items-center gap-1 text-sm\"\n >\n <Icon name=\"chevronLeft\" size={14} />\n {t('formDesign.allFields')}\n </button>\n <p className=\"text-fg mb-4 flex items-center gap-2 text-sm font-semibold\">\n <Icon name={family?.icon ?? 'formTextfield'} size={16} className=\"text-fg-muted shrink-0\" />\n <span className=\"min-w-0 truncate\">{field.name}</span>\n </p>\n <p className=\"text-fg-muted mb-3 text-[11px] font-semibold uppercase tracking-wide\">\n {t('demo.fieldSettingsTitle')}\n </p>\n <FieldSettings field={field} />\n {(field.family === 'radio' || field.family === 'checkbox') && <Buttons field={field} />}\n </div>\n );\n}\n\n/** A radio group's or a checkbox's buttons, each selectable, and a + for one more. */\nfunction Buttons({ field }: { field: FormFieldDTO & { family: 'radio' | 'checkbox' } }) {\n const t = useT();\n const design = useFormDesign();\n const form = useOptionalCapability(FormToken);\n const places = useOptionalSelector(\n FormToken,\n (capability) => capability.getWidgets(field.ref),\n NO_WIDGETS,\n );\n const chosen = useAnnotationState((state) => state.selected);\n const isChosen = (place: WidgetAnnotation) =>\n chosen.some(\n (record) => record.ref.kind === 'objectNumber' && record.ref.objectNumber === numberOf(place),\n );\n const radio = field.family === 'radio';\n const add = async () => {\n if (!form) return;\n const { widget } = await form.addWidget(field.ref);\n design.select(widget);\n };\n return (\n <section className=\"border-border-subtle mt-4 border-t pt-4\">\n <p className=\"text-fg-muted mb-2 text-[11px] font-semibold uppercase tracking-wide\">\n {t(radio ? 'formDesign.buttons' : 'formDesign.boxes')}\n </p>\n <ul className=\"mb-2 flex flex-col\">\n {places.map((place, at) => {\n const widget = field.widgets.find((each) => each.objectNumber === numberOf(place));\n return (\n <li key={numberOf(place)}>\n <button\n type=\"button\"\n aria-pressed={isChosen(place)}\n onClick={() => design.select(place)}\n className={`hover:bg-hover flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-start text-sm ${\n isChosen(place) ? 'bg-selected text-accent' : 'text-fg'\n }`}\n >\n <Icon name={radio ? 'formRadio' : 'formCheckbox'} size={14} className=\"shrink-0\" />\n <span className=\"min-w-0 flex-1 truncate\">\n {radio && widget && 'exportValue' in widget\n ? widget.exportValue\n : t('formDesign.box', { params: { number: at + 1 } })}\n </span>\n </button>\n </li>\n );\n })}\n </ul>\n <button\n type=\"button\"\n onClick={() => void add().catch(() => undefined)}\n className=\"text-accent flex items-center gap-1 text-sm\"\n >\n <Icon name=\"plus\" size={14} />\n {t(radio ? 'formDesign.addButton' : 'formDesign.addBox')}\n </button>\n </section>\n );\n}\n"],"mappings":"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"}
|