formeo 5.0.0 → 5.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
 
2
2
  /**
3
3
  formeo - https://formeo.io
4
- Version: 4.2.5
4
+ Version: 5.0.1
5
5
  Author: Draggable https://draggable.io
6
6
  */
7
7
 
@@ -434,7 +434,7 @@ if (window !== void 0) {
434
434
  window.SmartTooltip = SmartTooltip;
435
435
  }
436
436
  const name$1 = "formeo";
437
- const version$2 = "4.2.5";
437
+ const version$2 = "5.0.1";
438
438
  const pkg = {
439
439
  name: name$1,
440
440
  version: version$2
@@ -1206,9 +1206,9 @@ var hasRequired_cloneBuffer;
1206
1206
  function require_cloneBuffer() {
1207
1207
  if (hasRequired_cloneBuffer) return _cloneBuffer.exports;
1208
1208
  hasRequired_cloneBuffer = 1;
1209
- (function(module2, exports2) {
1209
+ (function(module2, exports$1) {
1210
1210
  var root = require_root();
1211
- var freeExports = exports2 && !exports2.nodeType && exports2;
1211
+ var freeExports = exports$1 && !exports$1.nodeType && exports$1;
1212
1212
  var freeModule = freeExports && true && module2 && !module2.nodeType && module2;
1213
1213
  var moduleExports = freeModule && freeModule.exports === freeExports;
1214
1214
  var Buffer = moduleExports ? root.Buffer : void 0, allocUnsafe = Buffer ? Buffer.allocUnsafe : void 0;
@@ -1454,9 +1454,9 @@ var hasRequiredIsBuffer;
1454
1454
  function requireIsBuffer() {
1455
1455
  if (hasRequiredIsBuffer) return isBuffer.exports;
1456
1456
  hasRequiredIsBuffer = 1;
1457
- (function(module2, exports2) {
1457
+ (function(module2, exports$1) {
1458
1458
  var root = require_root(), stubFalse = requireStubFalse();
1459
- var freeExports = exports2 && !exports2.nodeType && exports2;
1459
+ var freeExports = exports$1 && !exports$1.nodeType && exports$1;
1460
1460
  var freeModule = freeExports && true && module2 && !module2.nodeType && module2;
1461
1461
  var moduleExports = freeModule && freeModule.exports === freeExports;
1462
1462
  var Buffer = moduleExports ? root.Buffer : void 0;
@@ -1527,9 +1527,9 @@ var hasRequired_nodeUtil;
1527
1527
  function require_nodeUtil() {
1528
1528
  if (hasRequired_nodeUtil) return _nodeUtil.exports;
1529
1529
  hasRequired_nodeUtil = 1;
1530
- (function(module2, exports2) {
1530
+ (function(module2, exports$1) {
1531
1531
  var freeGlobal = require_freeGlobal();
1532
- var freeExports = exports2 && !exports2.nodeType && exports2;
1532
+ var freeExports = exports$1 && !exports$1.nodeType && exports$1;
1533
1533
  var freeModule = freeExports && true && module2 && !module2.nodeType && module2;
1534
1534
  var moduleExports = freeModule && freeModule.exports === freeExports;
1535
1535
  var freeProcess = moduleExports && freeGlobal.process;
@@ -10063,12 +10063,12 @@ class Control {
10063
10063
  // will auto navigated between the groups
10064
10064
  focus: ({ target }) => {
10065
10065
  const group = target.closest(`.${CONTROL_GROUP_CLASSNAME}`);
10066
- return group && Controls$2.panels.nav.refresh(indexOfNode(group));
10066
+ return group && Controls$1.panels.nav.refresh(indexOfNode(group));
10067
10067
  },
10068
10068
  click: ({ target }) => {
10069
10069
  const controlId = target.closest(".field-control")?.id;
10070
10070
  if (controlId) {
10071
- Controls$2.addElement(controlId);
10071
+ Controls$1.addElement(controlId);
10072
10072
  }
10073
10073
  }
10074
10074
  }
@@ -10130,7 +10130,7 @@ const defaultOptions = Object.freeze({
10130
10130
  container: null,
10131
10131
  panels: { displayType: "slider" }
10132
10132
  });
10133
- let Controls$1 = class Controls {
10133
+ let Controls$2 = class Controls {
10134
10134
  constructor() {
10135
10135
  this.data = /* @__PURE__ */ new Map();
10136
10136
  this.buttonActions = {
@@ -10440,11 +10440,11 @@ let Controls$1 = class Controls {
10440
10440
  return Promise.all(this.registerControls([...allControls, ...elements]));
10441
10441
  };
10442
10442
  };
10443
- const Controls$2 = new Controls$1();
10443
+ const Controls$1 = new Controls$2();
10444
10444
  const index$7 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
10445
10445
  __proto__: null,
10446
- Controls: Controls$1,
10447
- default: Controls$2
10446
+ Controls: Controls$2,
10447
+ default: Controls$1
10448
10448
  }, Symbol.toStringTag, { value: "Module" }));
10449
10449
  const checkableTypes = /* @__PURE__ */ new Set(["checkbox", "radio"]);
10450
10450
  const isSelectableType = /* @__PURE__ */ new Set(["radio", "checkbox", "select-one", "select-multiple"]);
@@ -10672,7 +10672,7 @@ let Fields$1 = class Fields extends ComponentData {
10672
10672
  get = (path) => {
10673
10673
  let found = path && get(this.data, path);
10674
10674
  if (!found) {
10675
- const control = Controls$2.get(path);
10675
+ const control = Controls$1.get(path);
10676
10676
  if (control) {
10677
10677
  found = this.add(null, control.controlData);
10678
10678
  }
@@ -10714,13 +10714,27 @@ const Stages2 = stages;
10714
10714
  const Rows2 = rows;
10715
10715
  const Columns2 = columns;
10716
10716
  const Fields2 = fields;
10717
- const Controls2 = Controls$2;
10717
+ const Controls2 = Controls$1;
10718
10718
  const getFormData = (formData, useSessionStorage = false) => {
10719
- if (formData) {
10720
- return clone$1(parseData(formData));
10719
+ if (formData !== void 0 && formData !== null) {
10720
+ const parsed = parseData(formData);
10721
+ if (parsed && typeof parsed === "object") {
10722
+ const cloned = clone$1(parsed);
10723
+ return {
10724
+ id: cloned.id || DEFAULT_FORMDATA().id,
10725
+ stages: cloned.stages || DEFAULT_FORMDATA().stages,
10726
+ rows: cloned.rows || {},
10727
+ columns: cloned.columns || {},
10728
+ fields: cloned.fields || {}
10729
+ };
10730
+ }
10731
+ console.warn("Formeo: Invalid formData provided, using default");
10721
10732
  }
10722
10733
  if (useSessionStorage) {
10723
- return sessionStorage.get(SESSION_FORMDATA_KEY) || DEFAULT_FORMDATA();
10734
+ const sessionData = sessionStorage.get(SESSION_FORMDATA_KEY);
10735
+ if (sessionData) {
10736
+ return sessionData;
10737
+ }
10724
10738
  }
10725
10739
  return DEFAULT_FORMDATA();
10726
10740
  };
@@ -10841,6 +10855,8 @@ const defaults$1 = {
10841
10855
  },
10842
10856
  onAdd: () => {
10843
10857
  },
10858
+ onRemove: () => {
10859
+ },
10844
10860
  onChange: (evt) => events.opts?.debug && console.log(evt),
10845
10861
  onUpdate: (evt) => events.opts?.debug && console.log(evt),
10846
10862
  onUpdateStage: (evt) => events.opts?.debug && console.log(evt),
@@ -10933,31 +10949,37 @@ document.addEventListener(EVENT_FORMEO_UPDATED_FIELD, (evt) => {
10933
10949
  document.addEventListener(EVENT_FORMEO_ADDED_ROW, (evt) => {
10934
10950
  const { timeStamp, type, detail } = evt;
10935
10951
  const eventData = { timeStamp, type, detail };
10952
+ events.opts.onAdd(eventData);
10936
10953
  events.opts.onAddRow(eventData);
10937
10954
  });
10938
10955
  document.addEventListener(EVENT_FORMEO_ADDED_COLUMN, (evt) => {
10939
10956
  const { timeStamp, type, detail } = evt;
10940
10957
  const eventData = { timeStamp, type, detail };
10958
+ events.opts.onAdd(eventData);
10941
10959
  events.opts.onAddColumn(eventData);
10942
10960
  });
10943
10961
  document.addEventListener(EVENT_FORMEO_ADDED_FIELD, (evt) => {
10944
10962
  const { timeStamp, type, detail } = evt;
10945
10963
  const eventData = { timeStamp, type, detail };
10964
+ events.opts.onAdd(eventData);
10946
10965
  events.opts.onAddField(eventData);
10947
10966
  });
10948
10967
  document.addEventListener(EVENT_FORMEO_REMOVED_ROW, (evt) => {
10949
10968
  const { timeStamp, type, detail } = evt;
10950
10969
  const eventData = { timeStamp, type, detail };
10970
+ events.opts.onRemove(eventData);
10951
10971
  events.opts.onRemoveRow(eventData);
10952
10972
  });
10953
10973
  document.addEventListener(EVENT_FORMEO_REMOVED_COLUMN, (evt) => {
10954
10974
  const { timeStamp, type, detail } = evt;
10955
10975
  const eventData = { timeStamp, type, detail };
10976
+ events.opts.onRemove(eventData);
10956
10977
  events.opts.onRemoveColumn(eventData);
10957
10978
  });
10958
10979
  document.addEventListener(EVENT_FORMEO_REMOVED_FIELD, (evt) => {
10959
10980
  const { timeStamp, type, detail } = evt;
10960
10981
  const eventData = { timeStamp, type, detail };
10982
+ events.opts.onRemove(eventData);
10961
10983
  events.opts.onRemoveField(eventData);
10962
10984
  });
10963
10985
  document.addEventListener(EVENT_FORMEO_ON_RENDER, (evt) => {
@@ -11124,7 +11146,18 @@ const defaults = {
11124
11146
  };
11125
11147
  }
11126
11148
  };
11149
+ const INIT_STATES = {
11150
+ CREATED: "created",
11151
+ LOADING_RESOURCES: "loading",
11152
+ INITIALIZING: "initializing",
11153
+ READY: "ready",
11154
+ ERROR: "error"
11155
+ };
11127
11156
  let FormeoEditor$1 = class FormeoEditor {
11157
+ #initState = INIT_STATES.CREATED;
11158
+ #initPromise = null;
11159
+ #lockedFormData = null;
11160
+ #dataLoadedOnce = false;
11128
11161
  /**
11129
11162
  * @param {Object} options formeo options
11130
11163
  * @param {String|Object} userFormData loaded formData
@@ -11139,7 +11172,9 @@ let FormeoEditor$1 = class FormeoEditor {
11139
11172
  this.opts = opts;
11140
11173
  dom.setOptions = opts;
11141
11174
  components.config = config;
11142
- this.userFormData = userFormData || formData;
11175
+ const providedData = userFormData || formData;
11176
+ this.#lockedFormData = providedData ? cleanFormData(providedData) : null;
11177
+ this.userFormData = this.#lockedFormData;
11143
11178
  this.Components = components;
11144
11179
  this.dom = dom;
11145
11180
  events.init({ debug, ...events$1 });
@@ -11154,7 +11189,9 @@ let FormeoEditor$1 = class FormeoEditor {
11154
11189
  return this.Components.formData;
11155
11190
  }
11156
11191
  set formData(data = {}) {
11157
- this.userFormData = cleanFormData(data);
11192
+ const cleaned = cleanFormData(data);
11193
+ this.#lockedFormData = cleaned;
11194
+ this.userFormData = cleaned;
11158
11195
  this.load(this.userFormData, this.opts);
11159
11196
  }
11160
11197
  loadData(data = {}) {
@@ -11168,7 +11205,9 @@ let FormeoEditor$1 = class FormeoEditor {
11168
11205
  * @return {void}
11169
11206
  */
11170
11207
  clear() {
11171
- this.userFormData = DEFAULT_FORMDATA();
11208
+ const defaultData = DEFAULT_FORMDATA();
11209
+ this.#lockedFormData = defaultData;
11210
+ this.userFormData = defaultData;
11172
11211
  this.Components.load(this.userFormData, this.opts);
11173
11212
  this.render();
11174
11213
  }
@@ -11178,6 +11217,7 @@ let FormeoEditor$1 = class FormeoEditor {
11178
11217
  */
11179
11218
  async loadResources() {
11180
11219
  document.removeEventListener("DOMContentLoaded", this.loadResources);
11220
+ this.#initState = INIT_STATES.LOADING_RESOURCES;
11181
11221
  const promises = [
11182
11222
  fetchIcons(this.opts.svgSprite),
11183
11223
  fetchFormeoStyle(this.opts.style),
@@ -11187,38 +11227,142 @@ let FormeoEditor$1 = class FormeoEditor {
11187
11227
  locale: globalThis.sessionStorage?.getItem(SESSION_LOCALE_KEY)
11188
11228
  })
11189
11229
  ].filter(Boolean);
11190
- await Promise.all(promises);
11191
- if (this.opts.allowEdit) {
11192
- this.init();
11230
+ try {
11231
+ await Promise.all(promises);
11232
+ if (this.opts.allowEdit) {
11233
+ this.init();
11234
+ }
11235
+ } catch (error) {
11236
+ this.#initState = INIT_STATES.ERROR;
11237
+ console.error("Failed to load resources:", error);
11238
+ throw error;
11193
11239
  }
11194
11240
  }
11195
11241
  /**
11196
11242
  * Formeo initializer
11197
- * @return {Object} References to formeo instance,
11243
+ * @return {Promise} References to formeo instance,
11198
11244
  * dom elements, actions events and more.
11199
11245
  */
11200
11246
  init() {
11201
- return Controls$2.init(this.opts.controls, this.opts.stickyControls).then((controls) => {
11247
+ if (this.#initState === INIT_STATES.INITIALIZING) {
11248
+ return this.#initPromise;
11249
+ }
11250
+ if (this.#initState === INIT_STATES.READY) {
11251
+ return this.#refreshUI();
11252
+ }
11253
+ this.#initState = INIT_STATES.INITIALIZING;
11254
+ this.#initPromise = Controls$1.init(this.opts.controls, this.opts.stickyControls).then((controls) => {
11202
11255
  this.controls = controls;
11203
- this.load(this.userFormData, this.opts);
11256
+ if (!this.#dataLoadedOnce) {
11257
+ this.#loadInitialData();
11258
+ this.#dataLoadedOnce = true;
11259
+ }
11204
11260
  this.formId = components.get("id");
11205
11261
  this.i18n = {
11206
- setLang: (formeoLocale) => {
11207
- globalThis.sessionStorage?.setItem(SESSION_LOCALE_KEY, formeoLocale);
11208
- const loadLang = mi18n.setCurrent(formeoLocale);
11209
- loadLang.then(() => {
11210
- this.init();
11211
- }, console.error);
11212
- }
11262
+ setLang: this.#setLanguage.bind(this)
11213
11263
  };
11264
+ this.render();
11265
+ this.#initState = INIT_STATES.READY;
11214
11266
  this.opts.onLoad?.(this);
11215
11267
  this.tooltipInstance = new SmartTooltip();
11268
+ return this;
11269
+ }).catch((error) => {
11270
+ this.#initState = INIT_STATES.ERROR;
11271
+ console.error("Failed to initialize editor:", error);
11272
+ throw error;
11216
11273
  });
11274
+ return this.#initPromise;
11275
+ }
11276
+ /**
11277
+ * Set language without reloading form data (fixes race condition)
11278
+ * @param {string} formeoLocale - locale code
11279
+ * @return {Promise}
11280
+ */
11281
+ async #setLanguage(formeoLocale) {
11282
+ globalThis.sessionStorage?.setItem(SESSION_LOCALE_KEY, formeoLocale);
11283
+ await mi18n.setCurrent(formeoLocale);
11284
+ await this.#refreshUI();
11285
+ }
11286
+ /**
11287
+ * Refresh UI without reloading data (used for language changes)
11288
+ * @return {Promise}
11289
+ */
11290
+ async #refreshUI() {
11291
+ this.controls = await Controls$1.init(this.opts.controls, this.opts.stickyControls);
11292
+ this.render();
11293
+ return this;
11294
+ }
11295
+ /**
11296
+ * Load initial data with proper priority
11297
+ */
11298
+ #loadInitialData() {
11299
+ const dataToLoad = this.#getDataWithPriority();
11300
+ this.Components.load(dataToLoad, this.opts);
11301
+ }
11302
+ /**
11303
+ * Get form data with proper priority:
11304
+ * 1. User-provided data (locked at construction)
11305
+ * 2. SessionStorage (if enabled)
11306
+ * 3. Default empty form
11307
+ * @return {Object} form data to load
11308
+ */
11309
+ #getDataWithPriority() {
11310
+ if (this.#lockedFormData) {
11311
+ return clone$1(this.#lockedFormData);
11312
+ }
11313
+ if (this.opts.sessionStorage) {
11314
+ const sessionData = sessionStorage.get(SESSION_FORMDATA_KEY);
11315
+ if (sessionData) {
11316
+ return sessionData;
11317
+ }
11318
+ }
11319
+ return DEFAULT_FORMDATA();
11217
11320
  }
11218
11321
  load(formData = this.userFormData, opts = this.opts) {
11219
11322
  this.Components.load(formData, opts);
11220
11323
  this.render();
11221
11324
  }
11325
+ /**
11326
+ * Get current initialization state
11327
+ * @return {string} current state
11328
+ */
11329
+ get initState() {
11330
+ return this.#initState;
11331
+ }
11332
+ /**
11333
+ * Check if the editor is ready
11334
+ * @return {boolean}
11335
+ */
11336
+ get isReady() {
11337
+ return this.#initState === INIT_STATES.READY;
11338
+ }
11339
+ /**
11340
+ * Wait for the editor to be ready
11341
+ * @return {Promise} resolves when editor is ready
11342
+ */
11343
+ async whenReady() {
11344
+ if (this.#initState === INIT_STATES.READY) {
11345
+ return this;
11346
+ }
11347
+ if (this.#initState === INIT_STATES.ERROR) {
11348
+ return Promise.reject(new Error("Editor initialization failed"));
11349
+ }
11350
+ if (this.#initPromise) {
11351
+ return this.#initPromise;
11352
+ }
11353
+ return new Promise((resolve, reject) => {
11354
+ const checkReady = () => {
11355
+ if (this.#initState === INIT_STATES.READY) {
11356
+ resolve(this);
11357
+ } else if (this.#initState === INIT_STATES.ERROR) {
11358
+ reject(new Error("Editor initialization failed"));
11359
+ } else {
11360
+ globalThis.requestAnimationFrame(checkReady);
11361
+ }
11362
+ };
11363
+ checkReady();
11364
+ });
11365
+ }
11222
11366
  /**
11223
11367
  * Render the formeo sections
11224
11368
  * @return {void}
package/dist/formeo.css CHANGED
@@ -1,7 +1,7 @@
1
1
 
2
2
  /**
3
3
  formeo - https://formeo.io
4
- Version: 4.2.5
4
+ Version: 5.0.1
5
5
  Author: Draggable https://draggable.io
6
6
  */
7
7