@optionfactory/fml 9.0.0-rc6 → 9.0.0-rc7

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/fml.iife.js CHANGED
@@ -9088,6 +9088,14 @@ var fml = (function (exports) {
9088
9088
  if (!this._interactive()) {
9089
9089
  return;
9090
9090
  }
9091
+ //a click on another control inside the select is that control's, not
9092
+ //the select's: a tooltip marker slotted into `info`, a button a page
9093
+ //put in an affix. Without this, reading the note beside a select
9094
+ //also stole the focus and dropped the dropdown over the note
9095
+ const elsewhere = e.target.closest('button, a[href], input, select, textarea');
9096
+ if (elsewhere && elsewhere !== this.#input) {
9097
+ return;
9098
+ }
9091
9099
  if (this.#ddmenu.shown) {
9092
9100
  this.#close();
9093
9101
  return;
@@ -10223,8 +10231,13 @@ var fml = (function (exports) {
10223
10231
  //started is stale, and neither renders nor updates the request a later
10224
10232
  //reload replays, whichever order the responses arrive in
10225
10233
  const claim = this.#loads.take();
10226
- this.#body.replaceChildren();
10227
- this.#loading.removeAttribute('hidden');
10234
+ //the rows stay while the table revalidates. Emptying the body and raising
10235
+ //the spinner row in its place collapsed the table to one tall row and
10236
+ //expanded it again on every sort, page and reload: two layout jumps for
10237
+ //what is the same table with newer rows in it. The spinner is for the load
10238
+ //with nothing to show yet, the first one and the one after a failure; the
10239
+ //rest announce themselves through aria-busy, which the stylesheet reads
10240
+ this.#loading.toggleAttribute('hidden', this.#body.childElementCount > 0);
10228
10241
  this.#feedback.setAttribute('hidden', '');
10229
10242
  this.#noAutoload.setAttribute('hidden', '');
10230
10243
  this.setAttribute('aria-busy', 'true');
@@ -10242,6 +10255,10 @@ var fml = (function (exports) {
10242
10255
  return;
10243
10256
  }
10244
10257
  this.#loading.setAttribute('hidden', '');
10258
+ //the rows the failed load was replacing go with it: what the table
10259
+ //holds is no longer what the request asked for, and leaving them
10260
+ //under the error would say the opposite
10261
+ this.#body.replaceChildren();
10245
10262
  this.#feedback.removeAttribute('hidden');
10246
10263
  this.#feedback.querySelector('[data-ref=feedback-error]').textContent = Failure.problemsText(
10247
10264
  error,
@@ -10388,6 +10405,20 @@ var fml = (function (exports) {
10388
10405
  //menu is where the localized words live
10389
10406
  this.#button.textContent = this.#display(choice);
10390
10407
  Attributes.set(this.#button, 'aria-label', this.#labelFor(choice));
10408
+ this.#mark();
10409
+ }
10410
+ /**
10411
+ * Marks the item the button currently holds, which is what a menu of one
10412
+ * choice among several owes the reader: the glyph on the button says which
10413
+ * one it is only to somebody who already knows the glyphs. The items are
10414
+ * `menuitemradio`, so the state is `aria-checked` rather than the
10415
+ * `aria-selected` a listbox would use, and the stylesheet draws it off that.
10416
+ */
10417
+ #mark() {
10418
+ const current = this.value;
10419
+ for (const item of this.#items()) {
10420
+ item.setAttribute('aria-checked', String(item.getAttribute('value') === current));
10421
+ }
10391
10422
  }
10392
10423
  /** The host's disabled claim, composed with the pin: lifting one cannot lift the other. */
10393
10424
  set claimed(claimed) {
@@ -10400,7 +10431,9 @@ var fml = (function (exports) {
10400
10431
  const li = document.createElement('li');
10401
10432
  li.setAttribute('role', 'none');
10402
10433
  const a = document.createElement('a');
10403
- a.setAttribute('role', 'menuitem');
10434
+ //one choice among several, which is what a radio item is: the
10435
+ //state belongs on the item, not on the button alone
10436
+ a.setAttribute('role', 'menuitemradio');
10404
10437
  a.setAttribute('tabindex', '-1');
10405
10438
  a.setAttribute('value', choice);
10406
10439
  const word = this.#labelFor(choice);
@@ -10418,6 +10451,7 @@ var fml = (function (exports) {
10418
10451
  return li;
10419
10452
  }),
10420
10453
  );
10454
+ this.#mark();
10421
10455
  }
10422
10456
  #sync() {
10423
10457
  const pinned = this.pinned;