@optionfactory/ful 4.0.12 → 4.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
@@ -1724,24 +1724,24 @@ class InputFile extends Input {
1724
1724
  <div data-ref="dropzone" class="dropzone" data-tpl-if="!slots.dropzone">
1725
1725
  {{ #l10n:t('dropzonelabel') }}
1726
1726
  </div>
1727
- <div data-ref="items" class="items"></div>
1727
+ <ful-item-list></ful-item-list>
1728
1728
  <ful-field-warnings></ful-field-warnings>
1729
1729
  <ful-field-error></ful-field-error>
1730
1730
  `;
1731
1731
  static templates = {
1732
1732
  items: `
1733
- <div class="item" data-tpl-each="files" data-tpl-var="file" data-tpl-data-name="file.name">
1734
- <div class="filename"><span>{{ file.name }}</span></div>
1735
- <div class="size">{{ #bytes:format(file.size) }}</div>
1736
- <button class="btn btn-sm btn-outline-danger"><i class="bi bi-x-lg"></i></button>
1737
- </div>
1733
+ <ful-item data-tpl-each="files" data-tpl-var="file" data-tpl-data-name="file.name">
1734
+ <div>{{ file.name }}</div>
1735
+ <div>{{ #bytes:format(file.size) }}</div>
1736
+ <button type="button" class="btn btn-sm btn-outline-danger bi bi-x-lg"></button>
1737
+ </ful-item>
1738
1738
  `,
1739
1739
  warning: `<ful-field-warning>{{ #l10n:t(key, args) }}</ful-field-warning>`
1740
1740
  }
1741
1741
  render(conf) {
1742
1742
  const { observed } = conf;
1743
1743
  super.render(conf);
1744
- this.#items = this.querySelector("[data-ref=items]");
1744
+ this.#items = this.querySelector("ful-item-list");
1745
1745
  this.#dropzone = this.querySelector("[data-ref=dropzone]");
1746
1746
  this.#warnings = this.querySelector("ful-field-warnings");
1747
1747
  this.accept = observed.accept;
@@ -1757,7 +1757,7 @@ class InputFile extends Input {
1757
1757
  if (!e.target.closest("button")) {
1758
1758
  return;
1759
1759
  }
1760
- const fileName = e.target.closest(".item").dataset.name;
1760
+ const fileName = e.target.closest("ful-item").dataset.name;
1761
1761
  const dt = new DataTransfer();
1762
1762
  [...this.files].filter(f => f.name !== fileName).forEach(f => dt.items.add(f));
1763
1763
  this.files = dt.files;
@@ -1789,11 +1789,7 @@ class InputFile extends Input {
1789
1789
  this.#ensureAcceptable();
1790
1790
  this.#ensureFileSizes();
1791
1791
  this.#ensureTotalSize();
1792
- if(this.#useItemlist){
1793
- this.template('items').withOverlay({ files: this.files }).withModule('bytes', { format: this.#formatByteSize }).renderTo(this.#items);
1794
- }else {
1795
- this.#items.replaceChildren();
1796
- }
1792
+ this.template('items').withOverlay({ files: this.files }).withModule('bytes', { format: this.#formatByteSize }).renderTo(this.#items);
1797
1793
  }
1798
1794
  warning(key, args) {
1799
1795
  this.template('warning').withOverlay({ key, args }).renderTo(this.#warnings);
@@ -1854,7 +1850,7 @@ class InputFile extends Input {
1854
1850
  set multiple(v) {
1855
1851
  this._input.multiple = v;
1856
1852
  this.reflect(() => {
1857
- this.setAttribute('multiple', this._input.multiple);
1853
+ Attributes.toggle(this, "multiple", v);
1858
1854
  });
1859
1855
  }
1860
1856
  get files() {
@@ -1887,7 +1883,6 @@ class InputFile extends Input {
1887
1883
  this.reflect(() => {
1888
1884
  this.setAttribute('maxfilesize', v);
1889
1885
  });
1890
-
1891
1886
  }
1892
1887
  #maxtotalsize;
1893
1888
  get maxtotalsize() {
@@ -1905,7 +1900,6 @@ class InputFile extends Input {
1905
1900
  }
1906
1901
  set itemlist(v) {
1907
1902
  this.#useItemlist = v;
1908
- Attributes.toggle(this.#items, "hidden", !v);
1909
1903
  this.reflect(() => {
1910
1904
  Attributes.toggle(this, "itemlist", v);
1911
1905
  });
@@ -1916,7 +1910,6 @@ class InputFile extends Input {
1916
1910
  }
1917
1911
  set dropzone(v) {
1918
1912
  this.#useDropzone = v;
1919
- Attributes.toggle(this.#dropzone, "hidden", !v);
1920
1913
  this.reflect(() => {
1921
1914
  Attributes.toggle(this, "dropzone", v);
1922
1915
  });
@@ -1964,6 +1957,10 @@ class RemoteLoader {
1964
1957
  await this.#ensureFetched();
1965
1958
  return this.#data.filter(([k, v]) => (v ?? '').toLowerCase().includes(needle?.toLowerCase()));
1966
1959
  }
1960
+ async reconfigureUrl(url){
1961
+ this.#data = null;
1962
+ this.#url = url;
1963
+ }
1967
1964
  async #ensureFetched() {
1968
1965
  if (this.#data !== null) {
1969
1966
  return
@@ -2141,7 +2138,7 @@ class Dropdown extends ParsedElement {
2141
2138
  }
2142
2139
 
2143
2140
  class Select extends ParsedElement {
2144
- static observed = ['value:csvm', 'readonly:presence']
2141
+ static observed = ['value:csvm', 'readonly:presence', 'itemlist:presence']
2145
2142
  static slots = true
2146
2143
  static template = `
2147
2144
  <div class="form-label">
@@ -2161,8 +2158,17 @@ class Select extends ParsedElement {
2161
2158
  {{{{ slots.after }}}}
2162
2159
  <span data-tpl-if="slots.iafter" class="input-group-text">{{{{ slots.iafter }}}}</span>
2163
2160
  </div>
2161
+ <ful-item-list></ful-item-list>
2164
2162
  <ful-field-error></ful-field-error>
2165
2163
  `;
2164
+ static templates = {
2165
+ items: `
2166
+ <ful-item data-tpl-each="entries" data-tpl-var="entry" data-tpl-data-key="entry[0]">
2167
+ <div>{{ entry[1] }}</div>
2168
+ <button type="button" class="btn btn-sm btn-outline-danger bi bi-x-lg"></button>
2169
+ </ful-item>
2170
+ `
2171
+ }
2166
2172
  static mappers = {
2167
2173
  "csvm": (v, name, el) => {
2168
2174
  if (el.hasAttribute("multiple")) {
@@ -2177,6 +2183,7 @@ class Select extends ParsedElement {
2177
2183
  #badges
2178
2184
  #ddmenu
2179
2185
  #input
2186
+ #items;
2180
2187
  #multiple
2181
2188
  #fieldError
2182
2189
  #values = new Map()
@@ -2192,12 +2199,14 @@ class Select extends ParsedElement {
2192
2199
  await this.#loader.prefetch?.();
2193
2200
  const fragment = this.template().withOverlay({ slots, name }).render();
2194
2201
  this.#input = fragment.querySelector('input');
2202
+ this.#items = fragment.querySelector("ful-item-list");
2195
2203
  Attributes.forward('input-', this, this.#input);
2196
2204
  this.#badges = fragment.querySelector('badges');
2197
2205
 
2198
2206
  this.value = observed.value;
2199
2207
  this.disabled = disabled;
2200
2208
  this.readonly = observed.readonly;
2209
+ this.itemlist = observed.itemlist;
2201
2210
 
2202
2211
  this.#ddmenu = fragment.querySelector('ful-dropdown');
2203
2212
  const label = fragment.querySelector('label');
@@ -2222,6 +2231,22 @@ class Select extends ParsedElement {
2222
2231
  this.#input.focus();
2223
2232
  dload();
2224
2233
  });
2234
+ this.#items.addEventListener('click', (e) => {
2235
+ e.stopPropagation();
2236
+ if (!e.target.closest("button")) {
2237
+ return;
2238
+ }
2239
+ if(this.disabled || this.readonly){
2240
+ return;
2241
+ }
2242
+ const idx = [...this.#items.children].indexOf(e.target.closest('ful-item'));
2243
+ if (idx === -1) {
2244
+ return;
2245
+ }
2246
+ this.#values.delete(Array.from(this.#values.keys()).pop());
2247
+ this.#changed();
2248
+ this.#syncBadges();
2249
+ });
2225
2250
  this.#badges.addEventListener('click', (e) => {
2226
2251
  e.stopPropagation();
2227
2252
  if(this.disabled || this.readonly){
@@ -2307,8 +2332,8 @@ class Select extends ParsedElement {
2307
2332
  });
2308
2333
  this.replaceChildren(fragment);
2309
2334
  }
2310
- withLoader(fn) {
2311
- fn(this.#loader);
2335
+ async withLoader(fn) {
2336
+ await fn(this.#loader);
2312
2337
  }
2313
2338
  #changed() {
2314
2339
  const selection = [...this.#values.entries()].map(e => ({key: e[0], label: e[1][0], metadata: e[1].slice(1)}));
@@ -2329,6 +2354,8 @@ class Select extends ParsedElement {
2329
2354
  });
2330
2355
  this.#badges.replaceChildren();
2331
2356
  this.#badges.append(...badges);
2357
+ this.#items.replaceChildren();
2358
+ this.template('items').withOverlay({ entries: this.#values.entries() }).renderTo(this.#items);
2332
2359
  }
2333
2360
  set value(vs) {
2334
2361
  if(vs === null){
@@ -2369,7 +2396,17 @@ class Select extends ParsedElement {
2369
2396
  this.reflect(() => {
2370
2397
  Attributes.toggle(this, 'readonly', v);
2371
2398
  });
2372
- }
2399
+ }
2400
+ #useItemlist;
2401
+ get itemlist() {
2402
+ return this.#useItemlist;
2403
+ }
2404
+ set itemlist(v) {
2405
+ this.#useItemlist = v;
2406
+ this.reflect(() => {
2407
+ Attributes.toggle(this, "itemlist", v);
2408
+ });
2409
+ }
2373
2410
  focus(options) {
2374
2411
  this.#input.focus(options);
2375
2412
  }