web-mojo 2.1.294 → 2.1.337

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.
Files changed (68) hide show
  1. package/dist/admin.cjs.js +1 -1
  2. package/dist/admin.cjs.js.map +1 -1
  3. package/dist/admin.es.js +20 -25
  4. package/dist/admin.es.js.map +1 -1
  5. package/dist/auth.cjs.js +1 -1
  6. package/dist/auth.cjs.js.map +1 -1
  7. package/dist/auth.es.js +3 -3
  8. package/dist/auth.es.js.map +1 -1
  9. package/dist/charts.cjs.js +1 -1
  10. package/dist/charts.es.js +2 -2
  11. package/dist/chunks/{ContextMenu-DR9qV_8Z.js → ContextMenu-98dg4R2t.js} +106 -29
  12. package/dist/chunks/ContextMenu-98dg4R2t.js.map +1 -0
  13. package/dist/chunks/ContextMenu-Dl5BF8QJ.js +3 -0
  14. package/dist/chunks/ContextMenu-Dl5BF8QJ.js.map +1 -0
  15. package/dist/chunks/{DataView-CB3fkiWE.js → DataView-CTF7BN4B.js} +2 -2
  16. package/dist/chunks/{DataView-CB3fkiWE.js.map → DataView-CTF7BN4B.js.map} +1 -1
  17. package/dist/chunks/{DataView-DX2XDuNt.js → DataView-DZ2kF47b.js} +2 -2
  18. package/dist/chunks/{DataView-DX2XDuNt.js.map → DataView-DZ2kF47b.js.map} +1 -1
  19. package/dist/chunks/{Dialog-BUZEYiTL.js → Dialog-1GfD6-3r.js} +5 -5
  20. package/dist/chunks/{Dialog-BUZEYiTL.js.map → Dialog-1GfD6-3r.js.map} +1 -1
  21. package/dist/chunks/{Dialog-DCpfJ63g.js → Dialog-BgaP4o1D.js} +2 -2
  22. package/dist/chunks/{Dialog-DCpfJ63g.js.map → Dialog-BgaP4o1D.js.map} +1 -1
  23. package/dist/chunks/{FilePreviewView-A32KUENg.js → FilePreviewView-CiAkm9fN.js} +6 -6
  24. package/dist/chunks/{FilePreviewView-A32KUENg.js.map → FilePreviewView-CiAkm9fN.js.map} +1 -1
  25. package/dist/chunks/{FilePreviewView-DWLPUdX6.js → FilePreviewView-QlITXzbc.js} +2 -2
  26. package/dist/chunks/{FilePreviewView-DWLPUdX6.js.map → FilePreviewView-QlITXzbc.js.map} +1 -1
  27. package/dist/chunks/{FormView-GJqUOJqR.js → FormView-CglUjQ3E.js} +316 -34
  28. package/dist/chunks/FormView-CglUjQ3E.js.map +1 -0
  29. package/dist/chunks/FormView-eLjHQ4Yy.js +2 -0
  30. package/dist/chunks/FormView-eLjHQ4Yy.js.map +1 -0
  31. package/dist/chunks/{MetricsChart-BMtSNVSC.js → MetricsChart-Dr4iyfAI.js} +3 -3
  32. package/dist/chunks/{MetricsChart-BMtSNVSC.js.map → MetricsChart-Dr4iyfAI.js.map} +1 -1
  33. package/dist/chunks/{MetricsChart-khF2NtDH.js → MetricsChart-tsjbYCBw.js} +2 -2
  34. package/dist/chunks/{MetricsChart-khF2NtDH.js.map → MetricsChart-tsjbYCBw.js.map} +1 -1
  35. package/dist/chunks/{PDFViewer-DG_JyAZU.js → PDFViewer-7CGUMEOl.js} +2 -2
  36. package/dist/chunks/{PDFViewer-DG_JyAZU.js.map → PDFViewer-7CGUMEOl.js.map} +1 -1
  37. package/dist/chunks/{PDFViewer-DoHxXjiP.js → PDFViewer-Cyn2wZdi.js} +3 -3
  38. package/dist/chunks/{PDFViewer-DoHxXjiP.js.map → PDFViewer-Cyn2wZdi.js.map} +1 -1
  39. package/dist/chunks/{Page-uLnlAlwn.js → Page-BQkfWPCI.js} +2 -2
  40. package/dist/chunks/{Page-uLnlAlwn.js.map → Page-BQkfWPCI.js.map} +1 -1
  41. package/dist/chunks/{Page-CkziZoUi.js → Page-BV2Ym7gu.js} +2 -2
  42. package/dist/chunks/{Page-CkziZoUi.js.map → Page-BV2Ym7gu.js.map} +1 -1
  43. package/dist/chunks/{TopNav-MEetwvBb.js → TopNav-BqAMFlyI.js} +2 -2
  44. package/dist/chunks/{TopNav-MEetwvBb.js.map → TopNav-BqAMFlyI.js.map} +1 -1
  45. package/dist/chunks/{TopNav-BuFxvfyc.js → TopNav-a99nWNlO.js} +2 -2
  46. package/dist/chunks/{TopNav-BuFxvfyc.js.map → TopNav-a99nWNlO.js.map} +1 -1
  47. package/dist/chunks/WebApp-BlE_bW7n.js +2 -0
  48. package/dist/chunks/WebApp-BlE_bW7n.js.map +1 -0
  49. package/dist/chunks/{WebApp-CKLwTH9q.js → WebApp-ekvGNIXB.js} +15 -12
  50. package/dist/chunks/WebApp-ekvGNIXB.js.map +1 -0
  51. package/dist/core.css +114 -0
  52. package/dist/css/web-mojo.css +1 -1
  53. package/dist/docit.cjs.js +1 -1
  54. package/dist/docit.es.js +5 -5
  55. package/dist/index.cjs.js +1 -1
  56. package/dist/index.es.js +11 -11
  57. package/dist/lightbox.cjs.js +1 -1
  58. package/dist/lightbox.es.js +4 -4
  59. package/package.json +1 -1
  60. package/dist/chunks/ContextMenu-DLDSJEIk.js +0 -3
  61. package/dist/chunks/ContextMenu-DLDSJEIk.js.map +0 -1
  62. package/dist/chunks/ContextMenu-DR9qV_8Z.js.map +0 -1
  63. package/dist/chunks/FormView-CYJpCFJ2.js +0 -2
  64. package/dist/chunks/FormView-CYJpCFJ2.js.map +0 -1
  65. package/dist/chunks/FormView-GJqUOJqR.js.map +0 -1
  66. package/dist/chunks/WebApp-CKLwTH9q.js.map +0 -1
  67. package/dist/chunks/WebApp-D0A6nJtm.js +0 -2
  68. package/dist/chunks/WebApp-D0A6nJtm.js.map +0 -1
@@ -1,7 +1,8 @@
1
- import { M as Mustache, h as MOJOUtils, V as View } from "./WebApp-CKLwTH9q.js";
1
+ import { M as Mustache, h as MOJOUtils, V as View } from "./WebApp-ekvGNIXB.js";
2
2
  class FormBuilder {
3
3
  constructor(config = {}) {
4
4
  this.fields = config.fields || [];
5
+ this.structureOnly = config.structureOnly || false;
5
6
  this.fields.forEach((field) => {
6
7
  if (field.cols && !field.columns) {
7
8
  field.columns = field.cols;
@@ -1473,6 +1474,9 @@ class FormBuilder {
1473
1474
  * @returns {*} Field value
1474
1475
  */
1475
1476
  getFieldValue(name) {
1477
+ if (this.structureOnly) {
1478
+ return "";
1479
+ }
1476
1480
  return MOJOUtils.getContextData(this.data, name);
1477
1481
  }
1478
1482
  /**
@@ -4108,6 +4112,8 @@ class FormView extends View {
4108
4112
  errors = {},
4109
4113
  fileHandling = "base64",
4110
4114
  // 'base64' | 'multipart'
4115
+ autosaveModelField = false,
4116
+ // Auto-save model on field changes
4111
4117
  ...viewOptions
4112
4118
  } = options;
4113
4119
  super({
@@ -4121,12 +4127,15 @@ class FormView extends View {
4121
4127
  this.errors = errors;
4122
4128
  this.loading = false;
4123
4129
  this.fileHandling = fileHandling;
4130
+ this.autosaveModelField = autosaveModelField;
4124
4131
  this.customComponents = /* @__PURE__ */ new Map();
4132
+ this.fieldStatusManagers = /* @__PURE__ */ new Map();
4125
4133
  this.data = this.prepareFormData();
4126
4134
  this.formConfig = formConfig || { fields: fields || [] };
4127
4135
  this.formBuilder = new FormBuilder({
4128
4136
  ...this.formConfig,
4129
- data: this.data,
4137
+ structureOnly: true,
4138
+ // Only generate structure, FormView will control values
4130
4139
  errors
4131
4140
  });
4132
4141
  }
@@ -4158,12 +4167,49 @@ class FormView extends View {
4158
4167
  return this.formBuilder.buildFormHTML();
4159
4168
  }
4160
4169
  /**
4161
- * Initialize form after rendering
4170
+ * Called after form is rendered to populate values and initialize
4162
4171
  */
4163
4172
  async onAfterRender() {
4164
4173
  await super.onAfterRender();
4174
+ this.data = this.prepareFormData();
4175
+ this.populateFormValues();
4176
+ this.initializeFormComponents();
4177
+ }
4178
+ /**
4179
+ * Populate all form fields with current data values
4180
+ */
4181
+ populateFormValues() {
4182
+ if (!this.element || !this.formConfig?.fields) return;
4183
+ this.formConfig.fields.forEach((field) => {
4184
+ if (field.type === "group" && field.fields) {
4185
+ field.fields.forEach((groupField) => {
4186
+ this.populateFieldValue(groupField);
4187
+ });
4188
+ } else {
4189
+ this.populateFieldValue(field);
4190
+ }
4191
+ });
4192
+ }
4193
+ /**
4194
+ * Populate a single field with its value from data
4195
+ */
4196
+ populateFieldValue(fieldConfig) {
4197
+ if (!fieldConfig.name || !this.element) return;
4198
+ const fieldElement = this.element.querySelector(`[name="${fieldConfig.name}"]`);
4199
+ if (!fieldElement) return;
4200
+ const value = MOJOUtils.getContextData(this.data, fieldConfig.name);
4201
+ this.setFieldValue(fieldElement, fieldConfig, value);
4202
+ }
4203
+ /**
4204
+ * Initialize form components after rendering
4205
+ */
4206
+ initializeFormComponents() {
4165
4207
  this.initializeImageFields();
4166
4208
  this.initializeCustomComponents();
4209
+ this.initializeTagInputs();
4210
+ this.initializeCollectionSelects();
4211
+ this.initializeDatePickers();
4212
+ this.initializeDateRangePickers();
4167
4213
  this.initializePasswordFields();
4168
4214
  }
4169
4215
  /**
@@ -4317,24 +4363,59 @@ class FormView extends View {
4317
4363
  */
4318
4364
  handleFieldChange(fieldName, value) {
4319
4365
  this.data[fieldName] = value;
4320
- if (this.model && this.options.allowModelChange) {
4366
+ if (this.autosaveModelField && this.model) {
4367
+ this.handleFieldSave(fieldName, value);
4368
+ } else if (this.model && this.options.allowModelChange) {
4369
+ this._isFormDrivenChange = true;
4321
4370
  this.model.set(fieldName, value);
4322
4371
  }
4323
4372
  this.emit("field:change", { field: fieldName, value });
4324
4373
  }
4325
4374
  /**
4326
- * Refresh form data and rebuild FormBuilder
4327
- * Call this when model or data changes
4375
+ * Handle saving individual field changes to the model
4376
+ * @param {string} fieldName - Name of the field being saved
4377
+ * @param {*} value - New value to save
4378
+ */
4379
+ async handleFieldSave(fieldName, value) {
4380
+ if (!this.model) return;
4381
+ const statusManager = this.getFieldStatusManager(fieldName);
4382
+ try {
4383
+ statusManager.showStatus("saving");
4384
+ this._isFormDrivenChange = true;
4385
+ if (typeof this.model.save === "function") {
4386
+ await this.model.save({ [fieldName]: value });
4387
+ } else {
4388
+ this.model.set(fieldName, value);
4389
+ }
4390
+ statusManager.showStatus("saved");
4391
+ } catch (error) {
4392
+ console.error("Field save error:", error);
4393
+ statusManager.showStatus("error", { message: error.message });
4394
+ }
4395
+ }
4396
+ /**
4397
+ * Get or create a field status manager for a specific field
4398
+ * @param {string} fieldName - Name of the field
4399
+ * @returns {FieldStatusManager} Status manager instance
4400
+ */
4401
+ getFieldStatusManager(fieldName) {
4402
+ if (!this.fieldStatusManagers.has(fieldName)) {
4403
+ const fieldElement = this.element.querySelector(`[name="${fieldName}"]`);
4404
+ if (fieldElement) {
4405
+ const statusManager = new FieldStatusManager(fieldElement);
4406
+ this.fieldStatusManagers.set(fieldName, statusManager);
4407
+ }
4408
+ }
4409
+ return this.fieldStatusManagers.get(fieldName);
4410
+ }
4411
+ /**
4412
+ * Refresh form data and repopulate values
4413
+ * Call this when model or data changes externally
4328
4414
  */
4329
4415
  refreshForm() {
4330
4416
  this.data = this.prepareFormData();
4331
- this.formBuilder = new FormBuilder({
4332
- ...this.formConfig,
4333
- data: this.data,
4334
- errors: this.errors
4335
- });
4336
4417
  if (this.element) {
4337
- this.render();
4418
+ this.populateFormValues();
4338
4419
  }
4339
4420
  }
4340
4421
  /**
@@ -4519,12 +4600,9 @@ class FormView extends View {
4519
4600
  async onChangeValidateField(event, element) {
4520
4601
  const fieldName = element.name;
4521
4602
  if (fieldName) {
4603
+ const value = element.value;
4604
+ this.handleFieldChange(fieldName, value);
4522
4605
  this.validateField(fieldName);
4523
- this.emit("change", {
4524
- field: fieldName,
4525
- value: element.value,
4526
- form: this
4527
- });
4528
4606
  }
4529
4607
  }
4530
4608
  /**
@@ -4533,15 +4611,11 @@ class FormView extends View {
4533
4611
  async onChangeToggleSwitch(event, element) {
4534
4612
  const fieldName = element.getAttribute("data-field");
4535
4613
  if (fieldName) {
4536
- this.data[fieldName] = element.checked;
4614
+ const value = element.checked;
4615
+ this.handleFieldChange(fieldName, value);
4537
4616
  this.emit("switch:toggle", {
4538
4617
  field: fieldName,
4539
- checked: element.checked,
4540
- form: this
4541
- });
4542
- this.emit("change", {
4543
- field: fieldName,
4544
- value: element.checked,
4618
+ checked: value,
4545
4619
  form: this
4546
4620
  });
4547
4621
  }
@@ -4637,21 +4711,21 @@ class FormView extends View {
4637
4711
  * Handle range value changes
4638
4712
  */
4639
4713
  async onChangeRangeChanged(event, element) {
4714
+ const fieldName = element.name;
4715
+ const value = element.value;
4640
4716
  const targetId = element.getAttribute("data-target");
4641
4717
  if (targetId) {
4642
4718
  const valueDisplay = this.element.querySelector(`#${targetId}`);
4643
4719
  if (valueDisplay) {
4644
- valueDisplay.textContent = element.value;
4720
+ valueDisplay.textContent = value;
4645
4721
  }
4646
4722
  }
4723
+ if (fieldName) {
4724
+ this.handleFieldChange(fieldName, value);
4725
+ }
4647
4726
  this.emit("range:changed", {
4648
- field: element.name,
4649
- value: element.value,
4650
- form: this
4651
- });
4652
- this.emit("change", {
4653
- field: element.name,
4654
- value: element.value,
4727
+ field: fieldName,
4728
+ value,
4655
4729
  form: this
4656
4730
  });
4657
4731
  }
@@ -4815,9 +4889,114 @@ class FormView extends View {
4815
4889
  }
4816
4890
  }
4817
4891
  _onModelChange() {
4892
+ this.data = this.prepareFormData();
4818
4893
  if (this.isMounted()) {
4819
- this.refreshForm();
4894
+ if (!this._isFormDrivenChange) {
4895
+ this.syncFormWithModel();
4896
+ }
4897
+ this._isFormDrivenChange = false;
4898
+ }
4899
+ }
4900
+ /**
4901
+ * Sync form field values with current model data without full rebuild
4902
+ */
4903
+ syncFormWithModel() {
4904
+ if (!this.model || !this.element) return;
4905
+ if (this.formDataMatchesModelData(this.data)) {
4906
+ return;
4907
+ }
4908
+ this.populateFormValues();
4909
+ }
4910
+ /**
4911
+ * Compare current form values with new model data
4912
+ * @param {Object} newModelData - New data from model
4913
+ * @returns {boolean} True if form and model data match
4914
+ */
4915
+ formDataMatchesModelData(newModelData) {
4916
+ if (!this.formConfig?.fields || !this.element) return true;
4917
+ for (const field of this.formConfig.fields) {
4918
+ if (field.type === "group" && field.fields) {
4919
+ for (const groupField of field.fields) {
4920
+ if (!this.fieldValueMatchesModel(groupField, newModelData)) {
4921
+ return false;
4922
+ }
4923
+ }
4924
+ } else {
4925
+ if (!this.fieldValueMatchesModel(field, newModelData)) {
4926
+ return false;
4927
+ }
4928
+ }
4929
+ }
4930
+ return true;
4931
+ }
4932
+ /**
4933
+ * Check if a single field's current value matches the model data
4934
+ * @param {Object} fieldConfig - Field configuration
4935
+ * @param {Object} modelData - Model data to compare against
4936
+ * @returns {boolean} True if field value matches model
4937
+ */
4938
+ fieldValueMatchesModel(fieldConfig, modelData) {
4939
+ if (!fieldConfig.name) return true;
4940
+ const fieldElement = this.element.querySelector(`[name="${fieldConfig.name}"]`);
4941
+ if (!fieldElement) return true;
4942
+ const currentValue = this.getFieldCurrentValue(fieldElement, fieldConfig);
4943
+ const modelValue = MOJOUtils.getContextData(modelData, fieldConfig.name);
4944
+ return this.valuesAreDifferent(currentValue, modelValue) === false;
4945
+ }
4946
+ /**
4947
+ * Get current value from a form field element
4948
+ */
4949
+ getFieldCurrentValue(fieldElement, fieldConfig) {
4950
+ switch (fieldConfig.type) {
4951
+ case "checkbox":
4952
+ return fieldElement.checked;
4953
+ case "switch":
4954
+ return fieldElement.checked;
4955
+ case "radio":
4956
+ const checkedRadio = this.element.querySelector(`[name="${fieldConfig.name}"]:checked`);
4957
+ return checkedRadio ? checkedRadio.value : "";
4958
+ case "select":
4959
+ return fieldElement.multiple ? Array.from(fieldElement.selectedOptions).map((opt) => opt.value) : fieldElement.value;
4960
+ case "file":
4961
+ case "image":
4962
+ return null;
4963
+ // Don't sync file fields
4964
+ default:
4965
+ return fieldElement.value;
4966
+ }
4967
+ }
4968
+ /**
4969
+ * Set value on a form field element
4970
+ */
4971
+ setFieldValue(fieldElement, fieldConfig, newValue) {
4972
+ switch (fieldConfig.type) {
4973
+ case "checkbox":
4974
+ case "switch":
4975
+ fieldElement.checked = Boolean(newValue);
4976
+ break;
4977
+ case "radio":
4978
+ const radioOption = this.element.querySelector(`[name="${fieldConfig.name}"][value="${newValue}"]`);
4979
+ if (radioOption) {
4980
+ radioOption.checked = true;
4981
+ }
4982
+ break;
4983
+ case "select":
4984
+ if (fieldElement.multiple && Array.isArray(newValue)) {
4985
+ Array.from(fieldElement.options).forEach((option) => {
4986
+ option.selected = newValue.includes(option.value);
4987
+ });
4988
+ } else {
4989
+ fieldElement.value = newValue || "";
4990
+ }
4991
+ break;
4992
+ case "file":
4993
+ case "image":
4994
+ break;
4995
+ default:
4996
+ fieldElement.value = newValue || "";
4997
+ break;
4820
4998
  }
4999
+ fieldElement.dispatchEvent(new Event("change", { bubbles: true }));
4821
5000
  }
4822
5001
  /**
4823
5002
  * Set defaults (updates defaults and rebuilds form)
@@ -4896,6 +5075,7 @@ class FormView extends View {
4896
5075
  console.log("Saving changed data via model:", changes);
4897
5076
  console.log("Data type:", changes instanceof FormData ? "FormData (multipart)" : "Object (JSON/base64)");
4898
5077
  try {
5078
+ this._isFormDrivenChange = true;
4899
5079
  const result = await this.model.save(changes);
4900
5080
  console.log("Model save result:", result);
4901
5081
  return result;
@@ -5400,6 +5580,108 @@ class FormView extends View {
5400
5580
  }
5401
5581
  }
5402
5582
  }
5583
+ class FieldStatusManager {
5584
+ constructor(fieldElement) {
5585
+ this.fieldElement = fieldElement;
5586
+ this.statusContainer = this.findOrCreateStatusContainer();
5587
+ this.timeouts = /* @__PURE__ */ new Map();
5588
+ }
5589
+ /**
5590
+ * Find existing status container or create one
5591
+ */
5592
+ findOrCreateStatusContainer() {
5593
+ let container = this.fieldElement.parentElement.querySelector(".field-status");
5594
+ if (!container) {
5595
+ container = document.createElement("div");
5596
+ container.className = "field-status";
5597
+ container.innerHTML = `
5598
+ <div class="spinner-border spinner-border-sm text-primary d-none" data-status="saving" role="status">
5599
+ <span class="visually-hidden">Saving...</span>
5600
+ </div>
5601
+ <i class="bi bi-check-circle text-success d-none" data-status="saved"></i>
5602
+ <i class="bi bi-exclamation-circle text-danger d-none" data-status="error"></i>
5603
+ `;
5604
+ this.fieldElement.parentElement.appendChild(container);
5605
+ }
5606
+ return container;
5607
+ }
5608
+ /**
5609
+ * Show a status indicator
5610
+ * @param {string} type - Status type: 'saving', 'saved', 'error'
5611
+ * @param {object} options - Additional options
5612
+ */
5613
+ showStatus(type, options = {}) {
5614
+ this.clearTimeout(type);
5615
+ this.hideAllStatuses();
5616
+ const indicator = this.statusContainer.querySelector(`[data-status="${type}"]`);
5617
+ if (indicator) {
5618
+ indicator.classList.remove("d-none");
5619
+ indicator.classList.add("d-inline-block", "show");
5620
+ if (type === "saved") {
5621
+ this.setTimeout(type, () => this.hideStatus(type), 2500);
5622
+ } else if (type === "error") {
5623
+ if (options.message) {
5624
+ indicator.title = options.message;
5625
+ }
5626
+ this.setTimeout(type, () => this.hideStatus(type), 6e3);
5627
+ }
5628
+ }
5629
+ }
5630
+ /**
5631
+ * Hide a specific status indicator
5632
+ * @param {string} type - Status type to hide
5633
+ */
5634
+ hideStatus(type) {
5635
+ const indicator = this.statusContainer.querySelector(`[data-status="${type}"]`);
5636
+ if (indicator) {
5637
+ indicator.classList.remove("show");
5638
+ indicator.classList.add("hide");
5639
+ setTimeout(() => {
5640
+ indicator.classList.add("d-none");
5641
+ indicator.classList.remove("d-inline-block", "hide");
5642
+ indicator.title = "";
5643
+ }, 300);
5644
+ }
5645
+ }
5646
+ /**
5647
+ * Hide all status indicators
5648
+ */
5649
+ hideAllStatuses() {
5650
+ const indicators = this.statusContainer.querySelectorAll("[data-status]");
5651
+ indicators.forEach((indicator) => {
5652
+ indicator.classList.add("d-none");
5653
+ indicator.classList.remove("d-inline-block", "show", "hide");
5654
+ indicator.title = "";
5655
+ });
5656
+ }
5657
+ /**
5658
+ * Set a timeout for auto-hiding status
5659
+ * @param {string} type - Status type
5660
+ * @param {function} callback - Callback to execute
5661
+ * @param {number} delay - Delay in milliseconds
5662
+ */
5663
+ setTimeout(type, callback, delay) {
5664
+ const timeoutId = setTimeout(callback, delay);
5665
+ this.timeouts.set(type, timeoutId);
5666
+ }
5667
+ /**
5668
+ * Clear a specific timeout
5669
+ * @param {string} type - Status type
5670
+ */
5671
+ clearTimeout(type) {
5672
+ if (this.timeouts.has(type)) {
5673
+ clearTimeout(this.timeouts.get(type));
5674
+ this.timeouts.delete(type);
5675
+ }
5676
+ }
5677
+ /**
5678
+ * Clean up all timeouts
5679
+ */
5680
+ destroy() {
5681
+ this.timeouts.forEach((timeoutId) => clearTimeout(timeoutId));
5682
+ this.timeouts.clear();
5683
+ }
5684
+ }
5403
5685
  const FormView$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
5404
5686
  __proto__: null,
5405
5687
  FormView,
@@ -5410,4 +5692,4 @@ export {
5410
5692
  applyFileDropMixin as a,
5411
5693
  FormView$1 as b
5412
5694
  };
5413
- //# sourceMappingURL=FormView-GJqUOJqR.js.map
5695
+ //# sourceMappingURL=FormView-CglUjQ3E.js.map