@seed-ship/mcp-ui-solid 2.0.1 → 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 (133) hide show
  1. package/dist/components/AutocompleteDropdown.cjs +201 -0
  2. package/dist/components/AutocompleteDropdown.cjs.map +1 -0
  3. package/dist/components/AutocompleteDropdown.d.ts +71 -0
  4. package/dist/components/AutocompleteDropdown.d.ts.map +1 -0
  5. package/dist/components/AutocompleteDropdown.js +201 -0
  6. package/dist/components/AutocompleteDropdown.js.map +1 -0
  7. package/dist/components/AutocompleteFormField.cjs +289 -0
  8. package/dist/components/AutocompleteFormField.cjs.map +1 -0
  9. package/dist/components/AutocompleteFormField.d.ts +52 -0
  10. package/dist/components/AutocompleteFormField.d.ts.map +1 -0
  11. package/dist/components/AutocompleteFormField.js +289 -0
  12. package/dist/components/AutocompleteFormField.js.map +1 -0
  13. package/dist/components/DraggableGridItem.cjs +133 -0
  14. package/dist/components/DraggableGridItem.cjs.map +1 -0
  15. package/dist/components/DraggableGridItem.d.ts +95 -0
  16. package/dist/components/DraggableGridItem.d.ts.map +1 -0
  17. package/dist/components/DraggableGridItem.js +133 -0
  18. package/dist/components/DraggableGridItem.js.map +1 -0
  19. package/dist/components/EditableUIResourceRenderer.cjs +203 -0
  20. package/dist/components/EditableUIResourceRenderer.cjs.map +1 -0
  21. package/dist/components/EditableUIResourceRenderer.d.ts +43 -0
  22. package/dist/components/EditableUIResourceRenderer.d.ts.map +1 -0
  23. package/dist/components/EditableUIResourceRenderer.js +203 -0
  24. package/dist/components/EditableUIResourceRenderer.js.map +1 -0
  25. package/dist/components/GhostText.cjs +105 -0
  26. package/dist/components/GhostText.cjs.map +1 -0
  27. package/dist/components/GhostText.d.ts +113 -0
  28. package/dist/components/GhostText.d.ts.map +1 -0
  29. package/dist/components/GhostText.js +105 -0
  30. package/dist/components/GhostText.js.map +1 -0
  31. package/dist/components/ResizeHandle.cjs +173 -0
  32. package/dist/components/ResizeHandle.cjs.map +1 -0
  33. package/dist/components/ResizeHandle.d.ts +50 -0
  34. package/dist/components/ResizeHandle.d.ts.map +1 -0
  35. package/dist/components/ResizeHandle.js +173 -0
  36. package/dist/components/ResizeHandle.js.map +1 -0
  37. package/dist/context/AutocompleteContext.cjs +158 -0
  38. package/dist/context/AutocompleteContext.cjs.map +1 -0
  39. package/dist/context/AutocompleteContext.d.ts +77 -0
  40. package/dist/context/AutocompleteContext.d.ts.map +1 -0
  41. package/dist/context/AutocompleteContext.js +158 -0
  42. package/dist/context/AutocompleteContext.js.map +1 -0
  43. package/dist/hooks/index.d.ts +6 -0
  44. package/dist/hooks/index.d.ts.map +1 -1
  45. package/dist/hooks/useAutocomplete.cjs +234 -0
  46. package/dist/hooks/useAutocomplete.cjs.map +1 -0
  47. package/dist/hooks/useAutocomplete.d.ts +119 -0
  48. package/dist/hooks/useAutocomplete.d.ts.map +1 -0
  49. package/dist/hooks/useAutocomplete.js +234 -0
  50. package/dist/hooks/useAutocomplete.js.map +1 -0
  51. package/dist/hooks/useDragDrop.cjs +170 -0
  52. package/dist/hooks/useDragDrop.cjs.map +1 -0
  53. package/dist/hooks/useDragDrop.d.ts +100 -0
  54. package/dist/hooks/useDragDrop.d.ts.map +1 -0
  55. package/dist/hooks/useDragDrop.js +170 -0
  56. package/dist/hooks/useDragDrop.js.map +1 -0
  57. package/dist/hooks/useResize.cjs +209 -0
  58. package/dist/hooks/useResize.cjs.map +1 -0
  59. package/dist/hooks/useResize.d.ts +87 -0
  60. package/dist/hooks/useResize.d.ts.map +1 -0
  61. package/dist/hooks/useResize.js +209 -0
  62. package/dist/hooks/useResize.js.map +1 -0
  63. package/dist/hooks.cjs +6 -0
  64. package/dist/hooks.cjs.map +1 -1
  65. package/dist/hooks.d.cts +6 -0
  66. package/dist/hooks.d.ts +6 -0
  67. package/dist/hooks.js +6 -0
  68. package/dist/hooks.js.map +1 -1
  69. package/dist/index.cjs +29 -0
  70. package/dist/index.cjs.map +1 -1
  71. package/dist/index.d.cts +18 -3
  72. package/dist/index.d.ts +18 -3
  73. package/dist/index.d.ts.map +1 -1
  74. package/dist/index.js +29 -0
  75. package/dist/index.js.map +1 -1
  76. package/dist/plugins/duckdb.cjs +192 -0
  77. package/dist/plugins/duckdb.cjs.map +1 -0
  78. package/dist/plugins/duckdb.d.ts +20 -0
  79. package/dist/plugins/duckdb.d.ts.map +1 -0
  80. package/dist/plugins/duckdb.js +170 -0
  81. package/dist/plugins/duckdb.js.map +1 -0
  82. package/dist/plugins/groq.cjs +97 -0
  83. package/dist/plugins/groq.cjs.map +1 -0
  84. package/dist/plugins/groq.d.ts +13 -0
  85. package/dist/plugins/groq.d.ts.map +1 -0
  86. package/dist/plugins/groq.js +97 -0
  87. package/dist/plugins/groq.js.map +1 -0
  88. package/dist/plugins/index.d.ts +10 -0
  89. package/dist/plugins/index.d.ts.map +1 -0
  90. package/dist/plugins/rest.cjs +92 -0
  91. package/dist/plugins/rest.cjs.map +1 -0
  92. package/dist/plugins/rest.d.ts +13 -0
  93. package/dist/plugins/rest.d.ts.map +1 -0
  94. package/dist/plugins/rest.js +92 -0
  95. package/dist/plugins/rest.js.map +1 -0
  96. package/dist/plugins/supabase.cjs +79 -0
  97. package/dist/plugins/supabase.cjs.map +1 -0
  98. package/dist/plugins/supabase.d.ts +13 -0
  99. package/dist/plugins/supabase.d.ts.map +1 -0
  100. package/dist/plugins/supabase.js +79 -0
  101. package/dist/plugins/supabase.js.map +1 -0
  102. package/dist/types/index.d.ts +430 -0
  103. package/dist/types/index.d.ts.map +1 -1
  104. package/dist/types.d.cts +430 -0
  105. package/dist/types.d.ts +430 -0
  106. package/package.json +16 -1
  107. package/src/components/AutocompleteDropdown.tsx +329 -0
  108. package/src/components/AutocompleteFormField.tsx +288 -0
  109. package/src/components/DraggableGridItem.tsx +274 -0
  110. package/src/components/EditableUIResourceRenderer.tsx +273 -0
  111. package/src/components/GhostText.tsx +262 -0
  112. package/src/components/ResizeHandle.tsx +262 -0
  113. package/src/context/AutocompleteContext.tsx +317 -0
  114. package/src/hooks/index.ts +23 -0
  115. package/src/hooks/useAutocomplete.test.ts +334 -0
  116. package/src/hooks/useAutocomplete.ts +466 -0
  117. package/src/hooks/useDragDrop.test.ts +355 -0
  118. package/src/hooks/useDragDrop.ts +379 -0
  119. package/src/hooks/useResize.test.ts +313 -0
  120. package/src/hooks/useResize.ts +372 -0
  121. package/src/index.ts +71 -0
  122. package/src/plugins/duckdb.ts +269 -0
  123. package/src/plugins/groq.ts +137 -0
  124. package/src/plugins/index.ts +14 -0
  125. package/src/plugins/rest.ts +147 -0
  126. package/src/plugins/supabase.ts +120 -0
  127. package/src/styles/autocomplete.css +356 -0
  128. package/src/styles/drag-drop.css +297 -0
  129. package/src/styles/index.css +7 -0
  130. package/src/types/index.ts +529 -0
  131. package/src/vite-env.d.ts +18 -0
  132. package/tsconfig.tsbuildinfo +1 -1
  133. package/vite.config.ts +2 -0
@@ -0,0 +1,262 @@
1
+ /**
2
+ * GhostText Component
3
+ * Displays LLM-style ghost text completion overlay
4
+ *
5
+ * Sprint Autocomplete Feature
6
+ */
7
+
8
+ import { Component, Show, JSX, createMemo } from 'solid-js'
9
+
10
+ /**
11
+ * Props for GhostText component
12
+ */
13
+ export interface GhostTextProps {
14
+ /**
15
+ * Current input value
16
+ */
17
+ inputValue: string
18
+
19
+ /**
20
+ * Ghost text to show (the completion after input)
21
+ */
22
+ ghostText: string
23
+
24
+ /**
25
+ * Whether ghost text is visible
26
+ */
27
+ visible?: boolean
28
+
29
+ /**
30
+ * Custom class for the container
31
+ */
32
+ class?: string
33
+
34
+ /**
35
+ * Custom class for the ghost text
36
+ */
37
+ ghostClass?: string
38
+
39
+ /**
40
+ * Accept hint text (e.g., "Tab to accept")
41
+ */
42
+ hintText?: string
43
+
44
+ /**
45
+ * Whether loading
46
+ */
47
+ isLoading?: boolean
48
+ }
49
+
50
+ /**
51
+ * GhostText Component
52
+ * Overlays ghost text on an input field to show completion suggestions
53
+ */
54
+ export const GhostText: Component<GhostTextProps> = (props) => {
55
+ const shouldShow = createMemo(() =>
56
+ props.visible !== false && props.ghostText && props.ghostText.length > 0
57
+ )
58
+
59
+ return (
60
+ <div
61
+ class={`mcp-ghost-text-container ${props.class || ''}`}
62
+ style={{
63
+ position: 'relative',
64
+ display: 'inline-block',
65
+ width: '100%'
66
+ }}
67
+ >
68
+ {/* Ghost text overlay */}
69
+ <Show when={shouldShow()}>
70
+ <div
71
+ class="mcp-ghost-text-overlay"
72
+ style={{
73
+ position: 'absolute',
74
+ top: '0',
75
+ left: '0',
76
+ right: '0',
77
+ bottom: '0',
78
+ 'pointer-events': 'none',
79
+ overflow: 'hidden',
80
+ 'white-space': 'pre',
81
+ padding: 'inherit',
82
+ font: 'inherit',
83
+ 'line-height': 'inherit',
84
+ 'letter-spacing': 'inherit'
85
+ }}
86
+ aria-hidden="true"
87
+ >
88
+ {/* Invisible placeholder for input text */}
89
+ <span style={{ visibility: 'hidden' }}>{props.inputValue}</span>
90
+ {/* Visible ghost text */}
91
+ <span
92
+ class={`mcp-ghost-text ${props.ghostClass || ''}`}
93
+ style={{
94
+ color: '#9ca3af',
95
+ opacity: '0.7'
96
+ }}
97
+ >
98
+ {props.ghostText}
99
+ </span>
100
+ </div>
101
+ </Show>
102
+
103
+ {/* Hint text */}
104
+ <Show when={shouldShow() && props.hintText}>
105
+ <div
106
+ class="mcp-ghost-text-hint"
107
+ style={{
108
+ position: 'absolute',
109
+ right: '8px',
110
+ top: '50%',
111
+ transform: 'translateY(-50%)',
112
+ 'font-size': '0.75rem',
113
+ color: '#6b7280',
114
+ 'background-color': 'rgba(255, 255, 255, 0.9)',
115
+ padding: '2px 6px',
116
+ 'border-radius': '4px',
117
+ 'pointer-events': 'none'
118
+ }}
119
+ >
120
+ {props.hintText}
121
+ </div>
122
+ </Show>
123
+
124
+ {/* Loading indicator */}
125
+ <Show when={props.isLoading}>
126
+ <div
127
+ class="mcp-ghost-text-loading"
128
+ style={{
129
+ position: 'absolute',
130
+ right: '8px',
131
+ top: '50%',
132
+ transform: 'translateY(-50%)'
133
+ }}
134
+ >
135
+ <span
136
+ style={{
137
+ display: 'inline-block',
138
+ width: '12px',
139
+ height: '12px',
140
+ border: '2px solid #e5e7eb',
141
+ 'border-top-color': '#3b82f6',
142
+ 'border-radius': '50%',
143
+ animation: 'mcp-spin 0.6s linear infinite'
144
+ }}
145
+ />
146
+ </div>
147
+ </Show>
148
+ </div>
149
+ )
150
+ }
151
+
152
+ /**
153
+ * Input wrapper that includes ghost text functionality
154
+ */
155
+ export interface GhostTextInputProps {
156
+ /**
157
+ * Current input value
158
+ */
159
+ value: string
160
+
161
+ /**
162
+ * Ghost text to show
163
+ */
164
+ ghostText: string
165
+
166
+ /**
167
+ * onChange handler
168
+ */
169
+ onInput?: (value: string) => void
170
+
171
+ /**
172
+ * onKeyDown handler
173
+ */
174
+ onKeyDown?: (e: KeyboardEvent) => void
175
+
176
+ /**
177
+ * Placeholder text
178
+ */
179
+ placeholder?: string
180
+
181
+ /**
182
+ * Input type
183
+ */
184
+ type?: 'text' | 'email' | 'search'
185
+
186
+ /**
187
+ * Whether input is disabled
188
+ */
189
+ disabled?: boolean
190
+
191
+ /**
192
+ * Input name
193
+ */
194
+ name?: string
195
+
196
+ /**
197
+ * Input ID
198
+ */
199
+ id?: string
200
+
201
+ /**
202
+ * Custom class for input
203
+ */
204
+ class?: string
205
+
206
+ /**
207
+ * Accept hint
208
+ */
209
+ hintText?: string
210
+
211
+ /**
212
+ * Whether loading
213
+ */
214
+ isLoading?: boolean
215
+
216
+ /**
217
+ * Whether ghost text is visible
218
+ */
219
+ showGhost?: boolean
220
+
221
+ /**
222
+ * Additional input attributes
223
+ */
224
+ inputProps?: JSX.InputHTMLAttributes<HTMLInputElement>
225
+ }
226
+
227
+ /**
228
+ * GhostTextInput Component
229
+ * Input field with integrated ghost text overlay
230
+ */
231
+ export const GhostTextInput: Component<GhostTextInputProps> = (props) => {
232
+ return (
233
+ <div class="mcp-ghost-text-input-wrapper" style={{ position: 'relative' }}>
234
+ <GhostText
235
+ inputValue={props.value}
236
+ ghostText={props.ghostText}
237
+ visible={props.showGhost}
238
+ hintText={props.hintText}
239
+ isLoading={props.isLoading}
240
+ />
241
+ <input
242
+ type={props.type || 'text'}
243
+ id={props.id}
244
+ name={props.name}
245
+ value={props.value}
246
+ placeholder={props.placeholder}
247
+ disabled={props.disabled}
248
+ class={`mcp-ghost-text-input ${props.class || ''}`}
249
+ style={{
250
+ position: 'relative',
251
+ 'background-color': 'transparent',
252
+ 'caret-color': 'inherit'
253
+ }}
254
+ onInput={(e) => props.onInput?.(e.currentTarget.value)}
255
+ onKeyDown={(e) => props.onKeyDown?.(e)}
256
+ {...(props.inputProps || {})}
257
+ />
258
+ </div>
259
+ )
260
+ }
261
+
262
+ export default GhostText
@@ -0,0 +1,262 @@
1
+ /**
2
+ * ResizeHandle Component
3
+ * Visual handle for resizing grid components
4
+ *
5
+ * Sprint Drag-Drop Feature
6
+ */
7
+
8
+ import { Component, JSX, createMemo, mergeProps } from 'solid-js'
9
+
10
+ /**
11
+ * Resize edge types
12
+ */
13
+ export type ResizeEdge = 'left' | 'right' | 'top' | 'bottom'
14
+
15
+ /**
16
+ * Props for ResizeHandle
17
+ */
18
+ export interface ResizeHandleProps {
19
+ /**
20
+ * Which edge this handle is on
21
+ */
22
+ edge: ResizeEdge
23
+
24
+ /**
25
+ * Callback when resize starts
26
+ */
27
+ onResizeStart?: (edge: ResizeEdge) => void
28
+
29
+ /**
30
+ * Whether the handle is disabled
31
+ */
32
+ disabled?: boolean
33
+
34
+ /**
35
+ * Whether resize is active
36
+ */
37
+ isActive?: boolean
38
+
39
+ /**
40
+ * Custom class
41
+ */
42
+ class?: string
43
+
44
+ /**
45
+ * Handle size in pixels
46
+ */
47
+ size?: number
48
+
49
+ /**
50
+ * Hit area size in pixels (larger than visible size for easier grabbing)
51
+ */
52
+ hitAreaSize?: number
53
+ }
54
+
55
+ /**
56
+ * Get cursor style for edge
57
+ */
58
+ function getCursor(edge: ResizeEdge): string {
59
+ switch (edge) {
60
+ case 'left':
61
+ case 'right':
62
+ return 'ew-resize'
63
+ case 'top':
64
+ case 'bottom':
65
+ return 'ns-resize'
66
+ default:
67
+ return 'default'
68
+ }
69
+ }
70
+
71
+ /**
72
+ * Get position styles for edge
73
+ */
74
+ function getPositionStyle(
75
+ edge: ResizeEdge,
76
+ hitAreaSize: number
77
+ ): JSX.CSSProperties {
78
+ const halfSize = hitAreaSize / 2
79
+
80
+ switch (edge) {
81
+ case 'left':
82
+ return {
83
+ left: `-${halfSize}px`,
84
+ top: '0',
85
+ width: `${hitAreaSize}px`,
86
+ height: '100%'
87
+ }
88
+ case 'right':
89
+ return {
90
+ right: `-${halfSize}px`,
91
+ top: '0',
92
+ width: `${hitAreaSize}px`,
93
+ height: '100%'
94
+ }
95
+ case 'top':
96
+ return {
97
+ top: `-${halfSize}px`,
98
+ left: '0',
99
+ width: '100%',
100
+ height: `${hitAreaSize}px`
101
+ }
102
+ case 'bottom':
103
+ return {
104
+ bottom: `-${halfSize}px`,
105
+ left: '0',
106
+ width: '100%',
107
+ height: `${hitAreaSize}px`
108
+ }
109
+ default:
110
+ return {}
111
+ }
112
+ }
113
+
114
+ /**
115
+ * Get visual indicator styles for edge
116
+ */
117
+ function getIndicatorStyle(
118
+ edge: ResizeEdge,
119
+ size: number,
120
+ isActive: boolean
121
+ ): JSX.CSSProperties {
122
+ const baseColor = isActive ? '#3b82f6' : '#9ca3af'
123
+
124
+ const common: JSX.CSSProperties = {
125
+ position: 'absolute',
126
+ 'background-color': baseColor,
127
+ 'border-radius': `${size / 2}px`,
128
+ transition: 'background-color 150ms ease, opacity 150ms ease',
129
+ opacity: isActive ? '1' : '0'
130
+ }
131
+
132
+ switch (edge) {
133
+ case 'left':
134
+ return {
135
+ ...common,
136
+ left: '50%',
137
+ top: '50%',
138
+ transform: 'translate(-50%, -50%)',
139
+ width: `${size}px`,
140
+ height: '40px',
141
+ 'max-height': '60%'
142
+ }
143
+ case 'right':
144
+ return {
145
+ ...common,
146
+ right: '50%',
147
+ top: '50%',
148
+ transform: 'translate(50%, -50%)',
149
+ width: `${size}px`,
150
+ height: '40px',
151
+ 'max-height': '60%'
152
+ }
153
+ case 'top':
154
+ return {
155
+ ...common,
156
+ top: '50%',
157
+ left: '50%',
158
+ transform: 'translate(-50%, -50%)',
159
+ width: '40px',
160
+ 'max-width': '60%',
161
+ height: `${size}px`
162
+ }
163
+ case 'bottom':
164
+ return {
165
+ ...common,
166
+ bottom: '50%',
167
+ left: '50%',
168
+ transform: 'translate(-50%, 50%)',
169
+ width: '40px',
170
+ 'max-width': '60%',
171
+ height: `${size}px`
172
+ }
173
+ default:
174
+ return common
175
+ }
176
+ }
177
+
178
+ /**
179
+ * ResizeHandle Component
180
+ */
181
+ export const ResizeHandle: Component<ResizeHandleProps> = (props) => {
182
+ const merged = mergeProps(
183
+ {
184
+ disabled: false,
185
+ isActive: false,
186
+ size: 4,
187
+ hitAreaSize: 12
188
+ },
189
+ props
190
+ )
191
+
192
+ const handlePointerDown = (e: PointerEvent) => {
193
+ if (merged.disabled) return
194
+
195
+ e.preventDefault()
196
+ e.stopPropagation()
197
+
198
+ props.onResizeStart?.(props.edge)
199
+ }
200
+
201
+ // Container styles
202
+ const containerStyle = createMemo((): JSX.CSSProperties => ({
203
+ position: 'absolute',
204
+ 'z-index': '10',
205
+ cursor: merged.disabled ? 'default' : getCursor(props.edge),
206
+ 'user-select': 'none',
207
+ 'touch-action': 'none',
208
+ ...getPositionStyle(props.edge, merged.hitAreaSize)
209
+ }))
210
+
211
+ // Indicator styles
212
+ const indicatorStyle = createMemo(() =>
213
+ getIndicatorStyle(props.edge, merged.size, merged.isActive)
214
+ )
215
+
216
+ // Class names
217
+ const classNames = createMemo(() => {
218
+ const classes = [
219
+ 'mcp-resize-handle',
220
+ `mcp-resize-handle-${props.edge}`
221
+ ]
222
+
223
+ if (merged.disabled) classes.push('mcp-resize-handle-disabled')
224
+ if (merged.isActive) classes.push('mcp-resize-handle-active')
225
+ if (props.class) classes.push(props.class)
226
+
227
+ return classes.join(' ')
228
+ })
229
+
230
+ return (
231
+ <div
232
+ class={classNames()}
233
+ style={containerStyle()}
234
+ onPointerDown={handlePointerDown}
235
+ data-resize-edge={props.edge}
236
+ role="separator"
237
+ aria-orientation={
238
+ props.edge === 'left' || props.edge === 'right'
239
+ ? 'vertical'
240
+ : 'horizontal'
241
+ }
242
+ aria-valuenow={undefined}
243
+ tabIndex={merged.disabled ? -1 : 0}
244
+ onKeyDown={(e) => {
245
+ // Allow keyboard resizing
246
+ if (merged.disabled) return
247
+ if (e.key === 'Enter' || e.key === ' ') {
248
+ e.preventDefault()
249
+ props.onResizeStart?.(props.edge)
250
+ }
251
+ }}
252
+ >
253
+ {/* Visual indicator */}
254
+ <div
255
+ class="mcp-resize-indicator"
256
+ style={indicatorStyle()}
257
+ />
258
+ </div>
259
+ )
260
+ }
261
+
262
+ export default ResizeHandle