@unlev/exeq 0.2.0 → 0.2.2

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/dist/index.mjs CHANGED
@@ -38,6 +38,12 @@ var FIELD_DEFAULTS = {
38
38
  placeholder: "Enter text",
39
39
  textSubtype: "freeform"
40
40
  },
41
+ dropdown: {
42
+ width: 20,
43
+ height: 3,
44
+ fontSize: 12,
45
+ placeholder: "Select..."
46
+ },
41
47
  signature: {
42
48
  width: 20,
43
49
  height: 6,
@@ -77,6 +83,7 @@ var FIELD_DEFAULTS = {
77
83
  };
78
84
  var TYPE_LABELS = {
79
85
  text: "Text Field",
86
+ dropdown: "Dropdown",
80
87
  signature: "Signature",
81
88
  "signed-date": "Signed Date",
82
89
  checkbox: "Checkbox",
@@ -148,12 +155,13 @@ import { jsx, jsxs } from "react/jsx-runtime";
148
155
  function PdfViewer({
149
156
  pages,
150
157
  fields,
151
- selectedFieldId,
158
+ selectedFieldIds,
152
159
  onSelectField,
153
160
  onFieldMove,
154
161
  onFieldResize,
155
162
  onPageClick,
156
163
  onDropField,
164
+ onGroupMove,
157
165
  mode,
158
166
  currentSigner,
159
167
  renderFieldContent
@@ -211,10 +219,13 @@ function PdfViewer({
211
219
  FieldOverlayItem,
212
220
  {
213
221
  field,
214
- isSelected: field.id === selectedFieldId,
215
- onSelect: () => onSelectField(field.id),
222
+ isSelected: selectedFieldIds.has(field.id),
223
+ isMultiSelected: selectedFieldIds.size > 1 && selectedFieldIds.has(field.id),
224
+ onSelect: (e) => onSelectField(field.id, e),
216
225
  onMove: onFieldMove,
217
226
  onResize: onFieldResize,
227
+ onGroupMove: selectedFieldIds.size > 1 && selectedFieldIds.has(field.id) ? onGroupMove : void 0,
228
+ selectedIds: selectedFieldIds,
218
229
  mode,
219
230
  currentSigner,
220
231
  renderContent: renderFieldContent
@@ -230,9 +241,12 @@ function PdfViewer({
230
241
  function FieldOverlayItem({
231
242
  field,
232
243
  isSelected,
244
+ isMultiSelected,
233
245
  onSelect,
234
246
  onMove,
235
247
  onResize,
248
+ onGroupMove,
249
+ selectedIds,
236
250
  mode,
237
251
  currentSigner,
238
252
  renderContent
@@ -249,7 +263,7 @@ function FieldOverlayItem({
249
263
  if (mode !== "designer" || !onMove) return;
250
264
  e.preventDefault();
251
265
  e.stopPropagation();
252
- onSelect();
266
+ onSelect(e);
253
267
  const pageEl = overlayRef.current?.closest(".pdf-page");
254
268
  if (!pageEl) return;
255
269
  dragStartRef.current = {
@@ -258,14 +272,20 @@ function FieldOverlayItem({
258
272
  fieldX: field.x,
259
273
  fieldY: field.y
260
274
  };
261
- const handleMouseMove = (e2) => {
275
+ const handleMouseMove = (ev) => {
262
276
  if (!dragStartRef.current) return;
263
277
  const rect = pageEl.getBoundingClientRect();
264
- const dx = (e2.clientX - dragStartRef.current.startX) / rect.width * 100;
265
- const dy = (e2.clientY - dragStartRef.current.startY) / rect.height * 100;
266
- const newX = Math.max(0, Math.min(100 - field.width, dragStartRef.current.fieldX + dx));
267
- const newY = Math.max(0, Math.min(100 - field.height, dragStartRef.current.fieldY + dy));
268
- onMove(field.id, field.page, newX, newY);
278
+ const dx = (ev.clientX - dragStartRef.current.startX) / rect.width * 100;
279
+ const dy = (ev.clientY - dragStartRef.current.startY) / rect.height * 100;
280
+ if (isMultiSelected && onGroupMove) {
281
+ onGroupMove(Array.from(selectedIds), dx, dy);
282
+ dragStartRef.current.startX = ev.clientX;
283
+ dragStartRef.current.startY = ev.clientY;
284
+ } else {
285
+ const newX = Math.max(0, Math.min(100 - field.width, dragStartRef.current.fieldX + dx));
286
+ const newY = Math.max(0, Math.min(100 - field.height, dragStartRef.current.fieldY + dy));
287
+ onMove(field.id, field.page, newX, newY);
288
+ }
269
289
  };
270
290
  const handleMouseUp = () => {
271
291
  dragStartRef.current = null;
@@ -274,7 +294,7 @@ function FieldOverlayItem({
274
294
  };
275
295
  window.addEventListener("mousemove", handleMouseMove);
276
296
  window.addEventListener("mouseup", handleMouseUp);
277
- }, [field, mode, onMove, onSelect]);
297
+ }, [field, mode, onMove, onSelect, isMultiSelected, onGroupMove, selectedIds]);
278
298
  const handleResizeMouseDown = useCallback((e) => {
279
299
  if (mode !== "designer" || !onResize) return;
280
300
  e.preventDefault();
@@ -322,7 +342,7 @@ function FieldOverlayItem({
322
342
  },
323
343
  onClick: (e) => {
324
344
  e.stopPropagation();
325
- onSelect();
345
+ onSelect(e);
326
346
  },
327
347
  onMouseDown: handleMouseDown,
328
348
  children: [
@@ -350,8 +370,8 @@ var INK_COLORS = [
350
370
  function FieldPropertyPanel({ field, signerRoles, onUpdate, onDelete }) {
351
371
  const color = getSignerColor(field.assignee);
352
372
  const isRedactField = field.type === "blackout" || field.type === "whiteout";
353
- const isTextField = field.type === "text" || field.type === "signed-date";
354
- const showInkColor = field.type === "text" || field.type === "signature" || field.type === "initials" || field.type === "signed-date";
373
+ const isTextField = field.type === "text" || field.type === "signed-date" || field.type === "dropdown";
374
+ const showInkColor = field.type === "text" || field.type === "dropdown" || field.type === "signature" || field.type === "initials" || field.type === "signed-date";
355
375
  const [newOption, setNewOption] = useState("");
356
376
  return /* @__PURE__ */ jsxs2("div", { className: "field-property-panel", children: [
357
377
  /* @__PURE__ */ jsxs2("div", { className: "panel-header", children: [
@@ -378,6 +398,7 @@ function FieldPropertyPanel({ field, signerRoles, onUpdate, onDelete }) {
378
398
  onChange: (e) => onUpdate(field.id, { type: e.target.value }),
379
399
  children: [
380
400
  /* @__PURE__ */ jsx2("option", { value: "text", children: "Text" }),
401
+ /* @__PURE__ */ jsx2("option", { value: "dropdown", children: "Dropdown" }),
381
402
  /* @__PURE__ */ jsx2("option", { value: "signature", children: "Signature" }),
382
403
  /* @__PURE__ */ jsx2("option", { value: "signed-date", children: "Signed Date" }),
383
404
  /* @__PURE__ */ jsx2("option", { value: "checkbox", children: "Checkbox" }),
@@ -529,8 +550,8 @@ function FieldPropertyPanel({ field, signerRoles, onUpdate, onDelete }) {
529
550
  c.value
530
551
  )) })
531
552
  ] }),
532
- field.type === "text" && /* @__PURE__ */ jsxs2("div", { className: "panel-field", children: [
533
- /* @__PURE__ */ jsx2("label", { children: "Predefined Options" }),
553
+ (field.type === "text" || field.type === "dropdown") && /* @__PURE__ */ jsxs2("div", { className: "panel-field", children: [
554
+ /* @__PURE__ */ jsx2("label", { children: field.type === "dropdown" ? "Options" : "Predefined Options" }),
534
555
  /* @__PURE__ */ jsxs2("div", { className: "panel-options-list", children: [
535
556
  (field.options || []).map((opt, i) => /* @__PURE__ */ jsxs2("div", { className: "panel-option-item", children: [
536
557
  /* @__PURE__ */ jsx2("span", { children: opt }),
@@ -576,7 +597,8 @@ function FieldPropertyPanel({ field, signerRoles, onUpdate, onDelete }) {
576
597
  )
577
598
  ] })
578
599
  ] }),
579
- (field.options?.length ?? 0) > 0 && /* @__PURE__ */ jsx2("span", { className: "panel-hint", children: "Signer will choose from these options via dropdown" })
600
+ field.type === "dropdown" && (field.options?.length ?? 0) === 0 && /* @__PURE__ */ jsx2("span", { className: "panel-hint", style: { color: "#c44" }, children: "Add at least one option" }),
601
+ field.type === "text" && (field.options?.length ?? 0) > 0 && /* @__PURE__ */ jsx2("span", { className: "panel-hint", children: "Signer will choose from these options via dropdown" })
580
602
  ] })
581
603
  ] });
582
604
  }
@@ -725,6 +747,7 @@ function isValidApiKey(key) {
725
747
  import { Fragment, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
726
748
  var FIELD_TYPE_META = [
727
749
  { type: "text", label: "Text", icon: "T" },
750
+ { type: "dropdown", label: "Dropdown", icon: "\u25BE" },
728
751
  { type: "signature", label: "Signature", icon: "\u270D" },
729
752
  { type: "signed-date", label: "Date", icon: "\u{1F4C5}" },
730
753
  { type: "checkbox", label: "Checkbox", icon: "\u2611" },
@@ -752,7 +775,7 @@ function DesignerView({
752
775
  }
753
776
  const [pages, setPages] = useState3([]);
754
777
  const [fields, setFields] = useState3(initialTemplate?.fields ?? []);
755
- const [selectedFieldId, setSelectedFieldId] = useState3(null);
778
+ const [selectedFieldIds, setSelectedFieldIds] = useState3(/* @__PURE__ */ new Set());
756
779
  const [signerRoles, setSignerRoles] = useState3(initialTemplate?.signerRoles ?? [...DEFAULT_SIGNER_ROLES]);
757
780
  const [activeRole, setActiveRole] = useState3("Sender");
758
781
  const [activeFieldType, setActiveFieldType] = useState3("text");
@@ -763,7 +786,7 @@ function DesignerView({
763
786
  const [newRoleName, setNewRoleName] = useState3("");
764
787
  const [draggingFieldType, setDraggingFieldType] = useState3(null);
765
788
  const [panelWidth, setPanelWidth] = useState3(380);
766
- const [clipboardField, setClipboardField] = useState3(null);
789
+ const [clipboardFields, setClipboardFields] = useState3([]);
767
790
  const dragGhostRef = useRef3(null);
768
791
  const resizingRef = useRef3(false);
769
792
  const lastStylesRef = useRef3({});
@@ -817,7 +840,7 @@ function DesignerView({
817
840
  const sticky = lastStylesRef.current[activeFieldType];
818
841
  const styledField = sticky ? { ...field, ...sticky } : field;
819
842
  setFields((prev) => [...prev, styledField]);
820
- setSelectedFieldId(styledField.id);
843
+ setSelectedFieldIds(/* @__PURE__ */ new Set([styledField.id]));
821
844
  setRightTab("properties");
822
845
  }, [activeFieldType, activeRole, fields]);
823
846
  const handleFieldMove = useCallback3((id, page, x, y) => {
@@ -855,8 +878,54 @@ function DesignerView({
855
878
  }, []);
856
879
  const handleFieldDelete = useCallback3((id) => {
857
880
  setFields((prev) => prev.filter((f) => f.id !== id));
858
- if (selectedFieldId === id) setSelectedFieldId(null);
859
- }, [selectedFieldId]);
881
+ setSelectedFieldIds((prev) => {
882
+ const next = new Set(prev);
883
+ next.delete(id);
884
+ return next;
885
+ });
886
+ }, []);
887
+ const handleSelectField = useCallback3((id, e) => {
888
+ if (!id) {
889
+ setSelectedFieldIds(/* @__PURE__ */ new Set());
890
+ return;
891
+ }
892
+ if (e && (e.metaKey || e.ctrlKey)) {
893
+ setSelectedFieldIds((prev) => {
894
+ const next = new Set(prev);
895
+ if (next.has(id)) next.delete(id);
896
+ else next.add(id);
897
+ return next;
898
+ });
899
+ } else if (e && e.shiftKey && selectedFieldIds.size > 0) {
900
+ const lastId = Array.from(selectedFieldIds).pop();
901
+ const sorted = sortedFields.map((f) => f.id);
902
+ const a = sorted.indexOf(lastId);
903
+ const b = sorted.indexOf(id);
904
+ if (a >= 0 && b >= 0) {
905
+ const start = Math.min(a, b);
906
+ const end = Math.max(a, b);
907
+ const range = sorted.slice(start, end + 1);
908
+ setSelectedFieldIds((prev) => {
909
+ const next = new Set(prev);
910
+ range.forEach((fid) => next.add(fid));
911
+ return next;
912
+ });
913
+ } else {
914
+ setSelectedFieldIds(/* @__PURE__ */ new Set([id]));
915
+ }
916
+ } else {
917
+ setSelectedFieldIds(/* @__PURE__ */ new Set([id]));
918
+ }
919
+ setRightTab("properties");
920
+ }, [selectedFieldIds]);
921
+ const handleGroupMove = useCallback3((ids, dx, dy) => {
922
+ setFields((prev) => prev.map((f) => {
923
+ if (!ids.includes(f.id)) return f;
924
+ const newX = Math.max(0, Math.min(100 - f.width, f.x + dx));
925
+ const newY = Math.max(0, Math.min(100 - f.height, f.y + dy));
926
+ return { ...f, x: newX, y: newY };
927
+ }));
928
+ }, []);
860
929
  const handleAddRole = useCallback3(() => {
861
930
  const name = newRoleName.trim();
862
931
  if (name && !signerRoles.includes(name)) {
@@ -919,56 +988,58 @@ function DesignerView({
919
988
  const sticky = lastStylesRef.current[fieldType];
920
989
  const styledField = sticky ? { ...field, ...sticky } : field;
921
990
  setFields((prev) => [...prev, styledField]);
922
- setSelectedFieldId(styledField.id);
991
+ setSelectedFieldIds(/* @__PURE__ */ new Set([styledField.id]));
923
992
  setRightTab("properties");
924
993
  }, [activeRole, fields]);
925
994
  useEffect2(() => {
926
995
  const handleKeyDown = (e) => {
927
996
  if (e.key !== "Delete" && e.key !== "Backspace") return;
928
- if (!selectedFieldId) return;
997
+ if (selectedFieldIds.size === 0) return;
929
998
  const tag = (document.activeElement?.tagName || "").toLowerCase();
930
999
  if (tag === "input" || tag === "textarea" || tag === "select") return;
931
1000
  if (document.activeElement?.isContentEditable) return;
932
1001
  e.preventDefault();
933
- if (window.confirm("Delete this field?")) {
934
- handleFieldDelete(selectedFieldId);
1002
+ const count = selectedFieldIds.size;
1003
+ if (window.confirm(`Delete ${count > 1 ? `${count} fields` : "this field"}?`)) {
1004
+ setFields((prev) => prev.filter((f) => !selectedFieldIds.has(f.id)));
1005
+ setSelectedFieldIds(/* @__PURE__ */ new Set());
935
1006
  }
936
1007
  };
937
1008
  window.addEventListener("keydown", handleKeyDown);
938
1009
  return () => window.removeEventListener("keydown", handleKeyDown);
939
- }, [selectedFieldId, handleFieldDelete]);
1010
+ }, [selectedFieldIds]);
940
1011
  useEffect2(() => {
941
1012
  const handleKeyDown = (e) => {
942
1013
  const tag = (document.activeElement?.tagName || "").toLowerCase();
943
1014
  if (tag === "input" || tag === "textarea" || tag === "select") return;
944
1015
  if (document.activeElement?.isContentEditable) return;
945
1016
  const isMod = e.metaKey || e.ctrlKey;
946
- if (isMod && e.key === "c" && selectedFieldId) {
947
- const field = fields.find((f) => f.id === selectedFieldId);
948
- if (field) {
1017
+ if (isMod && e.key === "c" && selectedFieldIds.size > 0) {
1018
+ const selected = fields.filter((f) => selectedFieldIds.has(f.id));
1019
+ if (selected.length > 0) {
949
1020
  e.preventDefault();
950
- setClipboardField(field);
1021
+ setClipboardFields(selected);
951
1022
  }
952
1023
  }
953
- if (isMod && e.key === "v" && clipboardField) {
1024
+ if (isMod && e.key === "v" && clipboardFields.length > 0) {
954
1025
  e.preventDefault();
955
- const existingLabels = fields.map((f) => f.label);
956
- const newField = {
957
- ...clipboardField,
958
- id: generateId(),
959
- label: uniqueLabel(clipboardField.label, existingLabels),
960
- x: clipboardField.x + 2,
961
- y: clipboardField.y + 2,
962
- value: ""
963
- };
964
- setFields((prev) => [...prev, newField]);
965
- setSelectedFieldId(newField.id);
1026
+ let existingLabels = fields.map((f) => f.label);
1027
+ const newIds = /* @__PURE__ */ new Set();
1028
+ const newFields = clipboardFields.map((cf) => {
1029
+ const label = uniqueLabel(cf.label, existingLabels);
1030
+ existingLabels.push(label);
1031
+ const id = generateId();
1032
+ newIds.add(id);
1033
+ return { ...cf, id, label, x: cf.x + 2, y: cf.y + 2, value: "" };
1034
+ });
1035
+ setFields((prev) => [...prev, ...newFields]);
1036
+ setSelectedFieldIds(newIds);
966
1037
  setRightTab("properties");
967
1038
  }
968
1039
  };
969
1040
  window.addEventListener("keydown", handleKeyDown);
970
1041
  return () => window.removeEventListener("keydown", handleKeyDown);
971
- }, [selectedFieldId, fields, clipboardField]);
1042
+ }, [selectedFieldIds, fields, clipboardFields]);
972
1043
  const handleResizeStart = useCallback3((e) => {
973
1044
  e.preventDefault();
974
1045
  resizingRef.current = true;
@@ -993,7 +1064,7 @@ function DesignerView({
993
1064
  if (Math.abs(a.y - b.y) > bandThreshold) return a.y - b.y;
994
1065
  return a.x - b.x;
995
1066
  });
996
- const selectedField = fields.find((f) => f.id === selectedFieldId) || null;
1067
+ const selectedField = selectedFieldIds.size === 1 ? fields.find((f) => f.id === Array.from(selectedFieldIds)[0]) || null : null;
997
1068
  const renderFieldContent = useCallback3((field) => {
998
1069
  if (field.type === "blackout" || field.type === "whiteout") {
999
1070
  return null;
@@ -1004,15 +1075,22 @@ function DesignerView({
1004
1075
  }
1005
1076
  }
1006
1077
  const inkColor = field.inkColor || "#000000";
1078
+ const cssFontFamily = field.fontFamily === "Courier" ? '"Courier New", Courier, monospace' : field.fontFamily === "TimesRoman" ? '"Times New Roman", Times, serif' : field.fontFamily === "Helvetica" ? "Helvetica, Arial, sans-serif" : void 0;
1007
1079
  return /* @__PURE__ */ jsx4(
1008
1080
  "div",
1009
1081
  {
1010
1082
  className: "field-overlay-placeholder",
1011
- style: { color: field.value ? inkColor : void 0, fontSize: `${field.fontSize * 0.6}px` },
1083
+ style: {
1084
+ color: field.value ? inkColor : void 0,
1085
+ fontSize: `${field.fontSize * 0.6}px`,
1086
+ fontFamily: cssFontFamily,
1087
+ letterSpacing: field.letterSpacing ? `${field.letterSpacing * 0.6}px` : void 0,
1088
+ lineHeight: field.lineHeight ? `${field.lineHeight}` : void 0
1089
+ },
1012
1090
  children: field.value || field.placeholder
1013
1091
  }
1014
1092
  );
1015
- }, []);
1093
+ }, [fields]);
1016
1094
  const headerButtons = pages.length > 0 ? /* @__PURE__ */ jsxs4(Fragment, { children: [
1017
1095
  /* @__PURE__ */ jsxs4("label", { className: "header-btn header-btn-outline", children: [
1018
1096
  "Change PDF",
@@ -1106,13 +1184,11 @@ function DesignerView({
1106
1184
  {
1107
1185
  pages,
1108
1186
  fields,
1109
- selectedFieldId,
1110
- onSelectField: (id) => {
1111
- setSelectedFieldId(id);
1112
- if (id) setRightTab("properties");
1113
- },
1187
+ selectedFieldIds,
1188
+ onSelectField: handleSelectField,
1114
1189
  onFieldMove: handleFieldMove,
1115
1190
  onFieldResize: handleFieldResize,
1191
+ onGroupMove: handleGroupMove,
1116
1192
  onPageClick: handlePageClick,
1117
1193
  onDropField: handleDropOnPage,
1118
1194
  mode: "designer",
@@ -1149,7 +1225,13 @@ function DesignerView({
1149
1225
  )
1150
1226
  ] }),
1151
1227
  /* @__PURE__ */ jsxs4("div", { className: "panel-tab-content", children: [
1152
- rightTab === "properties" && /* @__PURE__ */ jsx4(Fragment, { children: selectedField ? /* @__PURE__ */ jsxs4(Fragment, { children: [
1228
+ rightTab === "properties" && /* @__PURE__ */ jsx4(Fragment, { children: selectedFieldIds.size > 1 ? /* @__PURE__ */ jsxs4("div", { className: "panel-empty", children: [
1229
+ /* @__PURE__ */ jsxs4("strong", { children: [
1230
+ selectedFieldIds.size,
1231
+ " fields selected"
1232
+ ] }),
1233
+ /* @__PURE__ */ jsx4("p", { children: "Drag to move as a group. Press Delete to remove all. Cmd/Ctrl+C to copy." })
1234
+ ] }) : selectedField ? /* @__PURE__ */ jsxs4(Fragment, { children: [
1153
1235
  /* @__PURE__ */ jsx4(
1154
1236
  FieldPropertyPanel,
1155
1237
  {
@@ -1196,9 +1278,9 @@ function DesignerView({
1196
1278
  rightTab === "fields" && /* @__PURE__ */ jsx4(Fragment, { children: fields.length === 0 ? /* @__PURE__ */ jsx4("div", { className: "panel-empty", children: "No fields yet. Drag a field from the left palette onto the PDF, or click on the PDF to place one." }) : /* @__PURE__ */ jsx4("div", { className: "field-list", children: sortedFields.map((f) => /* @__PURE__ */ jsxs4(
1197
1279
  "div",
1198
1280
  {
1199
- className: `field-list-item ${f.id === selectedFieldId ? "active" : ""}`,
1281
+ className: `field-list-item ${selectedFieldIds.has(f.id) ? "active" : ""}`,
1200
1282
  onClick: () => {
1201
- setSelectedFieldId(f.id);
1283
+ setSelectedFieldIds(/* @__PURE__ */ new Set([f.id]));
1202
1284
  setRightTab("properties");
1203
1285
  },
1204
1286
  children: [
@@ -1793,9 +1875,10 @@ function SignerView({
1793
1875
  const fontStyle = {
1794
1876
  fontSize: `${field.fontSize * 0.6}px`,
1795
1877
  letterSpacing: field.letterSpacing ? `${field.letterSpacing * 0.6}px` : void 0,
1796
- fontFamily: field.fontFamily === "Courier" ? "monospace" : field.fontFamily === "TimesRoman" ? "serif" : void 0
1878
+ lineHeight: field.lineHeight ? `${field.lineHeight}` : void 0,
1879
+ fontFamily: field.fontFamily === "Courier" ? '"Courier New", Courier, monospace' : field.fontFamily === "TimesRoman" ? '"Times New Roman", Times, serif' : field.fontFamily === "Helvetica" ? "Helvetica, Arial, sans-serif" : void 0
1797
1880
  };
1798
- if (field.options && field.options.length > 0) {
1881
+ if (field.type === "dropdown" || field.options && field.options.length > 0) {
1799
1882
  return /* @__PURE__ */ jsxs6(
1800
1883
  "select",
1801
1884
  {
@@ -1807,7 +1890,7 @@ function SignerView({
1807
1890
  style: fontStyle,
1808
1891
  children: [
1809
1892
  /* @__PURE__ */ jsx6("option", { value: "", children: field.placeholder || "Select..." }),
1810
- field.options.map((opt) => /* @__PURE__ */ jsx6("option", { value: opt, children: opt }, opt))
1893
+ (field.options || []).map((opt) => /* @__PURE__ */ jsx6("option", { value: opt, children: opt }, opt))
1811
1894
  ]
1812
1895
  }
1813
1896
  );
@@ -1854,8 +1937,8 @@ function SignerView({
1854
1937
  {
1855
1938
  pages,
1856
1939
  fields,
1857
- selectedFieldId,
1858
- onSelectField: setSelectedFieldId,
1940
+ selectedFieldIds: new Set(selectedFieldId ? [selectedFieldId] : []),
1941
+ onSelectField: (id) => setSelectedFieldId(id),
1859
1942
  mode: "signer",
1860
1943
  currentSigner: signer,
1861
1944
  renderFieldContent
@@ -1887,8 +1970,8 @@ function SignerView({
1887
1970
  initialValue: selectedField.value
1888
1971
  }
1889
1972
  ),
1890
- selectedField.type === "text" && /* @__PURE__ */ jsxs6(Fragment2, { children: [
1891
- selectedField.options && selectedField.options.length > 0 ? /* @__PURE__ */ jsxs6(
1973
+ (selectedField.type === "text" || selectedField.type === "dropdown") && /* @__PURE__ */ jsxs6(Fragment2, { children: [
1974
+ selectedField.type === "dropdown" || selectedField.options && selectedField.options.length > 0 ? /* @__PURE__ */ jsxs6(
1892
1975
  "select",
1893
1976
  {
1894
1977
  value: selectedField.value,
@@ -1896,7 +1979,7 @@ function SignerView({
1896
1979
  className: "signer-text-input",
1897
1980
  children: [
1898
1981
  /* @__PURE__ */ jsx6("option", { value: "", children: selectedField.placeholder || "Select..." }),
1899
- selectedField.options.map((opt) => /* @__PURE__ */ jsx6("option", { value: opt, children: opt }, opt))
1982
+ (selectedField.options || []).map((opt) => /* @__PURE__ */ jsx6("option", { value: opt, children: opt }, opt))
1900
1983
  ]
1901
1984
  }
1902
1985
  ) : /* @__PURE__ */ jsx6(