labellife-design-tool 2.2.8 → 2.3.0

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/esm/index.js CHANGED
@@ -48,6 +48,15 @@ import '@mui/icons-material/Crop';
48
48
  import AutoAwesomeIcon from '@mui/icons-material/AutoAwesome';
49
49
  import SwapHorizIcon from '@mui/icons-material/SwapHoriz';
50
50
  import SwapVertIcon from '@mui/icons-material/SwapVert';
51
+ import OpenWithIcon from '@mui/icons-material/OpenWith';
52
+ import '@mui/icons-material/AlignHorizontalLeft';
53
+ import '@mui/icons-material/AlignHorizontalCenter';
54
+ import '@mui/icons-material/AlignHorizontalRight';
55
+ import '@mui/icons-material/AlignVerticalTop';
56
+ import '@mui/icons-material/AlignVerticalCenter';
57
+ import '@mui/icons-material/AlignVerticalBottom';
58
+ import VerticalAlignTopIcon from '@mui/icons-material/VerticalAlignTop';
59
+ import VerticalAlignBottomIcon from '@mui/icons-material/VerticalAlignBottom';
51
60
  import ZoomInIcon from '@mui/icons-material/ZoomIn';
52
61
  import ZoomOutIcon from '@mui/icons-material/ZoomOut';
53
62
  import FitScreenIcon from '@mui/icons-material/FitScreen';
@@ -6900,7 +6909,7 @@ function ImagesGrid(_ref) {
6900
6909
  });
6901
6910
  }
6902
6911
 
6903
- var _excluded$2 = ["inputField", "promptText", "inputType", "required", "placeholder", "options", "minSelections", "maxSelections"];
6912
+ var _excluded$2 = ["inputField", "promptText", "inputType", "required", "removeIfSkipped", "placeholder", "options", "minSelections", "maxSelections"];
6904
6913
  var IMAGE_PLACEHOLDER_SRC = "data:image/svg+xml;charset=utf-8,".concat(encodeURIComponent("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"400\" height=\"400\" viewBox=\"0 0 400 400\">\n <rect width=\"400\" height=\"400\" fill=\"#f0f2f5\" rx=\"12\"/>\n <rect x=\"110\" y=\"90\" width=\"180\" height=\"145\" rx=\"10\" fill=\"#dde1e7\"/>\n <circle cx=\"158\" cy=\"135\" r=\"22\" fill=\"#f0f2f5\"/>\n <polygon points=\"110,235 168,163 210,205 250,163 290,235\" fill=\"#c8cdd6\"/>\n <rect x=\"140\" y=\"268\" width=\"120\" height=\"14\" rx=\"7\" fill=\"#c8cdd6\"/>\n <rect x=\"160\" y=\"292\" width=\"80\" height=\"10\" rx=\"5\" fill=\"#dde1e7\"/>\n </svg>"));
6905
6914
 
6906
6915
  // ── Date formatting helpers ──────────────────────────────────────────
@@ -7141,6 +7150,30 @@ var InputFieldsPanelContent = observer(function (_ref3) {
7141
7150
  _useState30 = _slicedToArray(_useState29, 2),
7142
7151
  listOptions = _useState30[0],
7143
7152
  setListOptions = _useState30[1];
7153
+ var _useState31 = useState(false),
7154
+ _useState32 = _slicedToArray(_useState31, 2),
7155
+ textRemoveIfSkipped = _useState32[0],
7156
+ setTextRemoveIfSkipped = _useState32[1];
7157
+ var _useState33 = useState(false),
7158
+ _useState34 = _slicedToArray(_useState33, 2),
7159
+ dateRemoveIfSkipped = _useState34[0],
7160
+ setDateRemoveIfSkipped = _useState34[1];
7161
+ var _useState35 = useState(false),
7162
+ _useState36 = _slicedToArray(_useState35, 2),
7163
+ integerRemoveIfSkipped = _useState36[0],
7164
+ setIntegerRemoveIfSkipped = _useState36[1];
7165
+ var _useState37 = useState(false),
7166
+ _useState38 = _slicedToArray(_useState37, 2),
7167
+ imageRemoveIfSkipped = _useState38[0],
7168
+ setImageRemoveIfSkipped = _useState38[1];
7169
+ var _useState39 = useState(false),
7170
+ _useState40 = _slicedToArray(_useState39, 2),
7171
+ radioRemoveIfSkipped = _useState40[0],
7172
+ setRadioRemoveIfSkipped = _useState40[1];
7173
+ var _useState41 = useState(false),
7174
+ _useState42 = _slicedToArray(_useState41, 2),
7175
+ listRemoveIfSkipped = _useState42[0],
7176
+ setListRemoveIfSkipped = _useState42[1];
7144
7177
  var addInputElement = function addInputElement(inputType) {
7145
7178
  var extra = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
7146
7179
  var page = store.activePage;
@@ -7160,7 +7193,8 @@ var InputFieldsPanelContent = observer(function (_ref3) {
7160
7193
  inputType: 'image',
7161
7194
  placeholder: t('sidePanel.inputFields.imagePlaceholder', 'Upload image'),
7162
7195
  promptText: extra.promptText || t('sidePanel.inputFields.defaultImagePrompt', 'Please upload an image'),
7163
- required: extra.required || false
7196
+ required: extra.required || false,
7197
+ removeIfSkipped: extra.removeIfSkipped || false
7164
7198
  }
7165
7199
  });
7166
7200
  } else {
@@ -7216,7 +7250,8 @@ var InputFieldsPanelContent = observer(function (_ref3) {
7216
7250
  inputType: inputType,
7217
7251
  placeholder: placeholder,
7218
7252
  promptText: extra.promptText || defaultPrompt,
7219
- required: extra.required || false
7253
+ required: extra.required || false,
7254
+ removeIfSkipped: extra.removeIfSkipped || false
7220
7255
  }, inputType === 'date' ? {
7221
7256
  dateFormat: extra.dateFormat || 'MM-DD-YYYY'
7222
7257
  } : {}), ['radio', 'list'].includes(inputType) ? {
@@ -7267,7 +7302,8 @@ var InputFieldsPanelContent = observer(function (_ref3) {
7267
7302
  onClick: function onClick() {
7268
7303
  return addInputElement('text', {
7269
7304
  promptText: textPrompt,
7270
- required: textRequired
7305
+ required: textRequired,
7306
+ removeIfSkipped: textRemoveIfSkipped
7271
7307
  });
7272
7308
  }
7273
7309
  }), /*#__PURE__*/jsx(TextField, {
@@ -7302,6 +7338,23 @@ var InputFieldsPanelContent = observer(function (_ref3) {
7302
7338
  sx: {
7303
7339
  ml: 5.5
7304
7340
  }
7341
+ }), !textRequired && /*#__PURE__*/jsx(FormControlLabel, {
7342
+ control: /*#__PURE__*/jsx(Checkbox, {
7343
+ size: "small",
7344
+ checked: textRemoveIfSkipped,
7345
+ onChange: function onChange(e) {
7346
+ return setTextRemoveIfSkipped(e.target.checked);
7347
+ }
7348
+ }),
7349
+ label: /*#__PURE__*/jsx(Typography, {
7350
+ sx: {
7351
+ fontSize: 12
7352
+ },
7353
+ children: t('sidePanel.inputFields.removeIfSkipped', 'Remove if skipped')
7354
+ }),
7355
+ sx: {
7356
+ ml: 5.5
7357
+ }
7305
7358
  }), /*#__PURE__*/jsx(InputFieldCard, {
7306
7359
  icon: /*#__PURE__*/jsx(CalendarTodayIcon, {
7307
7360
  fontSize: "small"
@@ -7312,7 +7365,8 @@ var InputFieldsPanelContent = observer(function (_ref3) {
7312
7365
  return addInputElement('date', {
7313
7366
  dateFormat: dateFormat,
7314
7367
  promptText: datePrompt,
7315
- required: dateRequired
7368
+ required: dateRequired,
7369
+ removeIfSkipped: dateRemoveIfSkipped
7316
7370
  });
7317
7371
  }
7318
7372
  }), /*#__PURE__*/jsx(TextField, {
@@ -7347,6 +7401,23 @@ var InputFieldsPanelContent = observer(function (_ref3) {
7347
7401
  sx: {
7348
7402
  ml: 5.5
7349
7403
  }
7404
+ }), !dateRequired && /*#__PURE__*/jsx(FormControlLabel, {
7405
+ control: /*#__PURE__*/jsx(Checkbox, {
7406
+ size: "small",
7407
+ checked: dateRemoveIfSkipped,
7408
+ onChange: function onChange(e) {
7409
+ return setDateRemoveIfSkipped(e.target.checked);
7410
+ }
7411
+ }),
7412
+ label: /*#__PURE__*/jsx(Typography, {
7413
+ sx: {
7414
+ fontSize: 12
7415
+ },
7416
+ children: t('sidePanel.inputFields.removeIfSkipped', 'Remove if skipped')
7417
+ }),
7418
+ sx: {
7419
+ ml: 5.5
7420
+ }
7350
7421
  }), /*#__PURE__*/jsxs(FormControl, {
7351
7422
  size: "small",
7352
7423
  sx: {
@@ -7386,7 +7457,8 @@ var InputFieldsPanelContent = observer(function (_ref3) {
7386
7457
  onClick: function onClick() {
7387
7458
  return addInputElement('integer', {
7388
7459
  promptText: integerPrompt,
7389
- required: integerRequired
7460
+ required: integerRequired,
7461
+ removeIfSkipped: integerRemoveIfSkipped
7390
7462
  });
7391
7463
  }
7392
7464
  }), /*#__PURE__*/jsx(TextField, {
@@ -7421,6 +7493,23 @@ var InputFieldsPanelContent = observer(function (_ref3) {
7421
7493
  sx: {
7422
7494
  ml: 5.5
7423
7495
  }
7496
+ }), !integerRequired && /*#__PURE__*/jsx(FormControlLabel, {
7497
+ control: /*#__PURE__*/jsx(Checkbox, {
7498
+ size: "small",
7499
+ checked: integerRemoveIfSkipped,
7500
+ onChange: function onChange(e) {
7501
+ return setIntegerRemoveIfSkipped(e.target.checked);
7502
+ }
7503
+ }),
7504
+ label: /*#__PURE__*/jsx(Typography, {
7505
+ sx: {
7506
+ fontSize: 12
7507
+ },
7508
+ children: t('sidePanel.inputFields.removeIfSkipped', 'Remove if skipped')
7509
+ }),
7510
+ sx: {
7511
+ ml: 5.5
7512
+ }
7424
7513
  }), /*#__PURE__*/jsx(InputFieldCard, {
7425
7514
  icon: /*#__PURE__*/jsx(ImageIcon, {
7426
7515
  fontSize: "small"
@@ -7430,7 +7519,8 @@ var InputFieldsPanelContent = observer(function (_ref3) {
7430
7519
  onClick: function onClick() {
7431
7520
  return addInputElement('image', {
7432
7521
  promptText: imagePrompt,
7433
- required: imageRequired
7522
+ required: imageRequired,
7523
+ removeIfSkipped: imageRemoveIfSkipped
7434
7524
  });
7435
7525
  }
7436
7526
  }), /*#__PURE__*/jsx(TextField, {
@@ -7465,6 +7555,23 @@ var InputFieldsPanelContent = observer(function (_ref3) {
7465
7555
  sx: {
7466
7556
  ml: 5.5
7467
7557
  }
7558
+ }), !imageRequired && /*#__PURE__*/jsx(FormControlLabel, {
7559
+ control: /*#__PURE__*/jsx(Checkbox, {
7560
+ size: "small",
7561
+ checked: imageRemoveIfSkipped,
7562
+ onChange: function onChange(e) {
7563
+ return setImageRemoveIfSkipped(e.target.checked);
7564
+ }
7565
+ }),
7566
+ label: /*#__PURE__*/jsx(Typography, {
7567
+ sx: {
7568
+ fontSize: 12
7569
+ },
7570
+ children: t('sidePanel.inputFields.removeIfSkipped', 'Remove if skipped')
7571
+ }),
7572
+ sx: {
7573
+ ml: 5.5
7574
+ }
7468
7575
  }), /*#__PURE__*/jsx(InputFieldCard, {
7469
7576
  icon: /*#__PURE__*/jsx(RadioButtonCheckedIcon, {
7470
7577
  fontSize: "small"
@@ -7475,7 +7582,8 @@ var InputFieldsPanelContent = observer(function (_ref3) {
7475
7582
  return addInputElement('radio', {
7476
7583
  promptText: radioPrompt,
7477
7584
  required: radioRequired,
7478
- options: radioOptions
7585
+ options: radioOptions,
7586
+ removeIfSkipped: radioRemoveIfSkipped
7479
7587
  });
7480
7588
  }
7481
7589
  }), /*#__PURE__*/jsx(TextField, {
@@ -7510,6 +7618,23 @@ var InputFieldsPanelContent = observer(function (_ref3) {
7510
7618
  sx: {
7511
7619
  ml: 5.5
7512
7620
  }
7621
+ }), !radioRequired && /*#__PURE__*/jsx(FormControlLabel, {
7622
+ control: /*#__PURE__*/jsx(Checkbox, {
7623
+ size: "small",
7624
+ checked: radioRemoveIfSkipped,
7625
+ onChange: function onChange(e) {
7626
+ return setRadioRemoveIfSkipped(e.target.checked);
7627
+ }
7628
+ }),
7629
+ label: /*#__PURE__*/jsx(Typography, {
7630
+ sx: {
7631
+ fontSize: 12
7632
+ },
7633
+ children: t('sidePanel.inputFields.removeIfSkipped', 'Remove if skipped')
7634
+ }),
7635
+ sx: {
7636
+ ml: 5.5
7637
+ }
7513
7638
  }), /*#__PURE__*/jsx(OptionsEditor, {
7514
7639
  options: radioOptions,
7515
7640
  onChange: setRadioOptions
@@ -7524,7 +7649,8 @@ var InputFieldsPanelContent = observer(function (_ref3) {
7524
7649
  promptText: listPrompt,
7525
7650
  minSelections: listMinSelections,
7526
7651
  maxSelections: listMaxSelections,
7527
- options: listOptions
7652
+ options: listOptions,
7653
+ removeIfSkipped: listRemoveIfSkipped
7528
7654
  });
7529
7655
  }
7530
7656
  }), /*#__PURE__*/jsx(TextField, {
@@ -7597,6 +7723,23 @@ var InputFieldsPanelContent = observer(function (_ref3) {
7597
7723
  fontSize: 10
7598
7724
  },
7599
7725
  children: listMinSelections > 0 ? "Required \xB7 min ".concat(listMinSelections).concat(listMaxSelections > 0 ? ", max ".concat(listMaxSelections) : ', no max') : "Optional \xB7 max ".concat(listMaxSelections > 0 ? listMaxSelections : '∞')
7726
+ }), listMinSelections === 0 && /*#__PURE__*/jsx(FormControlLabel, {
7727
+ control: /*#__PURE__*/jsx(Checkbox, {
7728
+ size: "small",
7729
+ checked: listRemoveIfSkipped,
7730
+ onChange: function onChange(e) {
7731
+ return setListRemoveIfSkipped(e.target.checked);
7732
+ }
7733
+ }),
7734
+ label: /*#__PURE__*/jsx(Typography, {
7735
+ sx: {
7736
+ fontSize: 12
7737
+ },
7738
+ children: t('sidePanel.inputFields.removeIfSkipped', 'Remove if skipped')
7739
+ }),
7740
+ sx: {
7741
+ ml: 5.5
7742
+ }
7600
7743
  })]
7601
7744
  }), /*#__PURE__*/jsx(Divider, {
7602
7745
  sx: {
@@ -7629,30 +7772,34 @@ var InputFieldsPanelContent = observer(function (_ref3) {
7629
7772
  var MarkAsVariableForm = observer(function (_ref4) {
7630
7773
  var _selectedElement$cust;
7631
7774
  var store = _ref4.store;
7632
- var _useState31 = useState(''),
7633
- _useState32 = _slicedToArray(_useState31, 2),
7634
- markLabel = _useState32[0],
7635
- setMarkLabel = _useState32[1];
7636
- var _useState33 = useState(false),
7637
- _useState34 = _slicedToArray(_useState33, 2),
7638
- markRequired = _useState34[0],
7639
- setMarkRequired = _useState34[1];
7640
- var _useState35 = useState('text'),
7641
- _useState36 = _slicedToArray(_useState35, 2),
7642
- markInputType = _useState36[0],
7643
- setMarkInputType = _useState36[1];
7644
- var _useState37 = useState(['Option 1', 'Option 2']),
7645
- _useState38 = _slicedToArray(_useState37, 2),
7646
- markOptions = _useState38[0],
7647
- setMarkOptions = _useState38[1];
7648
- var _useState39 = useState(0),
7649
- _useState40 = _slicedToArray(_useState39, 2),
7650
- markMinSelections = _useState40[0],
7651
- setMarkMinSelections = _useState40[1];
7652
- var _useState41 = useState(2),
7653
- _useState42 = _slicedToArray(_useState41, 2),
7654
- markMaxSelections = _useState42[0],
7655
- setMarkMaxSelections = _useState42[1];
7775
+ var _useState43 = useState(''),
7776
+ _useState44 = _slicedToArray(_useState43, 2),
7777
+ markLabel = _useState44[0],
7778
+ setMarkLabel = _useState44[1];
7779
+ var _useState45 = useState(false),
7780
+ _useState46 = _slicedToArray(_useState45, 2),
7781
+ markRequired = _useState46[0],
7782
+ setMarkRequired = _useState46[1];
7783
+ var _useState47 = useState('text'),
7784
+ _useState48 = _slicedToArray(_useState47, 2),
7785
+ markInputType = _useState48[0],
7786
+ setMarkInputType = _useState48[1];
7787
+ var _useState49 = useState(['Option 1', 'Option 2']),
7788
+ _useState50 = _slicedToArray(_useState49, 2),
7789
+ markOptions = _useState50[0],
7790
+ setMarkOptions = _useState50[1];
7791
+ var _useState51 = useState(0),
7792
+ _useState52 = _slicedToArray(_useState51, 2),
7793
+ markMinSelections = _useState52[0],
7794
+ setMarkMinSelections = _useState52[1];
7795
+ var _useState53 = useState(2),
7796
+ _useState54 = _slicedToArray(_useState53, 2),
7797
+ markMaxSelections = _useState54[0],
7798
+ setMarkMaxSelections = _useState54[1];
7799
+ var _useState55 = useState(false),
7800
+ _useState56 = _slicedToArray(_useState55, 2),
7801
+ markRemoveIfSkipped = _useState56[0],
7802
+ setMarkRemoveIfSkipped = _useState56[1];
7656
7803
  var selectedIds = store.selectedElementsIds || [];
7657
7804
  var selectedElement = selectedIds.length === 1 ? store.getElementById(selectedIds[0]) : null;
7658
7805
  var isImageElement = (selectedElement === null || selectedElement === void 0 ? void 0 : selectedElement.type) === 'image';
@@ -7661,13 +7808,14 @@ var MarkAsVariableForm = observer(function (_ref4) {
7661
7808
  var isAlreadyVariable = !!(selectedElement !== null && selectedElement !== void 0 && (_selectedElement$cust = selectedElement.custom) !== null && _selectedElement$cust !== void 0 && _selectedElement$cust.inputField);
7662
7809
  useEffect(function () {
7663
7810
  if (selectedElement && isSupportedElement) {
7664
- var _selectedElement$cust2, _selectedElement$cust3, _selectedElement$cust4, _selectedElement$cust5, _selectedElement$cust6, _selectedElement$cust7;
7811
+ var _selectedElement$cust2, _selectedElement$cust3, _selectedElement$cust4, _selectedElement$cust5, _selectedElement$cust6, _selectedElement$cust7, _selectedElement$cust8;
7665
7812
  setMarkLabel(((_selectedElement$cust2 = selectedElement.custom) === null || _selectedElement$cust2 === void 0 ? void 0 : _selectedElement$cust2.promptText) || '');
7666
7813
  setMarkRequired(!!((_selectedElement$cust3 = selectedElement.custom) !== null && _selectedElement$cust3 !== void 0 && _selectedElement$cust3.required));
7667
7814
  setMarkInputType(isImageElement ? 'image' : ((_selectedElement$cust4 = selectedElement.custom) === null || _selectedElement$cust4 === void 0 ? void 0 : _selectedElement$cust4.inputType) || 'text');
7668
7815
  setMarkOptions(((_selectedElement$cust5 = selectedElement.custom) === null || _selectedElement$cust5 === void 0 ? void 0 : _selectedElement$cust5.options) || ['Option 1', 'Option 2']);
7669
7816
  setMarkMinSelections(((_selectedElement$cust6 = selectedElement.custom) === null || _selectedElement$cust6 === void 0 ? void 0 : _selectedElement$cust6.minSelections) || 0);
7670
7817
  setMarkMaxSelections(((_selectedElement$cust7 = selectedElement.custom) === null || _selectedElement$cust7 === void 0 ? void 0 : _selectedElement$cust7.maxSelections) || 2);
7818
+ setMarkRemoveIfSkipped(!!((_selectedElement$cust8 = selectedElement.custom) !== null && _selectedElement$cust8 !== void 0 && _selectedElement$cust8.removeIfSkipped));
7671
7819
  } else {
7672
7820
  setMarkLabel('');
7673
7821
  setMarkRequired(false);
@@ -7675,6 +7823,7 @@ var MarkAsVariableForm = observer(function (_ref4) {
7675
7823
  setMarkOptions(['Option 1', 'Option 2']);
7676
7824
  setMarkMinSelections(0);
7677
7825
  setMarkMaxSelections(2);
7826
+ setMarkRemoveIfSkipped(false);
7678
7827
  }
7679
7828
  }, [selectedElement === null || selectedElement === void 0 ? void 0 : selectedElement.id]);
7680
7829
  var handleMark = function handleMark() {
@@ -7685,7 +7834,8 @@ var MarkAsVariableForm = observer(function (_ref4) {
7685
7834
  inputField: true,
7686
7835
  promptText: markLabel.trim(),
7687
7836
  inputType: effectiveType,
7688
- required: markRequired
7837
+ required: markRequired,
7838
+ removeIfSkipped: !markRequired && markRemoveIfSkipped
7689
7839
  }, ['radio', 'list'].includes(effectiveType) ? {
7690
7840
  options: markOptions.filter(Boolean)
7691
7841
  } : {}), effectiveType === 'list' ? {
@@ -7702,6 +7852,7 @@ var MarkAsVariableForm = observer(function (_ref4) {
7702
7852
  _ref5.promptText;
7703
7853
  _ref5.inputType;
7704
7854
  _ref5.required;
7855
+ _ref5.removeIfSkipped;
7705
7856
  _ref5.placeholder;
7706
7857
  _ref5.options;
7707
7858
  _ref5.minSelections;
@@ -7922,6 +8073,20 @@ var MarkAsVariableForm = observer(function (_ref4) {
7922
8073
  },
7923
8074
  children: t('sidePanel.inputFields.required', 'Required')
7924
8075
  })
8076
+ }), !markRequired && /*#__PURE__*/jsx(FormControlLabel, {
8077
+ control: /*#__PURE__*/jsx(Checkbox, {
8078
+ size: "small",
8079
+ checked: markRemoveIfSkipped,
8080
+ onChange: function onChange(e) {
8081
+ return setMarkRemoveIfSkipped(e.target.checked);
8082
+ }
8083
+ }),
8084
+ label: /*#__PURE__*/jsx(Typography, {
8085
+ sx: {
8086
+ fontSize: 12
8087
+ },
8088
+ children: t('sidePanel.inputFields.removeIfSkipped', 'Remove if skipped')
8089
+ })
7925
8090
  }), /*#__PURE__*/jsx(Button, {
7926
8091
  variant: "contained",
7927
8092
  size: "small",
@@ -8063,6 +8228,21 @@ function _loadGoogleFont() {
8063
8228
  var DEFAULT_FONTS = ['ABeeZee', 'Abel', 'Abhaya Libre', 'Abril Fatface', 'Aclonica', 'Acme', 'Actor', 'Adamina', 'Advent Pro', 'Aguafina Script', 'Akronim', 'Aladin', 'Alata', 'Alatsi', 'Albert Sans', 'Aldrich', 'Alef', 'Alegreya', 'Alegreya Sans', 'Alegreya Sans SC', 'Alegreya SC', 'Aleo', 'Alex Brush', 'Alfa Slab One', 'Alice', 'Alike', 'Alike Angular', 'Allan', 'Allerta', 'Allerta Stencil', 'Allison', 'Allura', 'Almarai', 'Almendra', 'Almendra Display', 'Almendra SC', 'Alumni Sans', 'Alumni Sans Inline One', 'Amarante', 'Amaranth', 'Amatic SC', 'Amethysta', 'Amiko', 'Amiri', 'Amita', 'Anaheim', 'Andada Pro', 'Andika', 'Anek Bangla', 'Anek Devanagari', 'Anek Gujarati', 'Anek Gurmukhi', 'Anek Kannada', 'Anek Latin', 'Anek Malayalam', 'Anek Odia', 'Anek Tamil', 'Anek Telugu', 'Angkor', 'Annie Use Your Telescope', 'Anonymous Pro', 'Antic', 'Antic Didone', 'Antic Slab', 'Anton', 'Antonio', 'Anybody', 'Arapey', 'Arbutus', 'Arbutus Slab', 'Architects Daughter', 'Archivo', 'Archivo Black', 'Archivo Narrow', 'Are You Serious', 'Aref Ruqaa', 'Arima', 'Arimo', 'Arizonia', 'Armata', 'Arsenal', 'Artifika', 'Arvo', 'Arya', 'Asap', 'Asap Condensed', 'Asar', 'Asset', 'Assistant', 'Astloch', 'Asul', 'Athiti', 'Atkinson Hyperlegible', 'Atma', 'Atomic Age', 'Aubrey', 'Audiowide', 'Autour One', 'Average', 'Average Sans', 'Averia Gruesa Libre', 'Averia Libre', 'Averia Sans Libre', 'Averia Serif Libre', 'Azeret Mono', 'B612', 'B612 Mono', 'Bad Script', 'Bahiana', 'Bahianita', 'Bai Jamjuree', 'Bakbak One', 'Ballet', 'Baloo 2', 'Baloo Bhai 2', 'Baloo Bhaijaan 2', 'Baloo Bhaina 2', 'Baloo Chettan 2', 'Baloo Da 2', 'Baloo Paaji 2', 'Baloo Tamma 2', 'Baloo Tammudu 2', 'Baloo Thambi 2', 'Balsamiq Sans', 'Balthazar', 'Bangers', 'Barlow', 'Barlow Condensed', 'Barlow Semi Condensed', 'Barriecito', 'Barrio', 'Basic', 'Baskervville', 'Battambang', 'Baumans', 'Bayon', 'Be Vietnam Pro', 'Beau Rivage', 'Bebas Neue', 'Belgrano', 'Bellefair', 'Belleza', 'Bellota', 'Bellota Text', 'BenchNine', 'Benne', 'Bentham', 'Berkshire Swash', 'Besley', 'Beth Ellen', 'Bevan', 'BIZ UDGothic', 'BIZ UDMincho', 'BIZ UDPGothic', 'BIZ UDPMincho', 'Big Shoulders Display', 'Big Shoulders Inline Display', 'Big Shoulders Inline Text', 'Big Shoulders Stencil Display', 'Big Shoulders Stencil Text', 'Big Shoulders Text', 'Bigelow Rules', 'Bigshot One', 'Bilbo', 'Bilbo Swash Caps', 'BioRhyme', 'BioRhyme Expanded', 'Birthstone', 'Birthstone Bounce', 'Bitter', 'Black And White Picture', 'Black Han Sans', 'Black Ops One', 'Blaka', 'Blaka Hollow', 'Blaka Ink', 'Blinker', 'Bodoni Moda', 'Bokor', 'Bona Nova', 'Bonbon', 'Bonheur Royale', 'Boogaloo', 'Bowlby One', 'Bowlby One SC', 'Brawler', 'Bree Serif', 'Brygada 1918', 'Bubblegum Sans', 'Bubbler One', 'Buda', 'Buenard', 'Bungee', 'Bungee Hairline', 'Bungee Inline', 'Bungee Outline', 'Bungee Shade', 'Bungee Spice', 'Butcherman', 'Butterfly Kids', 'Cabin', 'Cabin Condensed', 'Cabin Sketch', 'Caesar Dressing', 'Cagliostro', 'Cairo', 'Cairo Play', 'Caladea', 'Calistoga', 'Calligraffitti', 'Cambay', 'Cambo', 'Candal', 'Cantarell', 'Cantata One', 'Cantora One', 'Caprasimo', 'Capriola', 'Caramel', 'Carattere', 'Cardo', 'Carlito', 'Carme', 'Carrois Gothic', 'Carrois Gothic SC', 'Carter One', 'Castoro', 'Catamaran', 'Caudex', 'Caveat', 'Caveat Brush', 'Cedarville Cursive', 'Ceviche One', 'Chakra Petch', 'Changa', 'Changa One', 'Chango', 'Charis SIL', 'Charm', 'Charmonman', 'Chathura', 'Chau Philomene One', 'Chela One', 'Chelsea Market', 'Chenla', 'Cherry Bomb One', 'Cherry Cream Soda', 'Cherry Swash', 'Chewy', 'Chicle', 'Chilanka', 'Chivo', 'Chivo Mono', 'Chonburi', 'Cinzel', 'Cinzel Decorative', 'Clicker Script', 'Coda', 'Coda Caption', 'Codystar', 'Coiny', 'Combo', 'Comfortaa', 'Comforter', 'Comforter Brush', 'Comic Neue', 'Coming Soon', 'Commissioner', 'Concert One', 'Condiment', 'Content', 'Contrail One', 'Convergence', 'Cookie', 'Copse', 'Corben', 'Corinthia', 'Cormorant', 'Cormorant Garamond', 'Cormorant Infant', 'Cormorant SC', 'Cormorant Unicase', 'Cormorant Upright', 'Courgette', 'Courier Prime', 'Cousine', 'Coustard', 'Covered By Your Grace', 'Crafty Girls', 'Creepster', 'Crete Round', 'Crimson Pro', 'Crimson Text', 'Croissant One', 'Crushed', 'Cuprum', 'Cute Font', 'Cutive', 'Cutive Mono', 'DM Mono', 'DM Sans', 'DM Serif Display', 'DM Serif Text', 'Damion', 'Dancing Script', 'Dangrek', 'Darker Grotesque', 'David Libre', 'Dawning of a New Day', 'Days One', 'Dekko', 'Dela Gothic One', 'Delius', 'Delius Swash Caps', 'Delius Unicase', 'Della Respira', 'Denk One', 'Devonshire', 'Dhurjati', 'Didact Gothic', 'Diplomata', 'Diplomata SC', 'Do Hyeon', 'Dokdo', 'Domine', 'Donegal One', 'Dongle', 'Doppio One', 'Dorsa', 'Dosis', 'DotGothic16', 'Dr Sugiyama', 'Duru Sans', 'DynaPuff', 'Dynalight', 'EB Garamond', 'Eagle Lake', 'East Sea Dokdo', 'Eater', 'Economica', 'Eczar', 'El Messiri', 'Electrolize', 'Elsie', 'Elsie Swash Caps', 'Emblema One', 'Emilys Candy', 'Encode Sans', 'Encode Sans Condensed', 'Encode Sans Expanded', 'Encode Sans SC', 'Encode Sans Semi Condensed', 'Encode Sans Semi Expanded', 'Engagement', 'Englebert', 'Enriqueta', 'Ephesis', 'Epilogue', 'Erica One', 'Esteban', 'Estonia', 'Euphoria Script', 'Ewert', 'Exo', 'Exo 2', 'Expletus Sans', 'Explora', 'Fahkwang', 'Familjen Grotesk', 'Fanwood Text', 'Farro', 'Farsan', 'Fascinate', 'Fascinate Inline', 'Faster One', 'Fasthand', 'Fauna One', 'Faustina', 'Federant', 'Federo', 'Felipa', 'Fenix', 'Festive', 'Finger Paint', 'Finlandica', 'Fira Code', 'Fira Mono', 'Fira Sans', 'Fira Sans Condensed', 'Fira Sans Extra Condensed', 'Fjalla One', 'Fjord One', 'Flamenco', 'Flavors', 'Fleur De Leah', 'Flow Block', 'Flow Circular', 'Flow Rounded', 'Fondamento', 'Fontdiner Swanky', 'Forum', 'Fragment Mono', 'Francois One', 'Frank Ruhl Libre', 'Fraunces', 'Freckle Face', 'Fredericka the Great', 'Fredoka', 'Freehand', 'Fresca', 'Frijole', 'Fruktur', 'Fugaz One', 'Fuggles', 'Fuzzy Bubbles', 'GFS Didot', 'GFS Neohellenic', 'Gabriela', 'Gaegu', 'Gafata', 'Galada', 'Galdeano', 'Galindo', 'Gamja Flower', 'Gantari', 'Gas', 'Gayathri', 'Gelasio', 'Gemunu Libre', 'Genos', 'Gentium Book Plus', 'Gentium Plus', 'Geo', 'Georama', 'Geostar', 'Geostar Fill', 'Germania One', 'Gideon Roman', 'Gidugu', 'Gilda Display', 'Girassol', 'Give You Glory', 'Glass Antiqua', 'Glegoo', 'Gloria Hallelujah', 'Glory', 'Gluten', 'Goblin One', 'Gochi Hand', 'Goldman', 'Goldplay', 'Golos Text', 'Gorditas', 'Gothic A1', 'Gotu', 'Goudy Bookletter 1911', 'Gowun Batang', 'Gowun Dodum', 'Graduate', 'Grand Hotel', 'Grandstander', 'Grape Nuts', 'Gravitas One', 'Great Vibes', 'Grechen Fuemen', 'Grenze', 'Grenze Gotisch', 'Grey Qo', 'Griffy', 'Gruppo', 'Gudea', 'Gugi', 'Gulzar', 'Gupter', 'Gurajada', 'Gwendolyn', 'Habibi', 'Hachi Maru Pop', 'Hahmlet', 'Halant', 'Hammersmith One', 'Hanalei', 'Hanalei Fill', 'Handlee', 'Hanken Grotesk', 'Hanuman', 'Happy Monkey', 'Harmattan', 'Headland One', 'Heebo', 'Henny Penny', 'Hepta Slab', 'Herr Von Muellerhoff', 'Hi Melody', 'Hina Mincho', 'Hind', 'Hind Guntur', 'Hind Madurai', 'Hind Siliguri', 'Hind Vadodara', 'Holtwood One SC', 'Homemade Apple', 'Homenaje', 'Hubballi', 'Hurricane', 'IBM Plex Mono', 'IBM Plex Sans', 'IBM Plex Sans Arabic', 'IBM Plex Sans Condensed', 'IBM Plex Sans Devanagari', 'IBM Plex Sans Hebrew', 'IBM Plex Sans JP', 'IBM Plex Sans KR', 'IBM Plex Sans Thai', 'IBM Plex Sans Thai Looped', 'IBM Plex Serif', 'Iceberg', 'Iceland', 'Imbue', 'Imperial Script', 'Imprima', 'Inconsolata', 'Inder', 'Indie Flower', 'Ingrid Darling', 'Inika', 'Inknut Antiqua', 'Inria Sans', 'Inria Serif', 'Inspiration', 'Inter', 'Inter Tight', 'Irish Grover', 'Island Moments', 'Istok Web', 'Italiana', 'Italianno', 'Itim', 'Jacques Francois', 'Jacques Francois Shadow', 'Jaldi', 'JetBrains Mono', 'Jim Nightshade', 'Joan', 'Jockey One', 'Jolly Lodger', 'Jomhuria', 'Jomolhari', 'Josefin Sans', 'Josefin Slab', 'Jost', 'Joti One', 'Jua', 'Judson', 'Julee', 'Julius Sans One', 'Junge', 'Jura', 'K2D', 'Kadwa', 'Kaisei Decol', 'Kaisei HarunoUmi', 'Kaisei Opti', 'Kaisei Tokumin', 'Kalam', 'Kameron', 'Kanit', 'Kantumruy Pro', 'Karantina', 'Karla', 'Karma', 'Katibeh', 'Kaushan Script', 'Kavivanar', 'Kavoon', 'Kdam Thmor Pro', 'Keania One', 'Kelly Slab', 'Kenia', 'Khand', 'Khmer', 'Khula', 'Kings', 'Kirang Haerang', 'Kite One', 'Kiwi Maru', 'Klee One', 'Knewave', 'KoHo', 'Kodchasan', 'Koh Santepheap', 'Kolker Brush', 'Konkhmer Sleokchher', 'Kosugi', 'Kosugi Maru', 'Kotta One', 'Koulen', 'Kranky', 'Kreon', 'Kristi', 'Krona One', 'Krub', 'Kufam', 'Kulim Park', 'Kumar One', 'Kumar One Outline', 'Kumbh Sans', 'Kurale', 'La Belle Aurore', 'Lacquer', 'Laila', 'Lakki Reddy', 'Lalezar', 'Lancelot', 'Langar', 'Lango', 'Lateef', 'Lato', 'Lavishly Yours', 'League Gothic', 'League Script', 'League Spartan', 'Leckerli One', 'Ledger', 'Lekton', 'Lemon', 'Lemonada', 'Lexend', 'Lexend Deca', 'Lexend Exa', 'Lexend Giga', 'Lexend Mega', 'Lexend Peta', 'Lexend Tera', 'Lexend Zetta', 'Libre Barcode 128', 'Libre Barcode 128 Text', 'Libre Barcode 39', 'Libre Barcode 39 Extended', 'Libre Barcode 39 Extended Text', 'Libre Barcode 39 Text', 'Libre Barcode EAN13 Text', 'Libre Baskerville', 'Libre Bodoni', 'Libre Caslon Display', 'Libre Caslon Text', 'Libre Franklin', 'Licorice', 'Life Savers', 'Lilita One', 'Lily Script One', 'Limelight', 'Linden Hill', 'Lingua Franca', 'Literata', 'Liu Jian Mao Cao', 'Livvic', 'Lobster', 'Lobster Two', 'Londrina Outline', 'Londrina Shadow', 'Londrina Sketch', 'Londrina Solid', 'Long Cang', 'Lora', 'Love Light', 'Love Ya Like A Sister', 'Loved by the King', 'Lovers Quarrel', 'Luckiest Guy', 'Lusitana', 'Lustria', 'Luxurious Roman', 'Luxurious Script', 'M PLUS 1', 'M PLUS 1 Code', 'M PLUS 1p', 'M PLUS 2', 'M PLUS Code Latin', 'M PLUS Rounded 1c', 'Ma Shan Zheng', 'Macondo', 'Macondo Swash Caps', 'Mada', 'Magra', 'Maiden Orange', 'Maitree', 'Major Mono Display', 'Mako', 'Mali', 'Mallanna', 'Mandali', 'Manjari', 'Manrope', 'Mansalva', 'Manuale', 'Marcellus', 'Marcellus SC', 'Marck Script', 'Margarine', 'Marhey', 'Markazi Text', 'Marko One', 'Marmelad', 'Martel', 'Martel Sans', 'Marvel', 'Mate', 'Mate SC', 'Maven Pro', 'McLaren', 'Mea Culpa', 'Meddon', 'MedievalSharp', 'Medula One', 'Meera Inimai', 'Megrim', 'Meie Script', 'Meow Script', 'Merienda', 'Merriweather', 'Merriweather Sans', 'Metal', 'Metal Mania', 'Metamorphous', 'Metrophobic', 'Michroma', 'Milonga', 'Miltonian', 'Miltonian Tattoo', 'Mina', 'Miniver', 'Miriam Libre', 'Mirza', 'Miss Fajardose', 'Mitr', 'Mochiy Pop One', 'Mochiy Pop P One', 'Modak', 'Modern Antiqua', 'Mogra', 'Mohave', 'Moirai One', 'Molengo', 'Molle', 'Monda', 'Monofett', 'Monoton', 'Monsieur La Doulaise', 'Montaga', 'Montagu Slab', 'MonteCarlo', 'Montez', 'Montserrat', 'Montserrat Alternates', 'Montserrat Subrayada', 'Moon Dance', 'Moul', 'Moulpali', 'Mountains of Christmas', 'Mouse Memoirs', 'Mr Bedfort', 'Mr Dafoe', 'Mr De Haviland', 'Mrs Saint Delafield', 'Mrs Sheppards', 'Mukta', 'Mukta Mahee', 'Mukta Malar', 'Mukta Vaani', 'Mulish', 'Murecho', 'MuseoModerno', 'My Soul', 'Mynerve', 'Mystery Quest', 'NTR', 'Nabla', 'Nanum Brush Script', 'Nanum Gothic', 'Nanum Gothic Coding', 'Nanum Myeongjo', 'Nanum Pen Script', 'Neonderthaw', 'Nerko One', 'Neucha', 'Neuton', 'New Rocker', 'New Tegomin', 'News Cycle', 'Newsreader', 'Niconne', 'Niramit', 'Nixie One', 'Nobile', 'Nokora', 'Norican', 'Nosifer', 'Notable', 'Nothing You Could Do', 'Noticia Text', 'Noto Color Emoji', 'Noto Emoji', 'Noto Kufi Arabic', 'Noto Music', 'Noto Naskh Arabic', 'Noto Nastaliq Urdu', 'Noto Sans', 'Noto Sans Arabic', 'Noto Sans Display', 'Noto Sans Mono', 'Noto Serif', 'Noto Serif Display', 'Nova Cut', 'Nova Flat', 'Nova Mono', 'Nova Oval', 'Nova Round', 'Nova Script', 'Nova Slim', 'Nova Square', 'Numans', 'Nunito', 'Nunito Sans', 'Odibee Sans', 'Odor Mean Chey', 'Offside', 'Oi', 'Old Standard TT', 'Oldenburg', 'Ole', 'Oleo Script', 'Oleo Script Swash Caps', 'Oooh Baby', 'Open Sans', 'Oranienbaum', 'Orbit', 'Orbitron', 'Oregano', 'Orelega One', 'Orienta', 'Original Surfer', 'Oswald', 'Outfit', 'Over the Rainbow', 'Overlock', 'Overlock SC', 'Overpass', 'Overpass Mono', 'Ovo', 'Oxanium', 'Oxygen', 'Oxygen Mono', 'PT Mono', 'PT Sans', 'PT Sans Caption', 'PT Sans Narrow', 'PT Serif', 'PT Serif Caption', 'Pacifico', 'Padauk', 'Padyakke Expanded One', 'Palanquin', 'Palanquin Dark', 'Palette Mosaic', 'Pangolin', 'Paprika', 'Parisienne', 'Passero One', 'Passion One', 'Passions Conflict', 'Pathway Extreme', 'Pathway Gothic One', 'Patrick Hand', 'Patrick Hand SC', 'Pattaya', 'Patua One', 'Pavanam', 'Paytone One', 'Peddana', 'Peralta', 'Permanent Marker', 'Petit Formal Script', 'Petrona', 'Philosopher', 'Phudu', 'Piazzolla', 'Piedra', 'Pinyon Script', 'Pirata One', 'Plaster', 'Play', 'Playball', 'Playfair Display', 'Playfair Display SC', 'Playpen Sans', 'Plus Jakarta Sans', 'Podkova', 'Poiret One', 'Poller One', 'Poltawski Nowy', 'Poly', 'Pompiere', 'Pontano Sans', 'Poor Story', 'Poppins', 'Port Lligat Sans', 'Port Lligat Slab', 'Potta One', 'Pragati Narrow', 'Praise', 'Prata', 'Preahvihear', 'Press Start 2P', 'Pridi', 'Princess Sofia', 'Prociono', 'Prompt', 'Prosto One', 'Proza Libre', 'Public Sans', 'Puppies Play', 'Puritan', 'Purple Purse', 'Pushster', 'Quando', 'Quantico', 'Quattrocento', 'Quattrocento Sans', 'Questrial', 'Quicksand', 'Quintessential', 'Qwigley', 'Qwitcher Grypen', 'REM', 'Racing Sans One', 'Radio Canada', 'Radley', 'Rajdhani', 'Rakkas', 'Raleway', 'Raleway Dots', 'Ramabhadra', 'Ramaraja', 'Rambla', 'Rammetto One', 'Rampart One', 'Ranchers', 'Rancho', 'Ranga', 'Rasa', 'Rationale', 'Ravi Prakash', 'Readex Pro', 'Recursive', 'Red Hat Display', 'Red Hat Mono', 'Red Hat Text', 'Red Rose', 'Redacted', 'Redacted Script', 'Redressed', 'Reem Kufi', 'Reem Kufi Fun', 'Reem Kufi Ink', 'Reenie Beanie', 'Reggae One', 'Revalia', 'Rhodium Libre', 'Ribeye', 'Ribeye Marrow', 'Righteous', 'Risque', 'Road Rage', 'RocknRoll One', 'Rokkitt', 'Romanesco', 'Ropa Sans', 'Rosario', 'Rosarivo', 'Rouge Script', 'Rowdies', 'Rozha One', 'Rubik', 'Rubik Beastly', 'Rubik Bubbles', 'Rubik Burned', 'Rubik Dirt', 'Rubik Distressed', 'Rubik Gemstones', 'Rubik Glitch', 'Rubik Iso', 'Rubik Marker Hatch', 'Rubik Maze', 'Rubik Microbe', 'Rubik Mono One', 'Rubik Moonrocks', 'Rubik Pixels', 'Rubik Puddles', 'Rubik Spray Paint', 'Rubik Storm', 'Rubik Vinyl', 'Rubik Wet Paint', 'Ruda', 'Rufina', 'Ruge Boogie', 'Ruluko', 'Rum Raisin', 'Ruslan Display', 'Russo One', 'Ruthie', 'Rye', 'STIX Two Text', 'Sacramento', 'Sahitya', 'Sail', 'Saira', 'Saira Condensed', 'Saira Extra Condensed', 'Saira Semi Condensed', 'Saira Stencil One', 'Salsa', 'Sanchez', 'Sancreek', 'Sansita', 'Sansita Swashed', 'Sarabun', 'Sarala', 'Sarina', 'Sarpanch', 'Sassybold', 'Satisfy', 'Sawarabi Gothic', 'Sawarabi Mincho', 'Scada', 'Scheherazade New', 'Schoolbell', 'Scope One', 'Seaweed Script', 'Secular One', 'Sedgwick Ave', 'Sedgwick Ave Display', 'Sen', 'Send Flowers', 'Sevillana', 'Seymour One', 'Shadows Into Light', 'Shadows Into Light Two', 'Shalimar', 'Shanti', 'Share', 'Share Tech', 'Share Tech Mono', 'Shippori Antique', 'Shippori Antique B1', 'Shippori Mincho', 'Shippori Mincho B1', 'Shizuru', 'Shojumaru', 'Short Stack', 'Shrikhand', 'Siemreap', 'Sigmar One', 'Signika', 'Signika Negative', 'Silkscreen', 'Simonetta', 'Single Day', 'Sintony', 'Sirin Stencil', 'Six Caps', 'Skranji', 'Slabo 13px', 'Slabo 27px', 'Slackey', 'Smokum', 'Smooch', 'Smooch Sans', 'Smythe', 'Sniglet', 'Snippet', 'Snowburst One', 'Sofadi One', 'Sofia', 'Sofia Sans', 'Sofia Sans Condensed', 'Sofia Sans Extra Condensed', 'Sofia Sans Semi Condensed', 'Solitreo', 'Solway', 'Song Myung', 'Sono', 'Sonsie One', 'Sora', 'Sorts Mill Goudy', 'Source Code Pro', 'Source Sans 3', 'Source Sans Pro', 'Source Serif 4', 'Source Serif Pro', 'Space Grotesk', 'Space Mono', 'Special Elite', 'Spectral', 'Spectral SC', 'Spicy Rice', 'Spinnaker', 'Spirax', 'Splash', 'Spline Sans', 'Spline Sans Mono', 'Squada One', 'Square Peg', 'Sree Krushnadevaraya', 'Sriracha', 'Srisakdi', 'Staatliches', 'Stalemate', 'Stalinist One', 'Stardos Stencil', 'Stick', 'Stick No Bills', 'Stint Ultra Condensed', 'Stint Ultra Expanded', 'Stoke', 'Strait', 'Style Script', 'Stylish', 'Sue Ellen Francisco', 'Suez One', 'Sulphur Point', 'Sumana', 'Sunflower', 'Sunshiney', 'Supermercado One', 'Sura', 'Suranna', 'Suravaram', 'Suwannaphum', 'Swanky and Moo Moo', 'Syncopate', 'Syne', 'Syne Mono', 'Syne Tactile', 'Tac One', 'Tai Heritage Pro', 'Tajawal', 'Tangerine', 'Tapestry', 'Taprom', 'Tauri', 'Taviraj', 'Teko', 'Telex', 'Tenali Ramakrishna', 'Tenor Sans', 'Text Me One', 'Texturina', 'Thasadith', 'The Girl Next Door', 'The Nautigal', 'Tienne', 'Tillana', 'Tilt Neon', 'Tilt Prism', 'Tilt Warp', 'Timmana', 'Tinos', 'Tiro Bangla', 'Tiro Devanagari Marathi', 'Tiro Devanagari Sanskrit', 'Tiro Gurmukhi', 'Tiro Kannada', 'Tiro Tamil', 'Tiro Telugu', 'Titan One', 'Titillium Web', 'Tomorrow', 'Tourney', 'Trade Winds', 'Train One', 'Trirong', 'Trispace', 'Trocchi', 'Trochut', 'Truculenta', 'Trykker', 'Tsukimi Rounded', 'Tulpen One', 'Turret Road', 'Twinkle Star', 'Ubuntu', 'Ubuntu Condensed', 'Ubuntu Mono', 'Uchen', 'Ultra', 'Unbounded', 'Uncial Antiqua', 'Underdog', 'Unica One', 'UnifrakturCook', 'UnifrakturMaguntia', 'Unkempt', 'Unlock', 'Unna', 'Updock', 'Urbanist', 'Vast Shadow', 'Vazirmatn', 'Vesper Libre', 'Viaoda Libre', 'Vibes', 'Vibur', 'Vidaloka', 'Viga', 'Voces', 'Volkhov', 'Vollkorn', 'Vollkorn SC', 'Voltaire', 'Vujahday Script', 'Waiting for the Sunrise', 'Wallpoet', 'Walter Turncoat', 'Warnes', 'Waterfall', 'Wavefont', 'Wellfleet', 'Wendy One', 'Whisper', 'WindSong', 'Wire One', 'Work Sans', 'Wix Madefor Display', 'Wix Madefor Text', 'Xanh Mono', 'Yaldevi', 'Yanone Kaffeesatz', 'Yantramanav', 'Yatra One', 'Yellowtail', 'Yeon Sung', 'Yeseva One', 'Yesteryear', 'Yomogi', 'Yrsa', 'Ysabeau', 'Ysabeau Infant', 'Ysabeau Office', 'Ysabeau SC', 'Yuji Boku', 'Yuji Hentaigana Akari', 'Yuji Hentaigana Akebono', 'Yuji Mai', 'Yuji Syuku', 'Yusei Magic', 'ZCOOL KuaiLe', 'ZCOOL QingKe HuangYou', 'ZCOOL XiaoWei', 'Zen Antique', 'Zen Antique Soft', 'Zen Dots', 'Zen Kaku Gothic Antique', 'Zen Kaku Gothic New', 'Zen Kurenaido', 'Zen Loop', 'Zen Maru Gothic', 'Zen Old Mincho', 'Zen Tokyo Zoo', 'Zeyada', 'Zhi Mang Xing', 'Zilla Slab', 'Zilla Slab Highlight'];
8064
8229
 
8065
8230
  var _excluded$1 = ["fontFamily"];
8231
+ var _positionMenuItemSx = {
8232
+ textTransform: 'none',
8233
+ fontSize: 12,
8234
+ fontWeight: 400,
8235
+ color: '#333',
8236
+ justifyContent: 'flex-start',
8237
+ px: 1,
8238
+ py: 0.6,
8239
+ minWidth: 0,
8240
+ '&:hover': {
8241
+ backgroundColor: 'rgba(13,131,205,0.08)'
8242
+ }
8243
+ };
8244
+
8245
+ // ── Font preview: lightweight Google Font subsets for dropdown ──
8066
8246
  var _fontPreviewLoaded = new Set();
8067
8247
  function loadFontPreview(fontFamily) {
8068
8248
  if (_fontPreviewLoaded.has(fontFamily)) return;
@@ -8743,10 +8923,270 @@ var LineToolbar = observer(function (_ref7) {
8743
8923
  });
8744
8924
  });
8745
8925
 
8746
- // Common controls for all element types
8747
- var CommonControls = observer(function (_ref8) {
8926
+ // Position + alignment popover button
8927
+ var PositionButton = observer(function (_ref8) {
8748
8928
  var element = _ref8.element,
8749
8929
  store = _ref8.store;
8930
+ var _useState3 = useState(null),
8931
+ _useState4 = _slicedToArray(_useState3, 2),
8932
+ anchorEl = _useState4[0],
8933
+ setAnchorEl = _useState4[1];
8934
+ var open = Boolean(anchorEl);
8935
+ var pageW = store.width;
8936
+ var pageH = store.height;
8937
+ var alignEl = function alignEl(xVal, yVal) {
8938
+ var attrs = {};
8939
+ if (xVal !== null) attrs.x = xVal;
8940
+ if (yVal !== null) attrs.y = yVal;
8941
+ element.set(attrs);
8942
+ store.history.addUndoState();
8943
+ };
8944
+ var layer = function layer(fn) {
8945
+ fn();
8946
+ store.history.addUndoState();
8947
+ };
8948
+ return /*#__PURE__*/jsxs(Fragment, {
8949
+ children: [/*#__PURE__*/jsx(Button, {
8950
+ size: "small",
8951
+ onClick: function onClick(e) {
8952
+ return setAnchorEl(e.currentTarget);
8953
+ },
8954
+ startIcon: /*#__PURE__*/jsx(OpenWithIcon, {
8955
+ sx: {
8956
+ fontSize: '16px !important'
8957
+ }
8958
+ }),
8959
+ sx: _objectSpread2({
8960
+ textTransform: 'none',
8961
+ fontSize: 12,
8962
+ whiteSpace: 'nowrap',
8963
+ px: 1.5,
8964
+ minWidth: 'auto'
8965
+ }, open ? {
8966
+ backgroundColor: '#e3f2fd',
8967
+ color: '#0d83cd'
8968
+ } : {}),
8969
+ children: t('toolbar.position', 'Position')
8970
+ }), /*#__PURE__*/jsxs(Popover, {
8971
+ open: open,
8972
+ anchorEl: anchorEl,
8973
+ onClose: function onClose() {
8974
+ return setAnchorEl(null);
8975
+ },
8976
+ anchorOrigin: {
8977
+ vertical: 'bottom',
8978
+ horizontal: 'left'
8979
+ },
8980
+ transformOrigin: {
8981
+ vertical: 'top',
8982
+ horizontal: 'left'
8983
+ },
8984
+ slotProps: {
8985
+ paper: {
8986
+ sx: {
8987
+ mt: 0.5,
8988
+ p: 2,
8989
+ width: 300,
8990
+ borderRadius: '10px',
8991
+ boxShadow: '0 4px 20px rgba(0,0,0,0.12)'
8992
+ }
8993
+ }
8994
+ },
8995
+ children: [/*#__PURE__*/jsx(Typography, {
8996
+ variant: "caption",
8997
+ sx: {
8998
+ fontWeight: 700,
8999
+ color: '#111',
9000
+ display: 'block',
9001
+ mb: 1,
9002
+ fontSize: 12
9003
+ },
9004
+ children: t('toolbar.layering', 'Layer order')
9005
+ }), /*#__PURE__*/jsxs(Box, {
9006
+ sx: {
9007
+ display: 'grid',
9008
+ gridTemplateColumns: '1fr 1fr',
9009
+ gap: 0.5,
9010
+ mb: 2
9011
+ },
9012
+ children: [/*#__PURE__*/jsx(Button, {
9013
+ size: "small",
9014
+ startIcon: /*#__PURE__*/jsx(ArrowUpwardIcon, {}),
9015
+ onClick: function onClick() {
9016
+ return layer(function () {
9017
+ return element.moveUp();
9018
+ });
9019
+ },
9020
+ sx: _positionMenuItemSx,
9021
+ children: t('toolbar.up', 'Up')
9022
+ }), /*#__PURE__*/jsx(Button, {
9023
+ size: "small",
9024
+ startIcon: /*#__PURE__*/jsx(ArrowDownwardIcon, {}),
9025
+ onClick: function onClick() {
9026
+ return layer(function () {
9027
+ return element.moveDown();
9028
+ });
9029
+ },
9030
+ sx: _positionMenuItemSx,
9031
+ children: t('toolbar.down', 'Down')
9032
+ }), /*#__PURE__*/jsx(Button, {
9033
+ size: "small",
9034
+ startIcon: /*#__PURE__*/jsx(VerticalAlignTopIcon, {}),
9035
+ onClick: function onClick() {
9036
+ return layer(function () {
9037
+ return element.moveTop();
9038
+ });
9039
+ },
9040
+ sx: _positionMenuItemSx,
9041
+ children: t('toolbar.toForward', 'To front')
9042
+ }), /*#__PURE__*/jsx(Button, {
9043
+ size: "small",
9044
+ startIcon: /*#__PURE__*/jsx(VerticalAlignBottomIcon, {}),
9045
+ onClick: function onClick() {
9046
+ return layer(function () {
9047
+ return element.moveBottom();
9048
+ });
9049
+ },
9050
+ sx: _positionMenuItemSx,
9051
+ children: t('toolbar.toBottom', 'To back')
9052
+ })]
9053
+ }), /*#__PURE__*/jsx(Divider, {
9054
+ sx: {
9055
+ mb: 1.5
9056
+ }
9057
+ }), /*#__PURE__*/jsx(Typography, {
9058
+ variant: "caption",
9059
+ sx: {
9060
+ fontWeight: 700,
9061
+ color: '#111',
9062
+ display: 'block',
9063
+ mb: 1,
9064
+ fontSize: 12
9065
+ },
9066
+ children: t('toolbar.position', 'Position')
9067
+ }), function () {
9068
+ var cx = (pageW - element.width) / 2;
9069
+ var cy = (pageH - element.height) / 2;
9070
+ var rx = pageW - element.width;
9071
+ var by = pageH - element.height;
9072
+ var positions = [{
9073
+ label: 'Top left',
9074
+ x: 0,
9075
+ y: 0,
9076
+ row: 0,
9077
+ col: 0
9078
+ }, {
9079
+ label: 'Top center',
9080
+ x: cx,
9081
+ y: 0,
9082
+ row: 0,
9083
+ col: 1
9084
+ }, {
9085
+ label: 'Top right',
9086
+ x: rx,
9087
+ y: 0,
9088
+ row: 0,
9089
+ col: 2
9090
+ }, {
9091
+ label: 'Middle left',
9092
+ x: 0,
9093
+ y: cy,
9094
+ row: 1,
9095
+ col: 0
9096
+ }, {
9097
+ label: 'Center',
9098
+ x: cx,
9099
+ y: cy,
9100
+ row: 1,
9101
+ col: 1
9102
+ }, {
9103
+ label: 'Middle right',
9104
+ x: rx,
9105
+ y: cy,
9106
+ row: 1,
9107
+ col: 2
9108
+ }, {
9109
+ label: 'Bottom left',
9110
+ x: 0,
9111
+ y: by,
9112
+ row: 2,
9113
+ col: 0
9114
+ }, {
9115
+ label: 'Bottom center',
9116
+ x: cx,
9117
+ y: by,
9118
+ row: 2,
9119
+ col: 1
9120
+ }, {
9121
+ label: 'Bottom right',
9122
+ x: rx,
9123
+ y: by,
9124
+ row: 2,
9125
+ col: 2
9126
+ }];
9127
+ return /*#__PURE__*/jsx(Box, {
9128
+ sx: {
9129
+ display: 'grid',
9130
+ gridTemplateColumns: 'repeat(3, 1fr)',
9131
+ gap: 0.5
9132
+ },
9133
+ children: positions.map(function (_ref9) {
9134
+ var label = _ref9.label,
9135
+ x = _ref9.x,
9136
+ y = _ref9.y;
9137
+ return /*#__PURE__*/jsx(Tooltip, {
9138
+ title: label,
9139
+ placement: "top",
9140
+ children: /*#__PURE__*/jsx(IconButton, {
9141
+ size: "small",
9142
+ onClick: function onClick() {
9143
+ return alignEl(x, y);
9144
+ },
9145
+ sx: {
9146
+ borderRadius: '6px',
9147
+ border: '1px solid #e0e0e0',
9148
+ p: 0.75,
9149
+ '&:hover': {
9150
+ backgroundColor: 'rgba(13,131,205,0.08)',
9151
+ borderColor: '#0d83cd'
9152
+ }
9153
+ },
9154
+ children: /*#__PURE__*/jsx(Box, {
9155
+ sx: {
9156
+ display: 'grid',
9157
+ gridTemplateColumns: 'repeat(3, 5px)',
9158
+ gap: '2px'
9159
+ },
9160
+ children: [0, 1, 2].map(function (r) {
9161
+ return [0, 1, 2].map(function (c) {
9162
+ return /*#__PURE__*/jsx(Box, {
9163
+ sx: {
9164
+ width: 5,
9165
+ height: 5,
9166
+ borderRadius: '1px',
9167
+ backgroundColor: r === positions.find(function (p) {
9168
+ return p.label === label;
9169
+ }).row && c === positions.find(function (p) {
9170
+ return p.label === label;
9171
+ }).col ? '#0d83cd' : '#ccc'
9172
+ }
9173
+ }, "".concat(r, "-").concat(c));
9174
+ });
9175
+ })
9176
+ })
9177
+ })
9178
+ }, label);
9179
+ })
9180
+ });
9181
+ }()]
9182
+ })]
9183
+ });
9184
+ });
9185
+
9186
+ // Common controls for all element types
9187
+ var CommonControls = observer(function (_ref0) {
9188
+ var element = _ref0.element,
9189
+ store = _ref0.store;
8750
9190
  var isLocked = element.locked;
8751
9191
  var handleDuplicate = function handleDuplicate() {
8752
9192
  if (element.clone) {
@@ -8787,14 +9227,6 @@ var CommonControls = observer(function (_ref8) {
8787
9227
  var handleOpacityCommit = function handleOpacityCommit() {
8788
9228
  store.history.addUndoState();
8789
9229
  };
8790
- var handleMoveUp = function handleMoveUp() {
8791
- element.moveUp();
8792
- store.history.addUndoState();
8793
- };
8794
- var handleMoveDown = function handleMoveDown() {
8795
- element.moveDown();
8796
- store.history.addUndoState();
8797
- };
8798
9230
  return /*#__PURE__*/jsxs(Fragment, {
8799
9231
  children: [/*#__PURE__*/jsx(Tooltip, {
8800
9232
  title: t('toolbar.opacity', 'Opacity'),
@@ -8829,24 +9261,9 @@ var CommonControls = observer(function (_ref8) {
8829
9261
  sx: {
8830
9262
  mx: 0.5
8831
9263
  }
8832
- }), /*#__PURE__*/jsx(Tooltip, {
8833
- title: t('toolbar.up', 'Move up'),
8834
- children: /*#__PURE__*/jsx(IconButton, {
8835
- size: "small",
8836
- onClick: handleMoveUp,
8837
- children: /*#__PURE__*/jsx(ArrowUpwardIcon, {
8838
- fontSize: "small"
8839
- })
8840
- })
8841
- }), /*#__PURE__*/jsx(Tooltip, {
8842
- title: t('toolbar.down', 'Move down'),
8843
- children: /*#__PURE__*/jsx(IconButton, {
8844
- size: "small",
8845
- onClick: handleMoveDown,
8846
- children: /*#__PURE__*/jsx(ArrowDownwardIcon, {
8847
- fontSize: "small"
8848
- })
8849
- })
9264
+ }), /*#__PURE__*/jsx(PositionButton, {
9265
+ element: element,
9266
+ store: store
8850
9267
  }), /*#__PURE__*/jsx(Divider, {
8851
9268
  orientation: "vertical",
8852
9269
  flexItem: true,
@@ -8890,26 +9307,26 @@ var CommonControls = observer(function (_ref8) {
8890
9307
  });
8891
9308
 
8892
9309
  // Download button with format/quality popover
8893
- var DefaultDownloadButton = observer(function (_ref9) {
8894
- var store = _ref9.store;
8895
- var _useState3 = useState(null),
8896
- _useState4 = _slicedToArray(_useState3, 2),
8897
- anchorEl = _useState4[0],
8898
- setAnchorEl = _useState4[1];
8899
- var _useState5 = useState('png'),
9310
+ var DefaultDownloadButton = observer(function (_ref1) {
9311
+ var store = _ref1.store;
9312
+ var _useState5 = useState(null),
8900
9313
  _useState6 = _slicedToArray(_useState5, 2),
8901
- fileType = _useState6[0],
8902
- setFileType = _useState6[1];
9314
+ anchorEl = _useState6[0],
9315
+ setAnchorEl = _useState6[1];
9316
+ var _useState7 = useState('png'),
9317
+ _useState8 = _slicedToArray(_useState7, 2),
9318
+ fileType = _useState8[0],
9319
+ setFileType = _useState8[1];
8903
9320
  // Default quality so pixelRatio=1 (output = template's own pixel size).
8904
9321
  // qualityToPixelRatio(q) = q * 3, so q = 1/3 → pixelRatio = 1.
8905
- var _useState7 = useState(1 / 3),
8906
- _useState8 = _slicedToArray(_useState7, 2),
8907
- quality = _useState8[0],
8908
- setQuality = _useState8[1];
8909
- var _useState9 = useState(false),
9322
+ var _useState9 = useState(1 / 3),
8910
9323
  _useState0 = _slicedToArray(_useState9, 2),
8911
- exporting = _useState0[0],
8912
- setExporting = _useState0[1];
9324
+ quality = _useState0[0],
9325
+ setQuality = _useState0[1];
9326
+ var _useState1 = useState(false),
9327
+ _useState10 = _slicedToArray(_useState1, 2),
9328
+ exporting = _useState10[0],
9329
+ setExporting = _useState10[1];
8913
9330
  var open = Boolean(anchorEl);
8914
9331
  var handleClick = function handleClick(e) {
8915
9332
  setAnchorEl(e.currentTarget);
@@ -9142,15 +9559,15 @@ var DefaultDownloadButton = observer(function (_ref9) {
9142
9559
  });
9143
9560
 
9144
9561
  // Import button — loads a JSON template file into the store
9145
- var DefaultImportButton = observer(function (_ref1) {
9146
- var store = _ref1.store;
9147
- var _useState1 = useState(false),
9148
- _useState10 = _slicedToArray(_useState1, 2),
9149
- importing = _useState10[0],
9150
- setImporting = _useState10[1];
9562
+ var DefaultImportButton = observer(function (_ref11) {
9563
+ var store = _ref11.store;
9564
+ var _useState11 = useState(false),
9565
+ _useState12 = _slicedToArray(_useState11, 2),
9566
+ importing = _useState12[0],
9567
+ setImporting = _useState12[1];
9151
9568
  var fileInputRef = React.useRef(null);
9152
9569
  var handleFileChange = useCallback(/*#__PURE__*/function () {
9153
- var _ref10 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2(e) {
9570
+ var _ref12 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2(e) {
9154
9571
  var _e$target$files;
9155
9572
  var file, text, jsonData, _t3;
9156
9573
  return _regenerator().w(function (_context2) {
@@ -9188,7 +9605,7 @@ var DefaultImportButton = observer(function (_ref1) {
9188
9605
  }, _callee2, null, [[2, 4, 5, 6]]);
9189
9606
  }));
9190
9607
  return function (_x) {
9191
- return _ref10.apply(this, arguments);
9608
+ return _ref12.apply(this, arguments);
9192
9609
  };
9193
9610
  }(), [store]);
9194
9611
  return /*#__PURE__*/jsxs(Fragment, {
@@ -9254,10 +9671,10 @@ var rowSx = {
9254
9671
  display: 'none'
9255
9672
  }
9256
9673
  };
9257
- var Toolbar = observer(function (_ref11) {
9258
- var store = _ref11.store,
9259
- _ref11$components = _ref11.components,
9260
- components = _ref11$components === void 0 ? {} : _ref11$components;
9674
+ var Toolbar = observer(function (_ref13) {
9675
+ var store = _ref13.store,
9676
+ _ref13$components = _ref13.components,
9677
+ components = _ref13$components === void 0 ? {} : _ref13$components;
9261
9678
  var ActionControls = components.ActionControls;
9262
9679
  var ImportButton = 'ImportButton' in components ? components.ImportButton : DefaultImportButton;
9263
9680
  var DownloadButton = 'DownloadButton' in components ? components.DownloadButton : DefaultDownloadButton;
@@ -9949,8 +10366,10 @@ var TextElementComponent = observer(function (_ref) {
9949
10366
  var scaleY = absScale.y;
9950
10367
  var cssFontStyle = element.fontStyle === 'italic' ? 'italic' : 'normal';
9951
10368
  var cssFontWeight = String(element.fontWeight || 'normal');
10369
+ var originalText = element.text;
9952
10370
  var textarea = document.createElement('textarea');
9953
- textarea.value = element.text;
10371
+ textarea.value = '';
10372
+ textarea.placeholder = originalText;
9954
10373
  textarea.style.position = 'absolute';
9955
10374
  textarea.style.top = "".concat(textPosition.y, "px");
9956
10375
  textarea.style.left = "".concat(textPosition.x, "px");
@@ -9983,15 +10402,21 @@ var TextElementComponent = observer(function (_ref) {
9983
10402
  textarea.style.wordBreak = 'break-word';
9984
10403
  textarea.style.minHeight = '0';
9985
10404
  textarea.style.minWidth = '0';
10405
+
10406
+ // Placeholder inherits the element's text color at 40% opacity
10407
+ var placeholderStyle = document.createElement('style');
10408
+ placeholderStyle.textContent = "\n textarea:placeholder-shown { opacity: 1; }\n textarea::placeholder { color: ".concat(element.fill, "; opacity: 0.4; }\n ");
10409
+ stageContainer.appendChild(placeholderStyle);
9986
10410
  stageContainer.appendChild(textarea);
9987
10411
  textarea.focus();
9988
- textarea.select();
9989
10412
  var removed = false;
9990
10413
  var removeTextarea = function removeTextarea() {
10414
+ var cancel = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
9991
10415
  if (removed) return;
9992
10416
  removed = true;
10417
+ var newText = !cancel && textarea.value.length > 0 ? textarea.value : originalText;
9993
10418
  element.set({
9994
- text: textarea.value
10419
+ text: newText
9995
10420
  });
9996
10421
  element.toggleEditMode(false);
9997
10422
  if (grp) grp.show();
@@ -9999,12 +10424,15 @@ var TextElementComponent = observer(function (_ref) {
9999
10424
  if (textarea.parentNode) {
10000
10425
  textarea.parentNode.removeChild(textarea);
10001
10426
  }
10427
+ if (placeholderStyle.parentNode) {
10428
+ placeholderStyle.parentNode.removeChild(placeholderStyle);
10429
+ }
10002
10430
  };
10003
- textarea.addEventListener('blur', removeTextarea);
10431
+ textarea.addEventListener('blur', function () {
10432
+ return removeTextarea(false);
10433
+ });
10004
10434
  textarea.addEventListener('keydown', function (e) {
10005
- if (e.key === 'Escape') {
10006
- removeTextarea();
10007
- }
10435
+ if (e.key === 'Escape') removeTextarea(true);
10008
10436
  });
10009
10437
  };
10010
10438
 
@@ -11164,6 +11592,7 @@ var InputFieldsDialog = observer(function (_ref2) {
11164
11592
  setDisplayIndex = _useState8[1];
11165
11593
  var initialTotalRef = useRef(0);
11166
11594
  var completedHistoryRef = useRef([]);
11595
+ var removedDueToSkipRef = useRef([]);
11167
11596
  var isGoingBackRef = useRef(false);
11168
11597
  var prevBackTriggerRef = useRef(backTrigger);
11169
11598
  var config = getInputFieldsConfig();
@@ -11206,14 +11635,24 @@ var InputFieldsDialog = observer(function (_ref2) {
11206
11635
  var last = completedHistoryRef.current.pop();
11207
11636
  if (!last) return;
11208
11637
  var el = last.el,
11209
- previousValue = last.previousValue;
11638
+ previousValue = last.previousValue,
11639
+ removed = last.removed;
11210
11640
  if (el) {
11211
11641
  var isImage = el.custom && el.custom.inputType === 'image';
11212
- el.set(isImage ? {
11213
- src: previousValue || ''
11214
- } : {
11215
- text: previousValue || ''
11216
- });
11642
+ if (removed) {
11643
+ el.set({
11644
+ visible: true
11645
+ });
11646
+ removedDueToSkipRef.current = removedDueToSkipRef.current.filter(function (e) {
11647
+ return e.id !== el.id;
11648
+ });
11649
+ } else {
11650
+ el.set(isImage ? {
11651
+ src: previousValue || ''
11652
+ } : {
11653
+ text: previousValue || ''
11654
+ });
11655
+ }
11217
11656
  isGoingBackRef.current = true;
11218
11657
  store._unresolveInputField(el);
11219
11658
  }
@@ -11231,6 +11670,15 @@ var InputFieldsDialog = observer(function (_ref2) {
11231
11670
  var currentField = fields[0];
11232
11671
  if (!currentField) return null;
11233
11672
 
11673
+ // ── Helper: clear the removed-elements tracking ref ──────────────────
11674
+ // Elements are kept in the canvas with visible:false — they don't render
11675
+ // on screen or in exports, and can be restored via back navigation at any
11676
+ // point (including back-from-summary via backTrigger) without touching
11677
+ // deleted MST nodes.
11678
+ var _flushRemovedElements = function _flushRemovedElements() {
11679
+ removedDueToSkipRef.current = [];
11680
+ };
11681
+
11234
11682
  // ── Shared submit / skip / back helpers ─────────────────────────────
11235
11683
  var handleSubmit = function handleSubmit(elementId, value) {
11236
11684
  var el = store.getElementById(elementId);
@@ -11254,6 +11702,7 @@ var InputFieldsDialog = observer(function (_ref2) {
11254
11702
  }
11255
11703
  store._resolveInputField(elementId);
11256
11704
  if (fields.length <= 1) {
11705
+ _flushRemovedElements();
11257
11706
  store.history.addUndoState();
11258
11707
  if (_onComplete) _onComplete();
11259
11708
  } else {
@@ -11266,13 +11715,24 @@ var InputFieldsDialog = observer(function (_ref2) {
11266
11715
  var el = store.getElementById(elementId);
11267
11716
  var isImage = el && el.custom && el.custom.inputType === 'image';
11268
11717
  var previousValue = el ? isImage ? el.src : el.text : '';
11718
+ var shouldRemove = !!(el && el.custom && el.custom.removeIfSkipped);
11719
+ if (shouldRemove) {
11720
+ el.set({
11721
+ visible: false
11722
+ });
11723
+ removedDueToSkipRef.current.push(el);
11724
+ }
11269
11725
  completedHistoryRef.current.push({
11270
11726
  el: el,
11271
11727
  previousValue: previousValue,
11272
- skipped: true
11728
+ skipped: true,
11729
+ removed: shouldRemove
11273
11730
  });
11274
11731
  store._resolveInputField(elementId);
11275
11732
  if (fields.length <= 1) {
11733
+ var hadRemovals = removedDueToSkipRef.current.length > 0;
11734
+ _flushRemovedElements();
11735
+ if (hadRemovals) store.history.addUndoState();
11276
11736
  if (_onComplete) _onComplete();
11277
11737
  } else {
11278
11738
  setDisplayIndex(function (prev) {
@@ -11284,14 +11744,24 @@ var InputFieldsDialog = observer(function (_ref2) {
11284
11744
  var last = completedHistoryRef.current.pop();
11285
11745
  if (!last) return;
11286
11746
  var el = last.el,
11287
- previousValue = last.previousValue;
11747
+ previousValue = last.previousValue,
11748
+ removed = last.removed;
11288
11749
  if (el) {
11289
11750
  var isImage = el.custom && el.custom.inputType === 'image';
11290
- el.set(isImage ? {
11291
- src: previousValue || ''
11292
- } : {
11293
- text: previousValue || ''
11294
- });
11751
+ if (removed) {
11752
+ el.set({
11753
+ visible: true
11754
+ });
11755
+ removedDueToSkipRef.current = removedDueToSkipRef.current.filter(function (e) {
11756
+ return e.id !== el.id;
11757
+ });
11758
+ } else {
11759
+ el.set(isImage ? {
11760
+ src: previousValue || ''
11761
+ } : {
11762
+ text: previousValue || ''
11763
+ });
11764
+ }
11295
11765
  store._unresolveInputField(el);
11296
11766
  }
11297
11767
  setDisplayIndex(function (prev) {
@@ -11325,6 +11795,7 @@ var InputFieldsDialog = observer(function (_ref2) {
11325
11795
  onBack: handleBack,
11326
11796
  canGoBack: canGoBack,
11327
11797
  onComplete: function onComplete() {
11798
+ _flushRemovedElements();
11328
11799
  store.history.addUndoState();
11329
11800
  if (_onComplete) _onComplete();
11330
11801
  }