@pdfme/ui 6.2.1-dev.20 → 6.2.1-dev.26

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.js CHANGED
@@ -56820,7 +56820,7 @@ var dictionaries = {
56820
56820
  bulkUpdateFieldName: "Bulk update field names",
56821
56821
  addPageAfter: "Add Page After",
56822
56822
  removePage: "Remove Current Page",
56823
- removePageConfirm: "Are you sure you want to delete this page? This action cannot be undone.",
56823
+ removePageConfirm: "Are you sure you want to delete this page?",
56824
56824
  zoomIn: "Zoom in",
56825
56825
  zoomOut: "Zoom out",
56826
56826
  fitWidth: "Fit width",
@@ -56940,7 +56940,7 @@ var dictionaries = {
56940
56940
  bulkUpdateFieldName: "批量更新字段名称",
56941
56941
  addPageAfter: "在之后添加页面",
56942
56942
  removePage: "删除当前页面",
56943
- removePageConfirm: "您确定要删除此页面吗?此操作无法撤销。",
56943
+ removePageConfirm: "您确定要删除此页面吗?",
56944
56944
  zoomIn: "放大",
56945
56945
  zoomOut: "缩小",
56946
56946
  fitWidth: "适合宽度",
@@ -57060,7 +57060,7 @@ var dictionaries = {
57060
57060
  bulkUpdateFieldName: "批量更新字段名稱",
57061
57061
  addPageAfter: "在之後添加頁面",
57062
57062
  removePage: "刪除當前頁面",
57063
- removePageConfirm: "您確定要刪除此頁面嗎?此操作無法撤銷。",
57063
+ removePageConfirm: "您確定要刪除此頁面嗎?",
57064
57064
  zoomIn: "放大",
57065
57065
  zoomOut: "縮小",
57066
57066
  fitWidth: "適合寬度",
@@ -57180,7 +57180,7 @@ var dictionaries = {
57180
57180
  bulkUpdateFieldName: "項目名を一括変更",
57181
57181
  addPageAfter: "次にページを追加",
57182
57182
  removePage: "現在のページを削除",
57183
- removePageConfirm: "ページを削除してもよろしいですか?この操作は元に戻せません。",
57183
+ removePageConfirm: "ページを削除してもよろしいですか?",
57184
57184
  zoomIn: "拡大",
57185
57185
  zoomOut: "縮小",
57186
57186
  fitWidth: "横幅に合わせる",
@@ -57300,7 +57300,7 @@ var dictionaries = {
57300
57300
  bulkUpdateFieldName: "필드 이름 일괄 업데이트",
57301
57301
  addPageAfter: "다음에 페이지 추가",
57302
57302
  removePage: "현재 페이지 제거",
57303
- removePageConfirm: "이 페이지를 삭제하시겠습니까? 이 작업은 취소할 수 없습니다.",
57303
+ removePageConfirm: "이 페이지를 삭제하시겠습니까?",
57304
57304
  zoomIn: "확대",
57305
57305
  zoomOut: "축소",
57306
57306
  fitWidth: "너비에 맞춤",
@@ -57420,7 +57420,7 @@ var dictionaries = {
57420
57420
  bulkUpdateFieldName: "تغيير الأسماء",
57421
57421
  addPageAfter: "إضافة صفحة بعد",
57422
57422
  removePage: "احذف الصفحة الحالية",
57423
- removePageConfirm: "هل أنت متأكد من رغبتك في حذف هذه الصفحة؟ لا يمكن التراجع عن هذا الإجراء.",
57423
+ removePageConfirm: "هل أنت متأكد من رغبتك في حذف هذه الصفحة؟",
57424
57424
  zoomIn: "تكبير",
57425
57425
  zoomOut: "تصغير",
57426
57426
  fitWidth: "ملاءمة العرض",
@@ -57540,7 +57540,7 @@ var dictionaries = {
57540
57540
  bulkUpdateFieldName: "แก้ไขชื่อฟิลด์เป็นชุด",
57541
57541
  addPageAfter: "เพิ่มหน้าถัดไป",
57542
57542
  removePage: "ลบหน้าปัจจุบัน",
57543
- removePageConfirm: "คุณแน่ใจหรือไม่ว่าต้องการลบหน้านี้? การกระทำนี้ไม่สามารถย้อนกลับได้",
57543
+ removePageConfirm: "คุณแน่ใจหรือไม่ว่าต้องการลบหน้านี้?",
57544
57544
  zoomIn: "ซูมเข้า",
57545
57545
  zoomOut: "ซูมออก",
57546
57546
  fitWidth: "พอดีกับความกว้าง",
@@ -57660,7 +57660,7 @@ var dictionaries = {
57660
57660
  bulkUpdateFieldName: "Alan adlarını toplu güncelle",
57661
57661
  addPageAfter: "Sonrasına Sayfa Ekle",
57662
57662
  removePage: "Mevcut Sayfayı Kaldır",
57663
- removePageConfirm: "Bu sayfayı silmek istediğinizden emin misiniz? Bu işlem geri alınamaz.",
57663
+ removePageConfirm: "Bu sayfayı silmek istediğinizden emin misiniz?",
57664
57664
  zoomIn: "Yakınlaştır",
57665
57665
  zoomOut: "Uzaklaştır",
57666
57666
  fitWidth: "Genişliğe sığdır",
@@ -57780,7 +57780,7 @@ var dictionaries = {
57780
57780
  bulkUpdateFieldName: "Modifica nomi campi in blocco",
57781
57781
  addPageAfter: "Aggiungi pagina dopo",
57782
57782
  removePage: "Rimuovi la Pagina Corrente",
57783
- removePageConfirm: "Sei sicuro di voler eliminare questa pagina? Questa azione non può essere annullata.",
57783
+ removePageConfirm: "Sei sicuro di voler eliminare questa pagina?",
57784
57784
  zoomIn: "Ingrandisci",
57785
57785
  zoomOut: "Riduci",
57786
57786
  fitWidth: "Adatta larghezza",
@@ -57900,7 +57900,7 @@ var dictionaries = {
57900
57900
  bulkUpdateFieldName: "Masowo aktualizuj klucze pól",
57901
57901
  addPageAfter: "Dodaj stronę po",
57902
57902
  removePage: "Usuń Bieżącą Stronę",
57903
- removePageConfirm: "Czy na pewno chcesz usunąć tę stronę? Tej operacji nie można cofnąć.",
57903
+ removePageConfirm: "Czy na pewno chcesz usunąć tę stronę?",
57904
57904
  zoomIn: "Powiększ",
57905
57905
  zoomOut: "Pomniejsz",
57906
57906
  fitWidth: "Dopasuj szerokość",
@@ -58020,7 +58020,7 @@ var dictionaries = {
58020
58020
  bulkUpdateFieldName: "Mehrfachaktualisierung der Feldnamen",
58021
58021
  addPageAfter: "Seite danach hinzufügen",
58022
58022
  removePage: "Aktuelle Seite entfernen",
58023
- removePageConfirm: "Sind Sie sicher, dass Sie diese Seite löschen möchten? Diese Aktion kann nicht rückgängig gemacht werden.",
58023
+ removePageConfirm: "Sind Sie sicher, dass Sie diese Seite löschen möchten?",
58024
58024
  zoomIn: "Vergrößern",
58025
58025
  zoomOut: "Verkleinern",
58026
58026
  fitWidth: "Breite anpassen",
@@ -58140,7 +58140,7 @@ var dictionaries = {
58140
58140
  bulkUpdateFieldName: "Actualizar en bloque el nombre de los campos",
58141
58141
  addPageAfter: "Insertar página",
58142
58142
  removePage: "Eliminar página actual",
58143
- removePageConfirm: "¿Estás seguro de que quieres eliminar esta página? Esta acción no se puede deshacer.",
58143
+ removePageConfirm: "¿Estás seguro de que quieres eliminar esta página?",
58144
58144
  zoomIn: "Acercar",
58145
58145
  zoomOut: "Alejar",
58146
58146
  fitWidth: "Ajustar ancho",
@@ -58260,7 +58260,7 @@ var dictionaries = {
58260
58260
  bulkUpdateFieldName: "Modifier les noms de champs en masse",
58261
58261
  addPageAfter: "Ajouter une page après",
58262
58262
  removePage: "Supprimer la page actuelle",
58263
- removePageConfirm: "Êtes-vous sûr de vouloir supprimer cette page ? Cette action est irréversible.",
58263
+ removePageConfirm: "Êtes-vous sûr de vouloir supprimer cette page ?",
58264
58264
  zoomIn: "Zoom avant",
58265
58265
  zoomOut: "Zoom arrière",
58266
58266
  fitWidth: "Ajuster la largeur",
@@ -88000,9 +88000,7 @@ var template2SchemasList = async (_template) => {
88000
88000
  const pdfArrayBuffer = b64toUint8Array(await getB64BasePdf(basePdf));
88001
88001
  pageSizes = await pdf2size(pdfArrayBuffer);
88002
88002
  }
88003
- const ssl = schemasForUI.length;
88004
- const psl = pageSizes.length;
88005
- return (ssl < psl ? schemasForUI.concat(Array.from({ length: psl - ssl }, () => cloneDeep$1([]))) : schemasForUI.slice(0, pageSizes.length)).map((schema, i) => {
88003
+ return alignSchemasListToPageCount(schemasForUI, pageSizes.length).map((schema, i) => {
88006
88004
  Object.values(schema).forEach((value) => {
88007
88005
  const { width, height } = pageSizes[i];
88008
88006
  const xEdge = value.position.x + value.width;
@@ -88013,6 +88011,26 @@ var template2SchemasList = async (_template) => {
88013
88011
  return schema;
88014
88012
  });
88015
88013
  };
88014
+ /**
88015
+ * Pad or truncate schema pages so the list length matches `pageCount`.
88016
+ * Empty pages are distinct arrays. This is the same alignment `template2SchemasList`
88017
+ * uses when a base PDF's page count and the schema pages differ.
88018
+ */
88019
+ var alignSchemasListToPageCount = (schemasList, pageCount) => {
88020
+ if (schemasList.length === pageCount) return schemasList;
88021
+ if (schemasList.length < pageCount) return schemasList.concat(Array.from({ length: pageCount - schemasList.length }, () => []));
88022
+ return schemasList.slice(0, Math.max(pageCount, 0));
88023
+ };
88024
+ /**
88025
+ * Fit a history snapshot to the pages of the current base PDF.
88026
+ * Blank PDFs follow the snapshot length. A non-blank PDF keeps `pageSizes.length`,
88027
+ * using the same pad/truncate as `template2SchemasList`. A zero page count means
88028
+ * sizes are not loaded yet, so the snapshot is left unchanged.
88029
+ */
88030
+ var normalizeSchemasListForBasePdf = (schemasList, basePdf, pageCount) => {
88031
+ if (isBlankPdf(basePdf) || pageCount <= 0) return schemasList;
88032
+ return alignSchemasListToPageCount(schemasList, pageCount);
88033
+ };
88016
88034
  var schemasList2template = (schemasList, basePdf) => ({
88017
88035
  schemas: cloneDeep$1(schemasList).map((page) => page.map((schema) => {
88018
88036
  delete schema.id;
@@ -133200,7 +133218,7 @@ var useMountStatus = () => {
133200
133218
  }, []);
133201
133219
  return isMounted;
133202
133220
  };
133203
- var useInitEvents = ({ pageCursor, pageSizes, activeElements, template, schemasList, changeSchemas, commitSchemas, removeSchemas, onSaveTemplate, past, future, setSchemasList, onEdit, onEditEnd }) => {
133221
+ var useInitEvents = ({ pageCursor, pageSizes, activeElements, template, schemasList, changeSchemas, commitSchemas, removeSchemas, onSaveTemplate, undo, redo, onEdit, onEditEnd }) => {
133204
133222
  const copiedSchemas = (0, import_react$9.useRef)(null);
133205
133223
  const initEvents = (0, import_react$9.useCallback)(() => {
133206
133224
  const getElementsByIds = (ids) => ids.map((id) => document.getElementById(id)).filter((element) => element instanceof HTMLElement);
@@ -133208,15 +133226,6 @@ var useInitEvents = ({ pageCursor, pageSizes, activeElements, template, schemasL
133208
133226
  const ids = activeElements.map((ae) => ae.id);
133209
133227
  return schemasList[pageCursor].filter((s) => ids.includes(s.id));
133210
133228
  };
133211
- const timeTravel = (mode) => {
133212
- const isUndo = mode === "undo";
133213
- const stack = isUndo ? past : future;
133214
- if (stack.current.length <= 0) return;
133215
- (isUndo ? future : past).current.push(cloneDeep$1(schemasList[pageCursor]));
133216
- const s = cloneDeep$1(schemasList);
133217
- s[pageCursor] = stack.current.pop();
133218
- setSchemasList(s);
133219
- };
133220
133229
  initShortCuts({
133221
133230
  move: (command, isShift) => {
133222
133231
  const pageSize = pageSizes[pageCursor];
@@ -133261,8 +133270,8 @@ var useInitEvents = ({ pageCursor, pageSizes, activeElements, template, schemasL
133261
133270
  });
133262
133271
  copiedSchemas.current = pasteSchemas;
133263
133272
  },
133264
- redo: () => timeTravel("redo"),
133265
- undo: () => timeTravel("undo"),
133273
+ redo: () => redo(),
133274
+ undo: () => undo(),
133266
133275
  save: () => onSaveTemplate && onSaveTemplate(schemasList2template(schemasList, template.basePdf)),
133267
133276
  remove: () => removeSchemas(getActiveSchemas().map((s) => s.id)),
133268
133277
  esc: onEditEnd,
@@ -133278,9 +133287,8 @@ var useInitEvents = ({ pageCursor, pageSizes, activeElements, template, schemasL
133278
133287
  schemasList,
133279
133288
  onSaveTemplate,
133280
133289
  removeSchemas,
133281
- past,
133282
- future,
133283
- setSchemasList,
133290
+ undo,
133291
+ redo,
133284
133292
  copiedSchemas,
133285
133293
  onEdit,
133286
133294
  onEditEnd
@@ -215803,7 +215811,7 @@ var TEXT_OVERFLOW_EXPAND_SCHEMA_TYPES = /* @__PURE__ */ new Set(["text", "multiV
215803
215811
  var getElementIds = (elements) => elements.map(({ id }) => id);
215804
215812
  var DetailView = (props) => {
215805
215813
  const { token } = theme.useToken();
215806
- const { schemasList, changeSchemas, deselectSchema, activeSchema, pageSize, basePdf } = props;
215814
+ const { schemasList, changeSchemas, syncSchemas, deselectSchema, activeSchema, pageSize, basePdf } = props;
215807
215815
  const formInstance = useForm();
215808
215816
  const form = (0, import_react$9.useRef)(formInstance).current;
215809
215817
  const i18n = (0, import_react$9.useContext)(I18nContext);
@@ -215877,7 +215885,7 @@ var DetailView = (props) => {
215877
215885
  (0, import_react$9.useEffect)(() => {
215878
215886
  if (isBlankPdf(basePdf) || !TEXT_OVERFLOW_EXPAND_SCHEMA_TYPES.has(activeSchema.type)) return;
215879
215887
  if (activeSchema.overflow !== "expand") return;
215880
- changeSchemas([{
215888
+ syncSchemas([{
215881
215889
  key: "overflow",
215882
215890
  value: TEXT_OVERFLOW_VISIBLE,
215883
215891
  schemaId: activeSchema.id
@@ -215885,7 +215893,7 @@ var DetailView = (props) => {
215885
215893
  }, [
215886
215894
  activeSchema,
215887
215895
  basePdf,
215888
- changeSchemas
215896
+ syncSchemas
215889
215897
  ]);
215890
215898
  (0, import_react$9.useEffect)(() => {
215891
215899
  uniqueSchemaName.current = (value) => {
@@ -236566,7 +236574,7 @@ var DeleteButton = ({ activeElements: aes, controlScale }) => {
236566
236574
  });
236567
236575
  };
236568
236576
  var Canvas = (props, ref) => {
236569
- const { basePdf, pageCursor, scale, renderScale, backgrounds, pageSizes, size, activeElements, schemasList, hoveringSchemaId, onEdit, changeSchemas, removeSchemas, onChangeHoveringSchemaId, paperRefs, sidebarOpen } = props;
236577
+ const { basePdf, pageCursor, scale, renderScale, backgrounds, pageSizes, size, activeElements, schemasList, hoveringSchemaId, onEdit, changeSchemas, syncSchemas, removeSchemas, onChangeHoveringSchemaId, paperRefs, sidebarOpen } = props;
236570
236578
  const { token } = theme.useToken();
236571
236579
  const pluginsRegistry = (0, import_react$9.useContext)(PluginsRegistry);
236572
236580
  const verticalGuides = (0, import_react$9.useRef)([]);
@@ -236906,11 +236914,19 @@ var Canvas = (props, ref) => {
236906
236914
  onChangeHoveringSchemaId,
236907
236915
  mode,
236908
236916
  onChange: (schemasList[pageCursor] || []).some((s) => s.id === schema.id) ? (arg) => {
236909
- changeSchemas((Array.isArray(arg) ? arg : [arg]).map(({ key, value }) => ({
236917
+ const changes = (Array.isArray(arg) ? arg : [arg]).map(({ key, value }) => ({
236910
236918
  key,
236911
236919
  value,
236912
236920
  schemaId: schema.id
236913
- })));
236921
+ }));
236922
+ if (changes.length > 0 && changes.every((change) => change.key === "height")) {
236923
+ syncSchemas(changes.map((change) => ({
236924
+ ...change,
236925
+ value: typeof change.value === "number" && Number.isFinite(change.value) ? round$2(change.value, 2) : change.value
236926
+ })));
236927
+ return;
236928
+ }
236929
+ changeSchemas(changes);
236914
236930
  } : void 0,
236915
236931
  stopEditing: () => setEditing(false),
236916
236932
  outline: `1px ${hoveringSchemaId === schema.id ? "solid" : "dashed"} ${schema.readOnly && hoveringSchemaId !== schema.id ? "transparent" : token.colorPrimary}`,
@@ -237334,6 +237350,22 @@ var CtlBar = (props) => {
237334
237350
  };
237335
237351
  //#endregion
237336
237352
  //#region src/components/Designer/index.tsx
237353
+ var MAX_HISTORY_LENGTH = 100;
237354
+ /** Release scroll suppression if a pending page scroll never finishes. */
237355
+ var SCROLL_SUPPRESS_FALLBACK_MS = 1e3;
237356
+ var pushHistory = (stack, entry) => {
237357
+ stack.push({
237358
+ schemasList: cloneDeep$1(entry.schemasList),
237359
+ pageCursor: entry.pageCursor,
237360
+ appliedCursor: entry.appliedCursor
237361
+ });
237362
+ if (stack.length > MAX_HISTORY_LENGTH) stack.splice(0, stack.length - MAX_HISTORY_LENGTH);
237363
+ };
237364
+ var clampPageCursor = (pageCursor, pageCount) => {
237365
+ if (pageCount <= 0) return 0;
237366
+ return Math.min(Math.max(Number.isFinite(pageCursor) ? Math.trunc(pageCursor) : 0, 0), pageCount - 1);
237367
+ };
237368
+ var schemasEqual = (left, right) => JSON.stringify(left) === JSON.stringify(right);
237337
237369
  /**
237338
237370
  * When the canvas scales there is a displacement of the starting position of the dragged schema.
237339
237371
  * It moves left or right from the top-left corner of the drag icon depending on the scale.
@@ -237348,6 +237380,12 @@ var MIN_CANVAS_WIDTH = 100;
237348
237380
  var TemplateEditor = ({ template, size, onSaveTemplate, onChangeTemplate, onPageCursorChange, onChangeSelection, onRegisterSchemaSelectionHandler, onUpdateTemplatePageApplied, updateTemplatePage }) => {
237349
237381
  const past = (0, import_react$9.useRef)([]);
237350
237382
  const future = (0, import_react$9.useRef)([]);
237383
+ const schemasListRef = (0, import_react$9.useRef)([[]]);
237384
+ const pageCursorRef = (0, import_react$9.useRef)(0);
237385
+ const pendingSelectionIdsRef = (0, import_react$9.useRef)(null);
237386
+ const suppressScrollPageCursorRef = (0, import_react$9.useRef)(false);
237387
+ const scrollSuppressTokenRef = (0, import_react$9.useRef)(0);
237388
+ const scrollSuppressTimerRef = (0, import_react$9.useRef)(null);
237351
237389
  const canvasRef = (0, import_react$9.useRef)(null);
237352
237390
  const paperRefs = (0, import_react$9.useRef)([]);
237353
237391
  const i18n = (0, import_react$9.useContext)(I18nContext);
@@ -237357,8 +237395,12 @@ var TemplateEditor = ({ template, size, onSaveTemplate, onChangeTemplate, onPage
237357
237395
  const canvasWidth = size.width - 45;
237358
237396
  const [hoveringSchemaId, setHoveringSchemaId] = (0, import_react$9.useState)(null);
237359
237397
  const [activeElements, setActiveElements] = (0, import_react$9.useState)([]);
237398
+ const activeElementsRef = (0, import_react$9.useRef)(activeElements);
237399
+ activeElementsRef.current = activeElements;
237360
237400
  const [schemasList, setSchemasList] = (0, import_react$9.useState)([[]]);
237361
237401
  const [pageCursor, setPageCursor] = (0, import_react$9.useState)(0);
237402
+ schemasListRef.current = schemasList;
237403
+ pageCursorRef.current = pageCursor;
237362
237404
  const [pendingScrollPage, setPendingScrollPage] = (0, import_react$9.useState)(null);
237363
237405
  const [sidebarOpen, setSidebarOpen] = (0, import_react$9.useState)(options.sidebarOpen ?? canvasWidth - 400 >= MIN_CANVAS_WIDTH);
237364
237406
  const [canvasHeight, setCanvasHeight] = (0, import_react$9.useState)(0);
@@ -237446,6 +237488,22 @@ var TemplateEditor = ({ template, size, onSaveTemplate, onChangeTemplate, onPage
237446
237488
  setActiveElements([]);
237447
237489
  setHoveringSchemaId(null);
237448
237490
  };
237491
+ const onEditRef = (0, import_react$9.useRef)(onEdit);
237492
+ const onEditEndRef = (0, import_react$9.useRef)(onEditEnd);
237493
+ onEditRef.current = onEdit;
237494
+ onEditEndRef.current = onEditEnd;
237495
+ (0, import_react$9.useLayoutEffect)(() => {
237496
+ const ids = pendingSelectionIdsRef.current;
237497
+ if (!ids) return;
237498
+ if (pageSizes.length !== schemasList.length || backgrounds.length !== schemasList.length) return;
237499
+ pendingSelectionIdsRef.current = null;
237500
+ const elements = ids.map((id) => document.getElementById(id)).filter((element) => element instanceof HTMLElement);
237501
+ onEditRef.current(elements);
237502
+ }, [
237503
+ backgrounds,
237504
+ pageSizes,
237505
+ schemasList
237506
+ ]);
237449
237507
  (0, import_react$9.useEffect)(() => {
237450
237508
  if (previousOptionsZoomLevelRef.current === options.zoomLevel) return;
237451
237509
  previousOptionsZoomLevelRef.current = options.zoomLevel;
@@ -237454,6 +237512,31 @@ var TemplateEditor = ({ template, size, onSaveTemplate, onChangeTemplate, onPage
237454
237512
  (0, import_react$9.useEffect)(() => {
237455
237513
  if (typeof options.sidebarOpen === "boolean") setSidebarOpen(options.sidebarOpen);
237456
237514
  }, [options.sidebarOpen]);
237515
+ const armScrollSuppression = (fallbackMs) => {
237516
+ const token = ++scrollSuppressTokenRef.current;
237517
+ suppressScrollPageCursorRef.current = true;
237518
+ if (scrollSuppressTimerRef.current !== null) {
237519
+ window.clearTimeout(scrollSuppressTimerRef.current);
237520
+ scrollSuppressTimerRef.current = null;
237521
+ }
237522
+ if (fallbackMs !== void 0) {
237523
+ scrollSuppressTimerRef.current = window.setTimeout(() => {
237524
+ scrollSuppressTimerRef.current = null;
237525
+ if (scrollSuppressTokenRef.current !== token) return;
237526
+ suppressScrollPageCursorRef.current = false;
237527
+ }, fallbackMs);
237528
+ return;
237529
+ }
237530
+ requestAnimationFrame(() => {
237531
+ if (scrollSuppressTokenRef.current !== token) return;
237532
+ suppressScrollPageCursorRef.current = false;
237533
+ });
237534
+ };
237535
+ (0, import_react$9.useEffect)(() => {
237536
+ return () => {
237537
+ if (scrollSuppressTimerRef.current !== null) window.clearTimeout(scrollSuppressTimerRef.current);
237538
+ };
237539
+ }, []);
237457
237540
  useScrollPageCursor({
237458
237541
  ref: canvasRef,
237459
237542
  paperRefs,
@@ -237461,6 +237544,7 @@ var TemplateEditor = ({ template, size, onSaveTemplate, onChangeTemplate, onPage
237461
237544
  scale: displayScale,
237462
237545
  pageCursor,
237463
237546
  onChangePageCursor: (p) => {
237547
+ if (suppressScrollPageCursorRef.current) return;
237464
237548
  setPageCursor(p);
237465
237549
  onPageCursorChange(p, schemasList.length);
237466
237550
  onEditEnd();
@@ -237475,6 +237559,7 @@ var TemplateEditor = ({ template, size, onSaveTemplate, onChangeTemplate, onPage
237475
237559
  if (!pageSizes.every((pageSize) => pageSize.width === width && pageSize.height === height)) return;
237476
237560
  } else if (pageSizes === queuedPageSizes) return;
237477
237561
  setPendingScrollPage(null);
237562
+ armScrollSuppression();
237478
237563
  canvasRef.current.scrollTop = getPagesScrollTopByIndex(pageSizes, pendingPage, displayScale);
237479
237564
  if (requestedPage !== void 0) onUpdateTemplatePageApplied?.(requestedPage);
237480
237565
  }, [
@@ -237497,44 +237582,122 @@ var TemplateEditor = ({ template, size, onSaveTemplate, onChangeTemplate, onPage
237497
237582
  return () => observer.disconnect();
237498
237583
  }
237499
237584
  }, [displayScale]);
237585
+ const applyDocument = (0, import_react$9.useCallback)((nextSchemasList, nextPageCursor, options) => {
237586
+ const basePdf = template.basePdf;
237587
+ const next = normalizeSchemasListForBasePdf(nextSchemasList, basePdf, pageSizes.length);
237588
+ const clampedCursor = clampPageCursor(nextPageCursor, next.length);
237589
+ const pageCountChanged = next.length !== schemasListRef.current.length;
237590
+ const cursorChanged = clampedCursor !== pageCursorRef.current;
237591
+ if (options.preserveSelection) {
237592
+ const landingPage = next[clampedCursor] ?? [];
237593
+ const previousIds = activeElementsRef.current.map((element) => element.id);
237594
+ const survivingIds = previousIds.filter((id) => landingPage.some((schema) => schema.id === id));
237595
+ if (survivingIds.length !== previousIds.length) onEditEndRef.current();
237596
+ pendingSelectionIdsRef.current = survivingIds.length > 0 ? survivingIds : null;
237597
+ }
237598
+ schemasListRef.current = next;
237599
+ pageCursorRef.current = clampedCursor;
237600
+ setSchemasList(next);
237601
+ setPageCursor(clampedCursor);
237602
+ const newTemplate = schemasList2template(next, basePdf);
237603
+ onChangeTemplate(newTemplate);
237604
+ if (options.notifyPageCursor === "always") onPageCursorChange(clampedCursor, next.length);
237605
+ if (pageCountChanged) refresh(newTemplate);
237606
+ if (cursorChanged) {
237607
+ if (pageCountChanged) {
237608
+ armScrollSuppression(SCROLL_SUPPRESS_FALLBACK_MS);
237609
+ setPendingScrollPage({
237610
+ page: clampedCursor,
237611
+ queuedPageSizes: pageSizes
237612
+ });
237613
+ } else if (canvasRef.current) {
237614
+ armScrollSuppression();
237615
+ canvasRef.current.scrollTop = getPagesScrollTopByIndex(pageSizes, clampedCursor, displayScale);
237616
+ }
237617
+ }
237618
+ }, [
237619
+ displayScale,
237620
+ onChangeTemplate,
237621
+ onPageCursorChange,
237622
+ pageSizes,
237623
+ refresh,
237624
+ template.basePdf
237625
+ ]);
237500
237626
  const commitSchemas = (0, import_react$9.useCallback)((newSchemas) => {
237627
+ const currentSchemas = schemasListRef.current;
237628
+ const currentPage = pageCursorRef.current;
237629
+ if (schemasEqual(currentSchemas[currentPage], newSchemas)) return;
237501
237630
  future.current = [];
237502
- past.current.push(cloneDeep$1(schemasList[pageCursor]));
237503
- const _schemasList = cloneDeep$1(schemasList);
237504
- _schemasList[pageCursor] = newSchemas;
237505
- setSchemasList(_schemasList);
237506
- onChangeTemplate(schemasList2template(_schemasList, template.basePdf));
237631
+ pushHistory(past.current, {
237632
+ schemasList: currentSchemas,
237633
+ pageCursor: currentPage,
237634
+ appliedCursor: currentPage
237635
+ });
237636
+ const next = cloneDeep$1(currentSchemas);
237637
+ next[currentPage] = newSchemas;
237638
+ applyDocument(next, currentPage, { notifyPageCursor: "never" });
237639
+ }, [applyDocument]);
237640
+ const syncSchemas = (0, import_react$9.useCallback)((objs) => {
237641
+ const currentPage = pageCursorRef.current;
237642
+ const pageSize = pageSizes[currentPage];
237643
+ if (!pageSize || objs.length === 0) return;
237644
+ changeSchemas({
237645
+ objs,
237646
+ schemas: schemasListRef.current[currentPage] ?? [],
237647
+ basePdf: template.basePdf,
237648
+ pluginsRegistry,
237649
+ pageSize,
237650
+ commitSchemas: (newSchemas) => {
237651
+ const currentSchemas = schemasListRef.current;
237652
+ if (schemasEqual(currentSchemas[currentPage], newSchemas)) return;
237653
+ const next = cloneDeep$1(currentSchemas);
237654
+ next[currentPage] = newSchemas;
237655
+ applyDocument(next, currentPage, { notifyPageCursor: "never" });
237656
+ }
237657
+ });
237507
237658
  }, [
237508
- template,
237509
- schemasList,
237510
- pageCursor,
237511
- onChangeTemplate
237659
+ applyDocument,
237660
+ pageSizes,
237661
+ pluginsRegistry,
237662
+ template.basePdf
237512
237663
  ]);
237513
237664
  const removeSchemas = (0, import_react$9.useCallback)((ids) => {
237514
- commitSchemas(schemasList[pageCursor].filter((schema) => !ids.includes(schema.id)));
237515
- onEditEnd();
237516
- }, [
237517
- schemasList,
237518
- pageCursor,
237519
- commitSchemas
237520
- ]);
237665
+ const currentPage = pageCursorRef.current;
237666
+ const pageSchemas = schemasListRef.current[currentPage] ?? [];
237667
+ commitSchemas(pageSchemas.filter((schema) => !ids.includes(schema.id)));
237668
+ onEditEndRef.current();
237669
+ }, [commitSchemas]);
237521
237670
  const changeSchemas$1 = (0, import_react$9.useCallback)((objs) => {
237671
+ const currentPage = pageCursorRef.current;
237522
237672
  changeSchemas({
237523
237673
  objs,
237524
- schemas: schemasList[pageCursor],
237674
+ schemas: schemasListRef.current[currentPage] ?? [],
237525
237675
  basePdf: template.basePdf,
237526
237676
  pluginsRegistry,
237527
- pageSize: pageSizes[pageCursor],
237677
+ pageSize: pageSizes[currentPage],
237528
237678
  commitSchemas
237529
237679
  });
237530
237680
  }, [
237531
237681
  commitSchemas,
237532
- pageCursor,
237533
- schemasList,
237534
- pluginsRegistry,
237535
237682
  pageSizes,
237683
+ pluginsRegistry,
237536
237684
  template.basePdf
237537
237685
  ]);
237686
+ const timeTravel = (0, import_react$9.useCallback)((mode) => {
237687
+ const source = mode === "undo" ? past : future;
237688
+ const destination = mode === "undo" ? future : past;
237689
+ const target = source.current.pop();
237690
+ if (!target) return;
237691
+ pushHistory(destination.current, {
237692
+ schemasList: schemasListRef.current,
237693
+ pageCursor: target.appliedCursor,
237694
+ appliedCursor: target.pageCursor
237695
+ });
237696
+ applyDocument(target.schemasList, target.pageCursor, {
237697
+ notifyPageCursor: "always",
237698
+ preserveSelection: true
237699
+ });
237700
+ }, [applyDocument]);
237538
237701
  useInitEvents({
237539
237702
  pageCursor,
237540
237703
  pageSizes,
@@ -237545,18 +237708,20 @@ var TemplateEditor = ({ template, size, onSaveTemplate, onChangeTemplate, onPage
237545
237708
  commitSchemas,
237546
237709
  removeSchemas,
237547
237710
  onSaveTemplate,
237548
- past,
237549
- future,
237550
- setSchemasList,
237711
+ undo: (0, import_react$9.useCallback)(() => timeTravel("undo"), [timeTravel]),
237712
+ redo: (0, import_react$9.useCallback)(() => timeTravel("redo"), [timeTravel]),
237551
237713
  onEdit,
237552
237714
  onEditEnd
237553
237715
  });
237554
237716
  const updateTemplate = (0, import_react$9.useCallback)(async (newTemplate, targetPage) => {
237555
237717
  const sl = await template2SchemasList(newTemplate);
237718
+ schemasListRef.current = sl;
237556
237719
  setSchemasList(sl);
237557
- onEditEnd();
237720
+ pendingSelectionIdsRef.current = null;
237721
+ onEditEndRef.current();
237558
237722
  if (targetPage !== void 0) {
237559
237723
  const clampedPage = Math.min(Math.max(Number.isFinite(targetPage) ? Math.trunc(targetPage) : 0, 0), sl.length - 1);
237724
+ pageCursorRef.current = clampedPage;
237560
237725
  setPageCursor(clampedPage);
237561
237726
  onPageCursorChange(clampedPage, sl.length);
237562
237727
  setPendingScrollPage({
@@ -237565,9 +237730,11 @@ var TemplateEditor = ({ template, size, onSaveTemplate, onChangeTemplate, onPage
237565
237730
  requestedPage: targetPage
237566
237731
  });
237567
237732
  } else {
237568
- const clampedPage = Math.min(pageCursor, sl.length - 1);
237733
+ const clampedPage = Math.min(pageCursorRef.current, sl.length - 1);
237734
+ const cursorChanged = clampedPage !== pageCursorRef.current;
237735
+ pageCursorRef.current = clampedPage;
237569
237736
  setPageCursor(clampedPage);
237570
- if (clampedPage !== pageCursor) {
237737
+ if (cursorChanged) {
237571
237738
  onPageCursorChange(clampedPage, sl.length);
237572
237739
  setPendingScrollPage({
237573
237740
  page: clampedPage,
@@ -237575,11 +237742,7 @@ var TemplateEditor = ({ template, size, onSaveTemplate, onChangeTemplate, onPage
237575
237742
  });
237576
237743
  }
237577
237744
  }
237578
- }, [
237579
- pageCursor,
237580
- pageSizes,
237581
- onPageCursorChange
237582
- ]);
237745
+ }, [pageSizes, onPageCursorChange]);
237583
237746
  const addSchema = (defaultSchema) => {
237584
237747
  const [paddingTop, paddingRight, paddingBottom, paddingLeft] = isBlankPdf(template.basePdf) ? template.basePdf.padding : [
237585
237748
  0,
@@ -237622,27 +237785,37 @@ var TemplateEditor = ({ template, size, onSaveTemplate, onChangeTemplate, onPage
237622
237785
  const onChangeHoveringSchemaId = (id) => {
237623
237786
  setHoveringSchemaId(id);
237624
237787
  };
237625
- const updatePage = async (sl, newPageCursor) => {
237626
- setPageCursor(newPageCursor);
237627
- const newTemplate = schemasList2template(sl, template.basePdf);
237628
- onChangeTemplate(newTemplate);
237629
- await updateTemplate(newTemplate, newPageCursor);
237630
- refresh(newTemplate);
237631
- setTimeout(() => {
237632
- if (canvasRef.current) canvasRef.current.scrollTop = getPagesScrollTopByIndex(pageSizes, newPageCursor, displayScale);
237633
- }, 0);
237634
- };
237635
237788
  const handleRemovePage = () => {
237636
- if (pageCursor === 0) return;
237789
+ const currentPage = pageCursorRef.current;
237790
+ if (currentPage === 0) return;
237637
237791
  if (!window.confirm(i18n("removePageConfirm"))) return;
237638
- const _schemasList = cloneDeep$1(schemasList);
237639
- _schemasList.splice(pageCursor, 1);
237640
- updatePage(_schemasList, pageCursor - 1);
237792
+ future.current = [];
237793
+ const currentSchemas = schemasListRef.current;
237794
+ pushHistory(past.current, {
237795
+ schemasList: currentSchemas,
237796
+ pageCursor: currentPage,
237797
+ appliedCursor: currentPage - 1
237798
+ });
237799
+ const next = cloneDeep$1(currentSchemas);
237800
+ next.splice(currentPage, 1);
237801
+ onEditEndRef.current();
237802
+ pendingSelectionIdsRef.current = null;
237803
+ applyDocument(next, currentPage - 1, { notifyPageCursor: "always" });
237641
237804
  };
237642
237805
  const handleAddPageAfter = () => {
237643
- const _schemasList = cloneDeep$1(schemasList);
237644
- _schemasList.splice(pageCursor + 1, 0, []);
237645
- updatePage(_schemasList, pageCursor + 1);
237806
+ future.current = [];
237807
+ const currentSchemas = schemasListRef.current;
237808
+ const currentPage = pageCursorRef.current;
237809
+ pushHistory(past.current, {
237810
+ schemasList: currentSchemas,
237811
+ pageCursor: currentPage,
237812
+ appliedCursor: currentPage + 1
237813
+ });
237814
+ const next = cloneDeep$1(currentSchemas);
237815
+ next.splice(currentPage + 1, 0, []);
237816
+ onEditEndRef.current();
237817
+ pendingSelectionIdsRef.current = null;
237818
+ applyDocument(next, currentPage + 1, { notifyPageCursor: "always" });
237646
237819
  };
237647
237820
  if (prevTemplate !== template) {
237648
237821
  setPrevTemplate(template);
@@ -237720,6 +237893,7 @@ var TemplateEditor = ({ template, size, onSaveTemplate, onChangeTemplate, onPage
237720
237893
  schemasList,
237721
237894
  schemas: schemasList[pageCursor] ?? [],
237722
237895
  changeSchemas: changeSchemas$1,
237896
+ syncSchemas,
237723
237897
  onSortEnd,
237724
237898
  onEdit: (id) => {
237725
237899
  const editingElem = document.getElementById(id);
@@ -237746,6 +237920,7 @@ var TemplateEditor = ({ template, size, onSaveTemplate, onChangeTemplate, onPage
237746
237920
  activeElements,
237747
237921
  schemasList,
237748
237922
  changeSchemas: changeSchemas$1,
237923
+ syncSchemas,
237749
237924
  removeSchemas,
237750
237925
  sidebarOpen,
237751
237926
  onEdit