@optionfactory/ful 1.0.13 → 1.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/ful.mjs CHANGED
@@ -1386,7 +1386,9 @@ class Form extends ParsedElement {
1386
1386
  this.spinner(false);
1387
1387
  }
1388
1388
  }
1389
-
1389
+ reset(){
1390
+ this.form.reset();
1391
+ }
1390
1392
  spinner(spin) {
1391
1393
  this.querySelectorAll('ful-spinner').forEach(el => {
1392
1394
  const hel = /** @type HTMLElement */ (el);
@@ -1431,11 +1433,16 @@ class Input extends ParsedElement {
1431
1433
  this.internals = this.attachInternals();
1432
1434
  this.internals.role = 'presentation';
1433
1435
  }
1434
- render({ slots }) {
1436
+ render({ slots, observed, disabled }) {
1435
1437
  const type = this.getAttribute("type") ?? 'text';
1436
1438
  const fragment = this.template().withOverlay({ type, slots }).render();
1437
1439
  this.#input = fragment.querySelector("input,textarea");
1440
+
1438
1441
  Attributes.forward('input-', this, this.#input);
1442
+ this.disabled = disabled;
1443
+ this.readonly = observed.readonly;
1444
+ this.value = observed.value;
1445
+
1439
1446
  this.#input.addEventListener('change', (evt) => {
1440
1447
  evt.stopPropagation();
1441
1448
  this.dispatchEvent(new CustomEvent('change', {
@@ -1465,6 +1472,12 @@ class Input extends ParsedElement {
1465
1472
  set readonly(v) {
1466
1473
  this.#input.readOnly = v;
1467
1474
  }
1475
+ get disabled(){
1476
+ return this.#input.hasAttribute('disabled');
1477
+ }
1478
+ set disabled(d){
1479
+ Attributes.toggle(this.#input, 'disabled', d);
1480
+ }
1468
1481
  focus(options) {
1469
1482
  this.#input.focus(options);
1470
1483
  }
@@ -1477,6 +1490,9 @@ class Input extends ParsedElement {
1477
1490
  this.internals.setValidity({ customError: true }, " ");
1478
1491
  this.#fieldError.innerText = error;
1479
1492
  }
1493
+ formResetCallback(){
1494
+ this.value = this.getAttribute("value");
1495
+ }
1480
1496
  }
1481
1497
 
1482
1498
  class CompleteSelectLoader {
@@ -1677,7 +1693,7 @@ class Dropdown extends ParsedElement {
1677
1693
  }
1678
1694
 
1679
1695
  class Select extends ParsedElement {
1680
- static observed = ['value:csvm']
1696
+ static observed = ['value:csvm', 'readonly:presence']
1681
1697
  static slots = true
1682
1698
  static template = `
1683
1699
  <label class="form-label">{{{{ slots.default }}}}</label>
@@ -1716,13 +1732,18 @@ class Select extends ParsedElement {
1716
1732
  this.internals = this.attachInternals();
1717
1733
  this.internals.role = 'presentation';
1718
1734
  }
1719
- async render({ slots, observed }) {
1735
+ async render({ slots, observed, disabled }) {
1720
1736
  const name = this.getAttribute("name");
1721
1737
  this.#loader = Loaders.fromAttributes(this, 'loaders:select', { options: slots.options });
1722
1738
  await this.#loader.prefetch?.();
1723
1739
  const fragment = this.template().withOverlay({ slots, name }).render();
1724
1740
  this.#input = fragment.querySelector('input');
1725
1741
  this.#badges = fragment.querySelector('badges');
1742
+
1743
+ this.value = observed.value;
1744
+ this.disabled = disabled;
1745
+ this.readonly = observed.readonly;
1746
+
1726
1747
  this.#ddmenu = fragment.querySelector('ful-dropdown');
1727
1748
  this.#multiple = this.hasAttribute("multiple");
1728
1749
  const label = fragment.querySelector('label');
@@ -1731,7 +1752,6 @@ class Select extends ParsedElement {
1731
1752
  this.#input.ariaDescribedByElements = [this.#fieldError];
1732
1753
  this.#input.ariaLabelledByElements = [label];
1733
1754
 
1734
-
1735
1755
  const self = this;
1736
1756
  const [dload, abortdload] = timing.debounce(400, () => self.#ddmenu.show(() => self.#loader.load(self.#input.value)));
1737
1757
  this.addEventListener('click', (/** @type any */e) => {
@@ -1824,6 +1844,11 @@ class Select extends ParsedElement {
1824
1844
  this.#badges.append(...badges);
1825
1845
  }
1826
1846
  set value(value) {
1847
+ if(value === null){
1848
+ this.#values = new Map();
1849
+ this.#syncBadges();
1850
+ return;
1851
+ }
1827
1852
  (async () => {
1828
1853
  const entries = await (this.#multiple ? this.#loader.exact(...value) : this.#loader.exact(value));
1829
1854
  this.#values = new Map(entries);
@@ -1851,7 +1876,7 @@ class Select extends ParsedElement {
1851
1876
  }
1852
1877
 
1853
1878
  class RadioGroup extends ParsedElement {
1854
- static observed = ['value'];
1879
+ static observed = ['value', 'readonly:presence'];
1855
1880
  static slots = true;
1856
1881
  static template = `
1857
1882
  <fieldset>
@@ -1876,6 +1901,7 @@ class RadioGroup extends ParsedElement {
1876
1901
  </fieldset>
1877
1902
  `;
1878
1903
  static formAssociated = true;
1904
+ #fieldset;
1879
1905
  #fieldError;
1880
1906
  #firstRadio;
1881
1907
  #booleanType;
@@ -1884,7 +1910,7 @@ class RadioGroup extends ParsedElement {
1884
1910
  this.internals = this.attachInternals();
1885
1911
  this.internals.role = 'radiogroup';
1886
1912
  }
1887
- render({ slots }) {
1913
+ render({ slots, observed, disabled }) {
1888
1914
  const name = this.getAttribute('name') ?? Attributes.uid('ful-radiogroup');
1889
1915
  const radioEls = Array.from(slots.default.querySelectorAll('ful-radio'));
1890
1916
  const inputsAndLabels = radioEls.map(el => {
@@ -1911,6 +1937,10 @@ class RadioGroup extends ParsedElement {
1911
1937
 
1912
1938
  radioEls.forEach(el => el.remove());
1913
1939
  this.template().withOverlay({ name, slots, inputsAndLabels }).renderTo(this);
1940
+ this.#fieldset = this.firstElementChild;
1941
+ this.disabled = disabled;
1942
+ this.readonly = observed.readonly;
1943
+ this.value = observed.value;
1914
1944
  this.#fieldError = this.querySelector('ful-field-error');
1915
1945
  this.ariaDescribedByElements = [this.#fieldError];
1916
1946
  this.#firstRadio = this.querySelector('input[type=radio]');
@@ -1933,7 +1963,19 @@ class RadioGroup extends ParsedElement {
1933
1963
  if (el) {
1934
1964
  el.checked = true;
1935
1965
  }
1966
+ }
1967
+ get readonly(){
1968
+ return this.#fieldset.inert;
1969
+ }
1970
+ set readonly(v) {
1971
+ this.#fieldset.inert = v;
1972
+ }
1973
+ get disabled(){
1974
+ return this.#fieldset.hasAttribute('disabled');
1936
1975
  }
1976
+ set disabled(d){
1977
+ Attributes.toggle(this.#fieldset, 'disabled', d);
1978
+ }
1937
1979
  focus(options) {
1938
1980
  this.#firstRadio.focus(options);
1939
1981
  }
@@ -1949,7 +1991,7 @@ class RadioGroup extends ParsedElement {
1949
1991
  }
1950
1992
 
1951
1993
  class Checkbox extends ParsedElement {
1952
- static observed = ['value:bool'];
1994
+ static observed = ['value:bool', 'readonly:presence'];
1953
1995
  static slots = true;
1954
1996
  static template = `
1955
1997
  <div data-tpl-class="klass">
@@ -1960,6 +2002,7 @@ class Checkbox extends ParsedElement {
1960
2002
  </div>
1961
2003
  <ful-field-error></ful-field-error>
1962
2004
  `;
2005
+ #container;
1963
2006
  #input;
1964
2007
  #fieldError;
1965
2008
  static formAssociated = true;
@@ -1968,11 +2011,15 @@ class Checkbox extends ParsedElement {
1968
2011
  this.internals = this.attachInternals();
1969
2012
  this.internals.role = 'presentation';
1970
2013
  }
1971
- render({ slots }) {
2014
+ render({ slots, observed, disabled }) {
1972
2015
  const klass = this.getAttribute('type') == 'switch' ? "form-check form-switch" : "form-check";
1973
2016
  const fragment = this.template().withOverlay({ slots, klass }).render();
2017
+ this.#container = fragment.firstElementChild;
1974
2018
  this.#input = fragment.querySelector("input");
1975
2019
  Attributes.forward('input-', this, this.#input);
2020
+ this.disabled = disabled;
2021
+ this.readonly = observed.readonly;
2022
+ this.value = observed.value;
1976
2023
  this.#input.addEventListener('change', (evt) => {
1977
2024
  evt.stopPropagation();
1978
2025
  this.dispatchEvent(new CustomEvent('change', {
@@ -1984,7 +2031,13 @@ class Checkbox extends ParsedElement {
1984
2031
  }));
1985
2032
  });
1986
2033
  const label = fragment.querySelector('label');
1987
- label.addEventListener('click', () => { this.focus(); this.value = !this.value; });
2034
+ label.addEventListener('click', () => {
2035
+ this.focus();
2036
+ if (this.disabled || this.readonly) {
2037
+ return;
2038
+ }
2039
+ this.value = !this.value;
2040
+ });
1988
2041
  this.#fieldError = fragment.querySelector('ful-field-error');
1989
2042
  this.#input.ariaDescribedByElements = [this.#fieldError];
1990
2043
  this.#input.ariaLabelledByElements = [label];
@@ -1996,6 +2049,18 @@ class Checkbox extends ParsedElement {
1996
2049
  set value(value) {
1997
2050
  this.#input.checked = value;
1998
2051
  }
2052
+ get readonly(){
2053
+ return this.#container.inert;
2054
+ }
2055
+ set readonly(v) {
2056
+ this.#container.inert = v;
2057
+ }
2058
+ get disabled() {
2059
+ return this.#input.hasAttribute('disabled');
2060
+ }
2061
+ set disabled(d) {
2062
+ Attributes.toggle(this.#input, 'disabled', d);
2063
+ }
1999
2064
  focus(options) {
2000
2065
  this.#input.focus(options);
2001
2066
  }