bootstrap5-toggle 5.2.0-rc2 → 5.2.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,5 +1,5 @@
1
1
  /* Copyright Notice
2
- * bootstrap5-toggle v5.2.0-rc2
2
+ * bootstrap5-toggle v5.2.0
3
3
  * https://palcarazm.github.io/bootstrap5-toggle/
4
4
  * @author 2011-2014 Min Hur (https://github.com/minhur)
5
5
  * @author 2018-2019 Brent Ely (https://github.com/gitbrent)
@@ -135,7 +135,7 @@
135
135
  DOMBuilder.prototype.createInvCheckbox = function (offValue) {
136
136
  var invCheckbox = this.checkbox.cloneNode(true);
137
137
  invCheckbox.value = offValue;
138
- invCheckbox.setAttribute("data-toggle", "invert-toggle");
138
+ invCheckbox.dataset.toggle = "invert-toggle";
139
139
  invCheckbox.removeAttribute("id");
140
140
  return invCheckbox;
141
141
  };
@@ -151,8 +151,8 @@
151
151
  DOMBuilder.prototype.renderToggle = function (_a) {
152
152
  var _b;
153
153
  var style = _a.style, width = _a.width, height = _a.height, tabindex = _a.tabindex;
154
- this.toggle.setAttribute("class", "toggle btn ".concat(this.sizeClass, " ").concat(style));
155
- this.toggle.setAttribute("data-toggle", "toggle");
154
+ this.toggle.className = "toggle btn ".concat(this.sizeClass, " ").concat(style);
155
+ this.toggle.dataset.toggle = "toggle";
156
156
  this.toggle.tabIndex = tabindex;
157
157
  this.toggle.role = "button";
158
158
  (_b = this.checkbox.parentElement) === null || _b === void 0 ? void 0 : _b.insertBefore(this.toggle, this.checkbox);
@@ -170,7 +170,7 @@
170
170
  */
171
171
  DOMBuilder.prototype.createToggleGroup = function () {
172
172
  var toggleGroup = document.createElement("div");
173
- toggleGroup.setAttribute("class", "toggle-group");
173
+ toggleGroup.className = "toggle-group";
174
174
  toggleGroup.appendChild(this.toggleOn);
175
175
  toggleGroup.appendChild(this.toggleOff);
176
176
  toggleGroup.appendChild(this.toggleHandle);
@@ -188,10 +188,10 @@
188
188
  */
189
189
  DOMBuilder.prototype.createToggleSpan = function (label, style, title) {
190
190
  var toggleSpan = document.createElement("span");
191
- toggleSpan.setAttribute("class", "btn ".concat(this.sizeClass, " ").concat(style));
191
+ toggleSpan.className = "btn ".concat(this.sizeClass, " ").concat(style);
192
192
  toggleSpan.innerHTML = label;
193
193
  if (title)
194
- toggleSpan.setAttribute("title", title);
194
+ toggleSpan.title = title;
195
195
  return toggleSpan;
196
196
  };
197
197
  /**
@@ -201,7 +201,7 @@
201
201
  */
202
202
  DOMBuilder.prototype.createToggleHandle = function () {
203
203
  var toggleHandle = document.createElement("span");
204
- toggleHandle.setAttribute("class", "toggle-handle btn ".concat(this.sizeClass));
204
+ toggleHandle.className = "toggle-handle btn ".concat(this.sizeClass);
205
205
  return toggleHandle;
206
206
  };
207
207
  /**
@@ -212,15 +212,6 @@
212
212
  * @param height The height of the toggle element.
213
213
  */
214
214
  DOMBuilder.prototype.handleToggleSize = function (width, height) {
215
- function calcH(toggleSpan) {
216
- var styles = window.getComputedStyle(toggleSpan);
217
- var height = toggleSpan.offsetHeight;
218
- var borderTopWidth = parseFloat(styles.borderTopWidth);
219
- var borderBottomWidth = parseFloat(styles.borderBottomWidth);
220
- var paddingTop = parseFloat(styles.paddingTop);
221
- var paddingBottom = parseFloat(styles.paddingBottom);
222
- return (height - borderBottomWidth - borderTopWidth - paddingTop - paddingBottom);
223
- }
224
215
  if (width) {
225
216
  this.toggle.style.width = width;
226
217
  }
@@ -241,20 +232,50 @@
241
232
  this.toggleOff.classList.add("toggle-off");
242
233
  // C: Finally, set lineHeight if needed
243
234
  if (height) {
244
- this.toggleOn.style.lineHeight = calcH(this.toggleOn) + "px";
245
- this.toggleOff.style.lineHeight = calcH(this.toggleOff) + "px";
235
+ this.toggleOn.style.lineHeight = DOMBuilder.calcH(this.toggleOn) + "px";
236
+ this.toggleOff.style.lineHeight = DOMBuilder.calcH(this.toggleOff) + "px";
246
237
  }
247
238
  };
239
+ /**
240
+ * Calculates the height of the toggle element that should be used for the line-height property.
241
+ * This calculation is used when the toggle element is given a height that is not explicitly set.
242
+ * The calculation takes into account the height of the toggle element, the border-top and border-bottom widths,
243
+ * and the padding-top and padding-bottom of the toggle element.
244
+ * @param toggleSpan The HTMLElement that represents the toggle element.
245
+ * @returns The height of the toggle element that should be used for the line-height property.
246
+ */
247
+ DOMBuilder.calcH = function (toggleSpan) {
248
+ var styles = globalThis.window.getComputedStyle(toggleSpan);
249
+ var height = toggleSpan.offsetHeight;
250
+ var borderTopWidth = Number.parseFloat(styles.borderTopWidth);
251
+ var borderBottomWidth = Number.parseFloat(styles.borderBottomWidth);
252
+ var paddingTop = Number.parseFloat(styles.paddingTop);
253
+ var paddingBottom = Number.parseFloat(styles.paddingBottom);
254
+ return (height - borderBottomWidth - borderTopWidth - paddingTop - paddingBottom);
255
+ };
248
256
  /**
249
257
  * Renders the toggle element based on the provided state if the toggle is already built.
250
258
  * This method should be called whenever the state of the toggle changes.
251
259
  * @param {ToggleState} state The state of the toggle element.
252
260
  */
253
261
  DOMBuilder.prototype.render = function (state) {
254
- this.toggle.classList.remove(this.onStyle, this.offStyle, "off", "indeterminate");
255
262
  this.lastState = state;
256
263
  if (!this.isBuilt)
257
264
  return;
265
+ this.updateToggleByValue(state);
266
+ this.updateToggleByChecked(state);
267
+ this.updateToggleByState(state);
268
+ };
269
+ /************* ✨ Windsurf Command ⭐ *************/
270
+ /**
271
+ * Updates the class of the toggle element based on the provided state.
272
+ * Removes any existing on/off/indeterminate classes and adds the appropriate class based on the state.
273
+ * If the state is indeterminate, adds the 'indeterminate' class and either the on or off class based on the checked attribute.
274
+ * @param {ToggleState} state The state of the toggle element.
275
+ */
276
+ /******* 9e620de0-7e60-44a0-b26d-be36099794af *******/
277
+ DOMBuilder.prototype.updateToggleByValue = function (state) {
278
+ this.toggle.classList.remove(this.onStyle, this.offStyle, "off", "indeterminate");
258
279
  switch (state.value) {
259
280
  case ToggleStateValue.ON:
260
281
  this.toggle.classList.add(this.onStyle);
@@ -272,42 +293,78 @@
272
293
  }
273
294
  break;
274
295
  }
296
+ };
297
+ /**
298
+ * Updates the toggle element based on the provided state.
299
+ * Calls {@link DOMBuilder.updateCheckboxByChecked} and {@link DOMBuilder.updateInvCheckboxByChecked} to update the checkbox and inverted checkbox elements respectively.
300
+ * @param {ToggleState} state The state of the toggle element.
301
+ */
302
+ DOMBuilder.prototype.updateToggleByChecked = function (state) {
303
+ this.updateCheckboxByChecked(state);
304
+ this.updateInvCheckboxByChecked(state);
305
+ };
306
+ /**
307
+ * Updates the checkbox element based on the provided state.
308
+ * Sets the checked attribute of the checkbox based on the state's checked attribute.
309
+ * Sets the disabled and readonly attributes of the checkbox based on the state's status.
310
+ * Adds or removes the 'disabled' class from the toggle element based on the state's status.
311
+ * @param {ToggleState} state The state of the toggle element.
312
+ */
313
+ DOMBuilder.prototype.updateCheckboxByChecked = function (state) {
275
314
  this.checkbox.checked = state.checked;
276
- if (this.invCheckbox)
277
- this.invCheckbox.checked = !state.checked;
278
- this.toggle.classList.add(state.checked ? this.onStyle : this.offStyle);
279
315
  switch (state.status) {
280
316
  case ToggleStateStatus.ENABLED:
281
- this.toggle.classList.remove("disabled");
282
- this.toggle.removeAttribute("disabled");
283
317
  this.checkbox.disabled = false;
284
318
  this.checkbox.readOnly = false;
285
- if (this.invCheckbox) {
286
- this.invCheckbox.disabled = false;
287
- this.invCheckbox.readOnly = false;
288
- }
319
+ this.toggle.classList.remove("disabled");
320
+ this.toggle.removeAttribute("disabled");
289
321
  break;
290
322
  case ToggleStateStatus.DISABLED:
291
- this.toggle.classList.add("disabled");
292
- this.toggle.setAttribute("disabled", "");
293
323
  this.checkbox.disabled = true;
294
324
  this.checkbox.readOnly = false;
295
- if (this.invCheckbox) {
296
- this.invCheckbox.disabled = true;
297
- this.invCheckbox.readOnly = false;
298
- }
299
- break;
300
- case ToggleStateStatus.READONLY:
301
325
  this.toggle.classList.add("disabled");
302
326
  this.toggle.setAttribute("disabled", "");
327
+ break;
328
+ case ToggleStateStatus.READONLY:
303
329
  this.checkbox.disabled = false;
304
330
  this.checkbox.readOnly = true;
305
- if (this.invCheckbox) {
306
- this.invCheckbox.disabled = false;
307
- this.invCheckbox.readOnly = true;
308
- }
331
+ this.toggle.classList.add("disabled");
332
+ this.toggle.setAttribute("disabled", "");
309
333
  break;
310
334
  }
335
+ };
336
+ /**
337
+ * Updates the inverted checkbox element based on the provided state.
338
+ * Sets the checked attribute of the inverted checkbox to the opposite of the state's checked attribute.
339
+ * Sets the disabled and readonly attributes of the inverted checkbox based on the state's status.
340
+ * @param {ToggleState} state The state of the toggle element.
341
+ */
342
+ DOMBuilder.prototype.updateInvCheckboxByChecked = function (state) {
343
+ if (!this.invCheckbox)
344
+ return;
345
+ this.invCheckbox.checked = !state.checked;
346
+ switch (state.status) {
347
+ case ToggleStateStatus.ENABLED:
348
+ this.invCheckbox.disabled = false;
349
+ this.invCheckbox.readOnly = false;
350
+ break;
351
+ case ToggleStateStatus.DISABLED:
352
+ this.invCheckbox.disabled = true;
353
+ this.invCheckbox.readOnly = false;
354
+ break;
355
+ case ToggleStateStatus.READONLY:
356
+ this.invCheckbox.disabled = false;
357
+ this.invCheckbox.readOnly = true;
358
+ break;
359
+ }
360
+ };
361
+ /**
362
+ * Updates the indeterminate attribute of the checkbox and inverted checkbox elements based on the provided state.
363
+ * If the state is indeterminate, sets the indeterminate attribute of the checkbox and inverted checkbox to true and removes the name attribute.
364
+ * If the state is not indeterminate, sets the indeterminate attribute of the checkbox and inverted checkbox to false and sets the name attribute to the provided name.
365
+ * @param {ToggleState} state The state of the toggle element.
366
+ */
367
+ DOMBuilder.prototype.updateToggleByState = function (state) {
311
368
  if (state.indeterminate) {
312
369
  this.checkbox.indeterminate = true;
313
370
  this.checkbox.removeAttribute("name");
@@ -343,10 +400,10 @@
343
400
  * Also disconnects the ResizeObserver if it was used.
344
401
  */
345
402
  DOMBuilder.prototype.destroy = function () {
346
- var _a, _b, _c;
403
+ var _a, _b;
347
404
  (_a = this.toggle.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(this.checkbox, this.toggle);
348
- (_b = this.toggle.parentNode) === null || _b === void 0 ? void 0 : _b.removeChild(this.toggle);
349
- (_c = this.resizeObserver) === null || _c === void 0 ? void 0 : _c.disconnect();
405
+ this.toggle.remove();
406
+ (_b = this.resizeObserver) === null || _b === void 0 ? void 0 : _b.disconnect();
350
407
  this.resizeObserver = undefined;
351
408
  this.isBuilt = false;
352
409
  };
@@ -364,6 +421,7 @@
364
421
  "'": "'",
365
422
  "/": "/"
366
423
  };
424
+ // Using replace with regex for single-pass character mapping compatible with ES5
367
425
  return text.replace(/[&<>"'/]/g, function (m) { return map[m]; });
368
426
  }
369
427
  /**
@@ -391,6 +449,46 @@
391
449
  function OptionResolver() {
392
450
  }
393
451
  /**
452
+ * Gets a sanitized attribute value from an HTML element
453
+ * @param element HTMLInputElement to read
454
+ * @param attrName Attribute name
455
+ * @param options method options
456
+ * @param options.sanitized Flag to indicate if the attribute value needs to be sanitized (default: `true`)
457
+ * @returns Sanitized attribute value or null
458
+ */
459
+ OptionResolver.getAttr = function (element, attrName, opts) {
460
+ var _a = (opts !== null && opts !== void 0 ? opts : {}).sanitized, sanitized = _a === void 0 ? true : _a;
461
+ var value = element.getAttribute(attrName);
462
+ return sanitized ? sanitize(value) : value;
463
+ };
464
+ /**
465
+ * Returns the value of an attribute, user-provided value, or default value
466
+ * @param element HTMLInputElement to read
467
+ * @param attrName Attribute name
468
+ * @param userValue Value provided by the user
469
+ * @param defaultValue Default value if neither attribute nor user value exists
470
+ * @param sanitized Flag to indicate if the attribute value needs to be sanitized (default: {@code true})
471
+ * @returns Final attribute value
472
+ */
473
+ OptionResolver.getAttrOrDefault = function (element, attrName, userValue, defaultValue, sanitized) {
474
+ if (sanitized === void 0) { sanitized = true; }
475
+ return OptionResolver.getAttr(element, attrName, { sanitized: sanitized }) || userValue || defaultValue;
476
+ };
477
+ /**
478
+ * Returns the value of an attribute, user-provided value, or marks as deprecated
479
+ * @param element HTMLInputElement to read
480
+ * @param attrName Attribute name
481
+ * @param userValue Value provided by the user
482
+ * @param sanitized Flag to indicate if the attribute value needs to be sanitized (default: {@code true})
483
+ * @returns Final attribute value or DeprecationConfig.value if not found
484
+ */
485
+ OptionResolver.getAttrOrDeprecation = function (element, attrName, userValue, sanitized) {
486
+ if (sanitized === void 0) { sanitized = true; }
487
+ return OptionResolver.getAttr(element, attrName, { sanitized: sanitized }) ||
488
+ userValue ||
489
+ DeprecationConfig.value;
490
+ };
491
+ /**
394
492
  * Resolves all toggle options from the element and user options
395
493
  * @param element HTMLInputElement representing the toggle
396
494
  * @param userOptions Options provided by the user
@@ -444,44 +542,6 @@
444
542
  tristate: false,
445
543
  name: null,
446
544
  };
447
- /**
448
- * Gets a sanitized attribute value from an HTML element
449
- * @param element HTMLInputElement to read
450
- * @param attrName Attribute name
451
- * @param sanitized Flag to indicate if the attribute value needs to be sanitized (default: {@code true})
452
- * @returns Sanitized attribute value or null
453
- */
454
- OptionResolver.getAttr = function (element, attrName, sanitized) {
455
- if (sanitized === void 0) { sanitized = true; }
456
- return sanitized ? sanitize(element.getAttribute(attrName)) : element.getAttribute(attrName);
457
- };
458
- /**
459
- * Returns the value of an attribute, user-provided value, or default value
460
- * @param element HTMLInputElement to read
461
- * @param attrName Attribute name
462
- * @param userValue Value provided by the user
463
- * @param defaultValue Default value if neither attribute nor user value exists
464
- * @param sanitized Flag to indicate if the attribute value needs to be sanitized (default: {@code true})
465
- * @returns Final attribute value
466
- */
467
- OptionResolver.getAttrOrDefault = function (element, attrName, userValue, defaultValue, sanitized) {
468
- if (sanitized === void 0) { sanitized = true; }
469
- return OptionResolver.getAttr(element, attrName, sanitized) || userValue || defaultValue;
470
- };
471
- /**
472
- * Returns the value of an attribute, user-provided value, or marks as deprecated
473
- * @param element HTMLInputElement to read
474
- * @param attrName Attribute name
475
- * @param userValue Value provided by the user
476
- * @param sanitized Flag to indicate if the attribute value needs to be sanitized (default: {@code true})
477
- * @returns Final attribute value or DeprecationConfig.value if not found
478
- */
479
- OptionResolver.getAttrOrDeprecation = function (element, attrName, userValue, sanitized) {
480
- if (sanitized === void 0) { sanitized = true; }
481
- return OptionResolver.getAttr(element, attrName, sanitized) ||
482
- userValue ||
483
- DeprecationConfig.value;
484
- };
485
545
  return OptionResolver;
486
546
  }());
487
547
  /** Types of deprecation source */
@@ -582,14 +642,29 @@
582
642
  */
583
643
  StateReducer.prototype.getElementState = function (element) {
584
644
  var checked = element.checked;
585
- var status = element.disabled ? ToggleStateStatus.DISABLED : element.readOnly ? ToggleStateStatus.READONLY : ToggleStateStatus.ENABLED;
645
+ var status;
646
+ if (element.disabled) {
647
+ status = ToggleStateStatus.DISABLED;
648
+ }
649
+ else if (element.readOnly) {
650
+ status = ToggleStateStatus.READONLY;
651
+ }
652
+ else {
653
+ status = ToggleStateStatus.ENABLED;
654
+ }
586
655
  var indeterminate = this.isTristate && element.indeterminate;
656
+ var value;
657
+ if (indeterminate) {
658
+ value = ToggleStateValue.INDETERMINATE;
659
+ }
660
+ else if (checked) {
661
+ value = ToggleStateValue.ON;
662
+ }
663
+ else {
664
+ value = ToggleStateValue.OFF;
665
+ }
587
666
  return {
588
- value: indeterminate
589
- ? ToggleStateValue.INDETERMINATE
590
- : checked
591
- ? ToggleStateValue.ON
592
- : ToggleStateValue.OFF,
667
+ value: value,
593
668
  checked: checked,
594
669
  status: status,
595
670
  indeterminate: indeterminate,
@@ -626,87 +701,115 @@
626
701
  * If the toggle is currently in the target state of the action, the action will return {@code false}.
627
702
  * If the toggle is in the indeterminate state and the action is {@code ToggleActionType.DETERMINATE},
628
703
  * the toggle will be set to the checked state.
629
- * If the action is {@code ToggleActionType.TOGGLE} :
704
+ * If the action is {@code ToggleActionType.NEXT} :
630
705
  * - For a tristate toggle, the toggle will do ON -> INDETERMINATE -> OFF -> INDETERMINATE -> ON.
631
706
  * - For a non-tristate toggle, the toggle will do ON -> OFF -> ON.
632
707
  */
633
708
  StateReducer.prototype.do = function (action) {
709
+ var actionsRequiringInteract = [
710
+ ToggleActionType.ON,
711
+ ToggleActionType.OFF,
712
+ ToggleActionType.TOGGLE,
713
+ ToggleActionType.INDETERMINATE,
714
+ ToggleActionType.DETERMINATE,
715
+ ToggleActionType.NEXT,
716
+ ToggleActionType.READONLY,
717
+ ];
718
+ if (actionsRequiringInteract.includes(action) && !this.canInteract())
719
+ return false;
634
720
  switch (action) {
635
721
  case ToggleActionType.ON:
636
- if (!this.canInteract())
637
- return false;
638
- if (this.state.value === ToggleStateValue.ON)
639
- return false;
640
- this.state = __assign(__assign({}, this.state), { value: ToggleStateValue.ON, checked: true, indeterminate: false });
641
- return true;
722
+ return this.setValueIfChanged(ToggleStateValue.ON, true, false);
642
723
  case ToggleActionType.OFF:
643
- if (!this.canInteract())
644
- return false;
645
- if (this.state.value === ToggleStateValue.OFF)
646
- return false;
647
- this.state = __assign(__assign({}, this.state), { value: ToggleStateValue.OFF, checked: false, indeterminate: false });
648
- return true;
724
+ return this.setValueIfChanged(ToggleStateValue.OFF, false, false);
649
725
  case ToggleActionType.TOGGLE:
650
- if (!this.canInteract())
651
- return false;
652
726
  if (this.state.value === ToggleStateValue.ON)
653
727
  return this.do(ToggleActionType.OFF);
654
728
  if (this.state.value === ToggleStateValue.OFF)
655
729
  return this.do(ToggleActionType.ON);
656
730
  return false;
657
731
  case ToggleActionType.INDETERMINATE:
658
- if (!this.canInteract())
659
- return false;
660
- if (this.state.value === ToggleStateValue.INDETERMINATE)
661
- return false;
662
- this.state = __assign(__assign({}, this.state), { value: ToggleStateValue.INDETERMINATE, indeterminate: true });
663
- return true;
732
+ return this.setValueIfChanged(ToggleStateValue.INDETERMINATE, undefined, true);
664
733
  case ToggleActionType.DETERMINATE:
665
- if (!this.canInteract())
666
- return false;
667
734
  if (this.state.value != ToggleStateValue.INDETERMINATE)
668
735
  return false;
669
- this.state = __assign(__assign({}, this.state), { value: this.state.checked
670
- ? ToggleStateValue.ON
671
- : ToggleStateValue.OFF, indeterminate: false });
672
- return true;
736
+ return this.setValue(this.state.checked ? ToggleStateValue.ON : ToggleStateValue.OFF, this.state.checked, false);
673
737
  case ToggleActionType.NEXT:
674
- if (!this.canInteract())
675
- return false;
676
- if (this.isTristate) {
677
- if (this.state.value === ToggleStateValue.ON ||
678
- this.state.value === ToggleStateValue.OFF)
679
- return this.do(ToggleActionType.INDETERMINATE);
680
- if (this.state.value === ToggleStateValue.INDETERMINATE &&
681
- this.state.checked)
682
- return this.do(ToggleActionType.OFF);
683
- if (this.state.value === ToggleStateValue.INDETERMINATE &&
684
- !this.state.checked)
685
- return this.do(ToggleActionType.ON);
686
- }
687
- else {
688
- if (this.state.value === ToggleStateValue.ON)
689
- return this.do(ToggleActionType.OFF);
690
- if (this.state.value === ToggleStateValue.OFF)
691
- return this.do(ToggleActionType.ON);
692
- }
693
- return false;
738
+ return this.doNext();
694
739
  case ToggleActionType.DISABLE:
695
- if (this.state.status === ToggleStateStatus.DISABLED)
696
- return false;
697
- this.state = __assign(__assign({}, this.state), { status: ToggleStateStatus.DISABLED });
698
- return true;
740
+ return this.setStatusIfChanged(ToggleStateStatus.DISABLED);
699
741
  case ToggleActionType.ENABLE:
700
- if (this.state.status === ToggleStateStatus.ENABLED)
701
- return false;
702
- this.state = __assign(__assign({}, this.state), { status: ToggleStateStatus.ENABLED });
703
- return true;
742
+ return this.setStatusIfChanged(ToggleStateStatus.ENABLED);
704
743
  case ToggleActionType.READONLY:
705
- if (!this.canInteract())
706
- return false;
707
- this.state = __assign(__assign({}, this.state), { status: ToggleStateStatus.READONLY });
708
- return true;
744
+ return this.setStatus(ToggleStateStatus.READONLY);
745
+ }
746
+ };
747
+ /**
748
+ * Sets the state of the toggle to the provided value.
749
+ * If checked or indeterminate is provided, sets the corresponding property of the state to the provided value.
750
+ * Otherwise, leaves the property unchanged.
751
+ * @param value The value of the toggle to set.
752
+ * @param checked The checked state of the toggle to set. If not provided, the property is left unchanged.
753
+ * @param indeterminate The indeterminate state of the toggle to set. If not provided, the property is left unchanged.
754
+ * @returns A boolean indicating whether the state was updated.
755
+ */
756
+ StateReducer.prototype.setValue = function (value, checked, indeterminate) {
757
+ this.state = __assign(__assign({}, this.state), { value: value, checked: checked !== null && checked !== void 0 ? checked : this.state.checked, indeterminate: indeterminate !== null && indeterminate !== void 0 ? indeterminate : this.state.indeterminate });
758
+ return true;
759
+ };
760
+ /**
761
+ * Sets the state of the toggle to the provided value if the value is different from the current state.
762
+ * If checked or indeterminate is provided, sets the corresponding property of the state to the provided value.
763
+ * Otherwise, leaves the property unchanged.
764
+ * @returns A boolean indicating whether the state was updated.
765
+ */
766
+ StateReducer.prototype.setValueIfChanged = function (value, checked, indeterminate) {
767
+ if (this.state.value === value)
768
+ return false;
769
+ return this.setValue(value, checked, indeterminate);
770
+ };
771
+ /**
772
+ * Sets the status of the toggle to the provided value.
773
+ * @param status The new status of the toggle.
774
+ * @returns A boolean indicating whether the state was updated.
775
+ */
776
+ StateReducer.prototype.setStatus = function (status) {
777
+ this.state = __assign(__assign({}, this.state), { status: status });
778
+ return true;
779
+ };
780
+ /**
781
+ * Sets the status of the toggle to the provided value if the value is different from the current status.
782
+ * @param status The new status of the toggle.
783
+ * @returns A boolean indicating whether the state was updated.
784
+ */
785
+ StateReducer.prototype.setStatusIfChanged = function (status) {
786
+ if (this.state.status === status)
787
+ return false;
788
+ return this.setStatus(status);
789
+ };
790
+ /**
791
+ * Applies the next action based on the current state of the toggle.
792
+ * If the toggle is tristate, cycles through the on, off, and indeterminate states.
793
+ * If the toggle is not tristate, cycles through the on and off states.
794
+ * @returns A boolean indicating whether the state was updated.
795
+ */
796
+ StateReducer.prototype.doNext = function () {
797
+ if (this.isTristate) {
798
+ if (this.state.value === ToggleStateValue.ON || this.state.value === ToggleStateValue.OFF) {
799
+ return this.do(ToggleActionType.INDETERMINATE);
800
+ }
801
+ if (this.state.value === ToggleStateValue.INDETERMINATE) {
802
+ return this.state.checked
803
+ ? this.do(ToggleActionType.OFF)
804
+ : this.do(ToggleActionType.ON);
805
+ }
709
806
  }
807
+ else {
808
+ return this.state.value === ToggleStateValue.ON
809
+ ? this.do(ToggleActionType.OFF)
810
+ : this.do(ToggleActionType.ON);
811
+ }
812
+ return false;
710
813
  };
711
814
  return StateReducer;
712
815
  }());
@@ -723,6 +826,19 @@
723
826
  this.pointer = null;
724
827
  this.SCROLL_THRESHOLD = 10;
725
828
  this.eventsBound = false;
829
+ this.suppressExternalSync = false;
830
+ this.originalDescriptors = new Map();
831
+ /**
832
+ * Handles the change event of the input element of the toggle.
833
+ * This event listener is responsible for detecting when the input element
834
+ * of the toggle changes its state and triggering the update method to keep the toggle in sync.
835
+ */
836
+ this.onExternalChange = function () {
837
+ _this.update(true);
838
+ };
839
+ this.onFormReset = function () {
840
+ setTimeout(function () { return _this.onExternalChange(); }, 0);
841
+ };
726
842
  /**
727
843
  * Handles pointer down events by initiating the toggle action and setting up
728
844
  * listeners for pointer movement, release, and cancellation.
@@ -811,8 +927,54 @@
811
927
  this.stateReducer = new StateReducer(element, this.options.tristate);
812
928
  this.domBuilder = new DOMBuilder(element, this.options, this.stateReducer.get());
813
929
  this.bindEventListeners();
930
+ this.interceptInputProperties();
814
931
  this.element.bsToggle = this;
815
932
  }
933
+ /**
934
+ * Intercepts the following input properties to detect external changes:
935
+ * - checked
936
+ * - disabled
937
+ * - readonly
938
+ * - indeterminate
939
+ * This method is used to detect changes made to the input element directly,
940
+ * rather than through the BootstrapToggle API. It is used to maintain the
941
+ * state of the toggle in cases where the user changes the input element
942
+ * directly, rather than through the API.
943
+ * @returns void
944
+ */
945
+ Toggle.prototype.interceptInputProperties = function () {
946
+ var _this = this;
947
+ var props = ["checked", "disabled", "readOnly", "indeterminate"];
948
+ props.forEach(function (prop) {
949
+ var descriptor = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(_this.element), prop);
950
+ if (!(descriptor === null || descriptor === void 0 ? void 0 : descriptor.set))
951
+ return;
952
+ _this.originalDescriptors.set(prop, descriptor);
953
+ Object.defineProperty(_this.element, prop, {
954
+ configurable: true,
955
+ get: function () { return descriptor.get.call(_this.element); },
956
+ set: function (value) {
957
+ descriptor.set.call(_this.element, value);
958
+ if (_this.suppressExternalSync)
959
+ return;
960
+ _this.onExternalChange();
961
+ },
962
+ });
963
+ });
964
+ };
965
+ /**
966
+ * Restores the original input properties of the toggle element.
967
+ * This method is used to restore the original descriptors of the input properties
968
+ * which were intercepted by the BootstrapToggle to detect external changes.
969
+ * @returns void
970
+ */
971
+ Toggle.prototype.restoreInputProperties = function () {
972
+ var _this = this;
973
+ this.originalDescriptors.forEach(function (descriptor, prop) {
974
+ Object.defineProperty(_this.element, prop, descriptor);
975
+ });
976
+ this.originalDescriptors.clear();
977
+ };
816
978
  /**
817
979
  * Binds event listeners to the toggle element.
818
980
  * This method is called by the constructor and is responsible for
@@ -827,6 +989,7 @@
827
989
  Toggle.prototype.bindEventListeners = function () {
828
990
  if (this.eventsBound)
829
991
  return;
992
+ this.bindFormResetListener();
830
993
  this.bindPointerEventListener();
831
994
  this.bindKeyboardEventListener();
832
995
  this.bindLabelEventListener();
@@ -846,11 +1009,24 @@
846
1009
  Toggle.prototype.unbindEventListeners = function () {
847
1010
  if (!this.eventsBound)
848
1011
  return;
1012
+ this.unbindFormResetListener();
849
1013
  this.unbindPointerEventListener();
850
1014
  this.unbindKeyboardEventListener();
851
1015
  this.unbindLabelEventListener();
852
1016
  this.eventsBound = false;
853
1017
  };
1018
+ Toggle.prototype.bindFormResetListener = function () {
1019
+ var form = this.element.form;
1020
+ if (!form)
1021
+ return;
1022
+ form.addEventListener("reset", this.onFormReset);
1023
+ };
1024
+ Toggle.prototype.unbindFormResetListener = function () {
1025
+ var form = this.element.form;
1026
+ if (!form)
1027
+ return;
1028
+ form.removeEventListener("reset", this.onFormReset);
1029
+ };
854
1030
  /**
855
1031
  * Binds a pointerdown event listener to the root element of the toggle.
856
1032
  * The event listener is responsible for handling pointer events (e.g. mouse clicks, touch events)
@@ -938,11 +1114,17 @@
938
1114
  */
939
1115
  Toggle.prototype.apply = function (action, silent) {
940
1116
  if (silent === void 0) { silent = false; }
941
- if (this.stateReducer.do(action)) {
1117
+ if (!this.stateReducer.do(action))
1118
+ return;
1119
+ this.suppressExternalSync = true;
1120
+ try {
942
1121
  this.domBuilder.render(this.stateReducer.get());
943
1122
  if (!silent)
944
1123
  this.trigger();
945
1124
  }
1125
+ finally {
1126
+ this.suppressExternalSync = false;
1127
+ }
946
1128
  };
947
1129
  /**
948
1130
  * Toggles the state of the toggle.
@@ -1024,10 +1206,16 @@
1024
1206
  * @param {boolean} silent A boolean indicating whether to trigger the change event after synchronizing the toggle state.
1025
1207
  */
1026
1208
  Toggle.prototype.update = function (silent) {
1027
- this.stateReducer.sync(this.element);
1028
- this.domBuilder.render(this.stateReducer.get());
1029
- if (!silent)
1030
- this.trigger();
1209
+ this.suppressExternalSync = true;
1210
+ try {
1211
+ this.stateReducer.sync(this.element);
1212
+ this.domBuilder.render(this.stateReducer.get());
1213
+ if (!silent)
1214
+ this.trigger();
1215
+ }
1216
+ finally {
1217
+ this.suppressExternalSync = false;
1218
+ }
1031
1219
  };
1032
1220
  /**
1033
1221
  * Triggers the change event on the toggle's input element.
@@ -1045,6 +1233,7 @@
1045
1233
  *After calling this method, the toggle element will be removed from the DOM and all event listeners will be unbound.
1046
1234
  */
1047
1235
  Toggle.prototype.destroy = function () {
1236
+ this.restoreInputProperties();
1048
1237
  this.unbindEventListeners();
1049
1238
  this.domBuilder.destroy();
1050
1239
  delete this.element.bsToggle;