glass-ui-solid 0.3.4 → 0.4.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 (84) hide show
  1. package/dist/components/Autocomplete/Autocomplete.js +32 -32
  2. package/dist/components/Autocomplete/Autocomplete.js.map +1 -1
  3. package/dist/components/Chat/Chat.d.ts.map +1 -1
  4. package/dist/components/Chat/Chat.js +3 -0
  5. package/dist/components/Chat/Chat.js.map +1 -1
  6. package/dist/components/Chat/ChatInput.d.ts.map +1 -1
  7. package/dist/components/Chat/ChatInput.js +34 -34
  8. package/dist/components/Chat/ChatInput.js.map +1 -1
  9. package/dist/components/Chat/ChatMessage.d.ts.map +1 -1
  10. package/dist/components/Chat/ChatMessage.js +68 -39
  11. package/dist/components/Chat/ChatMessage.js.map +1 -1
  12. package/dist/components/Chat/ChatMessageList.d.ts.map +1 -1
  13. package/dist/components/Chat/ChatMessageList.js +60 -57
  14. package/dist/components/Chat/ChatMessageList.js.map +1 -1
  15. package/dist/components/Chat/ChatToolCall.d.ts +7 -0
  16. package/dist/components/Chat/ChatToolCall.d.ts.map +1 -0
  17. package/dist/components/Chat/ChatToolCall.js +207 -0
  18. package/dist/components/Chat/ChatToolCall.js.map +1 -0
  19. package/dist/components/Chat/icons.d.ts +4 -0
  20. package/dist/components/Chat/icons.d.ts.map +1 -1
  21. package/dist/components/Chat/icons.js +33 -19
  22. package/dist/components/Chat/icons.js.map +1 -1
  23. package/dist/components/Chat/index.d.ts +2 -1
  24. package/dist/components/Chat/index.d.ts.map +1 -1
  25. package/dist/components/Chat/types.d.ts +31 -1
  26. package/dist/components/Chat/types.d.ts.map +1 -1
  27. package/dist/components/CommandPalette/CommandPalette.d.ts.map +1 -1
  28. package/dist/components/CommandPalette/CommandPalette.js +56 -55
  29. package/dist/components/CommandPalette/CommandPalette.js.map +1 -1
  30. package/dist/components/ContextMenu/ContextMenuItem.js +13 -13
  31. package/dist/components/ContextMenu/ContextMenuItem.js.map +1 -1
  32. package/dist/components/DatePicker/DatePicker.js +28 -28
  33. package/dist/components/DatePicker/DatePicker.js.map +1 -1
  34. package/dist/components/DatePicker/DateRangePicker.js +2 -2
  35. package/dist/components/DatePicker/DateRangePicker.js.map +1 -1
  36. package/dist/components/ErrorDisplay/ErrorDisplay.js +5 -5
  37. package/dist/components/ErrorDisplay/ErrorDisplay.js.map +1 -1
  38. package/dist/components/FileUpload/FileUpload.js +24 -24
  39. package/dist/components/FileUpload/FileUpload.js.map +1 -1
  40. package/dist/components/Input/Input.js +2 -2
  41. package/dist/components/Input/Input.js.map +1 -1
  42. package/dist/components/Input/Select.js +7 -7
  43. package/dist/components/Input/Select.js.map +1 -1
  44. package/dist/components/Input/Textarea.js +18 -18
  45. package/dist/components/Input/Textarea.js.map +1 -1
  46. package/dist/components/Markdown/Markdown.d.ts.map +1 -1
  47. package/dist/components/Markdown/Markdown.js +81 -19
  48. package/dist/components/Markdown/Markdown.js.map +1 -1
  49. package/dist/components/Markdown/index.d.ts +1 -1
  50. package/dist/components/Markdown/index.d.ts.map +1 -1
  51. package/dist/components/Markdown/types.d.ts +25 -0
  52. package/dist/components/Markdown/types.d.ts.map +1 -1
  53. package/dist/components/NumberInput/NumberInput.js +20 -20
  54. package/dist/components/NumberInput/NumberInput.js.map +1 -1
  55. package/dist/components/RadioGroup/RadioGroup.js +1 -1
  56. package/dist/components/RadioGroup/RadioGroup.js.map +1 -1
  57. package/dist/components/Sheet/Sheet.js +36 -36
  58. package/dist/components/Sheet/Sheet.js.map +1 -1
  59. package/dist/components/Snackbar/SnackbarContainer.d.ts.map +1 -1
  60. package/dist/components/Snackbar/SnackbarContainer.js +17 -26
  61. package/dist/components/Snackbar/SnackbarContainer.js.map +1 -1
  62. package/dist/components/index.d.ts +6 -6
  63. package/dist/components/index.d.ts.map +1 -1
  64. package/dist/components/shared/createNotificationStore.d.ts.map +1 -1
  65. package/dist/components/shared/createNotificationStore.js +42 -34
  66. package/dist/components/shared/createNotificationStore.js.map +1 -1
  67. package/dist/components/virtual/useVirtualizer.d.ts +1 -1
  68. package/dist/components/virtual/useVirtualizer.d.ts.map +1 -1
  69. package/dist/components/virtual/useVirtualizer.js +126 -117
  70. package/dist/components/virtual/useVirtualizer.js.map +1 -1
  71. package/dist/constants/animations.d.ts +4 -0
  72. package/dist/constants/animations.d.ts.map +1 -1
  73. package/dist/constants/animations.js +14 -12
  74. package/dist/constants/animations.js.map +1 -1
  75. package/dist/hooks/useBodyScrollLock.d.ts.map +1 -1
  76. package/dist/hooks/useBodyScrollLock.js +11 -11
  77. package/dist/hooks/useBodyScrollLock.js.map +1 -1
  78. package/dist/hooks/useCopyToClipboard.d.ts.map +1 -1
  79. package/dist/hooks/useCopyToClipboard.js +10 -7
  80. package/dist/hooks/useCopyToClipboard.js.map +1 -1
  81. package/dist/index.js +61 -59
  82. package/dist/index.js.map +1 -1
  83. package/dist/styles.css +1 -1
  84. package/package.json +1 -1
@@ -1,12 +1,12 @@
1
1
  import { template as b, insert as s, createComponent as u, effect as I, setAttribute as _, use as R, memo as ae, className as A, style as ie, delegateEvents as oe } from "solid-js/web";
2
- import { createSignal as M, createEffect as V, createMemo as z, on as se, onCleanup as de, Show as C, For as K } from "solid-js";
3
- import { useClickOutside as ce } from "../../hooks/useClickOutside.js";
2
+ import { createSignal as M, createEffect as V, createMemo as z, on as se, onCleanup as ce, Show as C, For as K } from "solid-js";
3
+ import { useClickOutside as de } from "../../hooks/useClickOutside.js";
4
4
  import { Spinner as ue } from "../Spinner/Spinner.js";
5
5
  import { CloseIcon as fe } from "../shared/icons/CloseIcon.js";
6
6
  import { ChevronDownIcon as he } from "../shared/icons/ChevronIcon.js";
7
7
  import { PortalWithDarkMode as ve } from "../shared/PortalWithDarkMode/PortalWithDarkMode.js";
8
8
  import { DROPDOWN_ITEM_SIZE_CLASSES as ge, INPUT_SIZE_CLASSES as me } from "../../constants/styles.js";
9
- var q = /* @__PURE__ */ b("<span>"), be = /* @__PURE__ */ b('<mark class="bg-primary-200 dark:bg-primary-700/50 text-inherit rounded-sm px-0.5">'), xe = /* @__PURE__ */ b('<label class="block text-sm font-medium text-surface-700 dark:text-surface-300 mb-1.5">'), we = /* @__PURE__ */ b("<div class=pointer-events-none>"), $e = /* @__PURE__ */ b('<button type=button class="p-1 rounded-full text-surface-400 hover:text-surface-600 dark:hover:text-surface-300 hover:bg-surface-200/50 dark:hover:bg-surface-700/50 transition-colors"tabindex=-1 aria-label="Clear selection">'), ke = /* @__PURE__ */ b('<button type=button class="p-1 text-surface-400 cursor-pointer disabled:cursor-not-allowed"tabindex=-1>'), Ce = /* @__PURE__ */ b('<p class="mt-1.5 text-sm text-red-500 dark:text-red-400">'), ye = /* @__PURE__ */ b('<div class="fixed z-50 glass-card rounded-xl shadow-lg overflow-hidden animate-in fade-in zoom-in-95 duration-150"role=listbox><div class="max-h-60 overflow-y-auto scrollbar-thin py-1">'), Ie = /* @__PURE__ */ b('<div><div class=relative><input type=text autocomplete=off role=combobox aria-haspopup=listbox aria-autocomplete=list><div class="absolute inset-y-0 right-0 flex items-center gap-1 pr-2">'), _e = /* @__PURE__ */ b("<div>"), Se = /* @__PURE__ */ b("<button type=button data-option role=option tabindex=-1>");
9
+ var q = /* @__PURE__ */ b("<span>"), be = /* @__PURE__ */ b('<mark class="bg-primary-200 dark:bg-primary-700/50 text-inherit rounded-sm px-0.5">'), xe = /* @__PURE__ */ b('<label class="block text-sm font-medium text-surface-700 dark:text-surface-300 mb-1.5">'), we = /* @__PURE__ */ b("<div class=pointer-events-none>"), $e = /* @__PURE__ */ b('<button type=button class="p-1 rounded-full text-surface-400 hover:text-surface-600 dark:hover:text-surface-300 hover:bg-surface-200/50 dark:hover:bg-surface-700/50 transition-colors"tabindex=-1 aria-label="Clear selection">'), ke = /* @__PURE__ */ b('<button type=button class="p-1 text-surface-400 cursor-pointer disabled:cursor-not-allowed"tabindex=-1>'), Ce = /* @__PURE__ */ b('<p class="mt-1.5 text-sm text-error-500 dark:text-error-400">'), ye = /* @__PURE__ */ b('<div class="fixed z-50 glass-card rounded-xl shadow-lg overflow-hidden animate-in fade-in zoom-in-95 duration-150"role=listbox><div class="max-h-60 overflow-y-auto scrollbar-thin py-1">'), Ie = /* @__PURE__ */ b('<div><div class=relative><input type=text autocomplete=off role=combobox aria-haspopup=listbox aria-autocomplete=list><div class="absolute inset-y-0 right-0 flex items-center gap-1 pr-2">'), _e = /* @__PURE__ */ b("<div>"), Se = /* @__PURE__ */ b("<button type=button data-option role=option tabindex=-1>");
10
10
  const Oe = (e, i) => e.label.toLowerCase().includes(i.toLowerCase()), Ee = (e) => {
11
11
  const i = z(() => {
12
12
  if (!e.highlight.trim())
@@ -15,15 +15,15 @@ const Oe = (e, i) => e.label.toLowerCase().includes(i.toLowerCase()), Ee = (e) =
15
15
  match: !1
16
16
  }];
17
17
  const w = e.text.toLowerCase(), f = e.highlight.toLowerCase(), r = [];
18
- let g = 0, d = w.indexOf(f, g);
19
- for (; d !== -1; )
20
- d > g && r.push({
21
- text: e.text.slice(g, d),
18
+ let g = 0, c = w.indexOf(f, g);
19
+ for (; c !== -1; )
20
+ c > g && r.push({
21
+ text: e.text.slice(g, c),
22
22
  match: !1
23
23
  }), r.push({
24
- text: e.text.slice(d, d + e.highlight.length),
24
+ text: e.text.slice(c, c + e.highlight.length),
25
25
  match: !0
26
- }), g = d + e.highlight.length, d = w.indexOf(f, g);
26
+ }), g = c + e.highlight.length, c = w.indexOf(f, g);
27
27
  return g < e.text.length && r.push({
28
28
  text: e.text.slice(g),
29
29
  match: !1
@@ -56,7 +56,7 @@ const Oe = (e, i) => e.label.toLowerCase().includes(i.toLowerCase()), Ee = (e) =
56
56
  })), w;
57
57
  })();
58
58
  }, Re = (e) => {
59
- const [i, w] = M(!1), [f, r] = M(""), [g, d] = M(-1);
59
+ const [i, w] = M(!1), [f, r] = M(""), [g, c] = M(-1);
60
60
  let T, O, y, H = !1;
61
61
  const G = (t) => {
62
62
  T = t, typeof e.ref == "function" ? e.ref(t) : e.ref;
@@ -72,7 +72,7 @@ const Oe = (e, i) => e.label.toLowerCase().includes(i.toLowerCase()), Ee = (e) =
72
72
  V(se(() => F(), () => {
73
73
  if (i()) {
74
74
  const t = E().length > 0 ? 0 : -1;
75
- d(t);
75
+ c(t);
76
76
  }
77
77
  })), V(() => {
78
78
  const t = g();
@@ -88,11 +88,11 @@ const Oe = (e, i) => e.label.toLowerCase().includes(i.toLowerCase()), Ee = (e) =
88
88
  return;
89
89
  w(!0);
90
90
  const t = E().length > 0 ? 0 : -1;
91
- d(t);
91
+ c(t);
92
92
  }, X = () => {
93
93
  e.disabled || (i() ? $() : (L(), T?.focus()));
94
94
  }, $ = () => {
95
- w(!1), d(-1);
95
+ w(!1), c(-1);
96
96
  }, N = (t) => {
97
97
  t.disabled || (r(t.label), e.onChange(t.value), $(), H = !0, T?.focus());
98
98
  }, Y = (t) => {
@@ -110,48 +110,48 @@ const Oe = (e, i) => e.label.toLowerCase().includes(i.toLowerCase()), Ee = (e) =
110
110
  y?.contains(o) || setTimeout(() => {
111
111
  if (!i())
112
112
  return;
113
- const l = e.options.find((c) => c.label.toLowerCase() === f().toLowerCase());
113
+ const l = e.options.find((d) => d.label.toLowerCase() === f().toLowerCase());
114
114
  if (l)
115
115
  e.onChange(l.value), r(l.label);
116
116
  else if (e.allowCustomValue)
117
117
  e.onChange(f());
118
118
  else {
119
- const c = e.options.find((x) => x.value === e.value);
120
- r(c?.label ?? "");
119
+ const d = e.options.find((x) => x.value === e.value);
120
+ r(d?.label ?? "");
121
121
  }
122
122
  $();
123
123
  }, 150);
124
124
  }, ne = (t) => {
125
- const o = E(), l = o.length, c = i(), x = g();
125
+ const o = E(), l = o.length, d = i(), x = g();
126
126
  switch (t.key) {
127
127
  case "ArrowDown":
128
- t.preventDefault(), c ? l > 0 && d((n) => Math.min(n + 1, l - 1)) : L();
128
+ t.preventDefault(), d ? l > 0 && c((n) => Math.min(n + 1, l - 1)) : L();
129
129
  break;
130
130
  case "ArrowUp":
131
- t.preventDefault(), c && l > 0 && d((n) => Math.max(n - 1, 0));
131
+ t.preventDefault(), d && l > 0 && c((n) => Math.max(n - 1, 0));
132
132
  break;
133
133
  case "Enter":
134
- t.preventDefault(), c && x >= 0 && x < l ? N(o[x]) : e.allowCustomValue && f().trim() && (e.onChange(f()), $());
134
+ t.preventDefault(), d && x >= 0 && x < l ? N(o[x]) : e.allowCustomValue && f().trim() && (e.onChange(f()), $());
135
135
  break;
136
136
  case "Escape":
137
- if (c) {
137
+ if (d) {
138
138
  t.preventDefault(), $();
139
139
  const n = e.options.find((h) => h.value === e.value);
140
140
  r(n?.label ?? (e.allowCustomValue ? e.value : ""));
141
141
  }
142
142
  break;
143
143
  case "Tab":
144
- c && $();
144
+ d && $();
145
145
  break;
146
146
  case "Home":
147
- c && l > 0 && (t.preventDefault(), d(0));
147
+ d && l > 0 && (t.preventDefault(), c(0));
148
148
  break;
149
149
  case "End":
150
- c && l > 0 && (t.preventDefault(), d(l - 1));
150
+ d && l > 0 && (t.preventDefault(), c(l - 1));
151
151
  break;
152
152
  }
153
153
  };
154
- ce({
154
+ de({
155
155
  refs: () => [O, y],
156
156
  onClickOutside: $,
157
157
  enabled: i
@@ -161,7 +161,7 @@ const Oe = (e, i) => e.label.toLowerCase().includes(i.toLowerCase()), Ee = (e) =
161
161
  const t = (o) => {
162
162
  y?.contains(o.target) || $();
163
163
  };
164
- window.addEventListener("scroll", t, !0), de(() => window.removeEventListener("scroll", t, !0));
164
+ window.addEventListener("scroll", t, !0), ce(() => window.removeEventListener("scroll", t, !0));
165
165
  });
166
166
  const le = z(() => {
167
167
  if (!i() || !O)
@@ -178,7 +178,7 @@ const Oe = (e, i) => e.label.toLowerCase().includes(i.toLowerCase()), Ee = (e) =
178
178
  };
179
179
  }), re = () => me[P()], U = () => ge[P()];
180
180
  return (() => {
181
- var t = Ie(), o = t.firstChild, l = o.firstChild, c = l.nextSibling, x = O;
181
+ var t = Ie(), o = t.firstChild, l = o.firstChild, d = l.nextSibling, x = O;
182
182
  return typeof x == "function" ? R(x, t) : O = t, s(t, u(C, {
183
183
  get when() {
184
184
  return e.label;
@@ -187,7 +187,7 @@ const Oe = (e, i) => e.label.toLowerCase().includes(i.toLowerCase()), Ee = (e) =
187
187
  var n = xe();
188
188
  return s(n, () => e.label), I(() => _(n, "for", e.id)), n;
189
189
  }
190
- }), o), l.$$click = () => !i() && L(), l.$$keydown = ne, l.addEventListener("blur", te), l.addEventListener("focus", ee), l.$$input = (n) => p(n.currentTarget.value), R(G, l), s(c, u(C, {
190
+ }), o), l.$$click = () => !i() && L(), l.$$keydown = ne, l.addEventListener("blur", te), l.addEventListener("focus", ee), l.$$input = (n) => p(n.currentTarget.value), R(G, l), s(d, u(C, {
191
191
  get when() {
192
192
  return e.loading;
193
193
  },
@@ -197,7 +197,7 @@ const Oe = (e, i) => e.label.toLowerCase().includes(i.toLowerCase()), Ee = (e) =
197
197
  size: "sm"
198
198
  })), n;
199
199
  }
200
- }), null), s(c, u(C, {
200
+ }), null), s(d, u(C, {
201
201
  get when() {
202
202
  return ae(() => !!(!e.loading && B()))() && !e.disabled;
203
203
  },
@@ -207,7 +207,7 @@ const Oe = (e, i) => e.label.toLowerCase().includes(i.toLowerCase()), Ee = (e) =
207
207
  class: "w-4 h-4"
208
208
  })), n;
209
209
  }
210
- }), null), s(c, u(C, {
210
+ }), null), s(d, u(C, {
211
211
  get when() {
212
212
  return !e.loading;
213
213
  },
@@ -263,7 +263,7 @@ const Oe = (e, i) => e.label.toLowerCase().includes(i.toLowerCase()), Ee = (e) =
263
263
  return m.addEventListener("mouseenter", () => {
264
264
  if (!a.disabled) {
265
265
  const v = E().indexOf(a);
266
- d(v);
266
+ c(v);
267
267
  }
268
268
  }), m.$$click = () => N(a), s(m, u(Ee, {
269
269
  get text() {
@@ -294,7 +294,7 @@ const Oe = (e, i) => e.label.toLowerCase().includes(i.toLowerCase()), Ee = (e) =
294
294
  });
295
295
  }
296
296
  }), null), I((n) => {
297
- var h = `w-full ${e.class ?? ""}`, k = e.id, a = e.name, D = `w-full glass-input text-surface-900 dark:text-surface-100 focus:outline-none disabled:opacity-50 disabled:cursor-not-allowed ${B() && !e.disabled ? "pr-16" : "pr-10"} ${re()} ${e.error ? "border-red-500 dark:border-red-400" : ""}`, S = e.placeholder, m = e.disabled, v = i();
297
+ var h = `w-full ${e.class ?? ""}`, k = e.id, a = e.name, D = `w-full glass-input text-surface-900 dark:text-surface-100 focus:outline-none disabled:opacity-50 disabled:cursor-not-allowed ${B() && !e.disabled ? "pr-16" : "pr-10"} ${re()} ${e.error ? "border-error-500 dark:border-error-400" : ""}`, S = e.placeholder, m = e.disabled, v = i();
298
298
  return h !== n.e && A(t, n.e = h), k !== n.t && _(l, "id", n.t = k), a !== n.a && _(l, "name", n.a = a), D !== n.o && A(l, n.o = D), S !== n.i && _(l, "placeholder", n.i = S), m !== n.n && (l.disabled = n.n = m), v !== n.s && _(l, "aria-expanded", n.s = v), n;
299
299
  }, {
300
300
  e: void 0,
@@ -1 +1 @@
1
- {"version":3,"file":"Autocomplete.js","sources":["../../../src/components/Autocomplete/Autocomplete.tsx"],"sourcesContent":["import {\n type Component,\n For,\n Show,\n createEffect,\n createMemo,\n createSignal,\n on,\n onCleanup,\n} from 'solid-js';\nimport {\n DROPDOWN_ITEM_SIZE_CLASSES,\n INPUT_SIZE_CLASSES,\n} from '../../constants';\nimport { useClickOutside } from '../../hooks';\nimport { Spinner } from '../Spinner';\nimport { ChevronDownIcon, CloseIcon, PortalWithDarkMode } from '../shared';\nimport type { AutocompleteOption, AutocompleteProps } from './types';\n\n/**\n * Default filter function - case-insensitive substring match\n */\nconst defaultFilterFn = (\n option: AutocompleteOption,\n inputValue: string,\n): boolean => {\n return option.label.toLowerCase().includes(inputValue.toLowerCase());\n};\n\n/**\n * Highlight matching text in a string\n */\nconst HighlightedText: Component<{ text: string; highlight: string }> = (\n props,\n) => {\n const parts = createMemo(() => {\n if (!props.highlight.trim()) {\n return [{ text: props.text, match: false }];\n }\n\n const lowerText = props.text.toLowerCase();\n const lowerHighlight = props.highlight.toLowerCase();\n const result: { text: string; match: boolean }[] = [];\n let lastIndex = 0;\n\n let index = lowerText.indexOf(lowerHighlight, lastIndex);\n while (index !== -1) {\n if (index > lastIndex) {\n result.push({ text: props.text.slice(lastIndex, index), match: false });\n }\n result.push({\n text: props.text.slice(index, index + props.highlight.length),\n match: true,\n });\n lastIndex = index + props.highlight.length;\n index = lowerText.indexOf(lowerHighlight, lastIndex);\n }\n\n if (lastIndex < props.text.length) {\n result.push({ text: props.text.slice(lastIndex), match: false });\n }\n\n return result.length > 0 ? result : [{ text: props.text, match: false }];\n });\n\n return (\n <span>\n <For each={parts()}>\n {(part) => (\n <Show when={part.match} fallback={<span>{part.text}</span>}>\n <mark class=\"bg-primary-200 dark:bg-primary-700/50 text-inherit rounded-sm px-0.5\">\n {part.text}\n </mark>\n </Show>\n )}\n </For>\n </span>\n );\n};\n\n/**\n * A glassmorphic Autocomplete/Combobox component with dropdown suggestions.\n *\n * @example\n * ```tsx\n * const [value, setValue] = createSignal('');\n *\n * <Autocomplete\n * options={[\n * { value: 'apple', label: 'Apple' },\n * { value: 'banana', label: 'Banana' },\n * { value: 'cherry', label: 'Cherry' },\n * ]}\n * value={value()}\n * onChange={setValue}\n * placeholder=\"Select a fruit...\"\n * />\n * ```\n */\nexport const Autocomplete: Component<AutocompleteProps> = (props) => {\n const [isOpen, setIsOpen] = createSignal(false);\n const [inputValue, setInputValue] = createSignal('');\n const [focusedIndex, setFocusedIndex] = createSignal(-1);\n\n let internalInputRef: HTMLInputElement | undefined;\n let containerRef: HTMLDivElement | undefined;\n let dropdownRef: HTMLDivElement | undefined;\n let justSelected = false;\n\n // Combine internal ref with user-provided ref\n const setInputRef = (el: HTMLInputElement) => {\n internalInputRef = el;\n if (typeof props.ref === 'function') {\n props.ref(el);\n } else if (props.ref !== undefined) {\n // For direct assignment refs, we can't set them directly\n // but SolidJS handles this case automatically\n }\n };\n\n const size = () => props.size ?? 'md';\n const emptyText = () => props.emptyText ?? 'No options found';\n const filterFn = () => props.filterFn ?? defaultFilterFn;\n\n // Sync input value with selected value\n createEffect(() => {\n const selectedOption = props.options.find(\n (opt) => opt.value === props.value,\n );\n if (selectedOption) {\n setInputValue(selectedOption.label);\n } else if (props.allowCustomValue) {\n setInputValue(props.value);\n } else {\n setInputValue('');\n }\n });\n\n // Filtered options based on input\n const filteredOptions = createMemo(() => {\n const input = inputValue().trim();\n if (!input) {\n return props.options;\n }\n return props.options.filter((opt) => filterFn()(opt, input));\n });\n\n // Focusable options (non-disabled)\n const focusableOptions = createMemo(() => {\n return filteredOptions().filter((opt) => !opt.disabled);\n });\n\n // Reset focused index when options change (keep first item highlighted)\n createEffect(\n on(\n () => filteredOptions(),\n () => {\n if (isOpen()) {\n const firstFocusable = focusableOptions().length > 0 ? 0 : -1;\n setFocusedIndex(firstFocusable);\n }\n },\n ),\n );\n\n // Scroll focused item into view\n createEffect(() => {\n const idx = focusedIndex();\n if (idx >= 0 && dropdownRef) {\n const items = dropdownRef.querySelectorAll('[data-option]');\n const item = items[idx];\n if (item) {\n item.scrollIntoView({ block: 'nearest' });\n }\n }\n });\n\n const handleOpen = () => {\n if (props.disabled) {\n return;\n }\n setIsOpen(true);\n // Pre-select first focusable option\n const firstFocusable = focusableOptions().length > 0 ? 0 : -1;\n setFocusedIndex(firstFocusable);\n };\n\n const handleToggle = () => {\n if (props.disabled) {\n return;\n }\n if (isOpen()) {\n handleClose();\n } else {\n handleOpen();\n internalInputRef?.focus();\n }\n };\n\n const handleClose = () => {\n setIsOpen(false);\n setFocusedIndex(-1);\n };\n\n const handleSelect = (option: AutocompleteOption) => {\n if (option.disabled) {\n return;\n }\n setInputValue(option.label);\n props.onChange(option.value);\n handleClose();\n justSelected = true;\n internalInputRef?.focus();\n };\n\n const handleClear = (e: MouseEvent) => {\n e.stopPropagation();\n setInputValue('');\n props.onChange('');\n props.onInputChange?.('');\n internalInputRef?.focus();\n };\n\n const hasValue = () => !!props.value;\n\n const handleInputChange = (value: string) => {\n setInputValue(value);\n props.onInputChange?.(value);\n if (!isOpen()) {\n handleOpen();\n }\n };\n\n const handleInputFocus = () => {\n if (justSelected) {\n justSelected = false;\n return;\n }\n handleOpen();\n };\n\n const handleInputBlur = (e: FocusEvent) => {\n // Delay close to allow click on option to register\n const relatedTarget = e.relatedTarget as Node | null;\n if (dropdownRef?.contains(relatedTarget)) {\n return;\n }\n\n // On blur, validate the input\n setTimeout(() => {\n if (!isOpen()) {\n return;\n }\n\n const matchingOption = props.options.find(\n (opt) => opt.label.toLowerCase() === inputValue().toLowerCase(),\n );\n\n if (matchingOption) {\n props.onChange(matchingOption.value);\n setInputValue(matchingOption.label);\n } else if (props.allowCustomValue) {\n props.onChange(inputValue());\n } else {\n // Reset to current value\n const selectedOption = props.options.find(\n (opt) => opt.value === props.value,\n );\n setInputValue(selectedOption?.label ?? '');\n }\n\n handleClose();\n }, 150);\n };\n\n const handleKeyDown = (e: KeyboardEvent) => {\n const options = focusableOptions();\n const len = options.length;\n const open = isOpen();\n const idx = focusedIndex();\n\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault();\n if (!open) {\n handleOpen();\n } else if (len > 0) {\n setFocusedIndex((prev) => Math.min(prev + 1, len - 1));\n }\n break;\n\n case 'ArrowUp':\n e.preventDefault();\n if (open && len > 0) {\n setFocusedIndex((prev) => Math.max(prev - 1, 0));\n }\n break;\n\n case 'Enter':\n e.preventDefault();\n if (open && idx >= 0 && idx < len) {\n handleSelect(options[idx]);\n } else if (props.allowCustomValue && inputValue().trim()) {\n props.onChange(inputValue());\n handleClose();\n }\n break;\n\n case 'Escape':\n if (open) {\n e.preventDefault();\n handleClose();\n const selected = props.options.find(\n (opt) => opt.value === props.value,\n );\n setInputValue(\n selected?.label ?? (props.allowCustomValue ? props.value : ''),\n );\n }\n break;\n\n case 'Tab':\n if (open) {\n handleClose();\n }\n break;\n\n case 'Home':\n if (open && len > 0) {\n e.preventDefault();\n setFocusedIndex(0);\n }\n break;\n\n case 'End':\n if (open && len > 0) {\n e.preventDefault();\n setFocusedIndex(len - 1);\n }\n break;\n }\n };\n\n // Click outside to close\n useClickOutside({\n refs: () => [containerRef, dropdownRef],\n onClickOutside: handleClose,\n enabled: isOpen,\n });\n\n // Close on scroll (any scrollable container, but not internal scroll)\n createEffect(() => {\n if (!isOpen()) {\n return;\n }\n\n const handleScroll = (e: Event) => {\n // Ignore scroll events from inside the dropdown\n if (dropdownRef?.contains(e.target as Node)) {\n return;\n }\n handleClose();\n };\n\n // Use capture to catch scroll events on any scrollable ancestor\n window.addEventListener('scroll', handleScroll, true);\n onCleanup(() => window.removeEventListener('scroll', handleScroll, true));\n });\n\n // Calculate dropdown position\n const dropdownPosition = createMemo(() => {\n // Track isOpen to recalculate when dropdown opens\n if (!isOpen() || !containerRef) {\n return {};\n }\n\n const rect = containerRef.getBoundingClientRect();\n const spaceBelow = window.innerHeight - rect.bottom;\n const spaceAbove = rect.top;\n const dropdownHeight = 240; // max-h-60 = 15rem = 240px\n\n // Prefer below, flip to above if not enough space\n const showAbove = spaceBelow < dropdownHeight && spaceAbove > spaceBelow;\n\n return {\n left: `${rect.left}px`,\n width: `${rect.width}px`,\n ...(showAbove\n ? { bottom: `${window.innerHeight - rect.top + 4}px` }\n : { top: `${rect.bottom + 4}px` }),\n };\n });\n\n const sizeClasses = () => INPUT_SIZE_CLASSES[size()];\n const itemSizeClasses = () => DROPDOWN_ITEM_SIZE_CLASSES[size()];\n\n return (\n <div class={`w-full ${props.class ?? ''}`} ref={containerRef}>\n <Show when={props.label}>\n <label\n for={props.id}\n class=\"block text-sm font-medium text-surface-700 dark:text-surface-300 mb-1.5\"\n >\n {props.label}\n </label>\n </Show>\n\n <div class=\"relative\">\n <input\n ref={setInputRef}\n type=\"text\"\n id={props.id}\n name={props.name}\n class={`w-full glass-input text-surface-900 dark:text-surface-100 focus:outline-none disabled:opacity-50 disabled:cursor-not-allowed ${hasValue() && !props.disabled ? 'pr-16' : 'pr-10'} ${sizeClasses()} ${props.error ? 'border-red-500 dark:border-red-400' : ''}`}\n placeholder={props.placeholder}\n value={inputValue()}\n disabled={props.disabled}\n autocomplete=\"off\"\n role=\"combobox\"\n aria-expanded={isOpen()}\n aria-haspopup=\"listbox\"\n aria-autocomplete=\"list\"\n onInput={(e) => handleInputChange(e.currentTarget.value)}\n onFocus={handleInputFocus}\n onBlur={handleInputBlur}\n onKeyDown={handleKeyDown}\n onClick={() => !isOpen() && handleOpen()}\n />\n\n {/* Right side indicators */}\n <div class=\"absolute inset-y-0 right-0 flex items-center gap-1 pr-2\">\n <Show when={props.loading}>\n <div class=\"pointer-events-none\">\n <Spinner size=\"sm\" />\n </div>\n </Show>\n\n <Show when={!props.loading && hasValue() && !props.disabled}>\n <button\n type=\"button\"\n class=\"p-1 rounded-full text-surface-400 hover:text-surface-600 dark:hover:text-surface-300 hover:bg-surface-200/50 dark:hover:bg-surface-700/50 transition-colors\"\n onClick={handleClear}\n tabIndex={-1}\n aria-label=\"Clear selection\"\n >\n <CloseIcon class=\"w-4 h-4\" />\n </button>\n </Show>\n\n <Show when={!props.loading}>\n <button\n type=\"button\"\n class=\"p-1 text-surface-400 cursor-pointer disabled:cursor-not-allowed\"\n onClick={handleToggle}\n disabled={props.disabled}\n tabIndex={-1}\n aria-label={isOpen() ? 'Close dropdown' : 'Open dropdown'}\n >\n <ChevronDownIcon\n class={`transition-transform duration-150 ${isOpen() ? 'rotate-180' : ''}`}\n />\n </button>\n </Show>\n </div>\n </div>\n\n <Show when={props.error}>\n <p class=\"mt-1.5 text-sm text-red-500 dark:text-red-400\">\n {props.error}\n </p>\n </Show>\n\n {/* Dropdown */}\n <Show when={isOpen()}>\n <PortalWithDarkMode>\n <div\n ref={dropdownRef}\n class=\"fixed z-50 glass-card rounded-xl shadow-lg overflow-hidden animate-in fade-in zoom-in-95 duration-150\"\n style={dropdownPosition()}\n role=\"listbox\"\n >\n <div class=\"max-h-60 overflow-y-auto scrollbar-thin py-1\">\n <Show\n when={filteredOptions().length > 0}\n fallback={\n <div\n class={`text-surface-500 dark:text-surface-400 text-center ${itemSizeClasses()}`}\n >\n {emptyText()}\n </div>\n }\n >\n <For each={filteredOptions()}>\n {(option) => {\n const isFocused = () => {\n const focusableIdx = focusableOptions().indexOf(option);\n return focusableIdx === focusedIndex();\n };\n const isSelected = () => option.value === props.value;\n\n return (\n <button\n type=\"button\"\n data-option\n class={`w-full text-left transition-colors ${itemSizeClasses()}\n ${\n option.disabled\n ? 'text-surface-400 dark:text-surface-600 cursor-not-allowed'\n : 'text-surface-700 dark:text-surface-200 cursor-pointer'\n }\n ${isFocused() ? 'bg-black/5 dark:bg-white/5' : ''}\n ${isSelected() ? 'bg-primary-50 dark:bg-primary-900/20 text-primary-700 dark:text-primary-300' : ''}\n ${!option.disabled && !isFocused() && !isSelected() ? 'hover:bg-black/5 dark:hover:bg-white/5' : ''}\n `}\n onClick={() => handleSelect(option)}\n onMouseEnter={() => {\n if (!option.disabled) {\n const focusableIdx =\n focusableOptions().indexOf(option);\n setFocusedIndex(focusableIdx);\n }\n }}\n disabled={option.disabled}\n role=\"option\"\n aria-selected={isSelected()}\n tabIndex={-1}\n >\n <HighlightedText\n text={option.label}\n highlight={inputValue()}\n />\n </button>\n );\n }}\n </For>\n </Show>\n </div>\n </div>\n </PortalWithDarkMode>\n </Show>\n </div>\n );\n};\n"],"names":["defaultFilterFn","option","inputValue","label","toLowerCase","includes","HighlightedText","props","parts","createMemo","highlight","trim","text","match","lowerText","lowerHighlight","result","lastIndex","index","indexOf","push","slice","length","_el$","_tmpl$","_$insert","_$createComponent","For","each","children","part","Show","when","fallback","_el$3","_el$2","_tmpl$2","Autocomplete","isOpen","setIsOpen","createSignal","setInputValue","focusedIndex","setFocusedIndex","internalInputRef","containerRef","dropdownRef","justSelected","setInputRef","el","ref","size","emptyText","filterFn","createEffect","selectedOption","options","find","opt","value","allowCustomValue","filteredOptions","input","filter","focusableOptions","disabled","on","firstFocusable","idx","item","querySelectorAll","scrollIntoView","block","handleOpen","handleToggle","handleClose","focus","handleSelect","onChange","handleClear","e","stopPropagation","onInputChange","hasValue","handleInputChange","handleInputFocus","handleInputBlur","relatedTarget","contains","setTimeout","matchingOption","handleKeyDown","len","open","key","preventDefault","prev","Math","min","max","selected","useClickOutside","refs","onClickOutside","enabled","handleScroll","target","window","addEventListener","onCleanup","removeEventListener","dropdownPosition","rect","getBoundingClientRect","spaceBelow","innerHeight","bottom","spaceAbove","top","showAbove","left","width","sizeClasses","INPUT_SIZE_CLASSES","itemSizeClasses","DROPDOWN_ITEM_SIZE_CLASSES","_el$4","_tmpl$9","_el$6","firstChild","_el$7","_el$8","nextSibling","_ref$","_$use","_el$5","_tmpl$3","_$effect","_$setAttribute","id","$$click","$$keydown","$$input","currentTarget","loading","_el$9","_tmpl$4","Spinner","_$memo","_el$0","_tmpl$5","CloseIcon","_el$1","_tmpl$6","ChevronDownIcon","_p$","_v$","_v$2","t","undefined","error","_el$10","_tmpl$7","PortalWithDarkMode","_el$11","_tmpl$8","_el$12","_ref$2","_el$13","_tmpl$0","_$className","isFocused","isSelected","_el$14","_tmpl$1","focusableIdx","_v$0","_v$1","_v$10","a","_$p","_$style","_v$3","class","_v$4","_v$5","name","_v$6","_v$7","placeholder","_v$8","_v$9","o","i","n","s","_$delegateEvents"],"mappings":"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"}
1
+ {"version":3,"file":"Autocomplete.js","sources":["../../../src/components/Autocomplete/Autocomplete.tsx"],"sourcesContent":["import {\n type Component,\n For,\n Show,\n createEffect,\n createMemo,\n createSignal,\n on,\n onCleanup,\n} from 'solid-js';\nimport {\n DROPDOWN_ITEM_SIZE_CLASSES,\n INPUT_SIZE_CLASSES,\n} from '../../constants';\nimport { useClickOutside } from '../../hooks';\nimport { Spinner } from '../Spinner';\nimport { ChevronDownIcon, CloseIcon, PortalWithDarkMode } from '../shared';\nimport type { AutocompleteOption, AutocompleteProps } from './types';\n\n/**\n * Default filter function - case-insensitive substring match\n */\nconst defaultFilterFn = (\n option: AutocompleteOption,\n inputValue: string,\n): boolean => {\n return option.label.toLowerCase().includes(inputValue.toLowerCase());\n};\n\n/**\n * Highlight matching text in a string\n */\nconst HighlightedText: Component<{ text: string; highlight: string }> = (\n props,\n) => {\n const parts = createMemo(() => {\n if (!props.highlight.trim()) {\n return [{ text: props.text, match: false }];\n }\n\n const lowerText = props.text.toLowerCase();\n const lowerHighlight = props.highlight.toLowerCase();\n const result: { text: string; match: boolean }[] = [];\n let lastIndex = 0;\n\n let index = lowerText.indexOf(lowerHighlight, lastIndex);\n while (index !== -1) {\n if (index > lastIndex) {\n result.push({ text: props.text.slice(lastIndex, index), match: false });\n }\n result.push({\n text: props.text.slice(index, index + props.highlight.length),\n match: true,\n });\n lastIndex = index + props.highlight.length;\n index = lowerText.indexOf(lowerHighlight, lastIndex);\n }\n\n if (lastIndex < props.text.length) {\n result.push({ text: props.text.slice(lastIndex), match: false });\n }\n\n return result.length > 0 ? result : [{ text: props.text, match: false }];\n });\n\n return (\n <span>\n <For each={parts()}>\n {(part) => (\n <Show when={part.match} fallback={<span>{part.text}</span>}>\n <mark class=\"bg-primary-200 dark:bg-primary-700/50 text-inherit rounded-sm px-0.5\">\n {part.text}\n </mark>\n </Show>\n )}\n </For>\n </span>\n );\n};\n\n/**\n * A glassmorphic Autocomplete/Combobox component with dropdown suggestions.\n *\n * @example\n * ```tsx\n * const [value, setValue] = createSignal('');\n *\n * <Autocomplete\n * options={[\n * { value: 'apple', label: 'Apple' },\n * { value: 'banana', label: 'Banana' },\n * { value: 'cherry', label: 'Cherry' },\n * ]}\n * value={value()}\n * onChange={setValue}\n * placeholder=\"Select a fruit...\"\n * />\n * ```\n */\nexport const Autocomplete: Component<AutocompleteProps> = (props) => {\n const [isOpen, setIsOpen] = createSignal(false);\n const [inputValue, setInputValue] = createSignal('');\n const [focusedIndex, setFocusedIndex] = createSignal(-1);\n\n let internalInputRef: HTMLInputElement | undefined;\n let containerRef: HTMLDivElement | undefined;\n let dropdownRef: HTMLDivElement | undefined;\n let justSelected = false;\n\n // Combine internal ref with user-provided ref\n const setInputRef = (el: HTMLInputElement) => {\n internalInputRef = el;\n if (typeof props.ref === 'function') {\n props.ref(el);\n } else if (props.ref !== undefined) {\n // For direct assignment refs, we can't set them directly\n // but SolidJS handles this case automatically\n }\n };\n\n const size = () => props.size ?? 'md';\n const emptyText = () => props.emptyText ?? 'No options found';\n const filterFn = () => props.filterFn ?? defaultFilterFn;\n\n // Sync input value with selected value\n createEffect(() => {\n const selectedOption = props.options.find(\n (opt) => opt.value === props.value,\n );\n if (selectedOption) {\n setInputValue(selectedOption.label);\n } else if (props.allowCustomValue) {\n setInputValue(props.value);\n } else {\n setInputValue('');\n }\n });\n\n // Filtered options based on input\n const filteredOptions = createMemo(() => {\n const input = inputValue().trim();\n if (!input) {\n return props.options;\n }\n return props.options.filter((opt) => filterFn()(opt, input));\n });\n\n // Focusable options (non-disabled)\n const focusableOptions = createMemo(() => {\n return filteredOptions().filter((opt) => !opt.disabled);\n });\n\n // Reset focused index when options change (keep first item highlighted)\n createEffect(\n on(\n () => filteredOptions(),\n () => {\n if (isOpen()) {\n const firstFocusable = focusableOptions().length > 0 ? 0 : -1;\n setFocusedIndex(firstFocusable);\n }\n },\n ),\n );\n\n // Scroll focused item into view\n createEffect(() => {\n const idx = focusedIndex();\n if (idx >= 0 && dropdownRef) {\n const items = dropdownRef.querySelectorAll('[data-option]');\n const item = items[idx];\n if (item) {\n item.scrollIntoView({ block: 'nearest' });\n }\n }\n });\n\n const handleOpen = () => {\n if (props.disabled) {\n return;\n }\n setIsOpen(true);\n // Pre-select first focusable option\n const firstFocusable = focusableOptions().length > 0 ? 0 : -1;\n setFocusedIndex(firstFocusable);\n };\n\n const handleToggle = () => {\n if (props.disabled) {\n return;\n }\n if (isOpen()) {\n handleClose();\n } else {\n handleOpen();\n internalInputRef?.focus();\n }\n };\n\n const handleClose = () => {\n setIsOpen(false);\n setFocusedIndex(-1);\n };\n\n const handleSelect = (option: AutocompleteOption) => {\n if (option.disabled) {\n return;\n }\n setInputValue(option.label);\n props.onChange(option.value);\n handleClose();\n justSelected = true;\n internalInputRef?.focus();\n };\n\n const handleClear = (e: MouseEvent) => {\n e.stopPropagation();\n setInputValue('');\n props.onChange('');\n props.onInputChange?.('');\n internalInputRef?.focus();\n };\n\n const hasValue = () => !!props.value;\n\n const handleInputChange = (value: string) => {\n setInputValue(value);\n props.onInputChange?.(value);\n if (!isOpen()) {\n handleOpen();\n }\n };\n\n const handleInputFocus = () => {\n if (justSelected) {\n justSelected = false;\n return;\n }\n handleOpen();\n };\n\n const handleInputBlur = (e: FocusEvent) => {\n // Delay close to allow click on option to register\n const relatedTarget = e.relatedTarget as Node | null;\n if (dropdownRef?.contains(relatedTarget)) {\n return;\n }\n\n // On blur, validate the input\n setTimeout(() => {\n if (!isOpen()) {\n return;\n }\n\n const matchingOption = props.options.find(\n (opt) => opt.label.toLowerCase() === inputValue().toLowerCase(),\n );\n\n if (matchingOption) {\n props.onChange(matchingOption.value);\n setInputValue(matchingOption.label);\n } else if (props.allowCustomValue) {\n props.onChange(inputValue());\n } else {\n // Reset to current value\n const selectedOption = props.options.find(\n (opt) => opt.value === props.value,\n );\n setInputValue(selectedOption?.label ?? '');\n }\n\n handleClose();\n }, 150);\n };\n\n const handleKeyDown = (e: KeyboardEvent) => {\n const options = focusableOptions();\n const len = options.length;\n const open = isOpen();\n const idx = focusedIndex();\n\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault();\n if (!open) {\n handleOpen();\n } else if (len > 0) {\n setFocusedIndex((prev) => Math.min(prev + 1, len - 1));\n }\n break;\n\n case 'ArrowUp':\n e.preventDefault();\n if (open && len > 0) {\n setFocusedIndex((prev) => Math.max(prev - 1, 0));\n }\n break;\n\n case 'Enter':\n e.preventDefault();\n if (open && idx >= 0 && idx < len) {\n handleSelect(options[idx]);\n } else if (props.allowCustomValue && inputValue().trim()) {\n props.onChange(inputValue());\n handleClose();\n }\n break;\n\n case 'Escape':\n if (open) {\n e.preventDefault();\n handleClose();\n const selected = props.options.find(\n (opt) => opt.value === props.value,\n );\n setInputValue(\n selected?.label ?? (props.allowCustomValue ? props.value : ''),\n );\n }\n break;\n\n case 'Tab':\n if (open) {\n handleClose();\n }\n break;\n\n case 'Home':\n if (open && len > 0) {\n e.preventDefault();\n setFocusedIndex(0);\n }\n break;\n\n case 'End':\n if (open && len > 0) {\n e.preventDefault();\n setFocusedIndex(len - 1);\n }\n break;\n }\n };\n\n // Click outside to close\n useClickOutside({\n refs: () => [containerRef, dropdownRef],\n onClickOutside: handleClose,\n enabled: isOpen,\n });\n\n // Close on scroll (any scrollable container, but not internal scroll)\n createEffect(() => {\n if (!isOpen()) {\n return;\n }\n\n const handleScroll = (e: Event) => {\n // Ignore scroll events from inside the dropdown\n if (dropdownRef?.contains(e.target as Node)) {\n return;\n }\n handleClose();\n };\n\n // Use capture to catch scroll events on any scrollable ancestor\n window.addEventListener('scroll', handleScroll, true);\n onCleanup(() => window.removeEventListener('scroll', handleScroll, true));\n });\n\n // Calculate dropdown position\n const dropdownPosition = createMemo(() => {\n // Track isOpen to recalculate when dropdown opens\n if (!isOpen() || !containerRef) {\n return {};\n }\n\n const rect = containerRef.getBoundingClientRect();\n const spaceBelow = window.innerHeight - rect.bottom;\n const spaceAbove = rect.top;\n const dropdownHeight = 240; // max-h-60 = 15rem = 240px\n\n // Prefer below, flip to above if not enough space\n const showAbove = spaceBelow < dropdownHeight && spaceAbove > spaceBelow;\n\n return {\n left: `${rect.left}px`,\n width: `${rect.width}px`,\n ...(showAbove\n ? { bottom: `${window.innerHeight - rect.top + 4}px` }\n : { top: `${rect.bottom + 4}px` }),\n };\n });\n\n const sizeClasses = () => INPUT_SIZE_CLASSES[size()];\n const itemSizeClasses = () => DROPDOWN_ITEM_SIZE_CLASSES[size()];\n\n return (\n <div class={`w-full ${props.class ?? ''}`} ref={containerRef}>\n <Show when={props.label}>\n <label\n for={props.id}\n class=\"block text-sm font-medium text-surface-700 dark:text-surface-300 mb-1.5\"\n >\n {props.label}\n </label>\n </Show>\n\n <div class=\"relative\">\n <input\n ref={setInputRef}\n type=\"text\"\n id={props.id}\n name={props.name}\n class={`w-full glass-input text-surface-900 dark:text-surface-100 focus:outline-none disabled:opacity-50 disabled:cursor-not-allowed ${hasValue() && !props.disabled ? 'pr-16' : 'pr-10'} ${sizeClasses()} ${props.error ? 'border-error-500 dark:border-error-400' : ''}`}\n placeholder={props.placeholder}\n value={inputValue()}\n disabled={props.disabled}\n autocomplete=\"off\"\n role=\"combobox\"\n aria-expanded={isOpen()}\n aria-haspopup=\"listbox\"\n aria-autocomplete=\"list\"\n onInput={(e) => handleInputChange(e.currentTarget.value)}\n onFocus={handleInputFocus}\n onBlur={handleInputBlur}\n onKeyDown={handleKeyDown}\n onClick={() => !isOpen() && handleOpen()}\n />\n\n {/* Right side indicators */}\n <div class=\"absolute inset-y-0 right-0 flex items-center gap-1 pr-2\">\n <Show when={props.loading}>\n <div class=\"pointer-events-none\">\n <Spinner size=\"sm\" />\n </div>\n </Show>\n\n <Show when={!props.loading && hasValue() && !props.disabled}>\n <button\n type=\"button\"\n class=\"p-1 rounded-full text-surface-400 hover:text-surface-600 dark:hover:text-surface-300 hover:bg-surface-200/50 dark:hover:bg-surface-700/50 transition-colors\"\n onClick={handleClear}\n tabIndex={-1}\n aria-label=\"Clear selection\"\n >\n <CloseIcon class=\"w-4 h-4\" />\n </button>\n </Show>\n\n <Show when={!props.loading}>\n <button\n type=\"button\"\n class=\"p-1 text-surface-400 cursor-pointer disabled:cursor-not-allowed\"\n onClick={handleToggle}\n disabled={props.disabled}\n tabIndex={-1}\n aria-label={isOpen() ? 'Close dropdown' : 'Open dropdown'}\n >\n <ChevronDownIcon\n class={`transition-transform duration-150 ${isOpen() ? 'rotate-180' : ''}`}\n />\n </button>\n </Show>\n </div>\n </div>\n\n <Show when={props.error}>\n <p class=\"mt-1.5 text-sm text-error-500 dark:text-error-400\">\n {props.error}\n </p>\n </Show>\n\n {/* Dropdown */}\n <Show when={isOpen()}>\n <PortalWithDarkMode>\n <div\n ref={dropdownRef}\n class=\"fixed z-50 glass-card rounded-xl shadow-lg overflow-hidden animate-in fade-in zoom-in-95 duration-150\"\n style={dropdownPosition()}\n role=\"listbox\"\n >\n <div class=\"max-h-60 overflow-y-auto scrollbar-thin py-1\">\n <Show\n when={filteredOptions().length > 0}\n fallback={\n <div\n class={`text-surface-500 dark:text-surface-400 text-center ${itemSizeClasses()}`}\n >\n {emptyText()}\n </div>\n }\n >\n <For each={filteredOptions()}>\n {(option) => {\n const isFocused = () => {\n const focusableIdx = focusableOptions().indexOf(option);\n return focusableIdx === focusedIndex();\n };\n const isSelected = () => option.value === props.value;\n\n return (\n <button\n type=\"button\"\n data-option\n class={`w-full text-left transition-colors ${itemSizeClasses()}\n ${\n option.disabled\n ? 'text-surface-400 dark:text-surface-600 cursor-not-allowed'\n : 'text-surface-700 dark:text-surface-200 cursor-pointer'\n }\n ${isFocused() ? 'bg-black/5 dark:bg-white/5' : ''}\n ${isSelected() ? 'bg-primary-50 dark:bg-primary-900/20 text-primary-700 dark:text-primary-300' : ''}\n ${!option.disabled && !isFocused() && !isSelected() ? 'hover:bg-black/5 dark:hover:bg-white/5' : ''}\n `}\n onClick={() => handleSelect(option)}\n onMouseEnter={() => {\n if (!option.disabled) {\n const focusableIdx =\n focusableOptions().indexOf(option);\n setFocusedIndex(focusableIdx);\n }\n }}\n disabled={option.disabled}\n role=\"option\"\n aria-selected={isSelected()}\n tabIndex={-1}\n >\n <HighlightedText\n text={option.label}\n highlight={inputValue()}\n />\n </button>\n );\n }}\n </For>\n </Show>\n </div>\n </div>\n </PortalWithDarkMode>\n </Show>\n </div>\n );\n};\n"],"names":["defaultFilterFn","option","inputValue","label","toLowerCase","includes","HighlightedText","props","parts","createMemo","highlight","trim","text","match","lowerText","lowerHighlight","result","lastIndex","index","indexOf","push","slice","length","_el$","_tmpl$","_$insert","_$createComponent","For","each","children","part","Show","when","fallback","_el$3","_el$2","_tmpl$2","Autocomplete","isOpen","setIsOpen","createSignal","setInputValue","focusedIndex","setFocusedIndex","internalInputRef","containerRef","dropdownRef","justSelected","setInputRef","el","ref","size","emptyText","filterFn","createEffect","selectedOption","options","find","opt","value","allowCustomValue","filteredOptions","input","filter","focusableOptions","disabled","on","firstFocusable","idx","item","querySelectorAll","scrollIntoView","block","handleOpen","handleToggle","handleClose","focus","handleSelect","onChange","handleClear","e","stopPropagation","onInputChange","hasValue","handleInputChange","handleInputFocus","handleInputBlur","relatedTarget","contains","setTimeout","matchingOption","handleKeyDown","len","open","key","preventDefault","prev","Math","min","max","selected","useClickOutside","refs","onClickOutside","enabled","handleScroll","target","window","addEventListener","onCleanup","removeEventListener","dropdownPosition","rect","getBoundingClientRect","spaceBelow","innerHeight","bottom","spaceAbove","top","showAbove","left","width","sizeClasses","INPUT_SIZE_CLASSES","itemSizeClasses","DROPDOWN_ITEM_SIZE_CLASSES","_el$4","_tmpl$9","_el$6","firstChild","_el$7","_el$8","nextSibling","_ref$","_$use","_el$5","_tmpl$3","_$effect","_$setAttribute","id","$$click","$$keydown","$$input","currentTarget","loading","_el$9","_tmpl$4","Spinner","_$memo","_el$0","_tmpl$5","CloseIcon","_el$1","_tmpl$6","ChevronDownIcon","_p$","_v$","_v$2","t","undefined","error","_el$10","_tmpl$7","PortalWithDarkMode","_el$11","_tmpl$8","_el$12","_ref$2","_el$13","_tmpl$0","_$className","isFocused","isSelected","_el$14","_tmpl$1","focusableIdx","_v$0","_v$1","_v$10","a","_$p","_$style","_v$3","class","_v$4","_v$5","name","_v$6","_v$7","placeholder","_v$8","_v$9","o","i","n","s","_$delegateEvents"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Chat.d.ts","sourceRoot":"","sources":["../../../src/components/Chat/Chat.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAI1C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,eAAO,MAAM,IAAI,EAAE,SAAS,CAAC,SAAS,CAkCrC,CAAC"}
1
+ {"version":3,"file":"Chat.d.ts","sourceRoot":"","sources":["../../../src/components/Chat/Chat.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAI1C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,eAAO,MAAM,IAAI,EAAE,SAAS,CAAC,SAAS,CAmCrC,CAAC"}
@@ -37,6 +37,9 @@ const b = (e) => (() => {
37
37
  },
38
38
  get emptyState() {
39
39
  return e.emptyState;
40
+ },
41
+ get codeBlockActions() {
42
+ return e.codeBlockActions;
40
43
  }
41
44
  }), null), r(t, a(g, {
42
45
  get onSendMessage() {
@@ -1 +1 @@
1
- {"version":3,"file":"Chat.js","sources":["../../../src/components/Chat/Chat.tsx"],"sourcesContent":["import type { Component } from 'solid-js';\nimport { Show } from 'solid-js';\nimport { ChatInput } from './ChatInput';\nimport { ChatMessageList } from './ChatMessageList';\nimport type { ChatProps } from './types';\n\n/**\n * A complete chat interface with message list and input.\n *\n * @example\n * ```tsx\n * const [messages, setMessages] = createSignal<ChatMessage[]>([]);\n * const [isStreaming, setIsStreaming] = createSignal(false);\n *\n * const handleSend = (content: string) => {\n * // Add user message\n * setMessages(prev => [...prev, {\n * id: crypto.randomUUID(),\n * role: 'user',\n * content,\n * timestamp: new Date(),\n * status: 'complete'\n * }]);\n * // Start streaming response...\n * setIsStreaming(true);\n * };\n *\n * <Chat\n * messages={messages()}\n * onSendMessage={handleSend}\n * isStreaming={isStreaming()}\n * showTypingIndicator\n * userName=\"You\"\n * assistantName=\"Claude\"\n * />\n * ```\n */\nexport const Chat: Component<ChatProps> = (props) => {\n return (\n <div\n class={`flex flex-col h-full bg-white/30 dark:bg-surface-900/30 backdrop-blur-sm rounded-2xl overflow-hidden ${props.class ?? ''}`}\n >\n {/* Optional header */}\n <Show when={props.header}>\n <div class=\"border-b border-surface-200 dark:border-surface-700\">\n {props.header}\n </div>\n </Show>\n\n {/* Message list */}\n <ChatMessageList\n messages={props.messages}\n userName={props.userName}\n userAvatarUrl={props.userAvatarUrl}\n assistantName={props.assistantName}\n assistantAvatarUrl={props.assistantAvatarUrl}\n showTypingIndicator={props.showTypingIndicator}\n isStreaming={props.isStreaming}\n emptyState={props.emptyState}\n />\n\n {/* Input area */}\n <ChatInput\n onSendMessage={props.onSendMessage}\n onCancelStream={props.onCancelStream}\n isStreaming={props.isStreaming}\n disabled={props.disabled}\n placeholder={props.placeholder}\n />\n </div>\n );\n};\n"],"names":["Chat","props","_el$","_tmpl$2","_$insert","_$createComponent","Show","when","header","children","_el$2","_tmpl$","ChatMessageList","messages","userName","userAvatarUrl","assistantName","assistantAvatarUrl","showTypingIndicator","isStreaming","emptyState","ChatInput","onSendMessage","onCancelStream","disabled","placeholder","_$effect","_$className","class"],"mappings":";;;;;AAqCO,MAAMA,IAA8BC,CAAAA,OACzC,MAAA;AAAA,MAAAC,IAAAC,EAAAA;AAAAC,SAAAA,EAAAF,GAAAG,EAKKC,GAAI;AAAA,IAAA,IAACC,OAAI;AAAA,aAAEN,EAAMO;AAAAA,IAAM;AAAA,IAAA,IAAAC,WAAA;AAAA,UAAAC,IAAAC,EAAAA;AAAAP,aAAAA,EAAAM,GAAA,MAEnBT,EAAMO,MAAM,GAAAE;AAAAA,IAAA;AAAA,EAAA,CAAA,GAAA,IAAA,GAAAN,EAAAF,GAAAG,EAKhBO,GAAe;AAAA,IAAA,IACdC,WAAQ;AAAA,aAAEZ,EAAMY;AAAAA,IAAQ;AAAA,IAAA,IACxBC,WAAQ;AAAA,aAAEb,EAAMa;AAAAA,IAAQ;AAAA,IAAA,IACxBC,gBAAa;AAAA,aAAEd,EAAMc;AAAAA,IAAa;AAAA,IAAA,IAClCC,gBAAa;AAAA,aAAEf,EAAMe;AAAAA,IAAa;AAAA,IAAA,IAClCC,qBAAkB;AAAA,aAAEhB,EAAMgB;AAAAA,IAAkB;AAAA,IAAA,IAC5CC,sBAAmB;AAAA,aAAEjB,EAAMiB;AAAAA,IAAmB;AAAA,IAAA,IAC9CC,cAAW;AAAA,aAAElB,EAAMkB;AAAAA,IAAW;AAAA,IAAA,IAC9BC,aAAU;AAAA,aAAEnB,EAAMmB;AAAAA,IAAU;AAAA,EAAA,CAAA,GAAA,IAAA,GAAAhB,EAAAF,GAAAG,EAI7BgB,GAAS;AAAA,IAAA,IACRC,gBAAa;AAAA,aAAErB,EAAMqB;AAAAA,IAAa;AAAA,IAAA,IAClCC,iBAAc;AAAA,aAAEtB,EAAMsB;AAAAA,IAAc;AAAA,IAAA,IACpCJ,cAAW;AAAA,aAAElB,EAAMkB;AAAAA,IAAW;AAAA,IAAA,IAC9BK,WAAQ;AAAA,aAAEvB,EAAMuB;AAAAA,IAAQ;AAAA,IAAA,IACxBC,cAAW;AAAA,aAAExB,EAAMwB;AAAAA,IAAW;AAAA,EAAA,CAAA,GAAA,IAAA,GAAAC,EAAA,MAAAC,EAAAzB,GA3BzB,wGAAwGD,EAAM2B,SAAS,EAAE,EAAE,CAAA,GAAA1B;AAAA,GAAA;"}
1
+ {"version":3,"file":"Chat.js","sources":["../../../src/components/Chat/Chat.tsx"],"sourcesContent":["import type { Component } from 'solid-js';\nimport { Show } from 'solid-js';\nimport { ChatInput } from './ChatInput';\nimport { ChatMessageList } from './ChatMessageList';\nimport type { ChatProps } from './types';\n\n/**\n * A complete chat interface with message list and input.\n *\n * @example\n * ```tsx\n * const [messages, setMessages] = createSignal<ChatMessage[]>([]);\n * const [isStreaming, setIsStreaming] = createSignal(false);\n *\n * const handleSend = (content: string) => {\n * // Add user message\n * setMessages(prev => [...prev, {\n * id: crypto.randomUUID(),\n * role: 'user',\n * content,\n * timestamp: new Date(),\n * status: 'complete'\n * }]);\n * // Start streaming response...\n * setIsStreaming(true);\n * };\n *\n * <Chat\n * messages={messages()}\n * onSendMessage={handleSend}\n * isStreaming={isStreaming()}\n * showTypingIndicator\n * userName=\"You\"\n * assistantName=\"Claude\"\n * />\n * ```\n */\nexport const Chat: Component<ChatProps> = (props) => {\n return (\n <div\n class={`flex flex-col h-full bg-white/30 dark:bg-surface-900/30 backdrop-blur-sm rounded-2xl overflow-hidden ${props.class ?? ''}`}\n >\n {/* Optional header */}\n <Show when={props.header}>\n <div class=\"border-b border-surface-200 dark:border-surface-700\">\n {props.header}\n </div>\n </Show>\n\n {/* Message list */}\n <ChatMessageList\n messages={props.messages}\n userName={props.userName}\n userAvatarUrl={props.userAvatarUrl}\n assistantName={props.assistantName}\n assistantAvatarUrl={props.assistantAvatarUrl}\n showTypingIndicator={props.showTypingIndicator}\n isStreaming={props.isStreaming}\n emptyState={props.emptyState}\n codeBlockActions={props.codeBlockActions}\n />\n\n {/* Input area */}\n <ChatInput\n onSendMessage={props.onSendMessage}\n onCancelStream={props.onCancelStream}\n isStreaming={props.isStreaming}\n disabled={props.disabled}\n placeholder={props.placeholder}\n />\n </div>\n );\n};\n"],"names":["Chat","props","_el$","_tmpl$2","_$insert","_$createComponent","Show","when","header","children","_el$2","_tmpl$","ChatMessageList","messages","userName","userAvatarUrl","assistantName","assistantAvatarUrl","showTypingIndicator","isStreaming","emptyState","codeBlockActions","ChatInput","onSendMessage","onCancelStream","disabled","placeholder","_$effect","_$className","class"],"mappings":";;;;;AAqCO,MAAMA,IAA8BC,CAAAA,OACzC,MAAA;AAAA,MAAAC,IAAAC,EAAAA;AAAAC,SAAAA,EAAAF,GAAAG,EAKKC,GAAI;AAAA,IAAA,IAACC,OAAI;AAAA,aAAEN,EAAMO;AAAAA,IAAM;AAAA,IAAA,IAAAC,WAAA;AAAA,UAAAC,IAAAC,EAAAA;AAAAP,aAAAA,EAAAM,GAAA,MAEnBT,EAAMO,MAAM,GAAAE;AAAAA,IAAA;AAAA,EAAA,CAAA,GAAA,IAAA,GAAAN,EAAAF,GAAAG,EAKhBO,GAAe;AAAA,IAAA,IACdC,WAAQ;AAAA,aAAEZ,EAAMY;AAAAA,IAAQ;AAAA,IAAA,IACxBC,WAAQ;AAAA,aAAEb,EAAMa;AAAAA,IAAQ;AAAA,IAAA,IACxBC,gBAAa;AAAA,aAAEd,EAAMc;AAAAA,IAAa;AAAA,IAAA,IAClCC,gBAAa;AAAA,aAAEf,EAAMe;AAAAA,IAAa;AAAA,IAAA,IAClCC,qBAAkB;AAAA,aAAEhB,EAAMgB;AAAAA,IAAkB;AAAA,IAAA,IAC5CC,sBAAmB;AAAA,aAAEjB,EAAMiB;AAAAA,IAAmB;AAAA,IAAA,IAC9CC,cAAW;AAAA,aAAElB,EAAMkB;AAAAA,IAAW;AAAA,IAAA,IAC9BC,aAAU;AAAA,aAAEnB,EAAMmB;AAAAA,IAAU;AAAA,IAAA,IAC5BC,mBAAgB;AAAA,aAAEpB,EAAMoB;AAAAA,IAAgB;AAAA,EAAA,CAAA,GAAA,IAAA,GAAAjB,EAAAF,GAAAG,EAIzCiB,GAAS;AAAA,IAAA,IACRC,gBAAa;AAAA,aAAEtB,EAAMsB;AAAAA,IAAa;AAAA,IAAA,IAClCC,iBAAc;AAAA,aAAEvB,EAAMuB;AAAAA,IAAc;AAAA,IAAA,IACpCL,cAAW;AAAA,aAAElB,EAAMkB;AAAAA,IAAW;AAAA,IAAA,IAC9BM,WAAQ;AAAA,aAAExB,EAAMwB;AAAAA,IAAQ;AAAA,IAAA,IACxBC,cAAW;AAAA,aAAEzB,EAAMyB;AAAAA,IAAW;AAAA,EAAA,CAAA,GAAA,IAAA,GAAAC,EAAA,MAAAC,EAAA1B,GA5BzB,wGAAwGD,EAAM4B,SAAS,EAAE,EAAE,CAAA,GAAA3B;AAAA,GAAA;"}
@@ -1 +1 @@
1
- {"version":3,"file":"ChatInput.d.ts","sourceRoot":"","sources":["../../../src/components/Chat/ChatInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAG1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C;;GAEG;AACH,eAAO,MAAM,SAAS,EAAE,SAAS,CAAC,cAAc,CA4G/C,CAAC"}
1
+ {"version":3,"file":"ChatInput.d.ts","sourceRoot":"","sources":["../../../src/components/Chat/ChatInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAG1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C;;GAEG;AACH,eAAO,MAAM,SAAS,EAAE,SAAS,CAAC,cAAc,CA6G/C,CAAC"}
@@ -1,62 +1,62 @@
1
- import { template as u, insert as c, createComponent as d, effect as s, setAttribute as k, use as S, delegateEvents as C } from "solid-js/web";
2
- import { createSignal as _, createEffect as D, onMount as E, Show as H } from "solid-js";
1
+ import { template as u, insert as c, createComponent as d, effect as o, setAttribute as $, use as k, delegateEvents as C } from "solid-js/web";
2
+ import { createSignal as _, createEffect as H, onMount as D, Show as E } from "solid-js";
3
3
  import { StopIcon as I, SendIcon as j } from "./icons.js";
4
- var z = /* @__PURE__ */ u('<button type=button class="shrink-0 w-10 h-10 flex items-center justify-center rounded-xl bg-red-500 text-white hover:bg-red-600 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"aria-label="Stop generation">'), M = /* @__PURE__ */ u('<div class="flex items-end gap-2 p-4 border-t border-surface-200 dark:border-surface-700 bg-white/50 dark:bg-surface-900/50 backdrop-blur-sm"><div class=flex-1><textarea rows=1 class="w-full glass-input text-surface-800 dark:text-surface-200 resize-none focus:outline-none disabled:opacity-50 disabled:cursor-not-allowed py-2.5 px-4 min-h-[42px]"style=max-height:150px>'), K = /* @__PURE__ */ u('<button type=button class="shrink-0 w-10 h-10 flex items-center justify-center rounded-xl bg-accent-500 text-white hover:bg-accent-600 disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:bg-accent-500 transition-colors"aria-label="Send message">');
5
- const V = (a) => {
6
- const [i, h] = _("");
7
- let n;
8
- const x = () => a.placeholder ?? "Type a message...", o = () => a.disabled ?? !1, f = () => i().trim().length > 0 && !o(), b = () => {
9
- if (n) {
10
- n.style.height = "auto";
11
- const e = n.scrollHeight, r = 150;
12
- n.style.height = `${Math.min(e, r)}px`;
4
+ var z = /* @__PURE__ */ u('<button type=button class="shrink-0 w-[42px] h-[42px] flex items-center justify-center rounded-xl bg-error-500 text-white hover:bg-error-600 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"aria-label="Stop generation">'), M = /* @__PURE__ */ u('<div class="flex items-end gap-2 p-4 border-t border-surface-200 dark:border-surface-700 bg-white/50 dark:bg-surface-900/50 backdrop-blur-sm"><div class=flex-1><textarea rows=1 class="flex w-full glass-input text-surface-800 dark:text-surface-200 resize-none overflow-hidden focus:outline-none disabled:opacity-50 disabled:cursor-not-allowed py-2.5 px-4 min-h-[42px]">'), K = /* @__PURE__ */ u('<button type=button class="shrink-0 w-[42px] h-[42px] flex items-center justify-center rounded-xl bg-accent-500 text-white hover:bg-accent-600 disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:bg-accent-500 transition-colors"aria-label="Send message">');
5
+ const V = (n) => {
6
+ const [i, f] = _("");
7
+ let a;
8
+ const p = () => n.placeholder ?? "Type a message...", s = () => n.disabled ?? !1, h = () => i().trim().length > 0 && !s() && !n.isStreaming, g = () => {
9
+ if (a) {
10
+ a.style.height = "auto";
11
+ const e = a.scrollHeight, l = 150, r = Math.min(e, l);
12
+ a.style.height = `${r}px`, a.style.overflowY = e > l ? "auto" : "hidden";
13
13
  }
14
14
  };
15
- D(() => {
16
- i(), b();
17
- }), E(() => {
18
- b();
15
+ H(() => {
16
+ i(), g();
17
+ }), D(() => {
18
+ g();
19
19
  });
20
- const g = () => {
20
+ const b = () => {
21
21
  const e = i().trim();
22
- e && !o() && (a.onSendMessage(e), h(""), n && (n.style.height = "auto"));
22
+ e && !s() && !n.isStreaming && (n.onSendMessage(e), f(""), a && (a.style.height = "auto"));
23
23
  }, m = () => {
24
- a.onCancelStream && a.onCancelStream();
25
- }, $ = (e) => {
26
- e.key === "Enter" && !e.shiftKey ? (e.preventDefault(), f() && g()) : e.key === "Escape" && a.isStreaming && (e.preventDefault(), m());
24
+ n.onCancelStream && n.onCancelStream();
27
25
  }, w = (e) => {
28
- const r = e.target;
29
- h(r.value);
26
+ e.key === "Enter" && !e.shiftKey ? (e.preventDefault(), h() && b()) : e.key === "Escape" && n.isStreaming && (e.preventDefault(), m());
27
+ }, S = (e) => {
28
+ const l = e.target;
29
+ f(l.value);
30
30
  };
31
31
  return (() => {
32
- var e = M(), r = e.firstChild, l = r.firstChild;
33
- l.$$keydown = $, l.$$input = w;
34
- var v = n;
35
- return typeof v == "function" ? S(v, l) : n = l, c(e, d(H, {
32
+ var e = M(), l = e.firstChild, r = l.firstChild;
33
+ r.$$keydown = w, r.$$input = S;
34
+ var v = a;
35
+ return typeof v == "function" ? k(v, r) : a = r, c(e, d(E, {
36
36
  get when() {
37
- return a.isStreaming;
37
+ return n.isStreaming;
38
38
  },
39
39
  get fallback() {
40
40
  return (() => {
41
41
  var t = K();
42
- return t.$$click = g, c(t, d(j, {
42
+ return t.$$click = b, c(t, d(j, {
43
43
  size: 18
44
- })), s(() => t.disabled = !f()), t;
44
+ })), o(() => t.disabled = !h()), t;
45
45
  })();
46
46
  },
47
47
  get children() {
48
48
  var t = z();
49
49
  return t.$$click = m, c(t, d(I, {
50
50
  size: 18
51
- })), s(() => t.disabled = !a.onCancelStream), t;
51
+ })), o(() => t.disabled = !n.onCancelStream), t;
52
52
  }
53
- }), null), s((t) => {
54
- var y = x(), p = o();
55
- return y !== t.e && k(l, "placeholder", t.e = y), p !== t.t && (l.disabled = t.t = p), t;
53
+ }), null), o((t) => {
54
+ var x = p(), y = s();
55
+ return x !== t.e && $(r, "placeholder", t.e = x), y !== t.t && (r.disabled = t.t = y), t;
56
56
  }, {
57
57
  e: void 0,
58
58
  t: void 0
59
- }), s(() => l.value = i()), e;
59
+ }), o(() => r.value = i()), e;
60
60
  })();
61
61
  };
62
62
  C(["input", "keydown", "click"]);
@@ -1 +1 @@
1
- {"version":3,"file":"ChatInput.js","sources":["../../../src/components/Chat/ChatInput.tsx"],"sourcesContent":["import type { Component } from 'solid-js';\nimport { Show, createEffect, createSignal, onMount } from 'solid-js';\nimport { SendIcon, StopIcon } from './icons';\nimport type { ChatInputProps } from './types';\n\n/**\n * Chat input with textarea and send/stop button\n */\nexport const ChatInput: Component<ChatInputProps> = (props) => {\n const [value, setValue] = createSignal('');\n let textareaRef: HTMLTextAreaElement | undefined;\n\n const placeholder = () => props.placeholder ?? 'Type a message...';\n const isDisabled = () => props.disabled ?? false;\n const canSend = () => value().trim().length > 0 && !isDisabled();\n\n // Auto-resize textarea based on content\n const adjustHeight = () => {\n if (textareaRef) {\n textareaRef.style.height = 'auto';\n const scrollHeight = textareaRef.scrollHeight;\n // Max height of ~6 lines\n const maxHeight = 150;\n textareaRef.style.height = `${Math.min(scrollHeight, maxHeight)}px`;\n }\n };\n\n createEffect(() => {\n // Trigger resize when value changes\n value();\n adjustHeight();\n });\n\n onMount(() => {\n adjustHeight();\n });\n\n const handleSend = () => {\n const content = value().trim();\n if (content && !isDisabled()) {\n props.onSendMessage(content);\n setValue('');\n // Reset textarea height\n if (textareaRef) {\n textareaRef.style.height = 'auto';\n }\n }\n };\n\n const handleCancel = () => {\n if (props.onCancelStream) {\n props.onCancelStream();\n }\n };\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n if (canSend()) {\n handleSend();\n }\n } else if (e.key === 'Escape' && props.isStreaming) {\n e.preventDefault();\n handleCancel();\n }\n };\n\n const handleInput = (e: Event) => {\n const target = e.target as HTMLTextAreaElement;\n setValue(target.value);\n };\n\n return (\n <div class=\"flex items-end gap-2 p-4 border-t border-surface-200 dark:border-surface-700 bg-white/50 dark:bg-surface-900/50 backdrop-blur-sm\">\n {/* Textarea */}\n <div class=\"flex-1\">\n <textarea\n ref={textareaRef}\n value={value()}\n onInput={handleInput}\n onKeyDown={handleKeyDown}\n placeholder={placeholder()}\n disabled={isDisabled()}\n rows={1}\n class=\"w-full glass-input text-surface-800 dark:text-surface-200 resize-none focus:outline-none disabled:opacity-50 disabled:cursor-not-allowed py-2.5 px-4 min-h-[42px]\"\n style={{ 'max-height': '150px' }}\n />\n </div>\n\n {/* Send/Stop button */}\n <Show\n when={props.isStreaming}\n fallback={\n <button\n type=\"button\"\n onClick={handleSend}\n disabled={!canSend()}\n class=\"shrink-0 w-10 h-10 flex items-center justify-center rounded-xl bg-accent-500 text-white hover:bg-accent-600 disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:bg-accent-500 transition-colors\"\n aria-label=\"Send message\"\n >\n <SendIcon size={18} />\n </button>\n }\n >\n <button\n type=\"button\"\n onClick={handleCancel}\n disabled={!props.onCancelStream}\n class=\"shrink-0 w-10 h-10 flex items-center justify-center rounded-xl bg-red-500 text-white hover:bg-red-600 disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\n aria-label=\"Stop generation\"\n >\n <StopIcon size={18} />\n </button>\n </Show>\n </div>\n );\n};\n"],"names":["ChatInput","props","value","setValue","createSignal","textareaRef","placeholder","isDisabled","disabled","canSend","trim","length","adjustHeight","style","height","scrollHeight","maxHeight","Math","min","createEffect","onMount","handleSend","content","onSendMessage","handleCancel","onCancelStream","handleKeyDown","e","key","shiftKey","preventDefault","isStreaming","handleInput","target","_el$","_tmpl$2","_el$2","firstChild","_el$3","$$keydown","$$input","_ref$","_$use","_$insert","_$createComponent","Show","when","fallback","_el$5","_tmpl$3","$$click","SendIcon","size","_$effect","children","_el$4","_tmpl$","StopIcon","_p$","_v$","_v$2","_$setAttribute","t","undefined","_$delegateEvents"],"mappings":"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"}
1
+ {"version":3,"file":"ChatInput.js","sources":["../../../src/components/Chat/ChatInput.tsx"],"sourcesContent":["import type { Component } from 'solid-js';\nimport { Show, createEffect, createSignal, onMount } from 'solid-js';\nimport { SendIcon, StopIcon } from './icons';\nimport type { ChatInputProps } from './types';\n\n/**\n * Chat input with textarea and send/stop button\n */\nexport const ChatInput: Component<ChatInputProps> = (props) => {\n const [value, setValue] = createSignal('');\n let textareaRef: HTMLTextAreaElement | undefined;\n\n const placeholder = () => props.placeholder ?? 'Type a message...';\n const isDisabled = () => props.disabled ?? false;\n const canSend = () => value().trim().length > 0 && !isDisabled() && !props.isStreaming;\n\n // Auto-resize textarea based on content\n const adjustHeight = () => {\n if (textareaRef) {\n textareaRef.style.height = 'auto';\n const scrollHeight = textareaRef.scrollHeight;\n // Max height of ~6 lines\n const maxHeight = 150;\n const newHeight = Math.min(scrollHeight, maxHeight);\n textareaRef.style.height = `${newHeight}px`;\n textareaRef.style.overflowY = scrollHeight > maxHeight ? 'auto' : 'hidden';\n }\n };\n\n createEffect(() => {\n // Trigger resize when value changes\n value();\n adjustHeight();\n });\n\n onMount(() => {\n adjustHeight();\n });\n\n const handleSend = () => {\n const content = value().trim();\n if (content && !isDisabled() && !props.isStreaming) {\n props.onSendMessage(content);\n setValue('');\n // Reset textarea height\n if (textareaRef) {\n textareaRef.style.height = 'auto';\n }\n }\n };\n\n const handleCancel = () => {\n if (props.onCancelStream) {\n props.onCancelStream();\n }\n };\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n if (canSend()) {\n handleSend();\n }\n } else if (e.key === 'Escape' && props.isStreaming) {\n e.preventDefault();\n handleCancel();\n }\n };\n\n const handleInput = (e: Event) => {\n const target = e.target as HTMLTextAreaElement;\n setValue(target.value);\n };\n\n return (\n <div class=\"flex items-end gap-2 p-4 border-t border-surface-200 dark:border-surface-700 bg-white/50 dark:bg-surface-900/50 backdrop-blur-sm\">\n {/* Textarea */}\n <div class=\"flex-1\">\n <textarea\n ref={textareaRef}\n value={value()}\n onInput={handleInput}\n onKeyDown={handleKeyDown}\n placeholder={placeholder()}\n disabled={isDisabled()}\n rows={1}\n class=\"flex w-full glass-input text-surface-800 dark:text-surface-200 resize-none overflow-hidden focus:outline-none disabled:opacity-50 disabled:cursor-not-allowed py-2.5 px-4 min-h-[42px]\"\n />\n </div>\n\n {/* Send/Stop button */}\n <Show\n when={props.isStreaming}\n fallback={\n <button\n type=\"button\"\n onClick={handleSend}\n disabled={!canSend()}\n class=\"shrink-0 w-[42px] h-[42px] flex items-center justify-center rounded-xl bg-accent-500 text-white hover:bg-accent-600 disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:bg-accent-500 transition-colors\"\n aria-label=\"Send message\"\n >\n <SendIcon size={18} />\n </button>\n }\n >\n <button\n type=\"button\"\n onClick={handleCancel}\n disabled={!props.onCancelStream}\n class=\"shrink-0 w-[42px] h-[42px] flex items-center justify-center rounded-xl bg-error-500 text-white hover:bg-error-600 disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\n aria-label=\"Stop generation\"\n >\n <StopIcon size={18} />\n </button>\n </Show>\n </div>\n );\n};\n"],"names":["ChatInput","props","value","setValue","createSignal","textareaRef","placeholder","isDisabled","disabled","canSend","trim","length","isStreaming","adjustHeight","style","height","scrollHeight","maxHeight","newHeight","Math","min","overflowY","createEffect","onMount","handleSend","content","onSendMessage","handleCancel","onCancelStream","handleKeyDown","e","key","shiftKey","preventDefault","handleInput","target","_el$","_tmpl$2","_el$2","firstChild","_el$3","$$keydown","$$input","_ref$","_$use","_$insert","_$createComponent","Show","when","fallback","_el$5","_tmpl$3","$$click","SendIcon","size","_$effect","children","_el$4","_tmpl$","StopIcon","_p$","_v$","_v$2","_$setAttribute","t","undefined","_$delegateEvents"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ChatMessage.d.ts","sourceRoot":"","sources":["../../../src/components/Chat/ChatMessage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAK1C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEhD;;GAEG;AACH,eAAO,MAAM,WAAW,EAAE,SAAS,CAAC,gBAAgB,CAsGnD,CAAC"}
1
+ {"version":3,"file":"ChatMessage.d.ts","sourceRoot":"","sources":["../../../src/components/Chat/ChatMessage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAM1C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEhD;;GAEG;AACH,eAAO,MAAM,WAAW,EAAE,SAAS,CAAC,gBAAgB,CAwHnD,CAAC"}