@threadlabs/looma 0.23.10 → 0.23.11

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.
@@ -54,6 +54,12 @@
54
54
  >How the list narrows as the user types. label lists the options whose label contains the typed text, ignoring case. none lists every authored option, for
55
55
  options already narrowed elsewhere, such as a server search, so a result that matched on data other than its label still shows. Leaving the field still
56
56
  commits an option whose label matches the text, or the only one listed.</prop>
57
+ <prop name="autoHighlight" type="keyword" values="none, single" default="none"
58
+ >single highlights the only enabled authored suggestion while typing. Ambiguous results and an empty query stay unhighlighted. none preserves manual
59
+ highlighting with the arrow keys.</prop>
60
+ <prop name="selectOnTab" type="boolean" default="false"
61
+ >Commits a highlighted authored suggestion on forward Tab, then lets focus advance normally. In multiple mode a selected suggestion is retained without
62
+ duplication or removal. Shift+Tab does not commit, and Tab never chooses the create offer.</prop>
57
63
  <prop name="allowFreeText" type="boolean" default="false">Allows values that do not match an authored option.</prop>
58
64
  <prop name="allowCreate" type="boolean" default="false"
59
65
  >Offers the current query as a new option, reported as create-item. When nothing else matches, the offer is highlighted, so Enter creates it; with nothing
@@ -174,6 +174,10 @@ export default function controller(host) {
174
174
  // When nothing matches what was typed, the offer to create it is the only choice, so it is
175
175
  // the one Enter makes, and it is highlighted as such.
176
176
  if (query && !host.state.rows.some((row) => !row.disabled) && canCreate()) host.state.active = host.state.rows.length;
177
+ if (query && host.props.autoHighlight.value === "single") {
178
+ const enabled = host.state.rows.flatMap((row, index) => row.disabled ? [] : [index]);
179
+ if (enabled.length === 1) host.state.active = enabled[0];
180
+ }
177
181
  // Options in their declared shape: a row's `selected` flag is the list's own view state.
178
182
  host.dispatch("options-change", host.state.rows.map(asItem));
179
183
  };
@@ -441,7 +445,19 @@ export default function controller(host) {
441
445
  if (!host.state.raw && (input.selectionStart ?? 0) === 0 && event.key === "Backspace" && items().length) { event.preventDefault(); removeItemAt(items().length - 1, "keyboard"); return; }
442
446
  }
443
447
  if (event.key === "Escape" && host.state.expanded) { event.preventDefault(); event.stopPropagation(); close(); }
444
- else if (event.key === "Tab") { resolveTyped("keyboard"); close(); }
448
+ else if (event.key === "Tab") {
449
+ const highlighted = host.state.expanded ? (host.state.rows ?? [])[host.state.active] : undefined;
450
+ if (host.props.selectOnTab.value && !event.shiftKey && !event.altKey && !event.ctrlKey && !event.metaKey && highlighted && !highlighted.disabled) {
451
+ if (host.props.multiple.value) {
452
+ setMultiQuery("", "keyboard");
453
+ if (!selectedSet().has(highlighted.value)) addSelectedItem(highlighted, "keyboard");
454
+ } else {
455
+ commit(highlighted.value, highlighted.label, asItem(highlighted), "selection", "keyboard");
456
+ queueMicrotask(() => void validateCurrent());
457
+ }
458
+ } else if (!host.props.selectOnTab.value) resolveTyped("keyboard");
459
+ close();
460
+ }
445
461
  else if (!event.altKey && !event.ctrlKey && !event.metaKey && !event.shiftKey && ["ArrowDown", "ArrowUp"].includes(event.key)) { event.preventDefault(); if (!host.state.expanded) open("disclosure"); move(event.key); }
446
462
  else if (["Home", "End"].includes(event.key) && host.state.expanded && host.state.active >= 0) { event.preventDefault(); move(event.key); }
447
463
  else if (event.key === "Enter" && host.state.expanded) {