@seed-ship/mcp-ui-solid 2.0.0 → 2.1.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.
Files changed (140) hide show
  1. package/README.md +50 -1
  2. package/dist/components/AutocompleteDropdown.cjs +201 -0
  3. package/dist/components/AutocompleteDropdown.cjs.map +1 -0
  4. package/dist/components/AutocompleteDropdown.d.ts +71 -0
  5. package/dist/components/AutocompleteDropdown.d.ts.map +1 -0
  6. package/dist/components/AutocompleteDropdown.js +201 -0
  7. package/dist/components/AutocompleteDropdown.js.map +1 -0
  8. package/dist/components/AutocompleteFormField.cjs +289 -0
  9. package/dist/components/AutocompleteFormField.cjs.map +1 -0
  10. package/dist/components/AutocompleteFormField.d.ts +52 -0
  11. package/dist/components/AutocompleteFormField.d.ts.map +1 -0
  12. package/dist/components/AutocompleteFormField.js +289 -0
  13. package/dist/components/AutocompleteFormField.js.map +1 -0
  14. package/dist/components/DraggableGridItem.cjs +133 -0
  15. package/dist/components/DraggableGridItem.cjs.map +1 -0
  16. package/dist/components/DraggableGridItem.d.ts +95 -0
  17. package/dist/components/DraggableGridItem.d.ts.map +1 -0
  18. package/dist/components/DraggableGridItem.js +133 -0
  19. package/dist/components/DraggableGridItem.js.map +1 -0
  20. package/dist/components/EditableUIResourceRenderer.cjs +203 -0
  21. package/dist/components/EditableUIResourceRenderer.cjs.map +1 -0
  22. package/dist/components/EditableUIResourceRenderer.d.ts +43 -0
  23. package/dist/components/EditableUIResourceRenderer.d.ts.map +1 -0
  24. package/dist/components/EditableUIResourceRenderer.js +203 -0
  25. package/dist/components/EditableUIResourceRenderer.js.map +1 -0
  26. package/dist/components/GhostText.cjs +105 -0
  27. package/dist/components/GhostText.cjs.map +1 -0
  28. package/dist/components/GhostText.d.ts +113 -0
  29. package/dist/components/GhostText.d.ts.map +1 -0
  30. package/dist/components/GhostText.js +105 -0
  31. package/dist/components/GhostText.js.map +1 -0
  32. package/dist/components/ResizeHandle.cjs +173 -0
  33. package/dist/components/ResizeHandle.cjs.map +1 -0
  34. package/dist/components/ResizeHandle.d.ts +50 -0
  35. package/dist/components/ResizeHandle.d.ts.map +1 -0
  36. package/dist/components/ResizeHandle.js +173 -0
  37. package/dist/components/ResizeHandle.js.map +1 -0
  38. package/dist/context/AutocompleteContext.cjs +158 -0
  39. package/dist/context/AutocompleteContext.cjs.map +1 -0
  40. package/dist/context/AutocompleteContext.d.ts +77 -0
  41. package/dist/context/AutocompleteContext.d.ts.map +1 -0
  42. package/dist/context/AutocompleteContext.js +158 -0
  43. package/dist/context/AutocompleteContext.js.map +1 -0
  44. package/dist/hooks/index.d.ts +6 -0
  45. package/dist/hooks/index.d.ts.map +1 -1
  46. package/dist/hooks/useAutocomplete.cjs +234 -0
  47. package/dist/hooks/useAutocomplete.cjs.map +1 -0
  48. package/dist/hooks/useAutocomplete.d.ts +119 -0
  49. package/dist/hooks/useAutocomplete.d.ts.map +1 -0
  50. package/dist/hooks/useAutocomplete.js +234 -0
  51. package/dist/hooks/useAutocomplete.js.map +1 -0
  52. package/dist/hooks/useDragDrop.cjs +170 -0
  53. package/dist/hooks/useDragDrop.cjs.map +1 -0
  54. package/dist/hooks/useDragDrop.d.ts +100 -0
  55. package/dist/hooks/useDragDrop.d.ts.map +1 -0
  56. package/dist/hooks/useDragDrop.js +170 -0
  57. package/dist/hooks/useDragDrop.js.map +1 -0
  58. package/dist/hooks/useResize.cjs +209 -0
  59. package/dist/hooks/useResize.cjs.map +1 -0
  60. package/dist/hooks/useResize.d.ts +87 -0
  61. package/dist/hooks/useResize.d.ts.map +1 -0
  62. package/dist/hooks/useResize.js +209 -0
  63. package/dist/hooks/useResize.js.map +1 -0
  64. package/dist/hooks.cjs +6 -0
  65. package/dist/hooks.cjs.map +1 -1
  66. package/dist/hooks.d.cts +6 -0
  67. package/dist/hooks.d.ts +6 -0
  68. package/dist/hooks.js +6 -0
  69. package/dist/hooks.js.map +1 -1
  70. package/dist/index.cjs +29 -0
  71. package/dist/index.cjs.map +1 -1
  72. package/dist/index.d.cts +18 -3
  73. package/dist/index.d.ts +18 -3
  74. package/dist/index.d.ts.map +1 -1
  75. package/dist/index.js +29 -0
  76. package/dist/index.js.map +1 -1
  77. package/dist/plugins/duckdb.cjs +192 -0
  78. package/dist/plugins/duckdb.cjs.map +1 -0
  79. package/dist/plugins/duckdb.d.ts +20 -0
  80. package/dist/plugins/duckdb.d.ts.map +1 -0
  81. package/dist/plugins/duckdb.js +170 -0
  82. package/dist/plugins/duckdb.js.map +1 -0
  83. package/dist/plugins/groq.cjs +97 -0
  84. package/dist/plugins/groq.cjs.map +1 -0
  85. package/dist/plugins/groq.d.ts +13 -0
  86. package/dist/plugins/groq.d.ts.map +1 -0
  87. package/dist/plugins/groq.js +97 -0
  88. package/dist/plugins/groq.js.map +1 -0
  89. package/dist/plugins/index.d.ts +10 -0
  90. package/dist/plugins/index.d.ts.map +1 -0
  91. package/dist/plugins/rest.cjs +92 -0
  92. package/dist/plugins/rest.cjs.map +1 -0
  93. package/dist/plugins/rest.d.ts +13 -0
  94. package/dist/plugins/rest.d.ts.map +1 -0
  95. package/dist/plugins/rest.js +92 -0
  96. package/dist/plugins/rest.js.map +1 -0
  97. package/dist/plugins/supabase.cjs +79 -0
  98. package/dist/plugins/supabase.cjs.map +1 -0
  99. package/dist/plugins/supabase.d.ts +13 -0
  100. package/dist/plugins/supabase.d.ts.map +1 -0
  101. package/dist/plugins/supabase.js +79 -0
  102. package/dist/plugins/supabase.js.map +1 -0
  103. package/dist/services/validation.cjs +40 -1
  104. package/dist/services/validation.cjs.map +1 -1
  105. package/dist/services/validation.d.ts.map +1 -1
  106. package/dist/services/validation.js +40 -1
  107. package/dist/services/validation.js.map +1 -1
  108. package/dist/types/index.d.ts +430 -0
  109. package/dist/types/index.d.ts.map +1 -1
  110. package/dist/types.d.cts +430 -0
  111. package/dist/types.d.ts +430 -0
  112. package/package.json +16 -1
  113. package/src/components/AutocompleteDropdown.tsx +329 -0
  114. package/src/components/AutocompleteFormField.tsx +288 -0
  115. package/src/components/DraggableGridItem.tsx +274 -0
  116. package/src/components/EditableUIResourceRenderer.tsx +273 -0
  117. package/src/components/GhostText.tsx +262 -0
  118. package/src/components/ResizeHandle.tsx +262 -0
  119. package/src/context/AutocompleteContext.tsx +317 -0
  120. package/src/hooks/index.ts +23 -0
  121. package/src/hooks/useAutocomplete.test.ts +334 -0
  122. package/src/hooks/useAutocomplete.ts +466 -0
  123. package/src/hooks/useDragDrop.test.ts +355 -0
  124. package/src/hooks/useDragDrop.ts +379 -0
  125. package/src/hooks/useResize.test.ts +313 -0
  126. package/src/hooks/useResize.ts +372 -0
  127. package/src/index.ts +71 -0
  128. package/src/plugins/duckdb.ts +269 -0
  129. package/src/plugins/groq.ts +137 -0
  130. package/src/plugins/index.ts +14 -0
  131. package/src/plugins/rest.ts +147 -0
  132. package/src/plugins/supabase.ts +120 -0
  133. package/src/services/validation.ts +46 -0
  134. package/src/styles/autocomplete.css +356 -0
  135. package/src/styles/drag-drop.css +297 -0
  136. package/src/styles/index.css +7 -0
  137. package/src/types/index.ts +529 -0
  138. package/src/vite-env.d.ts +18 -0
  139. package/tsconfig.tsbuildinfo +1 -1
  140. package/vite.config.ts +2 -0
package/README.md CHANGED
@@ -5,6 +5,55 @@ SolidJS components for rendering MCP-generated UI resources. Part of the MCP UI
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 v2.0.0
9
+
10
+ ### Highlights
11
+
12
+ - **Configurable Iframe Whitelist** - Control iframe security with `IframePolicy`: `strict`, `extend`, or `allow-all`
13
+ - **60+ Whitelisted Domains** - Expanded default whitelist for business use cases
14
+ - **New Component Types** - Forms, Modals, Action Groups, Image Gallery, Video, Code, Map
15
+ - **Table Virtualization** - Handle 10,000+ rows with smooth scrolling
16
+ - **Map Clustering** - Auto-cluster markers for large datasets
17
+ - **Native Chart.js Support** - Optional direct Chart.js rendering (no iframe)
18
+
19
+ ### Configurable Iframe Security
20
+
21
+ ```typescript
22
+ import { validateComponent, DEFAULT_IFRAME_DOMAINS } from '@seed-ship/mcp-ui-solid'
23
+
24
+ // Default: strict whitelist
25
+ validateComponent(component)
26
+
27
+ // Extend whitelist with custom domains
28
+ validateComponent(component, {
29
+ iframePolicy: 'extend',
30
+ customIframeDomains: ['my-trusted-site.com']
31
+ })
32
+
33
+ // Disable whitelist (use with caution)
34
+ validateComponent(component, { iframePolicy: 'allow-all' })
35
+
36
+ // View default whitelist
37
+ console.log(DEFAULT_IFRAME_DOMAINS)
38
+ ```
39
+
40
+ ### Whitelisted Domains (v2.0.0)
41
+
42
+ | Category | Domains |
43
+ |----------|---------|
44
+ | **Video** | youtube.com, vimeo.com, loom.com, cloudflarestream.com, streamable.com |
45
+ | **Diagrams** | mermaid.live, excalidraw.com, lucidchart.com, figma.com, miro.com |
46
+ | **Code** | github.com, gitlab.com, codepen.io, codesandbox.io, stackblitz.com, replit.com |
47
+ | **Google** | docs, sheets, slides, drive, maps, datastudio, lookerstudio |
48
+ | **Business** | notion.so, airtable.com, calendly.com, typeform.com, cal.com |
49
+ | **Analytics** | tableau.com, powerbi.com, observablehq.com |
50
+ | **Design** | canva.com, figma.com |
51
+ | **Maps** | maps.google.com, openstreetmap.org |
52
+ | **Previews** | vercel.app, netlify.app |
53
+ | **E-commerce** | amazon.com, amazon.fr, amazon.de, amazon.co.uk, etc. |
54
+
55
+ ---
56
+
8
57
  ## Overview
9
58
 
10
59
  `@seed-ship/mcp-ui-solid` provides a complete rendering solution for MCP (Model Context Protocol) generated UIs. It enables AI/LLM systems to generate structured, interactive dashboards that are rendered with SolidJS.
@@ -389,7 +438,7 @@ function CustomStreaming() {
389
438
 
390
439
  This package follows [Semantic Versioning](https://semver.org/). See [CHANGELOG.md](./CHANGELOG.md) for release notes.
391
440
 
392
- **Current Version:** 1.0.43
441
+ **Current Version:** 2.0.1
393
442
 
394
443
  ## License
395
444
 
@@ -0,0 +1,201 @@
1
+ "use strict";
2
+ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
+ const web = require("solid-js/web");
4
+ const solidJs = require("solid-js");
5
+ var _tmpl$ = /* @__PURE__ */ web.template(`<strong class=mcp-autocomplete-highlight>`), _tmpl$2 = /* @__PURE__ */ web.template(`<span class=mcp-autocomplete-option-icon>`), _tmpl$3 = /* @__PURE__ */ web.template(`<span class=mcp-autocomplete-option-description>`), _tmpl$4 = /* @__PURE__ */ web.template(`<div class=mcp-autocomplete-option-content><!$><!/><div class=mcp-autocomplete-option-text><span class=mcp-autocomplete-option-label></span><!$><!/>`), _tmpl$5 = /* @__PURE__ */ web.template(`<div class=mcp-autocomplete-loading style="padding:12px 16px;color:#6b7280;font-size:0.875rem;display:flex;align-items:center;gap:8px"><span style="display:inline-block;width:14px;height:14px;border:2px solid #e5e7eb;border-top-color:#3b82f6;border-radius:50%;animation:mcp-spin 0.6s linear infinite"></span><!$><!/>`), _tmpl$6 = /* @__PURE__ */ web.template(`<div class=mcp-autocomplete-empty style="padding:12px 16px;color:#9ca3af;font-size:0.875rem;text-align:center">`), _tmpl$7 = /* @__PURE__ */ web.template(`<ul class=mcp-autocomplete-options style="margin:0;padding:4px 0;list-style:none">`), _tmpl$8 = /* @__PURE__ */ web.template(`<div class=mcp-autocomplete-footer style="padding:6px 12px;border-top:1px solid #e5e7eb;background-color:#f9fafb;font-size:0.75rem;color:#6b7280"><kbd style="background-color:#e5e7eb;padding:1px 4px;border-radius:2px;font-family:inherit;font-size:0.7rem">↑</kbd> <kbd style="background-color:#e5e7eb;padding:1px 4px;border-radius:2px;font-family:inherit;font-size:0.7rem">↓</kbd> to navigate, <kbd style="background-color:#e5e7eb;padding:1px 4px;border-radius:2px;font-family:inherit;font-size:0.7rem">Enter</kbd> to select, <kbd style="background-color:#e5e7eb;padding:1px 4px;border-radius:2px;font-family:inherit;font-size:0.7rem">Esc</kbd> to dismiss`), _tmpl$9 = /* @__PURE__ */ web.template(`<div role=listbox aria-label=Suggestions><!$><!/><!$><!/><!$><!/><!$><!/>`), _tmpl$0 = /* @__PURE__ */ web.template(`<li role=option style="padding:8px 16px;font-size:0.875rem;transition:background-color 150ms ease">`);
6
+ function highlightText(text, match) {
7
+ if (!match || !text) {
8
+ return text;
9
+ }
10
+ const lowerText = text.toLowerCase();
11
+ const lowerMatch = match.toLowerCase();
12
+ const startIndex = lowerText.indexOf(lowerMatch);
13
+ if (startIndex === -1) {
14
+ return text;
15
+ }
16
+ const before = text.slice(0, startIndex);
17
+ const matched = text.slice(startIndex, startIndex + match.length);
18
+ const after = text.slice(startIndex + match.length);
19
+ return [before, (() => {
20
+ var _el$ = web.getNextElement(_tmpl$);
21
+ web.insert(_el$, matched);
22
+ return _el$;
23
+ })(), after];
24
+ }
25
+ const DefaultOptionRenderer = (props) => {
26
+ const displayLabel = solidJs.createMemo(() => props.option.label || props.option.value);
27
+ return (() => {
28
+ var _el$2 = web.getNextElement(_tmpl$4), _el$9 = _el$2.firstChild, [_el$0, _co$2] = web.getNextMarker(_el$9.nextSibling), _el$4 = _el$0.nextSibling, _el$5 = _el$4.firstChild, _el$7 = _el$5.nextSibling, [_el$8, _co$] = web.getNextMarker(_el$7.nextSibling);
29
+ web.insert(_el$2, web.createComponent(solidJs.Show, {
30
+ get when() {
31
+ return props.option.icon;
32
+ },
33
+ get children() {
34
+ var _el$3 = web.getNextElement(_tmpl$2);
35
+ web.insert(_el$3, () => props.option.icon);
36
+ return _el$3;
37
+ }
38
+ }), _el$0, _co$2);
39
+ web.insert(_el$5, () => highlightText(displayLabel(), props.highlightMatch));
40
+ web.insert(_el$4, web.createComponent(solidJs.Show, {
41
+ get when() {
42
+ return props.option.description;
43
+ },
44
+ get children() {
45
+ var _el$6 = web.getNextElement(_tmpl$3);
46
+ web.insert(_el$6, () => props.option.description);
47
+ return _el$6;
48
+ }
49
+ }), _el$8, _co$);
50
+ return _el$2;
51
+ })();
52
+ };
53
+ const AutocompleteDropdown = (props) => {
54
+ const positionStyles = solidJs.createMemo(() => {
55
+ if (props.position === "top") {
56
+ return {
57
+ bottom: "100%",
58
+ "margin-bottom": "4px"
59
+ };
60
+ }
61
+ return {
62
+ top: "100%",
63
+ "margin-top": "4px"
64
+ };
65
+ });
66
+ const containerStyles = solidJs.createMemo(() => ({
67
+ position: "absolute",
68
+ left: "0",
69
+ right: "0",
70
+ "z-index": "50",
71
+ "background-color": "#ffffff",
72
+ border: "1px solid #e5e7eb",
73
+ "border-radius": "6px",
74
+ "box-shadow": "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)",
75
+ "max-height": props.maxHeight || "240px",
76
+ overflow: "auto",
77
+ ...positionStyles()
78
+ }));
79
+ return web.createComponent(solidJs.Show, {
80
+ get when() {
81
+ return props.isOpen;
82
+ },
83
+ get children() {
84
+ var _el$1 = web.getNextElement(_tmpl$9), _el$24 = _el$1.firstChild, [_el$25, _co$4] = web.getNextMarker(_el$24.nextSibling), _el$26 = _el$25.nextSibling, [_el$27, _co$5] = web.getNextMarker(_el$26.nextSibling), _el$28 = _el$27.nextSibling, [_el$29, _co$6] = web.getNextMarker(_el$28.nextSibling), _el$30 = _el$29.nextSibling, [_el$31, _co$7] = web.getNextMarker(_el$30.nextSibling);
85
+ web.insert(_el$1, web.createComponent(solidJs.Show, {
86
+ get when() {
87
+ return props.isLoading;
88
+ },
89
+ get children() {
90
+ var _el$10 = web.getNextElement(_tmpl$5), _el$11 = _el$10.firstChild, _el$12 = _el$11.nextSibling, [_el$13, _co$3] = web.getNextMarker(_el$12.nextSibling);
91
+ web.insert(_el$10, () => props.loadingMessage || "Loading...", _el$13, _co$3);
92
+ return _el$10;
93
+ }
94
+ }), _el$25, _co$4);
95
+ web.insert(_el$1, web.createComponent(solidJs.Show, {
96
+ get when() {
97
+ return web.memo(() => !!!props.isLoading)() && props.options.length === 0;
98
+ },
99
+ get children() {
100
+ var _el$14 = web.getNextElement(_tmpl$6);
101
+ web.insert(_el$14, () => props.emptyMessage || "No suggestions found");
102
+ return _el$14;
103
+ }
104
+ }), _el$27, _co$5);
105
+ web.insert(_el$1, web.createComponent(solidJs.Show, {
106
+ get when() {
107
+ return web.memo(() => !!!props.isLoading)() && props.options.length > 0;
108
+ },
109
+ get children() {
110
+ var _el$15 = web.getNextElement(_tmpl$7);
111
+ web.insert(_el$15, web.createComponent(solidJs.For, {
112
+ get each() {
113
+ return props.options;
114
+ },
115
+ children: (option, index) => {
116
+ const isSelected = () => index() === props.selectedIndex;
117
+ const isDisabled = () => option.disabled;
118
+ return (() => {
119
+ var _el$32 = web.getNextElement(_tmpl$0);
120
+ _el$32.addEventListener("mouseenter", () => {
121
+ var _a;
122
+ if (!isDisabled()) {
123
+ (_a = props.onHover) == null ? void 0 : _a.call(props, index());
124
+ }
125
+ });
126
+ _el$32.$$click = () => {
127
+ if (!isDisabled()) {
128
+ props.onSelect(option);
129
+ }
130
+ };
131
+ web.insert(_el$32, web.createComponent(solidJs.Show, {
132
+ get when() {
133
+ return props.renderOption;
134
+ },
135
+ get fallback() {
136
+ return web.createComponent(DefaultOptionRenderer, {
137
+ option,
138
+ get isSelected() {
139
+ return isSelected();
140
+ },
141
+ get highlightMatch() {
142
+ return props.highlightMatch;
143
+ }
144
+ });
145
+ },
146
+ get children() {
147
+ return props.renderOption(option, isSelected());
148
+ }
149
+ }));
150
+ web.effect((_p$) => {
151
+ var _v$3 = isSelected(), _v$4 = isDisabled(), _v$5 = `mcp-autocomplete-option ${isSelected() ? "mcp-autocomplete-option-selected" : ""} ${isDisabled() ? "mcp-autocomplete-option-disabled" : ""}`, _v$6 = isDisabled() ? "not-allowed" : "pointer", _v$7 = isSelected() ? "#eff6ff" : "transparent", _v$8 = isDisabled() ? "#9ca3af" : "#374151";
152
+ _v$3 !== _p$.e && web.setAttribute(_el$32, "aria-selected", _p$.e = _v$3);
153
+ _v$4 !== _p$.t && web.setAttribute(_el$32, "aria-disabled", _p$.t = _v$4);
154
+ _v$5 !== _p$.a && web.className(_el$32, _p$.a = _v$5);
155
+ _v$6 !== _p$.o && web.setStyleProperty(_el$32, "cursor", _p$.o = _v$6);
156
+ _v$7 !== _p$.i && web.setStyleProperty(_el$32, "background-color", _p$.i = _v$7);
157
+ _v$8 !== _p$.n && web.setStyleProperty(_el$32, "color", _p$.n = _v$8);
158
+ return _p$;
159
+ }, {
160
+ e: void 0,
161
+ t: void 0,
162
+ a: void 0,
163
+ o: void 0,
164
+ i: void 0,
165
+ n: void 0
166
+ });
167
+ web.runHydrationEvents();
168
+ return _el$32;
169
+ })();
170
+ }
171
+ }));
172
+ return _el$15;
173
+ }
174
+ }), _el$29, _co$6);
175
+ web.insert(_el$1, web.createComponent(solidJs.Show, {
176
+ get when() {
177
+ return web.memo(() => !!!props.isLoading)() && props.options.length > 0;
178
+ },
179
+ get children() {
180
+ var _el$16 = web.getNextElement(_tmpl$8), _el$17 = _el$16.firstChild, _el$18 = _el$17.nextSibling, _el$19 = _el$18.nextSibling, _el$20 = _el$19.nextSibling, _el$21 = _el$20.nextSibling, _el$22 = _el$21.nextSibling;
181
+ _el$22.nextSibling;
182
+ return _el$16;
183
+ }
184
+ }), _el$31, _co$7);
185
+ web.effect((_p$) => {
186
+ var _v$ = `mcp-autocomplete-dropdown ${props.class || ""}`, _v$2 = containerStyles();
187
+ _v$ !== _p$.e && web.className(_el$1, _p$.e = _v$);
188
+ _p$.t = web.style(_el$1, _v$2, _p$.t);
189
+ return _p$;
190
+ }, {
191
+ e: void 0,
192
+ t: void 0
193
+ });
194
+ return _el$1;
195
+ }
196
+ });
197
+ };
198
+ web.delegateEvents(["click"]);
199
+ exports.AutocompleteDropdown = AutocompleteDropdown;
200
+ exports.default = AutocompleteDropdown;
201
+ //# sourceMappingURL=AutocompleteDropdown.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AutocompleteDropdown.cjs","sources":["../../src/components/AutocompleteDropdown.tsx"],"sourcesContent":["/**\n * AutocompleteDropdown Component\n * Displays data-driven dropdown suggestions\n *\n * Sprint Autocomplete Feature\n */\n\nimport { Component, For, Show, createMemo, JSX } from 'solid-js'\nimport type { AutocompleteOption } from '../types'\n\n/**\n * Props for AutocompleteDropdown\n */\nexport interface AutocompleteDropdownProps {\n /**\n * Options to display\n */\n options: AutocompleteOption[]\n\n /**\n * Currently selected index\n */\n selectedIndex: number\n\n /**\n * Whether dropdown is visible\n */\n isOpen: boolean\n\n /**\n * Callback when option is selected\n */\n onSelect: (option: AutocompleteOption) => void\n\n /**\n * Callback when option is hovered\n */\n onHover?: (index: number) => void\n\n /**\n * Whether loading\n */\n isLoading?: boolean\n\n /**\n * Custom class\n */\n class?: string\n\n /**\n * Max height\n */\n maxHeight?: string\n\n /**\n * Empty state message\n */\n emptyMessage?: string\n\n /**\n * Loading message\n */\n loadingMessage?: string\n\n /**\n * Highlight matching text in options\n */\n highlightMatch?: string\n\n /**\n * Position (default: 'bottom')\n */\n position?: 'top' | 'bottom'\n\n /**\n * Custom option renderer\n */\n renderOption?: (option: AutocompleteOption, isSelected: boolean) => JSX.Element\n}\n\n/**\n * Highlight matching text\n */\nfunction highlightText(text: string, match?: string): JSX.Element {\n if (!match || !text) {\n return <>{text}</>\n }\n\n const lowerText = text.toLowerCase()\n const lowerMatch = match.toLowerCase()\n const startIndex = lowerText.indexOf(lowerMatch)\n\n if (startIndex === -1) {\n return <>{text}</>\n }\n\n const before = text.slice(0, startIndex)\n const matched = text.slice(startIndex, startIndex + match.length)\n const after = text.slice(startIndex + match.length)\n\n return (\n <>\n {before}\n <strong class=\"mcp-autocomplete-highlight\">{matched}</strong>\n {after}\n </>\n )\n}\n\n/**\n * Default option renderer\n */\nconst DefaultOptionRenderer: Component<{\n option: AutocompleteOption\n isSelected: boolean\n highlightMatch?: string\n}> = (props) => {\n const displayLabel = createMemo(() =>\n props.option.label || props.option.value\n )\n\n return (\n <div class=\"mcp-autocomplete-option-content\">\n <Show when={props.option.icon}>\n <span class=\"mcp-autocomplete-option-icon\">{props.option.icon}</span>\n </Show>\n <div class=\"mcp-autocomplete-option-text\">\n <span class=\"mcp-autocomplete-option-label\">\n {highlightText(displayLabel(), props.highlightMatch)}\n </span>\n <Show when={props.option.description}>\n <span class=\"mcp-autocomplete-option-description\">\n {props.option.description}\n </span>\n </Show>\n </div>\n </div>\n )\n}\n\n/**\n * AutocompleteDropdown Component\n */\nexport const AutocompleteDropdown: Component<AutocompleteDropdownProps> = (props) => {\n const positionStyles = createMemo((): JSX.CSSProperties => {\n if (props.position === 'top') {\n return {\n bottom: '100%',\n 'margin-bottom': '4px'\n }\n }\n return {\n top: '100%',\n 'margin-top': '4px'\n }\n })\n\n const containerStyles = createMemo((): JSX.CSSProperties => ({\n position: 'absolute',\n left: '0',\n right: '0',\n 'z-index': '50',\n 'background-color': '#ffffff',\n border: '1px solid #e5e7eb',\n 'border-radius': '6px',\n 'box-shadow': '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)',\n 'max-height': props.maxHeight || '240px',\n overflow: 'auto',\n ...positionStyles()\n }))\n\n return (\n <Show when={props.isOpen}>\n <div\n class={`mcp-autocomplete-dropdown ${props.class || ''}`}\n style={containerStyles()}\n role=\"listbox\"\n aria-label=\"Suggestions\"\n >\n {/* Loading state */}\n <Show when={props.isLoading}>\n <div\n class=\"mcp-autocomplete-loading\"\n style={{\n padding: '12px 16px',\n color: '#6b7280',\n 'font-size': '0.875rem',\n display: 'flex',\n 'align-items': 'center',\n gap: '8px'\n }}\n >\n <span\n style={{\n display: 'inline-block',\n width: '14px',\n height: '14px',\n border: '2px solid #e5e7eb',\n 'border-top-color': '#3b82f6',\n 'border-radius': '50%',\n animation: 'mcp-spin 0.6s linear infinite'\n }}\n />\n {props.loadingMessage || 'Loading...'}\n </div>\n </Show>\n\n {/* Empty state */}\n <Show when={!props.isLoading && props.options.length === 0}>\n <div\n class=\"mcp-autocomplete-empty\"\n style={{\n padding: '12px 16px',\n color: '#9ca3af',\n 'font-size': '0.875rem',\n 'text-align': 'center'\n }}\n >\n {props.emptyMessage || 'No suggestions found'}\n </div>\n </Show>\n\n {/* Options list */}\n <Show when={!props.isLoading && props.options.length > 0}>\n <ul\n class=\"mcp-autocomplete-options\"\n style={{ margin: '0', padding: '4px 0', 'list-style': 'none' }}\n >\n <For each={props.options}>\n {(option, index) => {\n const isSelected = () => index() === props.selectedIndex\n const isDisabled = () => option.disabled\n\n return (\n <li\n role=\"option\"\n aria-selected={isSelected()}\n aria-disabled={isDisabled()}\n class={`mcp-autocomplete-option ${isSelected() ? 'mcp-autocomplete-option-selected' : ''} ${isDisabled() ? 'mcp-autocomplete-option-disabled' : ''}`}\n style={{\n padding: '8px 16px',\n cursor: isDisabled() ? 'not-allowed' : 'pointer',\n 'background-color': isSelected() ? '#eff6ff' : 'transparent',\n color: isDisabled() ? '#9ca3af' : '#374151',\n 'font-size': '0.875rem',\n transition: 'background-color 150ms ease'\n }}\n onClick={() => {\n if (!isDisabled()) {\n props.onSelect(option)\n }\n }}\n onMouseEnter={() => {\n if (!isDisabled()) {\n props.onHover?.(index())\n }\n }}\n >\n <Show\n when={props.renderOption}\n fallback={\n <DefaultOptionRenderer\n option={option}\n isSelected={isSelected()}\n highlightMatch={props.highlightMatch}\n />\n }\n >\n {props.renderOption!(option, isSelected())}\n </Show>\n </li>\n )\n }}\n </For>\n </ul>\n </Show>\n\n {/* Footer hint */}\n <Show when={!props.isLoading && props.options.length > 0}>\n <div\n class=\"mcp-autocomplete-footer\"\n style={{\n padding: '6px 12px',\n 'border-top': '1px solid #e5e7eb',\n 'background-color': '#f9fafb',\n 'font-size': '0.75rem',\n color: '#6b7280'\n }}\n >\n <kbd style={{\n 'background-color': '#e5e7eb',\n padding: '1px 4px',\n 'border-radius': '2px',\n 'font-family': 'inherit',\n 'font-size': '0.7rem'\n }}>↑</kbd>\n {' '}\n <kbd style={{\n 'background-color': '#e5e7eb',\n padding: '1px 4px',\n 'border-radius': '2px',\n 'font-family': 'inherit',\n 'font-size': '0.7rem'\n }}>↓</kbd>\n {' to navigate, '}\n <kbd style={{\n 'background-color': '#e5e7eb',\n padding: '1px 4px',\n 'border-radius': '2px',\n 'font-family': 'inherit',\n 'font-size': '0.7rem'\n }}>Enter</kbd>\n {' to select, '}\n <kbd style={{\n 'background-color': '#e5e7eb',\n padding: '1px 4px',\n 'border-radius': '2px',\n 'font-family': 'inherit',\n 'font-size': '0.7rem'\n }}>Esc</kbd>\n {' to dismiss'}\n </div>\n </Show>\n </div>\n </Show>\n )\n}\n\nexport default AutocompleteDropdown\n"],"names":["highlightText","text","match","lowerText","toLowerCase","lowerMatch","startIndex","indexOf","before","slice","matched","length","after","_el$","_$getNextElement","_tmpl$","_$insert","DefaultOptionRenderer","props","displayLabel","createMemo","option","label","value","_el$2","_tmpl$4","_el$9","firstChild","_el$0","_co$2","_$getNextMarker","nextSibling","_el$4","_el$5","_el$7","_el$8","_co$","_$createComponent","Show","when","icon","children","_el$3","_tmpl$2","highlightMatch","description","_el$6","_tmpl$3","AutocompleteDropdown","positionStyles","position","bottom","top","containerStyles","left","right","border","maxHeight","overflow","isOpen","_el$1","_tmpl$9","_el$24","_el$25","_co$4","_el$26","_el$27","_co$5","_el$28","_el$29","_co$6","_el$30","_el$31","_co$7","isLoading","_el$10","_tmpl$5","_el$11","_el$12","_el$13","_co$3","loadingMessage","_$memo","options","_el$14","_tmpl$6","emptyMessage","_el$15","_tmpl$7","For","each","index","isSelected","selectedIndex","isDisabled","disabled","_el$32","_tmpl$0","addEventListener","onHover","$$click","onSelect","renderOption","fallback","_$effect","_p$","_v$3","_v$4","_v$5","_v$6","_v$7","_v$8","e","_$setAttribute","t","a","_$className","o","_$setStyleProperty","i","n","undefined","_$runHydrationEvents","_el$16","_tmpl$8","_el$17","_el$18","_el$19","_el$20","_el$21","_el$22","_v$","class","_v$2","_$style","_$delegateEvents"],"mappings":"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"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * AutocompleteDropdown Component
3
+ * Displays data-driven dropdown suggestions
4
+ *
5
+ * Sprint Autocomplete Feature
6
+ */
7
+ import { Component, JSX } from 'solid-js';
8
+ import type { AutocompleteOption } from '../types';
9
+ /**
10
+ * Props for AutocompleteDropdown
11
+ */
12
+ export interface AutocompleteDropdownProps {
13
+ /**
14
+ * Options to display
15
+ */
16
+ options: AutocompleteOption[];
17
+ /**
18
+ * Currently selected index
19
+ */
20
+ selectedIndex: number;
21
+ /**
22
+ * Whether dropdown is visible
23
+ */
24
+ isOpen: boolean;
25
+ /**
26
+ * Callback when option is selected
27
+ */
28
+ onSelect: (option: AutocompleteOption) => void;
29
+ /**
30
+ * Callback when option is hovered
31
+ */
32
+ onHover?: (index: number) => void;
33
+ /**
34
+ * Whether loading
35
+ */
36
+ isLoading?: boolean;
37
+ /**
38
+ * Custom class
39
+ */
40
+ class?: string;
41
+ /**
42
+ * Max height
43
+ */
44
+ maxHeight?: string;
45
+ /**
46
+ * Empty state message
47
+ */
48
+ emptyMessage?: string;
49
+ /**
50
+ * Loading message
51
+ */
52
+ loadingMessage?: string;
53
+ /**
54
+ * Highlight matching text in options
55
+ */
56
+ highlightMatch?: string;
57
+ /**
58
+ * Position (default: 'bottom')
59
+ */
60
+ position?: 'top' | 'bottom';
61
+ /**
62
+ * Custom option renderer
63
+ */
64
+ renderOption?: (option: AutocompleteOption, isSelected: boolean) => JSX.Element;
65
+ }
66
+ /**
67
+ * AutocompleteDropdown Component
68
+ */
69
+ export declare const AutocompleteDropdown: Component<AutocompleteDropdownProps>;
70
+ export default AutocompleteDropdown;
71
+ //# sourceMappingURL=AutocompleteDropdown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AutocompleteDropdown.d.ts","sourceRoot":"","sources":["../../src/components/AutocompleteDropdown.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAyB,GAAG,EAAE,MAAM,UAAU,CAAA;AAChE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAElD;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC;;OAEG;IACH,OAAO,EAAE,kBAAkB,EAAE,CAAA;IAE7B;;OAEG;IACH,aAAa,EAAE,MAAM,CAAA;IAErB;;OAEG;IACH,MAAM,EAAE,OAAO,CAAA;IAEf;;OAEG;IACH,QAAQ,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,IAAI,CAAA;IAE9C;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAEjC;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IAEnB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IAEd;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAElB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IAErB;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;IAEvB;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;IAEvB;;OAEG;IACH,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAA;IAE3B;;OAEG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,kBAAkB,EAAE,UAAU,EAAE,OAAO,KAAK,GAAG,CAAC,OAAO,CAAA;CAChF;AA8DD;;GAEG;AACH,eAAO,MAAM,oBAAoB,EAAE,SAAS,CAAC,yBAAyB,CAuLrE,CAAA;AAED,eAAe,oBAAoB,CAAA"}
@@ -0,0 +1,201 @@
1
+ import { delegateEvents, createComponent, getNextElement, template, getNextMarker, insert, memo, effect, setAttribute, className, setStyleProperty, runHydrationEvents, style } from "solid-js/web";
2
+ import { createMemo, Show, For } from "solid-js";
3
+ var _tmpl$ = /* @__PURE__ */ template(`<strong class=mcp-autocomplete-highlight>`), _tmpl$2 = /* @__PURE__ */ template(`<span class=mcp-autocomplete-option-icon>`), _tmpl$3 = /* @__PURE__ */ template(`<span class=mcp-autocomplete-option-description>`), _tmpl$4 = /* @__PURE__ */ template(`<div class=mcp-autocomplete-option-content><!$><!/><div class=mcp-autocomplete-option-text><span class=mcp-autocomplete-option-label></span><!$><!/>`), _tmpl$5 = /* @__PURE__ */ template(`<div class=mcp-autocomplete-loading style="padding:12px 16px;color:#6b7280;font-size:0.875rem;display:flex;align-items:center;gap:8px"><span style="display:inline-block;width:14px;height:14px;border:2px solid #e5e7eb;border-top-color:#3b82f6;border-radius:50%;animation:mcp-spin 0.6s linear infinite"></span><!$><!/>`), _tmpl$6 = /* @__PURE__ */ template(`<div class=mcp-autocomplete-empty style="padding:12px 16px;color:#9ca3af;font-size:0.875rem;text-align:center">`), _tmpl$7 = /* @__PURE__ */ template(`<ul class=mcp-autocomplete-options style="margin:0;padding:4px 0;list-style:none">`), _tmpl$8 = /* @__PURE__ */ template(`<div class=mcp-autocomplete-footer style="padding:6px 12px;border-top:1px solid #e5e7eb;background-color:#f9fafb;font-size:0.75rem;color:#6b7280"><kbd style="background-color:#e5e7eb;padding:1px 4px;border-radius:2px;font-family:inherit;font-size:0.7rem">↑</kbd> <kbd style="background-color:#e5e7eb;padding:1px 4px;border-radius:2px;font-family:inherit;font-size:0.7rem">↓</kbd> to navigate, <kbd style="background-color:#e5e7eb;padding:1px 4px;border-radius:2px;font-family:inherit;font-size:0.7rem">Enter</kbd> to select, <kbd style="background-color:#e5e7eb;padding:1px 4px;border-radius:2px;font-family:inherit;font-size:0.7rem">Esc</kbd> to dismiss`), _tmpl$9 = /* @__PURE__ */ template(`<div role=listbox aria-label=Suggestions><!$><!/><!$><!/><!$><!/><!$><!/>`), _tmpl$0 = /* @__PURE__ */ template(`<li role=option style="padding:8px 16px;font-size:0.875rem;transition:background-color 150ms ease">`);
4
+ function highlightText(text, match) {
5
+ if (!match || !text) {
6
+ return text;
7
+ }
8
+ const lowerText = text.toLowerCase();
9
+ const lowerMatch = match.toLowerCase();
10
+ const startIndex = lowerText.indexOf(lowerMatch);
11
+ if (startIndex === -1) {
12
+ return text;
13
+ }
14
+ const before = text.slice(0, startIndex);
15
+ const matched = text.slice(startIndex, startIndex + match.length);
16
+ const after = text.slice(startIndex + match.length);
17
+ return [before, (() => {
18
+ var _el$ = getNextElement(_tmpl$);
19
+ insert(_el$, matched);
20
+ return _el$;
21
+ })(), after];
22
+ }
23
+ const DefaultOptionRenderer = (props) => {
24
+ const displayLabel = createMemo(() => props.option.label || props.option.value);
25
+ return (() => {
26
+ var _el$2 = getNextElement(_tmpl$4), _el$9 = _el$2.firstChild, [_el$0, _co$2] = getNextMarker(_el$9.nextSibling), _el$4 = _el$0.nextSibling, _el$5 = _el$4.firstChild, _el$7 = _el$5.nextSibling, [_el$8, _co$] = getNextMarker(_el$7.nextSibling);
27
+ insert(_el$2, createComponent(Show, {
28
+ get when() {
29
+ return props.option.icon;
30
+ },
31
+ get children() {
32
+ var _el$3 = getNextElement(_tmpl$2);
33
+ insert(_el$3, () => props.option.icon);
34
+ return _el$3;
35
+ }
36
+ }), _el$0, _co$2);
37
+ insert(_el$5, () => highlightText(displayLabel(), props.highlightMatch));
38
+ insert(_el$4, createComponent(Show, {
39
+ get when() {
40
+ return props.option.description;
41
+ },
42
+ get children() {
43
+ var _el$6 = getNextElement(_tmpl$3);
44
+ insert(_el$6, () => props.option.description);
45
+ return _el$6;
46
+ }
47
+ }), _el$8, _co$);
48
+ return _el$2;
49
+ })();
50
+ };
51
+ const AutocompleteDropdown = (props) => {
52
+ const positionStyles = createMemo(() => {
53
+ if (props.position === "top") {
54
+ return {
55
+ bottom: "100%",
56
+ "margin-bottom": "4px"
57
+ };
58
+ }
59
+ return {
60
+ top: "100%",
61
+ "margin-top": "4px"
62
+ };
63
+ });
64
+ const containerStyles = createMemo(() => ({
65
+ position: "absolute",
66
+ left: "0",
67
+ right: "0",
68
+ "z-index": "50",
69
+ "background-color": "#ffffff",
70
+ border: "1px solid #e5e7eb",
71
+ "border-radius": "6px",
72
+ "box-shadow": "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)",
73
+ "max-height": props.maxHeight || "240px",
74
+ overflow: "auto",
75
+ ...positionStyles()
76
+ }));
77
+ return createComponent(Show, {
78
+ get when() {
79
+ return props.isOpen;
80
+ },
81
+ get children() {
82
+ var _el$1 = getNextElement(_tmpl$9), _el$24 = _el$1.firstChild, [_el$25, _co$4] = getNextMarker(_el$24.nextSibling), _el$26 = _el$25.nextSibling, [_el$27, _co$5] = getNextMarker(_el$26.nextSibling), _el$28 = _el$27.nextSibling, [_el$29, _co$6] = getNextMarker(_el$28.nextSibling), _el$30 = _el$29.nextSibling, [_el$31, _co$7] = getNextMarker(_el$30.nextSibling);
83
+ insert(_el$1, createComponent(Show, {
84
+ get when() {
85
+ return props.isLoading;
86
+ },
87
+ get children() {
88
+ var _el$10 = getNextElement(_tmpl$5), _el$11 = _el$10.firstChild, _el$12 = _el$11.nextSibling, [_el$13, _co$3] = getNextMarker(_el$12.nextSibling);
89
+ insert(_el$10, () => props.loadingMessage || "Loading...", _el$13, _co$3);
90
+ return _el$10;
91
+ }
92
+ }), _el$25, _co$4);
93
+ insert(_el$1, createComponent(Show, {
94
+ get when() {
95
+ return memo(() => !!!props.isLoading)() && props.options.length === 0;
96
+ },
97
+ get children() {
98
+ var _el$14 = getNextElement(_tmpl$6);
99
+ insert(_el$14, () => props.emptyMessage || "No suggestions found");
100
+ return _el$14;
101
+ }
102
+ }), _el$27, _co$5);
103
+ insert(_el$1, createComponent(Show, {
104
+ get when() {
105
+ return memo(() => !!!props.isLoading)() && props.options.length > 0;
106
+ },
107
+ get children() {
108
+ var _el$15 = getNextElement(_tmpl$7);
109
+ insert(_el$15, createComponent(For, {
110
+ get each() {
111
+ return props.options;
112
+ },
113
+ children: (option, index) => {
114
+ const isSelected = () => index() === props.selectedIndex;
115
+ const isDisabled = () => option.disabled;
116
+ return (() => {
117
+ var _el$32 = getNextElement(_tmpl$0);
118
+ _el$32.addEventListener("mouseenter", () => {
119
+ var _a;
120
+ if (!isDisabled()) {
121
+ (_a = props.onHover) == null ? void 0 : _a.call(props, index());
122
+ }
123
+ });
124
+ _el$32.$$click = () => {
125
+ if (!isDisabled()) {
126
+ props.onSelect(option);
127
+ }
128
+ };
129
+ insert(_el$32, createComponent(Show, {
130
+ get when() {
131
+ return props.renderOption;
132
+ },
133
+ get fallback() {
134
+ return createComponent(DefaultOptionRenderer, {
135
+ option,
136
+ get isSelected() {
137
+ return isSelected();
138
+ },
139
+ get highlightMatch() {
140
+ return props.highlightMatch;
141
+ }
142
+ });
143
+ },
144
+ get children() {
145
+ return props.renderOption(option, isSelected());
146
+ }
147
+ }));
148
+ effect((_p$) => {
149
+ var _v$3 = isSelected(), _v$4 = isDisabled(), _v$5 = `mcp-autocomplete-option ${isSelected() ? "mcp-autocomplete-option-selected" : ""} ${isDisabled() ? "mcp-autocomplete-option-disabled" : ""}`, _v$6 = isDisabled() ? "not-allowed" : "pointer", _v$7 = isSelected() ? "#eff6ff" : "transparent", _v$8 = isDisabled() ? "#9ca3af" : "#374151";
150
+ _v$3 !== _p$.e && setAttribute(_el$32, "aria-selected", _p$.e = _v$3);
151
+ _v$4 !== _p$.t && setAttribute(_el$32, "aria-disabled", _p$.t = _v$4);
152
+ _v$5 !== _p$.a && className(_el$32, _p$.a = _v$5);
153
+ _v$6 !== _p$.o && setStyleProperty(_el$32, "cursor", _p$.o = _v$6);
154
+ _v$7 !== _p$.i && setStyleProperty(_el$32, "background-color", _p$.i = _v$7);
155
+ _v$8 !== _p$.n && setStyleProperty(_el$32, "color", _p$.n = _v$8);
156
+ return _p$;
157
+ }, {
158
+ e: void 0,
159
+ t: void 0,
160
+ a: void 0,
161
+ o: void 0,
162
+ i: void 0,
163
+ n: void 0
164
+ });
165
+ runHydrationEvents();
166
+ return _el$32;
167
+ })();
168
+ }
169
+ }));
170
+ return _el$15;
171
+ }
172
+ }), _el$29, _co$6);
173
+ insert(_el$1, createComponent(Show, {
174
+ get when() {
175
+ return memo(() => !!!props.isLoading)() && props.options.length > 0;
176
+ },
177
+ get children() {
178
+ var _el$16 = getNextElement(_tmpl$8), _el$17 = _el$16.firstChild, _el$18 = _el$17.nextSibling, _el$19 = _el$18.nextSibling, _el$20 = _el$19.nextSibling, _el$21 = _el$20.nextSibling, _el$22 = _el$21.nextSibling;
179
+ _el$22.nextSibling;
180
+ return _el$16;
181
+ }
182
+ }), _el$31, _co$7);
183
+ effect((_p$) => {
184
+ var _v$ = `mcp-autocomplete-dropdown ${props.class || ""}`, _v$2 = containerStyles();
185
+ _v$ !== _p$.e && className(_el$1, _p$.e = _v$);
186
+ _p$.t = style(_el$1, _v$2, _p$.t);
187
+ return _p$;
188
+ }, {
189
+ e: void 0,
190
+ t: void 0
191
+ });
192
+ return _el$1;
193
+ }
194
+ });
195
+ };
196
+ delegateEvents(["click"]);
197
+ export {
198
+ AutocompleteDropdown,
199
+ AutocompleteDropdown as default
200
+ };
201
+ //# sourceMappingURL=AutocompleteDropdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AutocompleteDropdown.js","sources":["../../src/components/AutocompleteDropdown.tsx"],"sourcesContent":["/**\n * AutocompleteDropdown Component\n * Displays data-driven dropdown suggestions\n *\n * Sprint Autocomplete Feature\n */\n\nimport { Component, For, Show, createMemo, JSX } from 'solid-js'\nimport type { AutocompleteOption } from '../types'\n\n/**\n * Props for AutocompleteDropdown\n */\nexport interface AutocompleteDropdownProps {\n /**\n * Options to display\n */\n options: AutocompleteOption[]\n\n /**\n * Currently selected index\n */\n selectedIndex: number\n\n /**\n * Whether dropdown is visible\n */\n isOpen: boolean\n\n /**\n * Callback when option is selected\n */\n onSelect: (option: AutocompleteOption) => void\n\n /**\n * Callback when option is hovered\n */\n onHover?: (index: number) => void\n\n /**\n * Whether loading\n */\n isLoading?: boolean\n\n /**\n * Custom class\n */\n class?: string\n\n /**\n * Max height\n */\n maxHeight?: string\n\n /**\n * Empty state message\n */\n emptyMessage?: string\n\n /**\n * Loading message\n */\n loadingMessage?: string\n\n /**\n * Highlight matching text in options\n */\n highlightMatch?: string\n\n /**\n * Position (default: 'bottom')\n */\n position?: 'top' | 'bottom'\n\n /**\n * Custom option renderer\n */\n renderOption?: (option: AutocompleteOption, isSelected: boolean) => JSX.Element\n}\n\n/**\n * Highlight matching text\n */\nfunction highlightText(text: string, match?: string): JSX.Element {\n if (!match || !text) {\n return <>{text}</>\n }\n\n const lowerText = text.toLowerCase()\n const lowerMatch = match.toLowerCase()\n const startIndex = lowerText.indexOf(lowerMatch)\n\n if (startIndex === -1) {\n return <>{text}</>\n }\n\n const before = text.slice(0, startIndex)\n const matched = text.slice(startIndex, startIndex + match.length)\n const after = text.slice(startIndex + match.length)\n\n return (\n <>\n {before}\n <strong class=\"mcp-autocomplete-highlight\">{matched}</strong>\n {after}\n </>\n )\n}\n\n/**\n * Default option renderer\n */\nconst DefaultOptionRenderer: Component<{\n option: AutocompleteOption\n isSelected: boolean\n highlightMatch?: string\n}> = (props) => {\n const displayLabel = createMemo(() =>\n props.option.label || props.option.value\n )\n\n return (\n <div class=\"mcp-autocomplete-option-content\">\n <Show when={props.option.icon}>\n <span class=\"mcp-autocomplete-option-icon\">{props.option.icon}</span>\n </Show>\n <div class=\"mcp-autocomplete-option-text\">\n <span class=\"mcp-autocomplete-option-label\">\n {highlightText(displayLabel(), props.highlightMatch)}\n </span>\n <Show when={props.option.description}>\n <span class=\"mcp-autocomplete-option-description\">\n {props.option.description}\n </span>\n </Show>\n </div>\n </div>\n )\n}\n\n/**\n * AutocompleteDropdown Component\n */\nexport const AutocompleteDropdown: Component<AutocompleteDropdownProps> = (props) => {\n const positionStyles = createMemo((): JSX.CSSProperties => {\n if (props.position === 'top') {\n return {\n bottom: '100%',\n 'margin-bottom': '4px'\n }\n }\n return {\n top: '100%',\n 'margin-top': '4px'\n }\n })\n\n const containerStyles = createMemo((): JSX.CSSProperties => ({\n position: 'absolute',\n left: '0',\n right: '0',\n 'z-index': '50',\n 'background-color': '#ffffff',\n border: '1px solid #e5e7eb',\n 'border-radius': '6px',\n 'box-shadow': '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)',\n 'max-height': props.maxHeight || '240px',\n overflow: 'auto',\n ...positionStyles()\n }))\n\n return (\n <Show when={props.isOpen}>\n <div\n class={`mcp-autocomplete-dropdown ${props.class || ''}`}\n style={containerStyles()}\n role=\"listbox\"\n aria-label=\"Suggestions\"\n >\n {/* Loading state */}\n <Show when={props.isLoading}>\n <div\n class=\"mcp-autocomplete-loading\"\n style={{\n padding: '12px 16px',\n color: '#6b7280',\n 'font-size': '0.875rem',\n display: 'flex',\n 'align-items': 'center',\n gap: '8px'\n }}\n >\n <span\n style={{\n display: 'inline-block',\n width: '14px',\n height: '14px',\n border: '2px solid #e5e7eb',\n 'border-top-color': '#3b82f6',\n 'border-radius': '50%',\n animation: 'mcp-spin 0.6s linear infinite'\n }}\n />\n {props.loadingMessage || 'Loading...'}\n </div>\n </Show>\n\n {/* Empty state */}\n <Show when={!props.isLoading && props.options.length === 0}>\n <div\n class=\"mcp-autocomplete-empty\"\n style={{\n padding: '12px 16px',\n color: '#9ca3af',\n 'font-size': '0.875rem',\n 'text-align': 'center'\n }}\n >\n {props.emptyMessage || 'No suggestions found'}\n </div>\n </Show>\n\n {/* Options list */}\n <Show when={!props.isLoading && props.options.length > 0}>\n <ul\n class=\"mcp-autocomplete-options\"\n style={{ margin: '0', padding: '4px 0', 'list-style': 'none' }}\n >\n <For each={props.options}>\n {(option, index) => {\n const isSelected = () => index() === props.selectedIndex\n const isDisabled = () => option.disabled\n\n return (\n <li\n role=\"option\"\n aria-selected={isSelected()}\n aria-disabled={isDisabled()}\n class={`mcp-autocomplete-option ${isSelected() ? 'mcp-autocomplete-option-selected' : ''} ${isDisabled() ? 'mcp-autocomplete-option-disabled' : ''}`}\n style={{\n padding: '8px 16px',\n cursor: isDisabled() ? 'not-allowed' : 'pointer',\n 'background-color': isSelected() ? '#eff6ff' : 'transparent',\n color: isDisabled() ? '#9ca3af' : '#374151',\n 'font-size': '0.875rem',\n transition: 'background-color 150ms ease'\n }}\n onClick={() => {\n if (!isDisabled()) {\n props.onSelect(option)\n }\n }}\n onMouseEnter={() => {\n if (!isDisabled()) {\n props.onHover?.(index())\n }\n }}\n >\n <Show\n when={props.renderOption}\n fallback={\n <DefaultOptionRenderer\n option={option}\n isSelected={isSelected()}\n highlightMatch={props.highlightMatch}\n />\n }\n >\n {props.renderOption!(option, isSelected())}\n </Show>\n </li>\n )\n }}\n </For>\n </ul>\n </Show>\n\n {/* Footer hint */}\n <Show when={!props.isLoading && props.options.length > 0}>\n <div\n class=\"mcp-autocomplete-footer\"\n style={{\n padding: '6px 12px',\n 'border-top': '1px solid #e5e7eb',\n 'background-color': '#f9fafb',\n 'font-size': '0.75rem',\n color: '#6b7280'\n }}\n >\n <kbd style={{\n 'background-color': '#e5e7eb',\n padding: '1px 4px',\n 'border-radius': '2px',\n 'font-family': 'inherit',\n 'font-size': '0.7rem'\n }}>↑</kbd>\n {' '}\n <kbd style={{\n 'background-color': '#e5e7eb',\n padding: '1px 4px',\n 'border-radius': '2px',\n 'font-family': 'inherit',\n 'font-size': '0.7rem'\n }}>↓</kbd>\n {' to navigate, '}\n <kbd style={{\n 'background-color': '#e5e7eb',\n padding: '1px 4px',\n 'border-radius': '2px',\n 'font-family': 'inherit',\n 'font-size': '0.7rem'\n }}>Enter</kbd>\n {' to select, '}\n <kbd style={{\n 'background-color': '#e5e7eb',\n padding: '1px 4px',\n 'border-radius': '2px',\n 'font-family': 'inherit',\n 'font-size': '0.7rem'\n }}>Esc</kbd>\n {' to dismiss'}\n </div>\n </Show>\n </div>\n </Show>\n )\n}\n\nexport default AutocompleteDropdown\n"],"names":["highlightText","text","match","lowerText","toLowerCase","lowerMatch","startIndex","indexOf","before","slice","matched","length","after","_el$","_$getNextElement","_tmpl$","_$insert","DefaultOptionRenderer","props","displayLabel","createMemo","option","label","value","_el$2","_tmpl$4","_el$9","firstChild","_el$0","_co$2","_$getNextMarker","nextSibling","_el$4","_el$5","_el$7","_el$8","_co$","_$createComponent","Show","when","icon","children","_el$3","_tmpl$2","highlightMatch","description","_el$6","_tmpl$3","AutocompleteDropdown","positionStyles","position","bottom","top","containerStyles","left","right","border","maxHeight","overflow","isOpen","_el$1","_tmpl$9","_el$24","_el$25","_co$4","_el$26","_el$27","_co$5","_el$28","_el$29","_co$6","_el$30","_el$31","_co$7","isLoading","_el$10","_tmpl$5","_el$11","_el$12","_el$13","_co$3","loadingMessage","_$memo","options","_el$14","_tmpl$6","emptyMessage","_el$15","_tmpl$7","For","each","index","isSelected","selectedIndex","isDisabled","disabled","_el$32","_tmpl$0","addEventListener","onHover","$$click","onSelect","renderOption","fallback","_$effect","_p$","_v$3","_v$4","_v$5","_v$6","_v$7","_v$8","e","_$setAttribute","t","a","_$className","o","_$setStyleProperty","i","n","undefined","_$runHydrationEvents","_el$16","_tmpl$8","_el$17","_el$18","_el$19","_el$20","_el$21","_el$22","_v$","class","_v$2","_$style","_$delegateEvents"],"mappings":"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"}