@r2digisolutions/components 0.16.4 → 0.17.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.
@@ -134,25 +134,25 @@
134
134
 
135
135
  <div
136
136
  class={[
137
- 'flex flex-col overflow-hidden rounded-2xl border border-border bg-surface-elevated shadow-xl',
138
- 'h-[min(560px,70vh)] w-full min-w-[320px] max-w-[420px]',
137
+ 'rounded-2xl border-border bg-surface-elevated shadow-xl flex flex-col overflow-hidden border',
138
+ 'h-[min(560px,70vh)] w-full max-w-[420px] min-w-[320px]',
139
139
  className
140
140
  ]}
141
141
  role="complementary"
142
142
  aria-label={title}
143
143
  >
144
144
  <!-- Header -->
145
- <header class="flex shrink-0 items-center gap-2 border-b border-border px-3 py-2.5">
145
+ <header class="gap-2 border-border px-3 py-2.5 flex shrink-0 items-center border-b">
146
146
  <span
147
- class="flex h-7 w-7 shrink-0 items-center justify-center rounded-lg bg-brand-100 text-brand-600 dark:bg-brand-900/40 dark:text-brand-400"
147
+ class="h-7 w-7 rounded-lg bg-brand-100 text-brand-600 dark:bg-brand-900/40 dark:text-brand-400 flex shrink-0 items-center justify-center"
148
148
  aria-hidden="true"
149
149
  >
150
150
  <Sparkles size={15} strokeWidth={2} />
151
151
  </span>
152
152
  <div class="min-w-0 flex-1">
153
- <p class="truncate text-sm font-semibold text-primary">{title}</p>
153
+ <p class="text-sm font-semibold text-primary truncate">{title}</p>
154
154
  {#if statusLabel}
155
- <p class="truncate text-xs text-muted">{statusLabel}</p>
155
+ <p class="text-xs text-muted truncate">{statusLabel}</p>
156
156
  {/if}
157
157
  </div>
158
158
  <IconButton variant="ghost" size="xs" label={newChatLabel} onclick={() => onnewchat?.()}>
@@ -164,22 +164,22 @@
164
164
  </header>
165
165
 
166
166
  <!-- Body -->
167
- <div bind:this={scrollEl} class="min-h-0 flex-1 overflow-y-auto px-3 py-3">
167
+ <div bind:this={scrollEl} class="min-h-0 px-3 py-3 flex-1 overflow-y-auto">
168
168
  {#if isEmpty}
169
- <div class="flex flex-col items-center justify-center gap-4 py-8 text-center">
169
+ <div class="gap-4 py-8 flex flex-col items-center justify-center text-center">
170
170
  <span
171
- class="flex h-12 w-12 items-center justify-center rounded-2xl bg-brand-50 text-brand-500 dark:bg-brand-950/30 dark:text-brand-400"
171
+ class="h-12 w-12 rounded-2xl bg-brand-50 text-brand-500 dark:bg-brand-950/30 dark:text-brand-400 flex items-center justify-center"
172
172
  aria-hidden="true"
173
173
  >
174
174
  <Sparkles size={24} strokeWidth={1.5} />
175
175
  </span>
176
176
  <p class="text-sm text-muted">{emptyHint}</p>
177
177
  {#if suggestions.length}
178
- <div class="flex flex-wrap justify-center gap-2">
178
+ <div class="gap-2 flex flex-wrap justify-center">
179
179
  {#each suggestions as suggestion (suggestion)}
180
180
  <button
181
181
  type="button"
182
- class="rounded-full border border-border bg-surface px-3 py-1.5 text-xs text-secondary transition-colors hover:border-brand-400 hover:text-brand-600 dark:hover:text-brand-400"
182
+ class="border-border bg-surface px-3 py-1.5 text-xs text-secondary hover:border-brand-400 hover:text-brand-600 dark:hover:text-brand-400 rounded-full border transition-colors"
183
183
  onclick={() => handleSuggestion(suggestion)}
184
184
  >
185
185
  {suggestion}
@@ -189,27 +189,27 @@
189
189
  {/if}
190
190
  </div>
191
191
  {:else}
192
- <div class="flex flex-col gap-3">
192
+ <div class="gap-3 flex flex-col">
193
193
  {#each messages as message (message.id)}
194
194
  {#if message.role === 'user'}
195
195
  <div class="flex justify-end">
196
196
  <div
197
- class="max-w-[80%] rounded-2xl rounded-br-sm bg-brand-600 px-3.5 py-2.5 text-sm leading-relaxed text-white"
197
+ class="rounded-2xl rounded-br-sm bg-brand-600 px-3.5 py-2.5 text-sm leading-relaxed text-white max-w-[80%]"
198
198
  >
199
199
  {message.content}
200
200
  </div>
201
201
  </div>
202
202
  {:else}
203
- <div class="flex flex-col gap-1.5">
204
- <div class="flex items-start gap-2">
203
+ <div class="gap-1.5 flex flex-col">
204
+ <div class="gap-2 flex items-start">
205
205
  <span
206
- class="mt-0.5 flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-brand-100 text-brand-600 dark:bg-brand-900/40 dark:text-brand-400"
206
+ class="mt-0.5 h-6 w-6 bg-brand-100 text-brand-600 dark:bg-brand-900/40 dark:text-brand-400 flex shrink-0 items-center justify-center rounded-full"
207
207
  aria-hidden="true"
208
208
  >
209
209
  <Sparkles size={12} strokeWidth={2} />
210
210
  </span>
211
211
  <div
212
- class="max-w-[calc(100%-2rem)] rounded-2xl rounded-bl-sm bg-surface-overlay px-3.5 py-2.5 text-sm leading-relaxed text-primary"
212
+ class="rounded-2xl rounded-bl-sm bg-surface-overlay px-3.5 py-2.5 text-sm leading-relaxed text-primary max-w-[calc(100%-2rem)]"
213
213
  >
214
214
  {message.content}
215
215
  </div>
@@ -224,15 +224,15 @@
224
224
  {/each}
225
225
 
226
226
  {#if loading && showLoadingBubble}
227
- <div class="flex items-center gap-2">
227
+ <div class="gap-2 flex items-center">
228
228
  <span
229
- class="flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-brand-100 text-brand-600 dark:bg-brand-900/40 dark:text-brand-400"
229
+ class="h-6 w-6 bg-brand-100 text-brand-600 dark:bg-brand-900/40 dark:text-brand-400 flex shrink-0 items-center justify-center rounded-full"
230
230
  aria-hidden="true"
231
231
  >
232
232
  <Sparkles size={12} strokeWidth={2} />
233
233
  </span>
234
234
  <div
235
- class="flex items-center gap-2 rounded-2xl rounded-bl-sm bg-surface-overlay px-3.5 py-2.5"
235
+ class="gap-2 rounded-2xl rounded-bl-sm bg-surface-overlay px-3.5 py-2.5 flex items-center"
236
236
  >
237
237
  <LoaderCircle size={14} strokeWidth={2} class="animate-spin text-muted" />
238
238
  <span class="text-xs text-muted">{loadingLabel}</span>
@@ -244,22 +244,22 @@
244
244
  </div>
245
245
 
246
246
  <!-- Footer -->
247
- <footer class="shrink-0 border-t border-border px-3 py-2.5">
248
- <div class="flex items-center gap-1.5">
247
+ <footer class="border-border px-3 py-2.5 shrink-0 border-t">
248
+ <div class="gap-1.5 flex items-center">
249
249
  <input
250
250
  type="text"
251
251
  bind:value={draft}
252
252
  placeholder={listening ? statusLabel || placeholder : placeholder}
253
253
  class={[
254
- 'h-9 min-w-0 flex-1 rounded-xl border bg-surface px-3 text-sm text-primary outline-none transition-shadow placeholder:text-muted focus:border-brand-400 focus:ring-2 focus:ring-brand-500/20',
255
- listening ? 'border-red-400 ring-2 ring-red-500/20' : 'border-border'
254
+ 'h-9 min-w-0 rounded-xl bg-surface px-3 text-sm text-primary placeholder:text-muted focus:border-brand-400 focus:ring-brand-500/20 flex-1 border transition-shadow outline-none focus:ring-2',
255
+ listening ? 'border-red-400 ring-red-500/20 ring-2' : 'border-border'
256
256
  ]}
257
257
  disabled={loading}
258
258
  onkeydown={handleKeydown}
259
259
  aria-label={placeholder}
260
260
  />
261
261
 
262
- <div class="flex shrink-0 items-center gap-0.5">
262
+ <div class="gap-0.5 flex shrink-0 items-center">
263
263
  {#if voiceEnabled}
264
264
  <IconButton
265
265
  variant="ghost"
@@ -33,6 +33,8 @@
33
33
  loading?: boolean;
34
34
  voiceEnabled?: boolean;
35
35
  listening?: boolean;
36
+ /** When false, opening keeps the current query (voice dictation). */
37
+ resetQueryOnOpen?: boolean;
36
38
  micLabel?: string;
37
39
  stopMicLabel?: string;
38
40
  class?: string;
@@ -51,6 +53,7 @@
51
53
  loading = false,
52
54
  voiceEnabled = false,
53
55
  listening = false,
56
+ resetQueryOnOpen = true,
54
57
  micLabel = 'Hablar',
55
58
  stopMicLabel = 'Parar micrófono',
56
59
  class: className = '',
@@ -141,9 +144,11 @@
141
144
  $effect(() => {
142
145
  if (!dialogEl) return;
143
146
  if (open && !dialogEl.open) {
144
- query = '';
147
+ if (resetQueryOnOpen) {
148
+ query = '';
149
+ untrack(() => onquery?.(''));
150
+ }
145
151
  activeIndex = Math.max(0, firstEnabledIndex());
146
- untrack(() => onquery?.(''));
147
152
  ignoreBackdropUntil = Date.now() + 400;
148
153
  dialogEl.showModal();
149
154
  } else if (!open && dialogEl.open) {
@@ -24,6 +24,8 @@ interface CommandPaletteProps {
24
24
  loading?: boolean;
25
25
  voiceEnabled?: boolean;
26
26
  listening?: boolean;
27
+ /** When false, opening keeps the current query (voice dictation). */
28
+ resetQueryOnOpen?: boolean;
27
29
  micLabel?: string;
28
30
  stopMicLabel?: string;
29
31
  class?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@r2digisolutions/components",
3
- "version": "0.16.4",
3
+ "version": "0.17.0",
4
4
  "private": false,
5
5
  "description": "R2DigiSolutions Svelte 5 component library — Atomic Design, Tailwind 4, Light/Dark mode",
6
6
  "license": "MIT",