@seed-ship/mcp-ui-solid 4.2.2 → 4.3.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.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,42 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [4.3.0] - 2026-04-11
9
+
10
+ ### Added — Prefill Enhancements (Phase B)
11
+
12
+ #### `prefillMode: "resolve"` for autocomplete fields (Proposal 1)
13
+ - Autocomplete fields can receive display names (e.g. "Paris") instead of codes
14
+ - MCP-UI calls `apiUrl` to resolve to `valueField` (e.g. code "75056") client-side
15
+ - Reduces server-side complexity — no async value resolution needed before emitting forms
16
+ - Fallback: raw prefill value used if API call fails
17
+
18
+ #### Smart tag display (Proposal 2)
19
+ - Select/multi-select fields show `label` not `value` for prefilled codes
20
+ - Autocomplete shows `displayHint` or resolved label as chip text instead of raw code
21
+
22
+ #### Prefill confidence summary (Proposal 3)
23
+ - Shows "N champ(s) pré-rempli(s) sur M" when at least one field is prefilled
24
+ - Displayed in both FormRenderer and EmbeddedFormSection (scratchpad forms)
25
+
26
+ #### Auto-submit toast mode (Proposal 4)
27
+ - When ALL fields are prefilled + `autoSubmitDelay` set, shows compact toast instead of full form
28
+ - Toast shows prefilled values summary with countdown, "Modifier" to expand, × to cancel
29
+ - Any interaction cancels countdown and expands full form
30
+
31
+ #### `valueFormat` validation (Proposal 5)
32
+ - Optional regex pattern on form fields — validates submitted value format
33
+ - `valueFormatHint` for human-readable error message on failure
34
+ - Runs after type-specific validation, supports arrays (multi-select)
35
+
36
+ #### Autocomplete always submits `valueField` (Proposal 6)
37
+ - On blur without selection, auto-resolves typed text to first API result
38
+ - Ensures form never submits display names when `valueField` is configured
39
+ - Fixes silent data corruption when users type instead of selecting
40
+
41
+ ### Changed
42
+ - `@seed-ship/mcp-ui-spec` bumped to 3.2.0 (`prefillMode`, `valueFormat`, `valueFormatHint`)
43
+
8
44
  ## [4.2.2] - 2026-04-11
9
45
 
10
46
  ### Added — Prefilled Forms with Source Indicators
package/README.md CHANGED
@@ -5,13 +5,15 @@ SolidJS components + chat toolkit for MCP-generated UI. Part of the [MCP UI ecos
5
5
  [![npm version](https://img.shields.io/npm/v/@seed-ship/mcp-ui-solid.svg)](https://www.npmjs.com/package/@seed-ship/mcp-ui-solid)
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
7
 
8
- ## What's New in v4.2
8
+ ## What's New in v4.3
9
9
 
10
10
  - **Prefilled Forms** — Fields render with pre-populated values + source indicators (detected/inferred/default/user)
11
- - **Source badges**Visual cues showing how each value was obtained (checkmark, link, pencil icons)
12
- - **Muted fields** — High-confidence prefills display with reduced opacity, activate on focus/click
13
- - **Display hints** — Caption below prefilled fields (e.g. "Rhône déduit de Lyon")
14
- - **Auto-submit countdown** — When all required fields are prefilled, optional countdown with cancel
11
+ - **`prefillMode: "resolve"`**Autocomplete fields accept display names ("Paris"), resolve to codes ("75056") client-side
12
+ - **Smart tag display** — Select/autocomplete show labels not codes for prefilled values
13
+ - **Prefill summary** — "N champs pré-remplis sur M" shown when fields are prefilled
14
+ - **Auto-submit toast** — Compact summary with countdown when ALL fields are prefilled
15
+ - **`valueFormat` validation** — Regex-based format validation on form values (e.g. `"^\\d{5}$"` for INSEE codes)
16
+ - **Autocomplete valueField guarantee** — Always submits resolved code, never display text
15
17
 
16
18
  ### Prefilled Form Example
17
19
 
@@ -28,8 +30,11 @@ SolidJS components + chat toolkit for MCP-generated UI. Part of the [MCP UI ecos
28
30
  muted: true,
29
31
  },
30
32
  {
31
- name: 'commune', type: 'text',
32
- prefill: 'Lyon',
33
+ name: 'commune', type: 'autocomplete',
34
+ apiUrl: 'https://geo.api.gouv.fr/communes',
35
+ searchParam: 'nom', labelField: 'nom', valueField: 'code',
36
+ prefill: ['Lyon'],
37
+ prefillMode: 'resolve', // MCP-UI resolves "Lyon" → code "69123"
33
38
  source: 'detected',
34
39
  muted: true,
35
40
  },
@@ -39,7 +44,7 @@ SolidJS components + chat toolkit for MCP-generated UI. Part of the [MCP UI ecos
39
44
  // No prefill — user must choose
40
45
  },
41
46
  ],
42
- autoSubmitDelay: 3000, // optional countdown
47
+ autoSubmitDelay: 3000, // optional countdown + toast when all prefilled
43
48
  }
44
49
  ```
45
50
 
@@ -3,7 +3,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const web = require("solid-js/web");
4
4
  const solidJs = require("solid-js");
5
5
  const useConditionalField = require("../hooks/useConditionalField.cjs");
6
- var _tmpl$ = /* @__PURE__ */ web.template(`<span class=mr-1>`), _tmpl$2 = /* @__PURE__ */ web.template(`<span class="text-red-500 ml-1"aria-hidden=true>*`), _tmpl$3 = /* @__PURE__ */ web.template(`<span class="ml-2 text-[10px] font-medium bg-orange-100 dark:bg-orange-900/30 text-orange-600 dark:text-orange-400 px-1.5 py-0.5 rounded">Not supported`), _tmpl$4 = /* @__PURE__ */ web.template(`<span class="ml-2 text-[10px] font-medium bg-yellow-100 dark:bg-yellow-900/30 text-yellow-600 dark:text-yellow-400 px-1.5 py-0.5 rounded">?`), _tmpl$5 = /* @__PURE__ */ web.template(`<label><!$><!/><!$><!/><!$><!/><!$><!/><!$><!/>`), _tmpl$6 = /* @__PURE__ */ web.template(`<input>`), _tmpl$7 = /* @__PURE__ */ web.template(`<input type=number>`), _tmpl$8 = /* @__PURE__ */ web.template(`<input type=date>`), _tmpl$9 = /* @__PURE__ */ web.template(`<textarea>`), _tmpl$0 = /* @__PURE__ */ web.template(`<option value disabled>`), _tmpl$1 = /* @__PURE__ */ web.template(`<select><!$><!/><!$><!/>`), _tmpl$10 = /* @__PURE__ */ web.template(`<label class="flex items-center gap-2 cursor-pointer"><input type=checkbox class="w-4 h-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700"><span class="text-sm text-gray-700 dark:text-gray-300"><!$><!/><!$><!/>`), _tmpl$11 = /* @__PURE__ */ web.template(`<div class=space-y-2 role=radiogroup>`), _tmpl$12 = /* @__PURE__ */ web.template(`<div class="flex items-center gap-3"><input type=range class="flex-1 h-2 bg-gray-200 dark:bg-gray-600 rounded-lg appearance-none cursor-pointer accent-blue-600"><span class="text-sm font-mono text-gray-700 dark:text-gray-300 min-w-[3rem] text-right">`), _tmpl$13 = /* @__PURE__ */ web.template(`<label class="flex items-center gap-2 cursor-pointer"><button type=button role=switch><span></span></button><span class="text-sm text-gray-700 dark:text-gray-300">`), _tmpl$14 = /* @__PURE__ */ web.template(`<fieldset class="border border-gray-200 dark:border-gray-600 rounded-lg p-3"><legend class="text-xs font-medium text-gray-500 dark:text-gray-400 px-1"></legend><p class="text-xs text-gray-400">`), _tmpl$15 = /* @__PURE__ */ web.template(`<input type=text>`), _tmpl$16 = /* @__PURE__ */ web.template(`<p class="text-xs text-amber-500 mt-0.5">Unknown field type: <!$><!/>`), _tmpl$17 = /* @__PURE__ */ web.template(`<p>`), _tmpl$18 = /* @__PURE__ */ web.template(`<p class="text-xs text-gray-500 dark:text-gray-400">`), _tmpl$19 = /* @__PURE__ */ web.template(`<p role=alert class="text-xs text-red-600 dark:text-red-400">`), _tmpl$20 = /* @__PURE__ */ web.template(`<div class=space-y-1><!$><!/><!$><!/><!$><!/><!$><!/><!$><!/><!$><!/>`), _tmpl$21 = /* @__PURE__ */ web.template(`<option>`), _tmpl$22 = /* @__PURE__ */ web.template(`<label class="flex items-center gap-2 cursor-pointer"><input type=radio class="w-4 h-4 border-gray-300 text-blue-600 focus:ring-blue-500 dark:border-gray-600"><span class="text-sm text-gray-700 dark:text-gray-300">`), _tmpl$23 = /* @__PURE__ */ web.template(`<div class="flex flex-wrap gap-1 mb-1">`), _tmpl$24 = /* @__PURE__ */ web.template(`<div class="p-2 border-b border-gray-200 dark:border-gray-600 flex-shrink-0"><input type=text placeholder=Filter... class="w-full px-2 py-1 text-sm border border-gray-200 dark:border-gray-600 rounded bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:border-blue-400 outline-none"autofocus>`), _tmpl$25 = /* @__PURE__ */ web.template(`<p class="px-3 py-2 text-sm text-gray-400">No matches`), _tmpl$26 = /* @__PURE__ */ web.template(`<div class="absolute z-50 mt-1 w-full bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-600 rounded-md shadow-lg"style=max-height:320px;display:flex;flex-direction:column><!$><!/><div style=overflow-y:auto;flex:1;-webkit-overflow-scrolling:touch><!$><!/><!$><!/>`), _tmpl$27 = /* @__PURE__ */ web.template(`<div class=relative><!$><!/><button type=button><span></span><svg class="w-4 h-4 text-gray-400"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M19 9l-7 7-7-7"></path></svg></button><!$><!/>`), _tmpl$28 = /* @__PURE__ */ web.template(`<span class="inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium bg-blue-100 dark:bg-blue-900/30 text-blue-700 dark:text-blue-300 rounded-full"><!$><!/><button type=button class="hover:text-blue-900 dark:hover:text-blue-100">&times;`), _tmpl$29 = /* @__PURE__ */ web.template(`<label class="flex items-center gap-2 px-3 py-2 hover:bg-gray-100 dark:hover:bg-gray-700 cursor-pointer text-sm"><input type=checkbox class="w-4 h-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500 dark:border-gray-600"><span class="text-gray-900 dark:text-white">`), _tmpl$30 = /* @__PURE__ */ web.template(`<div class="absolute z-20 mt-1 w-full bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-600 rounded-md shadow-lg max-h-72 overflow-y-auto">`), _tmpl$31 = /* @__PURE__ */ web.template(`<div class=relative><!$><!/><input type=text autocomplete=off><!$><!/>`), _tmpl$32 = /* @__PURE__ */ web.template(`<span class="ml-2 text-xs">&#10003;`), _tmpl$33 = /* @__PURE__ */ web.template(`<button type=button><!$><!/><!$><!/>`), _tmpl$34 = /* @__PURE__ */ web.template(`<div><!$><!/><input type=text>`);
6
+ var _tmpl$ = /* @__PURE__ */ web.template(`<span class=mr-1>`), _tmpl$2 = /* @__PURE__ */ web.template(`<span class="text-red-500 ml-1"aria-hidden=true>*`), _tmpl$3 = /* @__PURE__ */ web.template(`<span class="ml-2 text-[10px] font-medium bg-orange-100 dark:bg-orange-900/30 text-orange-600 dark:text-orange-400 px-1.5 py-0.5 rounded">Not supported`), _tmpl$4 = /* @__PURE__ */ web.template(`<span class="ml-2 text-[10px] font-medium bg-yellow-100 dark:bg-yellow-900/30 text-yellow-600 dark:text-yellow-400 px-1.5 py-0.5 rounded">?`), _tmpl$5 = /* @__PURE__ */ web.template(`<label><!$><!/><!$><!/><!$><!/><!$><!/><!$><!/>`), _tmpl$6 = /* @__PURE__ */ web.template(`<input>`), _tmpl$7 = /* @__PURE__ */ web.template(`<input type=number>`), _tmpl$8 = /* @__PURE__ */ web.template(`<input type=date>`), _tmpl$9 = /* @__PURE__ */ web.template(`<textarea>`), _tmpl$0 = /* @__PURE__ */ web.template(`<option value disabled>`), _tmpl$1 = /* @__PURE__ */ web.template(`<select><!$><!/><!$><!/>`), _tmpl$10 = /* @__PURE__ */ web.template(`<label class="flex items-center gap-2 cursor-pointer"><input type=checkbox class="w-4 h-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700"><span class="text-sm text-gray-700 dark:text-gray-300"><!$><!/><!$><!/>`), _tmpl$11 = /* @__PURE__ */ web.template(`<div class=space-y-2 role=radiogroup>`), _tmpl$12 = /* @__PURE__ */ web.template(`<div class="flex items-center gap-3"><input type=range class="flex-1 h-2 bg-gray-200 dark:bg-gray-600 rounded-lg appearance-none cursor-pointer accent-blue-600"><span class="text-sm font-mono text-gray-700 dark:text-gray-300 min-w-[3rem] text-right">`), _tmpl$13 = /* @__PURE__ */ web.template(`<label class="flex items-center gap-2 cursor-pointer"><button type=button role=switch><span></span></button><span class="text-sm text-gray-700 dark:text-gray-300">`), _tmpl$14 = /* @__PURE__ */ web.template(`<fieldset class="border border-gray-200 dark:border-gray-600 rounded-lg p-3"><legend class="text-xs font-medium text-gray-500 dark:text-gray-400 px-1"></legend><p class="text-xs text-gray-400">`), _tmpl$15 = /* @__PURE__ */ web.template(`<input type=text>`), _tmpl$16 = /* @__PURE__ */ web.template(`<p class="text-xs text-amber-500 mt-0.5">Unknown field type: <!$><!/>`), _tmpl$17 = /* @__PURE__ */ web.template(`<p>`), _tmpl$18 = /* @__PURE__ */ web.template(`<p class="text-xs text-gray-500 dark:text-gray-400">`), _tmpl$19 = /* @__PURE__ */ web.template(`<p role=alert class="text-xs text-red-600 dark:text-red-400">`), _tmpl$20 = /* @__PURE__ */ web.template(`<div class=space-y-1><!$><!/><!$><!/><!$><!/><!$><!/><!$><!/><!$><!/>`), _tmpl$21 = /* @__PURE__ */ web.template(`<option>`), _tmpl$22 = /* @__PURE__ */ web.template(`<label class="flex items-center gap-2 cursor-pointer"><input type=radio class="w-4 h-4 border-gray-300 text-blue-600 focus:ring-blue-500 dark:border-gray-600"><span class="text-sm text-gray-700 dark:text-gray-300">`), _tmpl$23 = /* @__PURE__ */ web.template(`<div class="flex flex-wrap gap-1 mb-1">`), _tmpl$24 = /* @__PURE__ */ web.template(`<div class="p-2 border-b border-gray-200 dark:border-gray-600 flex-shrink-0"><input type=text placeholder=Filter... class="w-full px-2 py-1 text-sm border border-gray-200 dark:border-gray-600 rounded bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:border-blue-400 outline-none"autofocus>`), _tmpl$25 = /* @__PURE__ */ web.template(`<p class="px-3 py-2 text-sm text-gray-400">No matches`), _tmpl$26 = /* @__PURE__ */ web.template(`<div class="absolute z-50 mt-1 w-full bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-600 rounded-md shadow-lg"style=max-height:320px;display:flex;flex-direction:column><!$><!/><div style=overflow-y:auto;flex:1;-webkit-overflow-scrolling:touch><!$><!/><!$><!/>`), _tmpl$27 = /* @__PURE__ */ web.template(`<div class=relative><!$><!/><button type=button><span></span><svg class="w-4 h-4 text-gray-400"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M19 9l-7 7-7-7"></path></svg></button><!$><!/>`), _tmpl$28 = /* @__PURE__ */ web.template(`<span class="inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium bg-blue-100 dark:bg-blue-900/30 text-blue-700 dark:text-blue-300 rounded-full"><!$><!/><button type=button class="hover:text-blue-900 dark:hover:text-blue-100">&times;`), _tmpl$29 = /* @__PURE__ */ web.template(`<label class="flex items-center gap-2 px-3 py-2 hover:bg-gray-100 dark:hover:bg-gray-700 cursor-pointer text-sm"><input type=checkbox class="w-4 h-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500 dark:border-gray-600"><span class="text-gray-900 dark:text-white">`), _tmpl$30 = /* @__PURE__ */ web.template(`<div class="flex items-center gap-1 mb-1 text-xs text-gray-400"><span class="animate-spin h-3 w-3 border border-gray-400 border-t-transparent rounded-full"></span>Resolving...`), _tmpl$31 = /* @__PURE__ */ web.template(`<div class="absolute z-20 mt-1 w-full bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-600 rounded-md shadow-lg max-h-72 overflow-y-auto">`), _tmpl$32 = /* @__PURE__ */ web.template(`<div class=relative><!$><!/><!$><!/><input type=text autocomplete=off><!$><!/>`), _tmpl$33 = /* @__PURE__ */ web.template(`<span class="ml-2 text-xs">&#10003;`), _tmpl$34 = /* @__PURE__ */ web.template(`<button type=button><!$><!/><!$><!/>`), _tmpl$35 = /* @__PURE__ */ web.template(`<div><!$><!/><input type=text>`);
7
7
  const SOURCE_BADGES = {
8
8
  detected: {
9
9
  icon: "✅",
@@ -721,6 +721,7 @@ const AutocompleteField = (props) => {
721
721
  const [suggestions, setSuggestions] = solidJs.createSignal([]);
722
722
  const [isOpen, setIsOpen] = solidJs.createSignal(false);
723
723
  const [selectedLabels, setSelectedLabels] = solidJs.createSignal(/* @__PURE__ */ new Map());
724
+ const [resolving, setResolving] = solidJs.createSignal(false);
724
725
  let debounceTimer = null;
725
726
  const isMultiple = () => props.field.multiple === true;
726
727
  const selectedValues = () => isMultiple() ? Array.isArray(props.value) ? props.value : [] : [];
@@ -752,6 +753,69 @@ const AutocompleteField = (props) => {
752
753
  setSuggestions([]);
753
754
  }
754
755
  };
756
+ const resolvePrefill = async (prefillValues) => {
757
+ if (!props.field.apiUrl || !props.field.searchParam) return;
758
+ setResolving(true);
759
+ const labelField = props.field.labelField || "label";
760
+ const valueField = props.field.valueField || "value";
761
+ try {
762
+ const resolvedValues = [];
763
+ for (const pv of prefillValues) {
764
+ const params = new URLSearchParams({
765
+ [props.field.searchParam]: pv,
766
+ limit: "1"
767
+ });
768
+ if (props.field.extraParams) {
769
+ for (const [k, v] of Object.entries(props.field.extraParams)) params.set(k, v);
770
+ }
771
+ const res = await fetch(`${props.field.apiUrl}?${params}`);
772
+ if (!res.ok) {
773
+ resolvedValues.push(pv);
774
+ continue;
775
+ }
776
+ const data = await res.json();
777
+ const items = Array.isArray(data) ? data : data.results || data.features || [];
778
+ if (items.length > 0) {
779
+ const code = String(items[0][valueField] || pv);
780
+ const label = items[0][labelField] || pv;
781
+ resolvedValues.push(code);
782
+ setSelectedLabels((prev) => new Map(prev).set(code, label));
783
+ } else {
784
+ resolvedValues.push(pv);
785
+ setSelectedLabels((prev) => new Map(prev).set(pv, pv));
786
+ }
787
+ }
788
+ if (isMultiple()) {
789
+ props.onChange(resolvedValues);
790
+ } else {
791
+ props.onChange(resolvedValues[0] || "");
792
+ const label = selectedLabels().get(resolvedValues[0]);
793
+ if (label) setQuery(label);
794
+ }
795
+ } catch {
796
+ } finally {
797
+ setResolving(false);
798
+ }
799
+ };
800
+ solidJs.createEffect(() => {
801
+ const prefill = props.field.prefill;
802
+ if (!prefill) return;
803
+ const values = Array.isArray(prefill) ? prefill : [prefill];
804
+ if (values.length === 0) return;
805
+ if (props.field.prefillMode === "resolve") {
806
+ resolvePrefill(values);
807
+ } else {
808
+ for (const v of values) {
809
+ if (!selectedLabels().has(v)) {
810
+ setSelectedLabels((prev) => new Map(prev).set(v, props.field.displayHint || v));
811
+ }
812
+ }
813
+ if (!isMultiple() && values[0]) {
814
+ const label = props.field.displayHint || values[0];
815
+ setQuery(label);
816
+ }
817
+ }
818
+ });
755
819
  const handleInput = (value) => {
756
820
  setQuery(value);
757
821
  if (!isMultiple()) {
@@ -786,6 +850,14 @@ const AutocompleteField = (props) => {
786
850
  setSuggestions([]);
787
851
  }
788
852
  };
853
+ const handleBlur = () => {
854
+ setTimeout(() => {
855
+ setIsOpen(false);
856
+ if (!isMultiple() && query() && !props.value && props.field.valueField && suggestions().length > 0) {
857
+ selectSuggestion(suggestions()[0]);
858
+ }
859
+ }, 200);
860
+ };
789
861
  const removeChip = (val) => {
790
862
  props.onChange(selectedValues().filter((v) => v !== val));
791
863
  setSelectedLabels((prev) => {
@@ -799,88 +871,96 @@ const AutocompleteField = (props) => {
799
871
  if (debounceTimer) clearTimeout(debounceTimer);
800
872
  });
801
873
  return (() => {
802
- var _el$95 = web.getNextElement(_tmpl$31), _el$99 = _el$95.firstChild, [_el$100, _co$21] = web.getNextMarker(_el$99.nextSibling), _el$97 = _el$100.nextSibling, _el$101 = _el$97.nextSibling, [_el$102, _co$22] = web.getNextMarker(_el$101.nextSibling);
874
+ var _el$95 = web.getNextElement(_tmpl$32), _el$100 = _el$95.firstChild, [_el$101, _co$21] = web.getNextMarker(_el$100.nextSibling), _el$102 = _el$101.nextSibling, [_el$103, _co$22] = web.getNextMarker(_el$102.nextSibling), _el$98 = _el$103.nextSibling, _el$104 = _el$98.nextSibling, [_el$105, _co$23] = web.getNextMarker(_el$104.nextSibling);
875
+ web.insert(_el$95, web.createComponent(solidJs.Show, {
876
+ get when() {
877
+ return resolving();
878
+ },
879
+ get children() {
880
+ return web.getNextElement(_tmpl$30);
881
+ }
882
+ }), _el$101, _co$21);
803
883
  web.insert(_el$95, web.createComponent(solidJs.Show, {
804
884
  get when() {
805
885
  return web.memo(() => !!isMultiple())() && selectedValues().length > 0;
806
886
  },
807
887
  get children() {
808
- var _el$96 = web.getNextElement(_tmpl$23);
809
- web.insert(_el$96, web.createComponent(solidJs.For, {
888
+ var _el$97 = web.getNextElement(_tmpl$23);
889
+ web.insert(_el$97, web.createComponent(solidJs.For, {
810
890
  get each() {
811
891
  return selectedValues();
812
892
  },
813
893
  children: (val) => (() => {
814
- var _el$103 = web.getNextElement(_tmpl$28), _el$105 = _el$103.firstChild, [_el$106, _co$23] = web.getNextMarker(_el$105.nextSibling), _el$104 = _el$106.nextSibling;
815
- web.insert(_el$103, () => getLabel(val), _el$106, _co$23);
816
- _el$104.$$click = () => removeChip(val);
817
- web.effect(() => web.setAttribute(_el$104, "aria-label", `Remove ${getLabel(val)}`));
894
+ var _el$106 = web.getNextElement(_tmpl$28), _el$108 = _el$106.firstChild, [_el$109, _co$24] = web.getNextMarker(_el$108.nextSibling), _el$107 = _el$109.nextSibling;
895
+ web.insert(_el$106, () => getLabel(val), _el$109, _co$24);
896
+ _el$107.$$click = () => removeChip(val);
897
+ web.effect(() => web.setAttribute(_el$107, "aria-label", `Remove ${getLabel(val)}`));
818
898
  web.runHydrationEvents();
819
- return _el$103;
899
+ return _el$106;
820
900
  })()
821
901
  }));
822
- return _el$96;
902
+ return _el$97;
823
903
  }
824
- }), _el$100, _co$21);
825
- _el$97.addEventListener("blur", () => setTimeout(() => setIsOpen(false), 200));
826
- _el$97.addEventListener("focus", () => {
904
+ }), _el$103, _co$22);
905
+ _el$98.addEventListener("blur", handleBlur);
906
+ _el$98.addEventListener("focus", () => {
827
907
  if (suggestions().length) setIsOpen(true);
828
908
  });
829
- _el$97.$$input = (e) => handleInput(e.currentTarget.value);
909
+ _el$98.$$input = (e) => handleInput(e.currentTarget.value);
830
910
  web.insert(_el$95, web.createComponent(solidJs.Show, {
831
911
  get when() {
832
912
  return web.memo(() => !!isOpen())() && suggestions().length > 0;
833
913
  },
834
914
  get children() {
835
- var _el$98 = web.getNextElement(_tmpl$30);
836
- web.insert(_el$98, web.createComponent(solidJs.For, {
915
+ var _el$99 = web.getNextElement(_tmpl$31);
916
+ web.insert(_el$99, web.createComponent(solidJs.For, {
837
917
  get each() {
838
918
  return suggestions();
839
919
  },
840
920
  children: (item) => {
841
921
  const isSelected = () => isMultiple() && selectedValues().includes(item.value);
842
922
  return (() => {
843
- var _el$107 = web.getNextElement(_tmpl$33), _el$109 = _el$107.firstChild, [_el$110, _co$24] = web.getNextMarker(_el$109.nextSibling), _el$111 = _el$110.nextSibling, [_el$112, _co$25] = web.getNextMarker(_el$111.nextSibling);
844
- _el$107.$$click = () => selectSuggestion(item);
845
- _el$107.$$mousedown = (e) => e.preventDefault();
846
- web.insert(_el$107, () => item.label, _el$110, _co$24);
847
- web.insert(_el$107, web.createComponent(solidJs.Show, {
923
+ var _el$110 = web.getNextElement(_tmpl$34), _el$112 = _el$110.firstChild, [_el$113, _co$25] = web.getNextMarker(_el$112.nextSibling), _el$114 = _el$113.nextSibling, [_el$115, _co$26] = web.getNextMarker(_el$114.nextSibling);
924
+ _el$110.$$click = () => selectSuggestion(item);
925
+ _el$110.$$mousedown = (e) => e.preventDefault();
926
+ web.insert(_el$110, () => item.label, _el$113, _co$25);
927
+ web.insert(_el$110, web.createComponent(solidJs.Show, {
848
928
  get when() {
849
929
  return isSelected();
850
930
  },
851
931
  get children() {
852
- return web.getNextElement(_tmpl$32);
932
+ return web.getNextElement(_tmpl$33);
853
933
  }
854
- }), _el$112, _co$25);
934
+ }), _el$115, _co$26);
855
935
  web.effect((_p$) => {
856
936
  var _v$83 = `w-full text-left px-3 py-2 text-sm hover:bg-blue-50 dark:hover:bg-blue-900/20 ${isSelected() ? "text-blue-600 dark:text-blue-400 bg-blue-50/50 dark:bg-blue-900/10" : "text-gray-900 dark:text-white"}`, _v$84 = isSelected();
857
- _v$83 !== _p$.e && web.className(_el$107, _p$.e = _v$83);
858
- _v$84 !== _p$.t && web.setProperty(_el$107, "disabled", _p$.t = _v$84);
937
+ _v$83 !== _p$.e && web.className(_el$110, _p$.e = _v$83);
938
+ _v$84 !== _p$.t && web.setProperty(_el$110, "disabled", _p$.t = _v$84);
859
939
  return _p$;
860
940
  }, {
861
941
  e: void 0,
862
942
  t: void 0
863
943
  });
864
944
  web.runHydrationEvents();
865
- return _el$107;
945
+ return _el$110;
866
946
  })();
867
947
  }
868
948
  }));
869
- return _el$98;
949
+ return _el$99;
870
950
  }
871
- }), _el$102, _co$22);
951
+ }), _el$105, _co$23);
872
952
  web.effect((_p$) => {
873
- var _v$80 = isMultiple() && selectedValues().length ? "Add more..." : props.field.placeholder, _v$81 = props.disabled, _v$82 = props.baseClass;
874
- _v$80 !== _p$.e && web.setAttribute(_el$97, "placeholder", _p$.e = _v$80);
875
- _v$81 !== _p$.t && web.setProperty(_el$97, "disabled", _p$.t = _v$81);
876
- _v$82 !== _p$.a && web.className(_el$97, _p$.a = _v$82);
953
+ var _v$80 = isMultiple() && selectedValues().length ? "Add more..." : props.field.placeholder, _v$81 = props.disabled || resolving(), _v$82 = props.baseClass;
954
+ _v$80 !== _p$.e && web.setAttribute(_el$98, "placeholder", _p$.e = _v$80);
955
+ _v$81 !== _p$.t && web.setProperty(_el$98, "disabled", _p$.t = _v$81);
956
+ _v$82 !== _p$.a && web.className(_el$98, _p$.a = _v$82);
877
957
  return _p$;
878
958
  }, {
879
959
  e: void 0,
880
960
  t: void 0,
881
961
  a: void 0
882
962
  });
883
- web.effect(() => web.setProperty(_el$97, "value", query()));
963
+ web.effect(() => web.setProperty(_el$98, "value", query()));
884
964
  web.runHydrationEvents();
885
965
  return _el$95;
886
966
  })();
@@ -907,46 +987,46 @@ const TagsField = (props) => {
907
987
  }
908
988
  };
909
989
  return (() => {
910
- var _el$113 = web.getNextElement(_tmpl$34), _el$116 = _el$113.firstChild, [_el$117, _co$26] = web.getNextMarker(_el$116.nextSibling), _el$115 = _el$117.nextSibling;
911
- web.insert(_el$113, web.createComponent(solidJs.Show, {
990
+ var _el$116 = web.getNextElement(_tmpl$35), _el$119 = _el$116.firstChild, [_el$120, _co$27] = web.getNextMarker(_el$119.nextSibling), _el$118 = _el$120.nextSibling;
991
+ web.insert(_el$116, web.createComponent(solidJs.Show, {
912
992
  get when() {
913
993
  return (props.value || []).length > 0;
914
994
  },
915
995
  get children() {
916
- var _el$114 = web.getNextElement(_tmpl$23);
917
- web.insert(_el$114, web.createComponent(solidJs.For, {
996
+ var _el$117 = web.getNextElement(_tmpl$23);
997
+ web.insert(_el$117, web.createComponent(solidJs.For, {
918
998
  get each() {
919
999
  return props.value || [];
920
1000
  },
921
1001
  children: (tag) => (() => {
922
- var _el$118 = web.getNextElement(_tmpl$28), _el$120 = _el$118.firstChild, [_el$121, _co$27] = web.getNextMarker(_el$120.nextSibling), _el$119 = _el$121.nextSibling;
923
- web.insert(_el$118, tag, _el$121, _co$27);
924
- _el$119.$$click = () => removeTag(tag);
925
- web.setAttribute(_el$119, "aria-label", `Remove ${tag}`);
1002
+ var _el$121 = web.getNextElement(_tmpl$28), _el$123 = _el$121.firstChild, [_el$124, _co$28] = web.getNextMarker(_el$123.nextSibling), _el$122 = _el$124.nextSibling;
1003
+ web.insert(_el$121, tag, _el$124, _co$28);
1004
+ _el$122.$$click = () => removeTag(tag);
1005
+ web.setAttribute(_el$122, "aria-label", `Remove ${tag}`);
926
1006
  web.runHydrationEvents();
927
- return _el$118;
1007
+ return _el$121;
928
1008
  })()
929
1009
  }));
930
- return _el$114;
1010
+ return _el$117;
931
1011
  }
932
- }), _el$117, _co$26);
933
- _el$115.addEventListener("blur", addTag);
934
- _el$115.$$keydown = handleKeyDown;
935
- _el$115.$$input = (e) => setInput(e.currentTarget.value);
1012
+ }), _el$120, _co$27);
1013
+ _el$118.addEventListener("blur", addTag);
1014
+ _el$118.$$keydown = handleKeyDown;
1015
+ _el$118.$$input = (e) => setInput(e.currentTarget.value);
936
1016
  web.effect((_p$) => {
937
1017
  var _v$85 = props.placeholder || "Type and press Enter...", _v$86 = props.disabled, _v$87 = props.baseClass;
938
- _v$85 !== _p$.e && web.setAttribute(_el$115, "placeholder", _p$.e = _v$85);
939
- _v$86 !== _p$.t && web.setProperty(_el$115, "disabled", _p$.t = _v$86);
940
- _v$87 !== _p$.a && web.className(_el$115, _p$.a = _v$87);
1018
+ _v$85 !== _p$.e && web.setAttribute(_el$118, "placeholder", _p$.e = _v$85);
1019
+ _v$86 !== _p$.t && web.setProperty(_el$118, "disabled", _p$.t = _v$86);
1020
+ _v$87 !== _p$.a && web.className(_el$118, _p$.a = _v$87);
941
1021
  return _p$;
942
1022
  }, {
943
1023
  e: void 0,
944
1024
  t: void 0,
945
1025
  a: void 0
946
1026
  });
947
- web.effect(() => web.setProperty(_el$115, "value", input()));
1027
+ web.effect(() => web.setProperty(_el$118, "value", input()));
948
1028
  web.runHydrationEvents();
949
- return _el$113;
1029
+ return _el$116;
950
1030
  })();
951
1031
  };
952
1032
  web.delegateEvents(["focusin", "click", "input", "mousedown", "keydown"]);