formeo 5.5.0 → 5.6.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.
@@ -1,7 +1,7 @@
1
1
 
2
2
  /**
3
3
  formeo - https://formeo.io
4
- Version: 5.4.0
4
+ Version: 5.5.0
5
5
  Author: Draggable https://draggable.io
6
6
  */
7
7
 
@@ -6064,7 +6064,7 @@ Author: Draggable https://draggable.io
6064
6064
  var name$1, version$2, type, main, module$1, unpkg, exports$1, files, homepage, repository, author, contributors, bugs, description, keywords, ignore, config, scripts, devDependencies, dependencies, release, commitlint, package_default;
6065
6065
  var init_package = __esmMin((() => {
6066
6066
  name$1 = "formeo";
6067
- version$2 = "5.4.0";
6067
+ version$2 = "5.5.0";
6068
6068
  type = "module";
6069
6069
  main = "dist/formeo.cjs.js";
6070
6070
  module$1 = "dist/formeo.es.js";
@@ -11120,9 +11120,11 @@ Author: Draggable https://draggable.io
11120
11120
  */
11121
11121
  var Events = class {
11122
11122
  components = null;
11123
+ destroyed = false;
11123
11124
  constructor() {
11124
11125
  this.opts = this.defaults();
11125
11126
  this.formeoUpdatedThrottled = throttle$1(() => {
11127
+ if (this.destroyed) return;
11126
11128
  const eventData = {
11127
11129
  timeStamp: globalThis.performance.now(),
11128
11130
  type: EVENT_FORMEO_UPDATED,
@@ -11178,6 +11180,7 @@ Author: Draggable https://draggable.io
11178
11180
  return evt;
11179
11181
  }
11180
11182
  runCallbacks({ type, timeStamp, detail }) {
11183
+ if (this.destroyed) return;
11181
11184
  if (type === "formeoUpdated") return this.formeoUpdatedThrottled();
11182
11185
  if (type === "formeoSaved") return this.opts.onSave({
11183
11186
  timeStamp,
@@ -11205,6 +11208,7 @@ Author: Draggable https://draggable.io
11205
11208
  confirmClearAll = (detail) => {
11206
11209
  const evt = new globalThis.CustomEvent("confirmClearAll", { detail });
11207
11210
  document.dispatchEvent(evt);
11211
+ if (this.destroyed) return;
11208
11212
  this.opts.confirmClearAll({
11209
11213
  timeStamp: evt.timeStamp,
11210
11214
  type: evt.type,
@@ -11213,7 +11217,7 @@ Author: Draggable https://draggable.io
11213
11217
  };
11214
11218
  formeoLoaded = (formeo) => {
11215
11219
  document.dispatchEvent(new globalThis.CustomEvent("formeoLoaded", { detail: { formeo } }));
11216
- this.opts.formeoLoaded(formeo);
11220
+ if (!this.destroyed) this.opts.formeoLoaded(formeo);
11217
11221
  };
11218
11222
  columnResized = (detail) => document.dispatchEvent(new globalThis.CustomEvent("columnResized", { detail }));
11219
11223
  /**
@@ -11223,7 +11227,7 @@ Author: Draggable https://draggable.io
11223
11227
  */
11224
11228
  onResizeWindow = () => {
11225
11229
  const { columns, controls } = this.components || {};
11226
- if (!columns || !controls?.dom?.isConnected || this.resizeFrame) return;
11230
+ if (this.destroyed || !columns || !controls?.dom?.isConnected || this.resizeFrame) return;
11227
11231
  this.resizeFrame = window.requestAnimationFrame(() => {
11228
11232
  this.resizeFrame = null;
11229
11233
  for (const column of Object.values(columns.data)) {
@@ -11238,6 +11242,18 @@ Author: Draggable https://draggable.io
11238
11242
  }
11239
11243
  });
11240
11244
  };
11245
+ /**
11246
+ * Stop calling this editor's option callbacks, including a trailing onUpdate/onChange that is
11247
+ * already scheduled, and cancel a pending resize frame. FormeoEditor#destroy (#166) calls it.
11248
+ * DOM events are still dispatched, so page listeners are unaffected.
11249
+ */
11250
+ destroy() {
11251
+ this.destroyed = true;
11252
+ if (this.resizeFrame) {
11253
+ window.cancelAnimationFrame(this.resizeFrame);
11254
+ this.resizeFrame = null;
11255
+ }
11256
+ }
11241
11257
  };
11242
11258
  var events = new Events();
11243
11259
  //#endregion
@@ -13110,6 +13126,24 @@ Author: Draggable https://draggable.io
13110
13126
  Sortable.mount(Remove, Revert);
13111
13127
  }));
13112
13128
  //#endregion
13129
+ //#region src/lib/js/common/sortable.js
13130
+ var destroySortables;
13131
+ var init_sortable = __esmMin((() => {
13132
+ init_sortable_esm();
13133
+ destroySortables = (root) => {
13134
+ if (!root) return 0;
13135
+ let count = 0;
13136
+ for (const el of [root, ...root.querySelectorAll("*")]) {
13137
+ const sortable = Sortable.get(el);
13138
+ if (sortable) {
13139
+ sortable.destroy();
13140
+ count++;
13141
+ }
13142
+ }
13143
+ return count;
13144
+ };
13145
+ }));
13146
+ //#endregion
13113
13147
  //#region src/lib/js/components/panels.js
13114
13148
  var defaults$1, getTransition, Panels;
13115
13149
  var init_panels = __esmMin((() => {
@@ -13139,18 +13173,25 @@ Author: Draggable https://draggable.io
13139
13173
  const panelsWrap = this.createPanelsWrap();
13140
13174
  this.nav = this.navActions();
13141
13175
  this.nav.groupChange(this.activePanelIndex);
13142
- const resizeObserver = new window.ResizeObserver(([{ contentRect: { width } }]) => {
13176
+ this.resizeObserver = new window.ResizeObserver(([{ contentRect: { width } }]) => {
13143
13177
  if (this.currentWidth !== width) {
13144
13178
  this.toggleTabbedLayout();
13145
13179
  this.currentWidth = width;
13146
13180
  this.nav.setTranslateX(this.activePanelIndex, false);
13147
13181
  }
13148
13182
  });
13149
- const observeTimeout = window.setTimeout(() => {
13150
- resizeObserver.observe(panelsWrap);
13151
- window.clearTimeout(observeTimeout);
13183
+ this.observeTimeout = window.setTimeout(() => {
13184
+ this.resizeObserver?.observe(panelsWrap);
13152
13185
  }, ANIMATION_SPEED_SLOW);
13153
13186
  }
13187
+ /**
13188
+ * Stop watching the panels' size
13189
+ */
13190
+ destroy() {
13191
+ window.clearTimeout(this.observeTimeout);
13192
+ this.resizeObserver?.disconnect();
13193
+ this.resizeObserver = null;
13194
+ }
13154
13195
  getPanelDisplay() {
13155
13196
  const column = this.panelsWrap;
13156
13197
  const autoDisplayType = Number.parseInt(dom.getStyle(column, "width"), 10) > 390 ? "tabbed" : "slider";
@@ -13449,7 +13490,7 @@ Author: Draggable https://draggable.io
13449
13490
  }));
13450
13491
  //#endregion
13451
13492
  //#region src/lib/js/components/controls/options.js
13452
- init_sortable_esm();
13493
+ init_sortable();
13453
13494
  init_panels();
13454
13495
  init_control();
13455
13496
  var defaultOptions = Object.freeze({
@@ -14767,6 +14808,7 @@ Author: Draggable https://draggable.io
14767
14808
  var addAttributeActions, defaultConfigOptions, defaultConfigValues, EditPanel;
14768
14809
  var init_edit_panel = __esmMin((() => {
14769
14810
  init_i18n_es_min();
14811
+ init_sortable_esm();
14770
14812
  init_dom();
14771
14813
  init_helpers$2();
14772
14814
  init_string();
@@ -15092,6 +15134,7 @@ Author: Draggable https://draggable.io
15092
15134
  //#region src/lib/js/components/component.js
15093
15135
  var propertyOptions, Component;
15094
15136
  var init_component = __esmMin((() => {
15137
+ init_sortable_esm();
15095
15138
  init_animation();
15096
15139
  init_dom();
15097
15140
  init_helpers$2();
@@ -15246,6 +15289,8 @@ Author: Draggable https://draggable.io
15246
15289
  });
15247
15290
  forEach(children, (child) => child.remove());
15248
15291
  this.dom.remove();
15292
+ this.panels?.destroy();
15293
+ this.releaseSortables();
15249
15294
  remove(this.components.getAddress(siblingsPath), this.id);
15250
15295
  if (!parent.children.length) parent.emptyClass();
15251
15296
  if (parent.name === "row") parent.autoColumnWidths();
@@ -15594,6 +15639,20 @@ Author: Draggable https://draggable.io
15594
15639
  return this.saveChildOrder();
15595
15640
  };
15596
15641
  /**
15642
+ * Destroy the Sortables of this removed component and its descendants, so Sortable's page-wide
15643
+ * list stops holding them (and through them the editor). A column emptied by a drag is removed
15644
+ * from inside Sortable's drop handler; destroying that Sortable there would end the drop early,
15645
+ * so during a drag it is released once the drop has finished.
15646
+ */
15647
+ releaseSortables() {
15648
+ const { dom: removedDom } = this;
15649
+ if (Sortable.active) {
15650
+ queueMicrotask(() => destroySortables(removedDom));
15651
+ return;
15652
+ }
15653
+ destroySortables(removedDom);
15654
+ }
15655
+ /**
15597
15656
  * Handler for removing content from a sortable component
15598
15657
  * @param {Object} evt
15599
15658
  * @return {Array} updated child order
@@ -15819,6 +15878,7 @@ Author: Draggable https://draggable.io
15819
15878
  id: this.id,
15820
15879
  displayType: "auto"
15821
15880
  };
15881
+ this.panels?.destroy();
15822
15882
  this.panels = new Panels(panelsData);
15823
15883
  if (this.dom) {
15824
15884
  this.dom.querySelector(".panel-nav").replaceWith(this.panels.panelNav);
@@ -16597,6 +16657,7 @@ Author: Draggable https://draggable.io
16597
16657
  init_sortable_esm();
16598
16658
  init_dom();
16599
16659
  init_helpers$2();
16660
+ init_sortable();
16600
16661
  init_utils();
16601
16662
  init_object();
16602
16663
  init_constants();
@@ -16886,6 +16947,22 @@ Author: Draggable https://draggable.io
16886
16947
  if (group === "layout") return this.layoutTypes[metaId.replace("layout-", "")]();
16887
16948
  return this.layoutTypes.field(elementData);
16888
16949
  };
16950
+ /**
16951
+ * Remove the controls from the page and release their Sortables and Panels. A control drag in
16952
+ * progress in these controls is ended: its ghost is removed and the page overflow it hid is
16953
+ * restored. Safe to call more than once, and before init().
16954
+ */
16955
+ destroy() {
16956
+ const element = this.dom;
16957
+ if (element && Sortable.active?.el && element.contains(Sortable.active.el)) Sortable.ghost?.remove();
16958
+ if (this.originalDocumentOverflow != null) {
16959
+ document.documentElement.style.overflow = this.originalDocumentOverflow;
16960
+ this.originalDocumentOverflow = null;
16961
+ }
16962
+ destroySortables(element);
16963
+ this.panels?.destroy();
16964
+ element?.remove();
16965
+ }
16889
16966
  applyOptions = async (controlOptions = {}) => {
16890
16967
  const { container, elements, groupOrder, ...options } = merge(defaultOptions, controlOptions);
16891
16968
  this.container = dom.resolveContainer(container);
@@ -17925,6 +18002,7 @@ Author: Draggable https://draggable.io
17925
18002
  init_i18n_es_min();
17926
18003
  init_dom();
17927
18004
  init_loaders();
18005
+ init_sortable();
17928
18006
  init_utils();
17929
18007
  init_constants();
17930
18008
  /**
@@ -17935,9 +18013,11 @@ Author: Draggable https://draggable.io
17935
18013
  LOADING_RESOURCES: "loading",
17936
18014
  INITIALIZING: "initializing",
17937
18015
  READY: "ready",
17938
- ERROR: "error"
18016
+ ERROR: "error",
18017
+ DESTROYED: "destroyed"
17939
18018
  };
17940
18019
  var storageKeyHolders = /* @__PURE__ */ new Map();
18020
+ var pageTooltip = null;
17941
18021
  /**
17942
18022
  * Whether an editor is still on the page, or still on its way there. An editor whose container
17943
18023
  * left the page or no longer holds its DOM (a remount, a demo switch) no longer owns its key.
@@ -17945,7 +18025,7 @@ Author: Draggable https://draggable.io
17945
18025
  * @return {Boolean}
17946
18026
  */
17947
18027
  var isLiveEditor = (editor) => {
17948
- if (editor.initState === INIT_STATES.ERROR) return false;
18028
+ if (editor.initState === INIT_STATES.ERROR || editor.initState === INIT_STATES.DESTROYED) return false;
17949
18029
  if (!editor.editor) return !editor.editorContainer || editor.editorContainer.isConnected;
17950
18030
  return Boolean(editor.editorContainer?.isConnected && editor.editorContainer.contains(editor.editor));
17951
18031
  };
@@ -17957,6 +18037,7 @@ Author: Draggable https://draggable.io
17957
18037
  #initPromise = null;
17958
18038
  #lockedFormData = null;
17959
18039
  #dataLoadedOnce = false;
18040
+ #onDOMContentLoaded = () => this.loadResources();
17960
18041
  /**
17961
18042
  * @param {Object} options formeo options
17962
18043
  * @param {String|Object} userFormData loaded formData
@@ -17992,7 +18073,7 @@ Author: Draggable https://draggable.io
17992
18073
  if (holder && isLiveEditor(holder)) console.warn(`formeo: another editor on this page already saves to sessionStorage key "${key}". Give each editor its own key, e.g. sessionStorage: 'orders-form'.`);
17993
18074
  storageKeyHolders.set(key, this);
17994
18075
  }
17995
- if (document.readyState === "loading") document.addEventListener("DOMContentLoaded", this.loadResources.bind(this));
18076
+ if (document.readyState === "loading") document.addEventListener("DOMContentLoaded", this.#onDOMContentLoaded, { once: true });
17996
18077
  else this.loadResources();
17997
18078
  }
17998
18079
  get formData() {
@@ -18015,6 +18096,7 @@ Author: Draggable https://draggable.io
18015
18096
  * @return {void}
18016
18097
  */
18017
18098
  clear() {
18099
+ if (this.isDestroyed) return;
18018
18100
  const defaultData = DEFAULT_FORMDATA();
18019
18101
  this.#lockedFormData = defaultData;
18020
18102
  this.userFormData = defaultData;
@@ -18026,7 +18108,8 @@ Author: Draggable https://draggable.io
18026
18108
  * @return {Promise} asynchronously loaded remote resources
18027
18109
  */
18028
18110
  async loadResources() {
18029
- document.removeEventListener("DOMContentLoaded", this.loadResources);
18111
+ document.removeEventListener("DOMContentLoaded", this.#onDOMContentLoaded);
18112
+ if (this.isDestroyed) return;
18030
18113
  this.#initState = INIT_STATES.LOADING_RESOURCES;
18031
18114
  const promises = [
18032
18115
  fetchIcons(this.opts.svgSprite),
@@ -18039,8 +18122,10 @@ Author: Draggable https://draggable.io
18039
18122
  ].filter(Boolean);
18040
18123
  try {
18041
18124
  await Promise.all(promises);
18125
+ if (this.isDestroyed) return;
18042
18126
  if (this.opts.allowEdit) this.init();
18043
18127
  } catch (error) {
18128
+ if (this.isDestroyed) return;
18044
18129
  this.#initState = INIT_STATES.ERROR;
18045
18130
  console.error("Failed to load resources:", error);
18046
18131
  throw error;
@@ -18052,10 +18137,15 @@ Author: Draggable https://draggable.io
18052
18137
  * dom elements, actions events and more.
18053
18138
  */
18054
18139
  init() {
18140
+ if (this.isDestroyed) return Promise.resolve(this);
18055
18141
  if (this.#initState === INIT_STATES.INITIALIZING) return this.#initPromise;
18056
18142
  if (this.#initState === INIT_STATES.READY) return this.#refreshUI();
18057
18143
  this.#initState = INIT_STATES.INITIALIZING;
18058
18144
  this.#initPromise = new Controls(this.Components).init(this.opts.controls, this.opts.stickyControls).then((controls) => {
18145
+ if (this.isDestroyed) {
18146
+ controls.destroy();
18147
+ return this;
18148
+ }
18059
18149
  this.controls = controls;
18060
18150
  this.Components.controls = controls;
18061
18151
  if (!this.#dataLoadedOnce) {
@@ -18065,13 +18155,17 @@ Author: Draggable https://draggable.io
18065
18155
  this.formId = this.Components.get("id");
18066
18156
  this.i18n = { setLang: this.#setLanguage.bind(this) };
18067
18157
  this.render();
18158
+ if (this.isDestroyed) return this;
18068
18159
  this.onResize = this.events.onResizeWindow;
18069
18160
  window.addEventListener("resize", this.onResize);
18070
18161
  this.#initState = INIT_STATES.READY;
18071
18162
  this.opts.onLoad?.(this);
18163
+ if (this.isDestroyed) return this;
18072
18164
  this.tooltipInstance = new SmartTooltip();
18165
+ pageTooltip = this.tooltipInstance;
18073
18166
  return this;
18074
18167
  }).catch((error) => {
18168
+ if (this.isDestroyed) return this;
18075
18169
  this.#initState = INIT_STATES.ERROR;
18076
18170
  console.error("Failed to initialize editor:", error);
18077
18171
  throw error;
@@ -18093,7 +18187,13 @@ Author: Draggable https://draggable.io
18093
18187
  * @return {Promise}
18094
18188
  */
18095
18189
  async #refreshUI() {
18096
- this.controls = await new Controls(this.Components).init(this.opts.controls, this.opts.stickyControls);
18190
+ if (this.isDestroyed) return this;
18191
+ const controls = await new Controls(this.Components).init(this.opts.controls, this.opts.stickyControls);
18192
+ if (this.isDestroyed) {
18193
+ controls.destroy();
18194
+ return this;
18195
+ }
18196
+ this.controls = controls;
18097
18197
  this.Components.controls = this.controls;
18098
18198
  this.render();
18099
18199
  return this;
@@ -18121,6 +18221,7 @@ Author: Draggable https://draggable.io
18121
18221
  return DEFAULT_FORMDATA();
18122
18222
  }
18123
18223
  load(formData = this.userFormData, opts = this.opts) {
18224
+ if (this.isDestroyed) return;
18124
18225
  this.Components.load(formData, opts);
18125
18226
  this.render();
18126
18227
  }
@@ -18139,16 +18240,28 @@ Author: Draggable https://draggable.io
18139
18240
  return this.#initState === INIT_STATES.READY;
18140
18241
  }
18141
18242
  /**
18243
+ * Check if destroy() was called
18244
+ * @return {boolean}
18245
+ */
18246
+ get isDestroyed() {
18247
+ return this.#initState === INIT_STATES.DESTROYED;
18248
+ }
18249
+ /**
18142
18250
  * Wait for the editor to be ready
18143
18251
  * @return {Promise} resolves when editor is ready
18144
18252
  */
18145
18253
  async whenReady() {
18146
18254
  if (this.#initState === INIT_STATES.READY) return this;
18255
+ if (this.isDestroyed) return Promise.reject(/* @__PURE__ */ new Error("Editor was destroyed"));
18147
18256
  if (this.#initState === INIT_STATES.ERROR) return Promise.reject(/* @__PURE__ */ new Error("Editor initialization failed"));
18148
- if (this.#initPromise) return this.#initPromise;
18257
+ if (this.#initPromise) return this.#initPromise.then((editor) => {
18258
+ if (this.isDestroyed) throw new Error("Editor was destroyed");
18259
+ return editor;
18260
+ });
18149
18261
  return new Promise((resolve, reject) => {
18150
18262
  const checkReady = () => {
18151
18263
  if (this.#initState === INIT_STATES.READY) resolve(this);
18264
+ else if (this.isDestroyed) reject(/* @__PURE__ */ new Error("Editor was destroyed"));
18152
18265
  else if (this.#initState === INIT_STATES.ERROR) reject(/* @__PURE__ */ new Error("Editor initialization failed"));
18153
18266
  else globalThis.requestAnimationFrame(checkReady);
18154
18267
  };
@@ -18160,6 +18273,7 @@ Author: Draggable https://draggable.io
18160
18273
  * @return {void}
18161
18274
  */
18162
18275
  render() {
18276
+ if (this.isDestroyed) return;
18163
18277
  if (!this.controls) return globalThis.requestAnimationFrame(() => this.render());
18164
18278
  this.stages = Object.values(this.Components.get("stages"));
18165
18279
  if (this.opts.controlOnLeft) for (const stage of this.stages) stage.dom.style.order = 1;
@@ -18190,6 +18304,46 @@ Author: Draggable https://draggable.io
18190
18304
  }
18191
18305
  this.events.formeoLoaded(this);
18192
18306
  }
18307
+ /**
18308
+ * Remove the editor from the page and release what it holds: its Sortable instances, resize
18309
+ * observers, window resize listener, pending callbacks and loaded components. Other editors on
18310
+ * the page keep working, and a new editor can mount in the same container.
18311
+ * Safe to call more than once, and before the editor is ready.
18312
+ * @return {void}
18313
+ */
18314
+ destroy() {
18315
+ if (this.isDestroyed) return;
18316
+ this.#initState = INIT_STATES.DESTROYED;
18317
+ document.removeEventListener("DOMContentLoaded", this.#onDOMContentLoaded);
18318
+ window.removeEventListener("resize", this.onResize);
18319
+ this.events.destroy();
18320
+ if (this.opts.sessionStorage) {
18321
+ const key = formDataStorageKey(this.opts.sessionStorage);
18322
+ if (storageKeyHolders.get(key) === this) storageKeyHolders.delete(key);
18323
+ }
18324
+ this.controls?.destroy();
18325
+ destroySortables(this.editor);
18326
+ for (const type of [
18327
+ "stages",
18328
+ "rows",
18329
+ "columns",
18330
+ "fields"
18331
+ ]) {
18332
+ for (const component of Object.values(this.Components[type]?.data || {})) component.panels?.destroy();
18333
+ this.Components[type]?.empty();
18334
+ }
18335
+ this.editor?.remove();
18336
+ this.Components.empty();
18337
+ if (pageTooltip && !document.querySelector(".formeo-editor")) {
18338
+ pageTooltip.destroy();
18339
+ pageTooltip = null;
18340
+ }
18341
+ this.tooltipInstance = null;
18342
+ this.editor = null;
18343
+ this.controls = null;
18344
+ this.Components.controls = null;
18345
+ this.stages = [];
18346
+ }
18193
18347
  };
18194
18348
  //#endregion
18195
18349
  //#region src/lib/js/renderer/helpers.js
@@ -18471,7 +18625,7 @@ Author: Draggable https://draggable.io
18471
18625
  * `progress` only affects the wizard, adding a clickable step list above the pages
18472
18626
  * @param {Array<Object>} stages stage data in render order, for page titles
18473
18627
  * @param {Function} [onChange] called with (page, previousPage) whenever the page changes
18474
- * @return {{show: Function, index: Number, count: Number}|null} null when there is only one page
18628
+ * @return {{show: Function, index: Number, count: Number, destroy: Function}|null} null when there is only one page
18475
18629
  */
18476
18630
  var paginate = (form, { type, progress, labels }, stages, onChange) => {
18477
18631
  const pages = Array.from(form.children).filter((elem) => elem.classList.contains(STAGE_CLASSNAME));
@@ -18664,14 +18818,16 @@ Author: Draggable https://draggable.io
18664
18818
  }
18665
18819
  };
18666
18820
  const ownerDocument = form.ownerDocument;
18667
- ownerDocument.addEventListener("click", ({ target }) => {
18821
+ const onDocumentClick = ({ target }) => {
18668
18822
  const control = target.closest?.("button, input");
18669
18823
  if (control?.form !== form) return;
18670
18824
  if (control?.type === "submit" || control?.tagName === "INPUT" && control.type === "image") markReported();
18671
- }, true);
18672
- ownerDocument.addEventListener("keydown", ({ key, target }) => {
18825
+ };
18826
+ const onDocumentKeydown = ({ key, target }) => {
18673
18827
  if (key === "Enter" && target.tagName === "INPUT" && target.form === form) markReported();
18674
- }, true);
18828
+ };
18829
+ ownerDocument.addEventListener("click", onDocumentClick, true);
18830
+ ownerDocument.addEventListener("keydown", onDocumentKeydown, true);
18675
18831
  for (const method of ["requestSubmit", "reportValidity"]) {
18676
18832
  const native = HTMLFormElement.prototype[method];
18677
18833
  if (typeof native !== "function") continue;
@@ -18691,7 +18847,11 @@ Author: Draggable https://draggable.io
18691
18847
  get index() {
18692
18848
  return current;
18693
18849
  },
18694
- count
18850
+ count,
18851
+ destroy() {
18852
+ ownerDocument.removeEventListener("click", onDocumentClick, true);
18853
+ ownerDocument.removeEventListener("keydown", onDocumentKeydown, true);
18854
+ }
18695
18855
  };
18696
18856
  };
18697
18857
  //#endregion
@@ -18818,8 +18978,21 @@ Author: Draggable https://draggable.io
18818
18978
  formData: this.form
18819
18979
  });
18820
18980
  }
18981
+ /**
18982
+ * Remove the rendered form from the page and stop its pagination. render() can be called again afterwards.
18983
+ * @return {void}
18984
+ */
18985
+ destroy() {
18986
+ this.pager?.destroy();
18987
+ this.pager = null;
18988
+ this.renderedForm?.remove();
18989
+ this.renderedForm = null;
18990
+ this.components = Object.create(null);
18991
+ }
18821
18992
  getRenderedForm(formData = this.form) {
18822
18993
  this.form = cleanFormData(formData);
18994
+ this.pager?.destroy();
18995
+ this.pager = null;
18823
18996
  const renderCount = document.getElementsByClassName("formeo-render").length;
18824
18997
  const config = {
18825
18998
  ...this.config,
@@ -1,7 +1,7 @@
1
1
 
2
2
  /**
3
3
  formeo - https://formeo.io
4
- Version: 5.4.0
4
+ Version: 5.5.0
5
5
  Author: Draggable https://draggable.io
6
6
  */
7
7
 
@@ -1,7 +1,7 @@
1
1
 
2
2
  /**
3
3
  formeo - https://formeo.io
4
- Version: 5.4.0
4
+ Version: 5.5.0
5
5
  Author: Draggable https://draggable.io
6
6
  */
7
7
 
@@ -1,7 +1,7 @@
1
1
 
2
2
  /**
3
3
  formeo - https://formeo.io
4
- Version: 5.4.0
4
+ Version: 5.5.0
5
5
  Author: Draggable https://draggable.io
6
6
  */
7
7
 
@@ -1,7 +1,7 @@
1
1
 
2
2
  /**
3
3
  formeo - https://formeo.io
4
- Version: 5.4.0
4
+ Version: 5.5.0
5
5
  Author: Draggable https://draggable.io
6
6
  */
7
7
 
@@ -1 +1 @@
1
- <!doctype html><html lang="en" xml:lang="en"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="chrome=1"><meta name="viewport" content="user-scalable=no,width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1"><meta name="description" content="Vanilla Javascript form building module"><meta name="theme-color" content="#232323"><title>Formeo | Drag &amp; Drop Form Creation</title><script type="module" crossorigin src="/formeo/assets/js/demo.min.js"></script><link rel="stylesheet" crossorigin href="/formeo/assets/css/demo.min.css"></head><body><div class="site-wrap"><header id="demo-header"><div class="header-inner"><img id="formeo-logo" src="/formeo/assets/img/formeo-logo.svg" alt="Formeo Logo" width="100"><nav aria-label="Framework navigation"><ul><li><label for="framework-select">Framework:</label> <select name="framework-select" id="framework-select" class="form-control"><option value="vanilla">Vanilla JavaScript</option><option value="angular">Angular</option><option value="react">React</option></select></li><li><label for="locale">Language</label> <select name="locale" id="locale" class="form-control"><option value="af-ZA" dir="ltr">Afrikaans (Suid-Afrika)</option><option value="ar-TN" dir="rtl">العربية (تونس)</option><option value="cs-CZ" dir="ltr">čeština (Česko)</option><option value="de-DE" dir="ltr">Deutsch (Deutschland)</option><option value="en-US" dir="ltr">English</option><option value="es-ES" dir="ltr">español de España</option><option value="fa-IR" dir="rtl">فارسی (ایران)</option><option value="fi-FI" dir="ltr">suomi (Suomi)</option><option value="fr-FR" dir="ltr">français (France)</option><option value="he-IL" dir="rtl">עברית (ישראל)</option><option value="hi-IN" dir="ltr">हिन्दी (भारत)</option><option value="hu-HU" dir="ltr">magyar (Magyarország)</option><option value="it-IT" dir="ltr">italiano (Italia)</option><option value="ja-JP" dir="ltr">日本語 (日本)</option><option value="nb-NO" dir="ltr">norsk bokmål (Norge)</option><option value="pl-PL" dir="ltr">polski (Polska)</option><option value="pt-BR" dir="ltr">português (Brasil)</option><option value="pt-PT" dir="ltr">português europeu</option><option value="ro-RO" dir="ltr">română (România)</option><option value="ru-RU" dir="ltr">русский (Россия)</option><option value="th-TH" dir="ltr">ไทย (ไทย)</option><option value="tr-TR" dir="ltr">Türkçe (Türkiye)</option><option value="zh-CN" dir="ltr">中文(中国)</option><option value="zh-HK" dir="ltr">中文(中國香港特別行政區)</option></select></li><li><label for="control-filter">Control Filter:</label> <input id="control-filter" placeholder="ex. text" class="form-control"></li><li style="float:right">v5.4.0</li></ul></nav></div></header><section id="main_content" class="inner"><div id="framework-container"></div></section><div class="container render-btn-wrap" id="editor-action-buttons"></div><div id="formData-popover" popover><div class="popover-header"><h3>Test formData</h3><div><button type="button" id="format-json">Format</button> <button type="button" id="collapse-json">Collapse</button> <button type="button" id="copy-json">Copy to Clipboard</button></div></div><pre id="formData-editor"></pre><div class="formData-actions"><button popovertarget="formData-popover" popovertargetaction="hide" type="button">Cancel</button> <button id="submit-formData" type="button">Submit</button></div></div><footer id="demo-footer"><nav aria-label="Footer navigation"><ul><li><a href="https://github.com/Draggable/formeo" target="_blank" title="View project on GitHub"><img src="/formeo/assets/img/github.png" width="77" alt="GitHub"></a></li></ul></nav></footer></div></body></html>
1
+ <!doctype html><html lang="en" xml:lang="en"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="chrome=1"><meta name="viewport" content="user-scalable=no,width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1"><meta name="description" content="Vanilla Javascript form building module"><meta name="theme-color" content="#232323"><title>Formeo | Drag &amp; Drop Form Creation</title><script type="module" crossorigin src="/formeo/assets/js/demo.min.js"></script><link rel="stylesheet" crossorigin href="/formeo/assets/css/demo.min.css"></head><body><div class="site-wrap"><header id="demo-header"><div class="header-inner"><img id="formeo-logo" src="/formeo/assets/img/formeo-logo.svg" alt="Formeo Logo" width="100"><nav aria-label="Framework navigation"><ul><li><label for="framework-select">Framework:</label> <select name="framework-select" id="framework-select" class="form-control"><option value="vanilla">Vanilla JavaScript</option><option value="angular">Angular</option><option value="react">React</option></select></li><li><label for="locale">Language</label> <select name="locale" id="locale" class="form-control"><option value="af-ZA" dir="ltr">Afrikaans (Suid-Afrika)</option><option value="ar-TN" dir="rtl">العربية (تونس)</option><option value="cs-CZ" dir="ltr">čeština (Česko)</option><option value="de-DE" dir="ltr">Deutsch (Deutschland)</option><option value="en-US" dir="ltr">English</option><option value="es-ES" dir="ltr">español de España</option><option value="fa-IR" dir="rtl">فارسی (ایران)</option><option value="fi-FI" dir="ltr">suomi (Suomi)</option><option value="fr-FR" dir="ltr">français (France)</option><option value="he-IL" dir="rtl">עברית (ישראל)</option><option value="hi-IN" dir="ltr">हिन्दी (भारत)</option><option value="hu-HU" dir="ltr">magyar (Magyarország)</option><option value="it-IT" dir="ltr">italiano (Italia)</option><option value="ja-JP" dir="ltr">日本語 (日本)</option><option value="nb-NO" dir="ltr">norsk bokmål (Norge)</option><option value="pl-PL" dir="ltr">polski (Polska)</option><option value="pt-BR" dir="ltr">português (Brasil)</option><option value="pt-PT" dir="ltr">português europeu</option><option value="ro-RO" dir="ltr">română (România)</option><option value="ru-RU" dir="ltr">русский (Россия)</option><option value="th-TH" dir="ltr">ไทย (ไทย)</option><option value="tr-TR" dir="ltr">Türkçe (Türkiye)</option><option value="zh-CN" dir="ltr">中文(中国)</option><option value="zh-HK" dir="ltr">中文(中國香港特別行政區)</option></select></li><li><label for="control-filter">Control Filter:</label> <input id="control-filter" placeholder="ex. text" class="form-control"></li><li style="float:right">v5.5.0</li></ul></nav></div></header><section id="main_content" class="inner"><div id="framework-container"></div></section><div class="container render-btn-wrap" id="editor-action-buttons"></div><div id="formData-popover" popover><div class="popover-header"><h3>Test formData</h3><div><button type="button" id="format-json">Format</button> <button type="button" id="collapse-json">Collapse</button> <button type="button" id="copy-json">Copy to Clipboard</button></div></div><pre id="formData-editor"></pre><div class="formData-actions"><button popovertarget="formData-popover" popovertargetaction="hide" type="button">Cancel</button> <button id="submit-formData" type="button">Submit</button></div></div><footer id="demo-footer"><nav aria-label="Footer navigation"><ul><li><a href="https://github.com/Draggable/formeo" target="_blank" title="View project on GitHub"><img src="/formeo/assets/img/github.png" width="77" alt="GitHub"></a></li></ul></nav></footer></div></body></html>