@happyvertical/smrt-messages 0.34.6 → 0.34.8

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.
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "version": "1.0.0",
3
- "timestamp": 1782278435844,
3
+ "timestamp": 1782318242883,
4
4
  "packageName": "@happyvertical/smrt-messages",
5
- "packageVersion": "0.34.6",
5
+ "packageVersion": "0.34.8",
6
6
  "objects": {
7
7
  "@happyvertical/smrt-messages:AccountCollection": {
8
8
  "name": "accountcollection",
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "generatedAt": "2026-06-24T05:20:36.527Z",
3
+ "generatedAt": "2026-06-24T16:24:03.776Z",
4
4
  "packageName": "@happyvertical/smrt-messages",
5
- "packageVersion": "0.34.6",
5
+ "packageVersion": "0.34.8",
6
6
  "sourceManifestPath": "dist/manifest.json",
7
7
  "agentDocPath": "AGENTS.md",
8
8
  "sourceHashes": {
9
- "manifest": "74dd6bcd838fe3da57812b01b4e35eb63e6f61c12ff460a2ca6b75375598ffdb",
10
- "packageJson": "c68a8210454fbeb5aec5c41dbf13319fbc5bba00cf9b089eebd2e47a0a3949c4",
9
+ "manifest": "d1f7a55a2b6449350258b42e86f07dbf4acb7318582c17b232bc49d4da269875",
10
+ "packageJson": "5c0336ed38066651d6b70528138429f497205e16db193a655912ee226c25f5f2",
11
11
  "agents": "32563a30ceeb21bd8732042f894e2a148fd83727caffc1eec7c97540005c6fdc"
12
12
  },
13
13
  "exports": [
@@ -80,11 +80,12 @@ export interface Props {
80
80
  ondragleave={handleDragLeave}
81
81
  >
82
82
  <label class="upload-label">
83
+ <!-- raw-primitive-allow: native file input — the Input primitive binds value, which is invalid for type=file (throws InvalidStateError on the bind write-back) and renders a visible control; this hidden picker behind the drop zone stays native -->
83
84
  <input
84
85
  type="file"
85
86
  multiple
86
87
  class="file-input"
87
- onchange={(e) => handleFiles((e.target as HTMLInputElement).files)}
88
+ onchange={(e) => handleFiles((e.currentTarget as HTMLInputElement).files)}
88
89
  />
89
90
  <span class="upload-text">{t(M['messages.attachment_upload.drop_files'])}</span>
90
91
  </label>
@@ -155,7 +156,11 @@ export interface Props {
155
156
  cursor: pointer;
156
157
  }
157
158
 
158
- .file-input {
159
+ /*
160
+ * The native file input stays visually hidden — the visible affordance is the
161
+ * `.upload-text` label inside the styled drop-zone (issue #1589).
162
+ */
163
+ .upload-label .file-input {
159
164
  display: none;
160
165
  }
161
166
 
@@ -1 +1 @@
1
- {"version":3,"file":"AttachmentUpload.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/AttachmentUpload.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,WAAW,KAAK;IACpB,WAAW,EAAE,cAAc,EAAE,CAAC;IAC9B,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;IACnC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AA+ED,QAAA,MAAM,gBAAgB,2CAAwC,CAAC;AAC/D,KAAK,gBAAgB,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC5D,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"AttachmentUpload.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/AttachmentUpload.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,WAAW,KAAK;IACpB,WAAW,EAAE,cAAc,EAAE,CAAC;IAC9B,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;IACnC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAgFD,QAAA,MAAM,gBAAgB,2CAAwC,CAAC;AAC/D,KAAK,gBAAgB,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC5D,eAAe,gBAAgB,CAAC"}
@@ -18,6 +18,7 @@ export interface Props {
18
18
 
19
19
  <script lang="ts">
20
20
  import { useI18n } from '@happyvertical/smrt-ui/i18n';
21
+ import { Form, Input, Select, Textarea } from '@happyvertical/smrt-ui/forms';
21
22
  import { Button } from '@happyvertical/smrt-ui/ui';
22
23
  import { M } from '../i18n.js';
23
24
  import RecipientInput from './RecipientInput.svelte';
@@ -138,11 +139,12 @@ export interface Props {
138
139
  }
139
140
  </script>
140
141
 
141
- <form class="compose-form" onsubmit={(e) => { e.preventDefault(); handleSend(); }}>
142
+ <div class="compose-form-shell">
143
+ <Form class="compose-form" onsubmit={handleSend}>
142
144
  {#if accounts.length > 1}
143
145
  <div class="field">
144
146
  <label class="field-label" for="compose-account">From</label>
145
- <select
147
+ <Select
146
148
  id="compose-account"
147
149
  class="select"
148
150
  bind:value={accountId}
@@ -153,7 +155,7 @@ export interface Props {
153
155
  {account.name}{account.email ? ` <${account.email}>` : ''}
154
156
  </option>
155
157
  {/each}
156
- </select>
158
+ </Select>
157
159
  </div>
158
160
  {/if}
159
161
 
@@ -193,7 +195,7 @@ export interface Props {
193
195
 
194
196
  <div class="field">
195
197
  <label class="field-label" for="compose-subject">Subject</label>
196
- <input
198
+ <Input
197
199
  id="compose-subject"
198
200
  type="text"
199
201
  class="text-input"
@@ -205,7 +207,7 @@ export interface Props {
205
207
  {:else if type === 'slack'}
206
208
  <div class="field">
207
209
  <label class="field-label" for="compose-channel">Channel</label>
208
- <input
210
+ <Input
209
211
  id="compose-channel"
210
212
  type="text"
211
213
  class="text-input"
@@ -217,13 +219,12 @@ export interface Props {
217
219
  {/if}
218
220
 
219
221
  <div class="body-field">
220
- <textarea
221
- class="body-input"
222
+ <Textarea
222
223
  bind:value={body}
223
224
  oninput={markDirty}
224
225
  placeholder={type === 'tweet' ? "What's happening?" : 'Write your message...'}
225
226
  rows={type === 'tweet' ? 4 : 10}
226
- ></textarea>
227
+ />
227
228
  {#if type === 'tweet'}
228
229
  <div class="char-count" class:over-limit={isOverLimit}>
229
230
  {charCount}/280
@@ -274,10 +275,17 @@ export interface Props {
274
275
  Discard
275
276
  </Button>
276
277
  </div>
277
- </form>
278
+ </Form>
279
+ </div>
278
280
 
279
281
  <style>
280
- .compose-form {
282
+ /*
283
+ * The form now renders through smrt-ui's <Form> (Provider-free base `<form>`).
284
+ * `class="compose-form"` lands on the real `<form>` inside the Form child, so
285
+ * `.compose-form-shell :global(.compose-form)` anchors on the wrapper and
286
+ * pierces the child scope to keep the column layout / padding (issue #1589).
287
+ */
288
+ .compose-form-shell :global(.compose-form) {
281
289
  display: flex;
282
290
  flex-direction: column;
283
291
  gap: var(--smrt-spacing-2, 8px);
@@ -299,11 +307,22 @@ export interface Props {
299
307
  min-width: 56px;
300
308
  }
301
309
 
302
- .select,
303
- .text-input {
310
+ /*
311
+ * The From <Select> and Subject/Channel <Input>s now render through smrt-ui's
312
+ * form primitives. These are naked, borderless inline fields that sit on the
313
+ * `.field` row's bottom-border, so `.field :global(.select)` /
314
+ * `.field :global(.text-input)` pierce the child scopes to strip the
315
+ * primitives' border / background / focus box-shadow and restore the flush
316
+ * inline look. `appearance: auto` brings back the Select's native arrow (the
317
+ * primitive paints a chevron on its own background, which we've cleared) —
318
+ * issue #1589.
319
+ */
320
+ .field :global(.select),
321
+ .field :global(.text-input) {
304
322
  flex: 1;
305
323
  border: none;
306
324
  outline: none;
325
+ box-shadow: none;
307
326
  font-family: inherit;
308
327
  font-size: var(--smrt-typography-body-medium-size, 14px);
309
328
  padding: var(--smrt-spacing-2, 8px) 0;
@@ -311,6 +330,17 @@ export interface Props {
311
330
  color: var(--smrt-color-on-surface, #1c1b1f);
312
331
  }
313
332
 
333
+ .field :global(.select) {
334
+ appearance: auto;
335
+ cursor: pointer;
336
+ }
337
+
338
+ .field :global(.select):focus,
339
+ .field :global(.text-input):focus {
340
+ border: none;
341
+ box-shadow: none;
342
+ }
343
+
314
344
  .cc-toggles {
315
345
  display: flex;
316
346
  gap: var(--smrt-spacing-2, 8px);
@@ -335,24 +365,6 @@ export interface Props {
335
365
  position: relative;
336
366
  }
337
367
 
338
- .body-input {
339
- width: 100%;
340
- border: 1px solid var(--smrt-color-outline-variant, #cac4d0);
341
- border-radius: var(--smrt-radius-md, 12px);
342
- padding: var(--smrt-spacing-3, 12px);
343
- font-family: var(--smrt-font-family, system-ui);
344
- font-size: var(--smrt-typography-body-medium-size, 14px);
345
- resize: vertical;
346
- background: var(--smrt-color-surface, #fffbfe);
347
- color: var(--smrt-color-on-surface, #1c1b1f);
348
- box-sizing: border-box;
349
- }
350
-
351
- .body-input:focus {
352
- outline: 2px solid var(--smrt-color-primary, #6750a4);
353
- outline-offset: -1px;
354
- }
355
-
356
368
  .char-count {
357
369
  text-align: right;
358
370
  font-size: var(--smrt-typography-label-medium-size, 12px);
@@ -1 +1 @@
1
- {"version":3,"file":"ComposeForm.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/ComposeForm.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,WAAW,EAEX,YAAY,EAEb,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,KAAK;IACpB,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;IACnC,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC;IACzB,YAAY,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IACrC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IACvC,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IAC5C,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB;AAsOD,QAAA,MAAM,WAAW,2CAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"ComposeForm.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/ComposeForm.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,WAAW,EAEX,YAAY,EAEb,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,KAAK;IACpB,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;IACnC,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC;IACzB,YAAY,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IACrC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IACvC,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IAC5C,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB;AA0OD,QAAA,MAAM,WAAW,2CAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
@@ -5,6 +5,7 @@
5
5
  * Reusable component for adding, editing, testing, and removing
6
6
  * email accounts. Works with any backend via callback props.
7
7
  */
8
+ import { Input, Select } from '@happyvertical/smrt-ui/forms';
8
9
  import { useI18n } from '@happyvertical/smrt-ui/i18n';
9
10
  import { Button } from '@happyvertical/smrt-ui/ui';
10
11
  import { M } from '../i18n.js';
@@ -188,20 +189,20 @@ function getProviderLabel(type: string): string {
188
189
  <div class="form-row">
189
190
  <div class="form-field" style="flex: 1;">
190
191
  <label class="form-label" for="ea-name">{t(M['messages.email_account_manager.account_name'])}</label>
191
- <input id="ea-name" class="form-input" type="text" bind:value={maName} placeholder={t(M['messages.email_account_manager.account_name_placeholder'])} />
192
+ <Input id="ea-name" class="form-input" type="text" bind:value={maName} placeholder={t(M['messages.email_account_manager.account_name_placeholder'])} />
192
193
  </div>
193
194
  <div class="form-field" style="flex: 1;">
194
195
  <label class="form-label" for="ea-email">{t(M['messages.email_account_manager.email_address'])}</label>
195
- <input id="ea-email" class="form-input" type="email" bind:value={maEmail} placeholder={t(M['messages.email_account_manager.email_placeholder'])} />
196
+ <Input id="ea-email" class="form-input" type="email" bind:value={maEmail} placeholder={t(M['messages.email_account_manager.email_placeholder'])} />
196
197
  </div>
197
198
  <div class="form-field" style="flex: 0 0 130px;">
198
199
  <label class="form-label" for="ea-provider">Provider</label>
199
- <select id="ea-provider" class="form-select" bind:value={maProviderType}>
200
+ <Select id="ea-provider" class="form-select" bind:value={maProviderType}>
200
201
  <option value="imap">IMAP</option>
201
202
  <option value="gmail">Gmail</option>
202
203
  <option value="outlook">Outlook</option>
203
204
  <option value="exchange">Exchange</option>
204
- </select>
205
+ </Select>
205
206
  </div>
206
207
  </div>
207
208
 
@@ -209,19 +210,19 @@ function getProviderLabel(type: string): string {
209
210
  <div class="form-row">
210
211
  <div class="form-field" style="flex: 2;">
211
212
  <label class="form-label" for="ea-imap-host">Host</label>
212
- <input id="ea-imap-host" class="form-input" type="text" bind:value={maImapHost} placeholder={t(M['messages.email_account_manager.imap_host_placeholder'])} />
213
+ <Input id="ea-imap-host" class="form-input" type="text" bind:value={maImapHost} placeholder={t(M['messages.email_account_manager.imap_host_placeholder'])} />
213
214
  </div>
214
215
  <div class="form-field" style="flex: 0 0 90px;">
215
216
  <label class="form-label" for="ea-imap-port">Port</label>
216
- <input id="ea-imap-port" class="form-input" type="number" bind:value={maImapPort} />
217
+ <Input id="ea-imap-port" class="form-input" type="number" bind:value={maImapPort} />
217
218
  </div>
218
219
  <div class="form-field" style="flex: 0 0 120px;">
219
220
  <label class="form-label" for="ea-imap-sec">Security</label>
220
- <select id="ea-imap-sec" class="form-select" bind:value={maImapSecurity}>
221
+ <Select id="ea-imap-sec" class="form-select" bind:value={maImapSecurity}>
221
222
  <option value="ssl">SSL/TLS</option>
222
223
  <option value="starttls">STARTTLS</option>
223
224
  <option value="none">None</option>
224
- </select>
225
+ </Select>
225
226
  </div>
226
227
  </div>
227
228
 
@@ -229,19 +230,19 @@ function getProviderLabel(type: string): string {
229
230
  <div class="form-row">
230
231
  <div class="form-field" style="flex: 2;">
231
232
  <label class="form-label" for="ea-smtp-host">Host</label>
232
- <input id="ea-smtp-host" class="form-input" type="text" bind:value={maSmtpHost} placeholder={t(M['messages.email_account_manager.smtp_host_placeholder'])} />
233
+ <Input id="ea-smtp-host" class="form-input" type="text" bind:value={maSmtpHost} placeholder={t(M['messages.email_account_manager.smtp_host_placeholder'])} />
233
234
  </div>
234
235
  <div class="form-field" style="flex: 0 0 90px;">
235
236
  <label class="form-label" for="ea-smtp-port">Port</label>
236
- <input id="ea-smtp-port" class="form-input" type="number" bind:value={maSmtpPort} />
237
+ <Input id="ea-smtp-port" class="form-input" type="number" bind:value={maSmtpPort} />
237
238
  </div>
238
239
  <div class="form-field" style="flex: 0 0 120px;">
239
240
  <label class="form-label" for="ea-smtp-sec">Security</label>
240
- <select id="ea-smtp-sec" class="form-select" bind:value={maSmtpSecurity}>
241
+ <Select id="ea-smtp-sec" class="form-select" bind:value={maSmtpSecurity}>
241
242
  <option value="ssl">SSL/TLS</option>
242
243
  <option value="starttls">STARTTLS</option>
243
244
  <option value="none">None</option>
244
- </select>
245
+ </Select>
245
246
  </div>
246
247
  </div>
247
248
 
@@ -249,14 +250,15 @@ function getProviderLabel(type: string): string {
249
250
  <div class="form-row">
250
251
  <div class="form-field" style="flex: 1;">
251
252
  <label class="form-label" for="ea-username">Username</label>
252
- <input id="ea-username" class="form-input" type="text" bind:value={maUsername} placeholder={t(M['messages.email_account_manager.username_placeholder'])} />
253
+ <Input id="ea-username" class="form-input" type="text" bind:value={maUsername} placeholder={t(M['messages.email_account_manager.username_placeholder'])} />
253
254
  </div>
254
255
  <div class="form-field" style="flex: 1;">
255
256
  <label class="form-label" for="ea-password">Password</label>
256
- <input id="ea-password" class="form-input" type="password" bind:value={maPassword} placeholder={editingId ? '(unchanged)' : ''} />
257
+ <Input id="ea-password" class="form-input" type="password" bind:value={maPassword} placeholder={editingId ? '(unchanged)' : ''} />
257
258
  </div>
258
259
  <div class="form-field checkbox-field">
259
260
  <label class="form-label checkbox-label">
261
+ <!-- raw-primitive-allow: native checkbox; no Provider-free checkbox primitive (Toggle is a switch with different semantics, CheckboxInput requires a Provider) -->
260
262
  <input type="checkbox" bind:checked={maIsActive} />
261
263
  Active
262
264
  </label>
@@ -432,29 +434,14 @@ function getProviderLabel(type: string): string {
432
434
  color: var(--smrt-color-on-surface-variant, #43474e);
433
435
  }
434
436
 
435
- .form-input,
436
- .form-select {
437
- padding: 0.5rem 0.625rem;
438
- border-radius: var(--smrt-radius-md, 8px);
439
- border: 1px solid var(--smrt-color-outline-variant, #c2c7cf);
440
- background: var(--smrt-color-surface, #fefbff);
441
- color: var(--smrt-color-on-surface, #1a1c1e);
442
- font-size: var(--smrt-typography-body-medium-size, 0.8125rem);
443
- font-family: inherit;
444
- transition: border-color 150ms ease;
445
- }
446
-
447
- .form-input:focus,
448
- .form-select:focus {
449
- outline: none;
450
- border-color: var(--smrt-color-primary, #005ac1);
451
- }
452
-
453
- .form-input::placeholder {
454
- color: var(--smrt-color-on-surface-variant, #43474e);
455
- opacity: 0.5;
456
- }
457
-
437
+ /*
438
+ * The account-form fields now render through smrt-ui's <Input> / <Select>,
439
+ * which bring their own tokenised border / background / focus / placeholder
440
+ * styling and honor prefers-reduced-motion themselves. The old `.form-input` /
441
+ * `.form-select` rules (and their :focus / ::placeholder overrides) are dropped
442
+ * as dead — they targeted the raw elements that now live inside the primitive
443
+ * child scopes (issue #1589).
444
+ */
458
445
  .checkbox-field {
459
446
  justify-content: flex-end;
460
447
  padding-bottom: 0.5rem;
@@ -1 +1 @@
1
- {"version":3,"file":"EmailAccountManager.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/EmailAccountManager.svelte.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAGpD,MAAM,WAAW,KAAK;IACpB,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAC7B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,gBAAgB,CAAC,EAAE,EAAE,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACzE,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACxD,MAAM,CAAC,EAAE,CACP,OAAO,EAAE,gBAAgB,KACtB,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpD;AAgUD,QAAA,MAAM,mBAAmB,2CAAwC,CAAC;AAClE,KAAK,mBAAmB,GAAG,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAClE,eAAe,mBAAmB,CAAC"}
1
+ {"version":3,"file":"EmailAccountManager.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/EmailAccountManager.svelte.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAGpD,MAAM,WAAW,KAAK;IACpB,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAC7B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,gBAAgB,CAAC,EAAE,EAAE,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACzE,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACxD,MAAM,CAAC,EAAE,CACP,OAAO,EAAE,gBAAgB,KACtB,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpD;AAkUD,QAAA,MAAM,mBAAmB,2CAAwC,CAAC;AAClE,KAAK,mBAAmB,GAAG,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAClE,eAAe,mBAAmB,CAAC"}
@@ -5,6 +5,7 @@
5
5
  * Reusable component for managing email allow/block lists.
6
6
  * Works with any backend via callback props.
7
7
  */
8
+ import { Input, Select } from '@happyvertical/smrt-ui/forms';
8
9
  import { useI18n } from '@happyvertical/smrt-ui/i18n';
9
10
  import { Button } from '@happyvertical/smrt-ui/ui';
10
11
  import { M } from '../i18n.js';
@@ -215,15 +216,15 @@ function getPatternPlaceholder(type: string): string {
215
216
  <div class="form-row">
216
217
  <div class="form-field" style="flex: 0 0 120px;">
217
218
  <label class="form-label" for="wl-type">Type</label>
218
- <select id="wl-type" class="form-select" bind:value={wlType}>
219
+ <Select id="wl-type" class="form-select" bind:value={wlType}>
219
220
  <option value="email">Email</option>
220
221
  <option value="domain">Domain</option>
221
222
  <option value="regex">Regex</option>
222
- </select>
223
+ </Select>
223
224
  </div>
224
225
  <div class="form-field" style="flex: 1;">
225
226
  <label class="form-label" for="wl-pattern">Pattern</label>
226
- <input
227
+ <Input
227
228
  id="wl-pattern"
228
229
  class="form-input"
229
230
  type="text"
@@ -235,7 +236,7 @@ function getPatternPlaceholder(type: string): string {
235
236
  <div class="form-row">
236
237
  <div class="form-field" style="flex: 1;">
237
238
  <label class="form-label" for="wl-category">Category <span class="optional">(optional)</span></label>
238
- <input
239
+ <Input
239
240
  id="wl-category"
240
241
  class="form-input"
241
242
  type="text"
@@ -245,7 +246,7 @@ function getPatternPlaceholder(type: string): string {
245
246
  </div>
246
247
  <div class="form-field" style="flex: 2;">
247
248
  <label class="form-label" for="wl-desc">Description</label>
248
- <input
249
+ <Input
249
250
  id="wl-desc"
250
251
  class="form-input"
251
252
  type="text"
@@ -319,15 +320,15 @@ function getPatternPlaceholder(type: string): string {
319
320
  <div class="form-row">
320
321
  <div class="form-field" style="flex: 0 0 120px;">
321
322
  <label class="form-label" for="bl-type">Type</label>
322
- <select id="bl-type" class="form-select" bind:value={blType}>
323
+ <Select id="bl-type" class="form-select" bind:value={blType}>
323
324
  <option value="email">Email</option>
324
325
  <option value="domain">Domain</option>
325
326
  <option value="regex">Regex</option>
326
- </select>
327
+ </Select>
327
328
  </div>
328
329
  <div class="form-field" style="flex: 1;">
329
330
  <label class="form-label" for="bl-pattern">Pattern</label>
330
- <input
331
+ <Input
331
332
  id="bl-pattern"
332
333
  class="form-input"
333
334
  type="text"
@@ -339,7 +340,7 @@ function getPatternPlaceholder(type: string): string {
339
340
  <div class="form-row">
340
341
  <div class="form-field" style="flex: 1;">
341
342
  <label class="form-label" for="bl-reason">Reason</label>
342
- <input
343
+ <Input
343
344
  id="bl-reason"
344
345
  class="form-input"
345
346
  type="text"
@@ -349,6 +350,7 @@ function getPatternPlaceholder(type: string): string {
349
350
  </div>
350
351
  <div class="form-field checkbox-field">
351
352
  <label class="form-label checkbox-label">
353
+ <!-- raw-primitive-allow: native checkbox; no Provider-free checkbox primitive (Toggle is a switch with different semantics, CheckboxInput requires a Provider) -->
352
354
  <input type="checkbox" bind:checked={blAutoArchive} />
353
355
  Auto-archive
354
356
  </label>
@@ -502,29 +504,14 @@ function getPatternPlaceholder(type: string): string {
502
504
  opacity: 0.7;
503
505
  }
504
506
 
505
- .form-input,
506
- .form-select {
507
- padding: 0.5rem 0.625rem;
508
- border-radius: var(--smrt-radius-md, 8px);
509
- border: 1px solid var(--smrt-color-outline-variant, #c2c7cf);
510
- background: var(--smrt-color-surface, #fefbff);
511
- color: var(--smrt-color-on-surface, #1a1c1e);
512
- font-size: var(--smrt-typography-body-medium-size, 0.8125rem);
513
- font-family: inherit;
514
- transition: border-color 150ms ease;
515
- }
516
-
517
- .form-input:focus,
518
- .form-select:focus {
519
- outline: none;
520
- border-color: var(--smrt-color-primary, #005ac1);
521
- }
522
-
523
- .form-input::placeholder {
524
- color: var(--smrt-color-on-surface-variant, #43474e);
525
- opacity: 0.5;
526
- }
527
-
507
+ /*
508
+ * The form fields now render through smrt-ui's <Input> / <Select>, which bring
509
+ * their own tokenised border / background / focus / placeholder styling and
510
+ * honor prefers-reduced-motion themselves. The old `.form-input` / `.form-select`
511
+ * rules (and their :focus / ::placeholder overrides) are dropped as dead — they
512
+ * targeted the raw elements that now live inside the primitive child scopes
513
+ * (issue #1589).
514
+ */
528
515
  .checkbox-field {
529
516
  justify-content: flex-end;
530
517
  padding-bottom: 0.5rem;
@@ -1 +1 @@
1
- {"version":3,"file":"EmailFilterManager.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/EmailFilterManager.svelte.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlE,MAAM,WAAW,KAAK;IACpB,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrE,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7D,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrE,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9D;AAoUD,QAAA,MAAM,kBAAkB,2CAAwC,CAAC;AACjE,KAAK,kBAAkB,GAAG,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAChE,eAAe,kBAAkB,CAAC"}
1
+ {"version":3,"file":"EmailFilterManager.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/EmailFilterManager.svelte.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlE,MAAM,WAAW,KAAK;IACpB,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrE,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7D,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrE,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9D;AAsUD,QAAA,MAAM,kBAAkB,2CAAwC,CAAC;AACjE,KAAK,kBAAkB,GAAG,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAChE,eAAe,kBAAkB,CAAC"}
@@ -10,6 +10,7 @@ export interface Props {
10
10
 
11
11
  <script lang="ts">
12
12
  import { useI18n } from '@happyvertical/smrt-ui/i18n';
13
+ import { Textarea } from '@happyvertical/smrt-ui/forms';
13
14
  import { Button } from '@happyvertical/smrt-ui/ui';
14
15
  import { M } from '../i18n.js';
15
16
  import RecipientInput from './RecipientInput.svelte';
@@ -68,12 +69,11 @@ export interface Props {
68
69
  onchange={(r) => { to = r; }}
69
70
  />
70
71
 
71
- <textarea
72
- class="forward-body"
72
+ <Textarea
73
73
  bind:value={body}
74
74
  placeholder={t(M['messages.forward_form.note_placeholder'])}
75
75
  rows={3}
76
- ></textarea>
76
+ />
77
77
 
78
78
  <div class="forwarded-original">
79
79
  <pre class="forwarded-text">{forwardedBlock}</pre>
@@ -117,22 +117,6 @@ export interface Props {
117
117
  font-weight: var(--smrt-typography-weight-medium, 500);
118
118
  }
119
119
 
120
- .forward-body {
121
- width: 100%;
122
- border: 1px solid var(--smrt-color-outline-variant, #cac4d0);
123
- border-radius: var(--smrt-radius-sm, 8px);
124
- padding: var(--smrt-spacing-2, 8px);
125
- font-family: var(--smrt-font-family, system-ui);
126
- font-size: var(--smrt-typography-body-medium-size, 14px);
127
- resize: vertical;
128
- box-sizing: border-box;
129
- }
130
-
131
- .forward-body:focus {
132
- outline: 2px solid var(--smrt-color-primary, #6750a4);
133
- outline-offset: -1px;
134
- }
135
-
136
120
  .forwarded-original {
137
121
  padding: var(--smrt-spacing-2, 8px);
138
122
  background: var(--smrt-color-surface-variant, #e7e0ec);
@@ -1 +1 @@
1
- {"version":3,"file":"ForwardForm.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/ForwardForm.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE/D,MAAM,WAAW,KAAK;IACpB,eAAe,EAAE,WAAW,CAAC;IAC7B,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,cAAc,EAAE,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACtD,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;CACvB;AA4FD,QAAA,MAAM,WAAW,2CAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"ForwardForm.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/ForwardForm.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE/D,MAAM,WAAW,KAAK;IACpB,eAAe,EAAE,WAAW,CAAC;IAC7B,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,cAAc,EAAE,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACtD,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;CACvB;AA8FD,QAAA,MAAM,WAAW,2CAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
@@ -98,6 +98,7 @@ const _slackMeta = $derived.by(() => {
98
98
  >
99
99
  {#if onselect}
100
100
  <div class="select-col">
101
+ <!-- raw-primitive-allow: native checkbox; no Provider-free checkbox primitive (Toggle is a switch with different semantics, CheckboxInput requires a Provider) -->
101
102
  <input
102
103
  type="checkbox"
103
104
  checked={selected}
@@ -1 +1 @@
1
- {"version":3,"file":"MessageCard.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/MessageCard.svelte.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAK5D,MAAM,WAAW,KAAK;IACpB,OAAO,EAAE,WAAW,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;IACzC,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;IAC1C,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;IACxC,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,WAAW,CAAC,EAAE,OAAO,CAAC,CAAC;QAAE,OAAO,EAAE,WAAW,CAAA;KAAE,CAAC,CAAC,CAAC;CACnD;AA+ID,QAAA,MAAM,WAAW,2CAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"MessageCard.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/MessageCard.svelte.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAK5D,MAAM,WAAW,KAAK;IACpB,OAAO,EAAE,WAAW,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;IACzC,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;IAC1C,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;IACxC,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,WAAW,CAAC,EAAE,OAAO,CAAC,CAAC;QAAE,OAAO,EAAE,WAAW,CAAA;KAAE,CAAC,CAAC,CAAC;CACnD;AAgJD,QAAA,MAAM,WAAW,2CAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
@@ -2,6 +2,7 @@
2
2
  /**
3
3
  * MessageFilters - Filter/sort controls bar
4
4
  */
5
+ import { Input, Select } from '@happyvertical/smrt-ui/forms';
5
6
  import { useI18n } from '@happyvertical/smrt-ui/i18n';
6
7
  import { Button } from '@happyvertical/smrt-ui/ui';
7
8
  import { M } from '../i18n.messages.js';
@@ -78,7 +79,7 @@ const _hasActiveFilters = $derived(
78
79
 
79
80
  <div class="message-filters" role="search" aria-label={t(M['messages.message_filters.filters_label'])}>
80
81
  <div class="search-row">
81
- <input
82
+ <Input
82
83
  type="search"
83
84
  class="search-input"
84
85
  placeholder={t(M['messages.message_filters.search_placeholder'])}
@@ -90,37 +91,37 @@ const _hasActiveFilters = $derived(
90
91
  </div>
91
92
 
92
93
  <div class="filter-row">
93
- <select
94
+ <Select
94
95
  class="filter-select"
95
96
  value={filters.type || ''}
96
- onchange={(e) => updateFilter('type', (e.target as HTMLSelectElement).value)}
97
+ onchange={(e) => updateFilter('type', (e.currentTarget as HTMLSelectElement).value)}
97
98
  aria-label={t(M['messages.message_filters.filter_by_type'])}
98
99
  >
99
100
  <option value="">{t(M['messages.message_filters.all_types'])}</option>
100
101
  {#each availableTypes as type}
101
102
  <option value={type}>{type === 'email' ? 'Email' : type === 'tweet' ? 'Tweet' : type === 'slack' ? 'Slack' : type}</option>
102
103
  {/each}
103
- </select>
104
+ </Select>
104
105
 
105
106
  {#if accounts.length > 0}
106
- <select
107
+ <Select
107
108
  class="filter-select"
108
109
  value={filters.accountId || ''}
109
- onchange={(e) => updateFilter('accountId', (e.target as HTMLSelectElement).value)}
110
+ onchange={(e) => updateFilter('accountId', (e.currentTarget as HTMLSelectElement).value)}
110
111
  aria-label={t(M['messages.message_filters.filter_by_account'])}
111
112
  >
112
113
  <option value="">{t(M['messages.message_filters.all_accounts'])}</option>
113
114
  {#each accounts as account}
114
115
  <option value={account.id}>{account.name}</option>
115
116
  {/each}
116
- </select>
117
+ </Select>
117
118
  {/if}
118
119
 
119
- <select
120
+ <Select
120
121
  class="filter-select"
121
122
  value={filters.isRead === undefined ? '' : filters.isRead ? 'read' : 'unread'}
122
123
  onchange={(e) => {
123
- const val = (e.target as HTMLSelectElement).value;
124
+ const val = (e.currentTarget as HTMLSelectElement).value;
124
125
  updateFilter('isRead', val === '' ? undefined : val === 'read');
125
126
  }}
126
127
  aria-label={t(M['messages.message_filters.filter_by_read_status'])}
@@ -128,13 +129,14 @@ const _hasActiveFilters = $derived(
128
129
  <option value="">Read & unread</option>
129
130
  <option value="unread">{t(M['messages.message_filters.unread_only'])}</option>
130
131
  <option value="read">{t(M['messages.message_filters.read_only'])}</option>
131
- </select>
132
+ </Select>
132
133
 
133
134
  <label class="filter-checkbox">
135
+ <!-- raw-primitive-allow: native checkbox; no Provider-free checkbox primitive (Toggle is a switch with different semantics, CheckboxInput requires a Provider) -->
134
136
  <input
135
137
  type="checkbox"
136
138
  checked={filters.isFlagged === true}
137
- onchange={(e) => updateFilter('isFlagged', (e.target as HTMLInputElement).checked ? true : undefined)}
139
+ onchange={(e) => updateFilter('isFlagged', (e.currentTarget as HTMLInputElement).checked ? true : undefined)}
138
140
  />
139
141
  Flagged
140
142
  </label>
@@ -163,19 +165,14 @@ const _hasActiveFilters = $derived(
163
165
  gap: 0.5rem;
164
166
  }
165
167
 
166
- .search-input {
168
+ /*
169
+ * The search field now renders through smrt-ui's <Input>. The primitive owns
170
+ * border / background / focus; `.search-row :global(.search-input)` only
171
+ * re-asserts `flex: 1` so it shares the row with the Search button, piercing
172
+ * the Input child scope (issue #1589).
173
+ */
174
+ .search-row :global(.search-input) {
167
175
  flex: 1;
168
- padding: 0.5rem 0.75rem;
169
- border: 1px solid var(--smrt-color-outline, #72787e);
170
- border-radius: var(--smrt-radius-small, 0.25rem);
171
- font: var(--smrt-typography-body-medium-font, 0.875rem / 1.25 sans-serif);
172
- background: var(--smrt-color-surface, #fefbff);
173
- color: var(--smrt-color-on-surface, #1a1c1e);
174
- }
175
-
176
- .search-input:focus {
177
- outline: 2px solid var(--smrt-color-primary, #005ac1);
178
- outline-offset: -1px;
179
176
  }
180
177
 
181
178
  /*
@@ -197,13 +194,16 @@ const _hasActiveFilters = $derived(
197
194
  gap: 0.5rem;
198
195
  }
199
196
 
200
- .filter-select {
201
- padding: 0.375rem 0.5rem;
202
- border: 1px solid var(--smrt-color-outline, #72787e);
203
- border-radius: var(--smrt-radius-small, 0.25rem);
197
+ /*
198
+ * The filter dropdowns now render through smrt-ui's <Select>. The primitive
199
+ * owns border / background / focus / chevron; `.filter-row :global(.filter-select)`
200
+ * re-asserts the compact filter-bar sizing (auto width, tighter padding, small
201
+ * font) by piercing the Select child scope (issue #1589).
202
+ */
203
+ .filter-row :global(.filter-select) {
204
+ width: auto;
205
+ padding: 0.375rem 2rem 0.375rem 0.5rem;
204
206
  font: var(--smrt-typography-body-small-font, 0.75rem / 1.33 sans-serif);
205
- background: var(--smrt-color-surface, #fefbff);
206
- color: var(--smrt-color-on-surface, #1a1c1e);
207
207
  }
208
208
 
209
209
  .filter-checkbox {
@@ -1 +1 @@
1
- {"version":3,"file":"MessageFilters.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/MessageFilters.svelte.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EACV,WAAW,EACX,kBAAkB,EAClB,WAAW,EACX,WAAW,EACZ,MAAM,aAAa,CAAC;AAGrB,MAAM,WAAW,KAAK;IACpB,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC;IACzB,cAAc,CAAC,EAAE,WAAW,EAAE,CAAC;IAC/B,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,kBAAkB,KAAK,IAAI,CAAC;IACvD,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACpC;AAiHD,QAAA,MAAM,cAAc,2CAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"MessageFilters.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/MessageFilters.svelte.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,WAAW,EACX,kBAAkB,EAClB,WAAW,EACX,WAAW,EACZ,MAAM,aAAa,CAAC;AAGrB,MAAM,WAAW,KAAK;IACpB,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC;IACzB,cAAc,CAAC,EAAE,WAAW,EAAE,CAAC;IAC/B,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,kBAAkB,KAAK,IAAI,CAAC;IACvD,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACpC;AAmHD,QAAA,MAAM,cAAc,2CAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}
@@ -10,6 +10,7 @@ export interface Props {
10
10
  </script>
11
11
 
12
12
  <script lang="ts">
13
+ import { Input } from '@happyvertical/smrt-ui/forms';
13
14
  import { Button } from '@happyvertical/smrt-ui/ui';
14
15
 
15
16
  let {
@@ -71,10 +72,10 @@ export interface Props {
71
72
  >×</Button>
72
73
  </span>
73
74
  {/each}
74
- <input
75
+ <Input
75
76
  id={inputId}
76
77
  type="text"
77
- class="input"
78
+ class="recipient-field"
78
79
  bind:value={inputValue}
79
80
  {placeholder}
80
81
  onkeydown={handleKeydown}
@@ -145,15 +146,28 @@ export interface Props {
145
146
  opacity: 1;
146
147
  }
147
148
 
148
- .input {
149
+ /*
150
+ * The chip-bar field now renders through smrt-ui's <Input>. This is a naked,
151
+ * borderless inline field that sits among the recipient chips, so
152
+ * `.chips-container :global(.recipient-field)` pierces the Input child scope to
153
+ * strip the primitive's border / background / block padding / focus box-shadow
154
+ * and restore the flush inline look (issue #1589).
155
+ */
156
+ .chips-container :global(.recipient-field) {
149
157
  flex: 1;
150
158
  min-width: 120px;
151
159
  border: none;
152
160
  outline: none;
161
+ box-shadow: none;
153
162
  font-family: var(--smrt-font-family, system-ui);
154
163
  font-size: var(--smrt-typography-body-medium-size, 14px);
155
164
  padding: var(--smrt-spacing-1, 4px) 0;
156
165
  background: transparent;
157
166
  color: var(--smrt-color-on-surface, #1c1b1f);
158
167
  }
168
+
169
+ .chips-container :global(.recipient-field):focus {
170
+ border: none;
171
+ box-shadow: none;
172
+ }
159
173
  </style>
@@ -1 +1 @@
1
- {"version":3,"file":"RecipientInput.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/RecipientInput.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,WAAW,KAAK;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,QAAQ,CAAC,EAAE,CAAC,UAAU,EAAE,cAAc,EAAE,KAAK,IAAI,CAAC;IAClD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAwED,QAAA,MAAM,cAAc,2CAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"RecipientInput.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/RecipientInput.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,WAAW,KAAK;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,QAAQ,CAAC,EAAE,CAAC,UAAU,EAAE,cAAc,EAAE,KAAK,IAAI,CAAC;IAClD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AA0ED,QAAA,MAAM,cAAc,2CAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}
@@ -11,6 +11,7 @@ export interface Props {
11
11
 
12
12
  <script lang="ts">
13
13
  import { useI18n } from '@happyvertical/smrt-ui/i18n';
14
+ import { Textarea } from '@happyvertical/smrt-ui/forms';
14
15
  import { Button } from '@happyvertical/smrt-ui/ui';
15
16
  import { M } from '../i18n.js';
16
17
 
@@ -60,12 +61,11 @@ export interface Props {
60
61
  {replyAll ? 'Reply All' : 'Reply'} to {originalMessage.senderName || originalMessage.senderAddress}
61
62
  </div>
62
63
 
63
- <textarea
64
- class="reply-body"
64
+ <Textarea
65
65
  bind:value={body}
66
66
  placeholder={t(M['messages.reply_form.body_placeholder'])}
67
67
  rows={5}
68
- ></textarea>
68
+ />
69
69
 
70
70
  <div class="quoted-original">
71
71
  <pre class="quoted-text">{quotedBody}</pre>
@@ -109,22 +109,6 @@ export interface Props {
109
109
  font-weight: var(--smrt-typography-weight-medium, 500);
110
110
  }
111
111
 
112
- .reply-body {
113
- width: 100%;
114
- border: 1px solid var(--smrt-color-outline-variant, #cac4d0);
115
- border-radius: var(--smrt-radius-sm, 8px);
116
- padding: var(--smrt-spacing-2, 8px);
117
- font-family: var(--smrt-font-family, system-ui);
118
- font-size: var(--smrt-typography-body-medium-size, 14px);
119
- resize: vertical;
120
- box-sizing: border-box;
121
- }
122
-
123
- .reply-body:focus {
124
- outline: 2px solid var(--smrt-color-primary, #6750a4);
125
- outline-offset: -1px;
126
- }
127
-
128
112
  .quoted-original {
129
113
  padding: var(--smrt-spacing-2, 8px);
130
114
  border-left: 3px solid var(--smrt-color-outline-variant, #cac4d0);
@@ -1 +1 @@
1
- {"version":3,"file":"ReplyForm.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/ReplyForm.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,MAAM,WAAW,KAAK;IACpB,eAAe,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;CACvB;AAsFD,QAAA,MAAM,SAAS,2CAAwC,CAAC;AACxD,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAC9C,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"ReplyForm.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/ReplyForm.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,MAAM,WAAW,KAAK;IACpB,eAAe,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;CACvB;AAwFD,QAAA,MAAM,SAAS,2CAAwC,CAAC;AACxD,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAC9C,eAAe,SAAS,CAAC"}
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@happyvertical/smrt-messages",
3
- "version": "0.34.6",
3
+ "version": "0.34.8",
4
4
  "description": "Unified multi-channel messaging with STI-based hierarchies",
5
5
  "type": "module",
6
- "smrtRawPrimitives": "strict-buttons",
6
+ "smrtRawPrimitives": "strict",
7
7
  "main": "./dist/index.js",
8
8
  "types": "./dist/index.d.ts",
9
9
  "files": [
@@ -40,11 +40,11 @@
40
40
  "@happyvertical/messages": "^0.74.7",
41
41
  "@happyvertical/sql": "^0.74.7",
42
42
  "@happyvertical/utils": "^0.74.7",
43
- "@happyvertical/smrt-types": "0.34.6",
44
- "@happyvertical/smrt-secrets": "0.34.6",
45
- "@happyvertical/smrt-tenancy": "0.34.6",
46
- "@happyvertical/smrt-core": "0.34.6",
47
- "@happyvertical/smrt-ui": "0.34.6"
43
+ "@happyvertical/smrt-types": "0.34.8",
44
+ "@happyvertical/smrt-core": "0.34.8",
45
+ "@happyvertical/smrt-secrets": "0.34.8",
46
+ "@happyvertical/smrt-tenancy": "0.34.8",
47
+ "@happyvertical/smrt-ui": "0.34.8"
48
48
  },
49
49
  "peerDependencies": {
50
50
  "@happyvertical/encryption": "*",
@@ -67,7 +67,7 @@
67
67
  "typescript": "^5.9.3",
68
68
  "vite": "^7.3.1",
69
69
  "vitest": "^4.0.17",
70
- "@happyvertical/smrt-vitest": "0.34.6"
70
+ "@happyvertical/smrt-vitest": "0.34.8"
71
71
  },
72
72
  "keywords": [
73
73
  "email",