@happyvertical/smrt-messages 0.34.4 → 0.34.6

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 (32) hide show
  1. package/dist/manifest.json +2 -2
  2. package/dist/smrt-knowledge.json +4 -4
  3. package/dist/svelte/components/AccountCard.svelte +22 -13
  4. package/dist/svelte/components/AttachmentChip.svelte +26 -7
  5. package/dist/svelte/components/AttachmentChip.svelte.d.ts +0 -3
  6. package/dist/svelte/components/AttachmentChip.svelte.d.ts.map +1 -1
  7. package/dist/svelte/components/AttachmentUpload.svelte +12 -5
  8. package/dist/svelte/components/AttachmentUpload.svelte.d.ts.map +1 -1
  9. package/dist/svelte/components/ComposeForm.svelte +24 -45
  10. package/dist/svelte/components/ComposeForm.svelte.d.ts.map +1 -1
  11. package/dist/svelte/components/EmailAccountManager.svelte +57 -78
  12. package/dist/svelte/components/EmailAccountManager.svelte.d.ts.map +1 -1
  13. package/dist/svelte/components/EmailFilterManager.svelte +75 -95
  14. package/dist/svelte/components/EmailFilterManager.svelte.d.ts.map +1 -1
  15. package/dist/svelte/components/FolderNav.svelte +22 -15
  16. package/dist/svelte/components/FolderNav.svelte.d.ts.map +1 -1
  17. package/dist/svelte/components/ForwardForm.svelte +13 -29
  18. package/dist/svelte/components/ForwardForm.svelte.d.ts.map +1 -1
  19. package/dist/svelte/components/MessageCard.svelte +13 -6
  20. package/dist/svelte/components/MessageCard.svelte.d.ts.map +1 -1
  21. package/dist/svelte/components/MessageDetail.svelte +19 -12
  22. package/dist/svelte/components/MessageFilters.svelte +18 -14
  23. package/dist/svelte/components/MessageFilters.svelte.d.ts.map +1 -1
  24. package/dist/svelte/components/MessageToolbar.svelte +28 -20
  25. package/dist/svelte/components/MessageToolbar.svelte.d.ts.map +1 -1
  26. package/dist/svelte/components/RecipientInput.svelte +15 -6
  27. package/dist/svelte/components/RecipientInput.svelte.d.ts.map +1 -1
  28. package/dist/svelte/components/ReplyForm.svelte +13 -29
  29. package/dist/svelte/components/ReplyForm.svelte.d.ts.map +1 -1
  30. package/dist/svelte/components/ThreadView.svelte +19 -12
  31. package/dist/svelte/components/ThreadView.svelte.d.ts.map +1 -1
  32. package/package.json +8 -7
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "version": "1.0.0",
3
- "timestamp": 1782257816382,
3
+ "timestamp": 1782278435844,
4
4
  "packageName": "@happyvertical/smrt-messages",
5
- "packageVersion": "0.34.4",
5
+ "packageVersion": "0.34.6",
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-23T23:36:58.234Z",
3
+ "generatedAt": "2026-06-24T05:20:36.527Z",
4
4
  "packageName": "@happyvertical/smrt-messages",
5
- "packageVersion": "0.34.4",
5
+ "packageVersion": "0.34.6",
6
6
  "sourceManifestPath": "dist/manifest.json",
7
7
  "agentDocPath": "AGENTS.md",
8
8
  "sourceHashes": {
9
- "manifest": "d9c65ec777b181715b289c2b2219c1e32ea81ffb96a5fa94f358afd4f3ace795",
10
- "packageJson": "5e472dbdc50ae1f78e01a4466712499ff50a59429d2be9baaf9701ce3fe53b46",
9
+ "manifest": "74dd6bcd838fe3da57812b01b4e35eb63e6f61c12ff460a2ca6b75375598ffdb",
10
+ "packageJson": "c68a8210454fbeb5aec5c41dbf13319fbc5bba00cf9b089eebd2e47a0a3949c4",
11
11
  "agents": "32563a30ceeb21bd8732042f894e2a148fd83727caffc1eec7c97540005c6fdc"
12
12
  },
13
13
  "exports": [
@@ -2,7 +2,7 @@
2
2
  /**
3
3
  * AccountCard - Individual account card with status and actions
4
4
  */
5
- import { Card } from '@happyvertical/smrt-ui/ui';
5
+ import { Button, Card } from '@happyvertical/smrt-ui/ui';
6
6
  import type { AccountData } from '../types.js';
7
7
  import AccountAvatar from './AccountAvatar.svelte';
8
8
 
@@ -51,24 +51,24 @@ const _lastSyncFormatted = $derived.by(() => {
51
51
 
52
52
  <div class="actions">
53
53
  {#if onsync && account.isActive}
54
- <button class="action-btn" type="button" onclick={() => onsync?.(account)}>
54
+ <Button variant="ghost" size="sm" class="action-btn" onclick={() => onsync?.(account)}>
55
55
  Sync
56
- </button>
56
+ </Button>
57
57
  {/if}
58
58
  {#if account.isActive && ondeactivate}
59
- <button class="action-btn" type="button" onclick={() => ondeactivate?.(account)}>
59
+ <Button variant="ghost" size="sm" class="action-btn" onclick={() => ondeactivate?.(account)}>
60
60
  Deactivate
61
- </button>
61
+ </Button>
62
62
  {/if}
63
63
  {#if !account.isActive && onactivate}
64
- <button class="action-btn" type="button" onclick={() => onactivate?.(account)}>
64
+ <Button variant="ghost" size="sm" class="action-btn" onclick={() => onactivate?.(account)}>
65
65
  Activate
66
- </button>
66
+ </Button>
67
67
  {/if}
68
68
  {#if onremove}
69
- <button class="action-btn action-btn--danger" type="button" onclick={() => onremove?.(account)}>
69
+ <Button variant="ghost" size="sm" class="action-btn action-btn--danger" onclick={() => onremove?.(account)}>
70
70
  Remove
71
- </button>
71
+ </Button>
72
72
  {/if}
73
73
  </div>
74
74
  </div>
@@ -152,21 +152,30 @@ const _lastSyncFormatted = $derived.by(() => {
152
152
  gap: 0.375rem;
153
153
  }
154
154
 
155
- .action-btn {
155
+ /*
156
+ * The action buttons now render through smrt-ui's <Button variant="ghost">.
157
+ * Svelte scopes `.action-btn` to this component, but the <button> is emitted
158
+ * inside the Button child, so a plain `.action-btn {}` rule would not match —
159
+ * `.actions :global(.action-btn)` anchors on `.actions` (a real element here)
160
+ * and pierces into the child (issue #1589). These overrides keep the original
161
+ * outlined-surface look (border/radius/color); the modifier class is
162
+ * `action-btn--danger`, NOT `danger`, so it never collides with Button's own
163
+ * `.danger` variant class.
164
+ */
165
+ .actions :global(.action-btn) {
156
166
  padding: 0.375rem 0.75rem;
157
167
  border: 1px solid var(--smrt-color-outline, #72787e);
158
168
  border-radius: var(--smrt-radius-small, 0.25rem);
159
169
  background: var(--smrt-color-surface, #fefbff);
160
170
  color: var(--smrt-color-on-surface, #1a1c1e);
161
171
  font: var(--smrt-typography-label-medium-font, 500 0.75rem / 1.33 sans-serif);
162
- cursor: pointer;
163
172
  }
164
173
 
165
- .action-btn:hover {
174
+ .actions :global(.action-btn):hover {
166
175
  background: var(--smrt-color-surface-variant, #e1e2ec);
167
176
  }
168
177
 
169
- .action-btn--danger {
178
+ .actions :global(.action-btn--danger) {
170
179
  color: var(--smrt-color-error, #ba1a1a);
171
180
  border-color: var(--smrt-color-error, #ba1a1a);
172
181
  }
@@ -2,6 +2,7 @@
2
2
  /**
3
3
  * AttachmentChip - File chip with icon, name, and size
4
4
  */
5
+ import { Button } from '@happyvertical/smrt-ui/ui';
5
6
  import type { AttachmentData } from '../types.js';
6
7
 
7
8
  export interface Props {
@@ -33,16 +34,16 @@ const _formattedSize = $derived.by(() => {
33
34
  </script>
34
35
 
35
36
  {#if onclick}
36
- <button
37
- class="chip"
38
- type="button"
37
+ <Button
38
+ variant="ghost"
39
+ class="chip chip--button"
39
40
  onclick={() => onclick?.(attachment)}
40
41
  title={`${attachment.filename} (${_formattedSize})`}
41
42
  >
42
43
  <span class="icon">{_icon}</span>
43
44
  <span class="name">{attachment.filename}</span>
44
45
  <span class="size">{_formattedSize}</span>
45
- </button>
46
+ </Button>
46
47
  {:else}
47
48
  <span class="chip" title={`${attachment.filename} (${_formattedSize})`}>
48
49
  <span class="icon">{_icon}</span>
@@ -66,16 +67,34 @@ const _formattedSize = $derived.by(() => {
66
67
  max-width: 200px;
67
68
  }
68
69
 
69
- button.chip {
70
+ /*
71
+ * The interactive chip now renders through smrt-ui's <Button variant="ghost">.
72
+ * The <button> is emitted inside the Button child carrying Button's scope hash,
73
+ * so the local `.chip` rule above no longer reaches it. `:global(.chip--button)`
74
+ * pierces that scope to give the button the same chip styling plus the
75
+ * pressable affordances; `chip--button` is a non-colliding modifier (issue
76
+ * #1589). The non-interactive `<span class="chip">` branch still uses the
77
+ * scoped `.chip` rule above.
78
+ */
79
+ :global(.chip.chip--button) {
80
+ display: inline-flex;
81
+ align-items: center;
82
+ gap: 0.375rem;
83
+ padding: 0.25rem 0.625rem;
84
+ border-radius: var(--smrt-radius-small, 0.25rem);
85
+ background: var(--smrt-color-surface-variant, #e1e2ec);
86
+ color: var(--smrt-color-on-surface-variant, #43474e);
87
+ font: var(--smrt-typography-label-medium-font, 500 0.75rem / 1.33 sans-serif);
70
88
  cursor: pointer;
89
+ max-width: 200px;
71
90
  transition: background var(--smrt-duration-short2, 150ms) var(--smrt-easing-standard, ease);
72
91
  }
73
92
 
74
- button.chip:hover {
93
+ :global(.chip.chip--button):hover {
75
94
  background: color-mix(in srgb, var(--smrt-color-surface-variant, #e1e2ec) 92%, var(--smrt-color-shadow, #000));
76
95
  }
77
96
 
78
- button.chip:focus-visible {
97
+ :global(.chip.chip--button):focus-visible {
79
98
  outline: 2px solid var(--smrt-color-primary, #005ac1);
80
99
  outline-offset: 1px;
81
100
  }
@@ -1,6 +1,3 @@
1
- /**
2
- * AttachmentChip - File chip with icon, name, and size
3
- */
4
1
  import type { AttachmentData } from '../types.js';
5
2
  export interface Props {
6
3
  attachment: AttachmentData;
@@ -1 +1 @@
1
- {"version":3,"file":"AttachmentChip.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/AttachmentChip.svelte.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD,MAAM,WAAW,KAAK;IACpB,UAAU,EAAE,cAAc,CAAC;IAC3B,OAAO,CAAC,EAAE,CAAC,UAAU,EAAE,cAAc,KAAK,IAAI,CAAC;CAChD;AA+CD,QAAA,MAAM,cAAc,2CAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"AttachmentChip.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/AttachmentChip.svelte.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD,MAAM,WAAW,KAAK;IACpB,UAAU,EAAE,cAAc,CAAC;IAC3B,OAAO,CAAC,EAAE,CAAC,UAAU,EAAE,cAAc,KAAK,IAAI,CAAC;CAChD;AAgDD,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 { Button } from '@happyvertical/smrt-ui/ui';
14
15
  import { M } from '../i18n.js';
15
16
 
16
17
  const { t } = useI18n();
@@ -59,11 +60,12 @@ export interface Props {
59
60
  <div class="attachment-item">
60
61
  <span class="filename">{attachment.filename}</span>
61
62
  <span class="size">{formatSize(attachment.size)}</span>
62
- <button
63
+ <Button
64
+ variant="ghost"
65
+ size="sm"
63
66
  class="remove"
64
67
  onclick={() => onremove?.(i)}
65
- type="button"
66
- >×</button>
68
+ >×</Button>
67
69
  </div>
68
70
  {/each}
69
71
  </div>
@@ -122,10 +124,15 @@ export interface Props {
122
124
  font-size: var(--smrt-typography-label-small-size, 11px);
123
125
  }
124
126
 
125
- .remove {
127
+ /*
128
+ * The remove button now renders through smrt-ui's <Button variant="ghost">.
129
+ * The <button> lives inside the Button child, so `.attachment-item :global(.remove)`
130
+ * anchors on the real `.attachment-item` element and pierces the child scope to
131
+ * keep the compact error-colored icon styling (issue #1589).
132
+ */
133
+ .attachment-item :global(.remove) {
126
134
  background: none;
127
135
  border: none;
128
- cursor: pointer;
129
136
  padding: 0 var(--smrt-spacing-1, 4px);
130
137
  color: var(--smrt-color-error, #ba1a1a);
131
138
  font-size: var(--smrt-typography-label-large-size, 14px);
@@ -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;AA6ED,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;AA+ED,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 { Button } from '@happyvertical/smrt-ui/ui';
21
22
  import { M } from '../i18n.js';
22
23
  import RecipientInput from './RecipientInput.svelte';
23
24
  import AttachmentUpload from './AttachmentUpload.svelte';
@@ -182,10 +183,10 @@ export interface Props {
182
183
  {#if !showCc || !showBcc}
183
184
  <div class="cc-toggles">
184
185
  {#if !showCc}
185
- <button type="button" class="link-btn" onclick={() => showCc = true}>Cc</button>
186
+ <Button variant="ghost" size="sm" class="link-btn" onclick={() => showCc = true}>Cc</Button>
186
187
  {/if}
187
188
  {#if !showBcc}
188
- <button type="button" class="link-btn" onclick={() => showBcc = true}>Bcc</button>
189
+ <Button variant="ghost" size="sm" class="link-btn" onclick={() => showBcc = true}>Bcc</Button>
189
190
  {/if}
190
191
  </div>
191
192
  {/if}
@@ -259,19 +260,19 @@ export interface Props {
259
260
  {/if}
260
261
 
261
262
  <div class="actions">
262
- <button
263
+ <Button
263
264
  type="submit"
264
- class="btn-primary"
265
+ variant="primary"
265
266
  disabled={isSending || isOverLimit}
266
267
  >
267
268
  {isSending ? 'Sending...' : 'Send'}
268
- </button>
269
- <button type="button" class="btn-secondary" onclick={handleSaveDraft}>
269
+ </Button>
270
+ <Button variant="secondary" onclick={handleSaveDraft}>
270
271
  {t(M['messages.compose_form.save_draft'])}
271
- </button>
272
- <button type="button" class="btn-text" onclick={() => ondiscard?.()}>
272
+ </Button>
273
+ <Button variant="ghost" class="btn-text" onclick={() => ondiscard?.()}>
273
274
  Discard
274
- </button>
275
+ </Button>
275
276
  </div>
276
277
  </form>
277
278
 
@@ -316,10 +317,15 @@ export interface Props {
316
317
  justify-content: flex-end;
317
318
  }
318
319
 
319
- .link-btn {
320
+ /*
321
+ * The Cc/Bcc toggles now render through smrt-ui's <Button variant="ghost">.
322
+ * `.cc-toggles :global(.link-btn)` anchors on the real `.cc-toggles` element
323
+ * and pierces the Button child scope to keep the underlined text-link look
324
+ * (issue #1589).
325
+ */
326
+ .cc-toggles :global(.link-btn) {
320
327
  background: none;
321
328
  border: none;
322
- cursor: pointer;
323
329
  color: var(--smrt-color-primary, #6750a4);
324
330
  font-size: var(--smrt-typography-label-large-size, 13px);
325
331
  text-decoration: underline;
@@ -373,40 +379,13 @@ export interface Props {
373
379
  padding-top: var(--smrt-spacing-2, 8px);
374
380
  }
375
381
 
376
- .btn-primary {
377
- padding: var(--smrt-spacing-2, 8px) var(--smrt-spacing-6, 24px);
378
- border-radius: var(--smrt-radius-full, 20px);
379
- border: none;
380
- background: var(--smrt-color-primary, #6750a4);
381
- color: var(--smrt-color-on-primary, #fff);
382
- font-family: var(--smrt-font-family, system-ui);
383
- font-size: var(--smrt-typography-label-large-size, 14px);
384
- cursor: pointer;
385
- }
386
-
387
- .btn-primary:disabled {
388
- opacity: 0.6;
389
- cursor: not-allowed;
390
- }
391
-
392
- .btn-secondary {
393
- padding: var(--smrt-spacing-2, 8px) var(--smrt-spacing-4, 16px);
394
- border-radius: var(--smrt-radius-full, 20px);
395
- border: 1px solid var(--smrt-color-outline, #79747e);
396
- background: transparent;
397
- color: var(--smrt-color-primary, #6750a4);
398
- font-family: var(--smrt-font-family, system-ui);
399
- font-size: var(--smrt-typography-label-large-size, 14px);
400
- cursor: pointer;
401
- }
402
-
403
- .btn-text {
404
- padding: var(--smrt-spacing-2, 8px) var(--smrt-spacing-4, 16px);
405
- border: none;
406
- background: transparent;
382
+ /*
383
+ * Send/Save-draft now use Button's primary/secondary variants directly (dead
384
+ * .btn-primary/.btn-secondary CSS removed). The Discard button keeps its
385
+ * neutral on-surface-variant text via `.actions :global(.btn-text)` (Button's
386
+ * ghost uses the primary color) — issue #1589.
387
+ */
388
+ .actions :global(.btn-text) {
407
389
  color: var(--smrt-color-on-surface-variant, #49454f);
408
- font-family: var(--smrt-font-family, system-ui);
409
- font-size: var(--smrt-typography-label-large-size, 14px);
410
- cursor: pointer;
411
390
  }
412
391
  </style>
@@ -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;AAoOD,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;AAsOD,QAAA,MAAM,WAAW,2CAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
@@ -6,6 +6,7 @@
6
6
  * email accounts. Works with any backend via callback props.
7
7
  */
8
8
  import { useI18n } from '@happyvertical/smrt-ui/i18n';
9
+ import { Button } from '@happyvertical/smrt-ui/ui';
9
10
  import { M } from '../i18n.js';
10
11
  import type { EmailAccountData } from '../types.js';
11
12
 
@@ -171,10 +172,12 @@ function getProviderLabel(type: string): string {
171
172
  {t(M['messages.email_account_manager.section_description'])}
172
173
  </div>
173
174
  {#if !isReadonly && onsave}
174
- <button
175
+ <Button
176
+ variant="secondary"
177
+ size="sm"
175
178
  class="add-btn"
176
179
  onclick={() => { resetForm(); showForm = true; }}
177
- >{t(M['messages.email_account_manager.add_account'])}</button>
180
+ >{t(M['messages.email_account_manager.add_account'])}</Button>
178
181
  {/if}
179
182
  </div>
180
183
 
@@ -261,10 +264,10 @@ function getProviderLabel(type: string): string {
261
264
  </div>
262
265
 
263
266
  <div class="form-actions">
264
- <button class="cancel-btn" onclick={resetForm} disabled={saving}>Cancel</button>
265
- <button class="save-btn" onclick={save} disabled={saving || !maName.trim() || !maEmail.trim()}>
267
+ <Button variant="secondary" size="sm" class="cancel-btn" onclick={resetForm} disabled={saving}>Cancel</Button>
268
+ <Button variant="primary" size="sm" class="save-btn" onclick={save} disabled={saving || !maName.trim() || !maEmail.trim()}>
266
269
  {saving ? 'Saving...' : editingId ? 'Update' : 'Add Account'}
267
- </button>
270
+ </Button>
268
271
  </div>
269
272
  </div>
270
273
  {/if}
@@ -272,12 +275,13 @@ function getProviderLabel(type: string): string {
272
275
  {#if actionError}
273
276
  <div class="test-result failure" role="alert" aria-live="assertive">
274
277
  {actionError}
275
- <button
276
- type="button"
278
+ <Button
279
+ variant="ghost"
280
+ size="sm"
277
281
  class="dismiss-btn"
278
282
  aria-label={t(M['messages.email_account_manager.dismiss_error'])}
279
283
  onclick={() => actionError = null}
280
- >&times;</button>
284
+ >&times;</Button>
281
285
  </div>
282
286
  {/if}
283
287
 
@@ -288,7 +292,7 @@ function getProviderLabel(type: string): string {
288
292
  {:else}
289
293
  {t(M['messages.email_account_manager.connection_failed'])} {testResult.error ?? 'Unknown error'}
290
294
  {/if}
291
- <button class="dismiss-btn" onclick={() => testResult = null}>&times;</button>
295
+ <Button variant="ghost" size="sm" class="dismiss-btn" onclick={() => testResult = null}>&times;</Button>
292
296
  </div>
293
297
  {/if}
294
298
 
@@ -327,21 +331,25 @@ function getProviderLabel(type: string): string {
327
331
  {#if !isReadonly}
328
332
  <div class="entry-actions">
329
333
  {#if ontest}
330
- <button
334
+ <Button
335
+ variant="ghost"
336
+ size="sm"
331
337
  class="test-btn"
332
338
  onclick={(e) => { e.stopPropagation(); testConnection(acct); }}
333
339
  disabled={testingId === acct.id}
334
340
  title={t(M['messages.email_account_manager.test_connection'])}
335
341
  >
336
342
  {testingId === acct.id ? '...' : 'Test'}
337
- </button>
343
+ </Button>
338
344
  {/if}
339
345
  {#if ondelete}
340
- <button
346
+ <Button
347
+ variant="ghost"
348
+ size="sm"
341
349
  class="delete-btn"
342
350
  onclick={(e) => { e.stopPropagation(); remove(acct); }}
343
351
  title={t(M['messages.email_account_manager.remove'])}
344
- >&times;</button>
352
+ >&times;</Button>
345
353
  {/if}
346
354
  </div>
347
355
  {/if}
@@ -370,25 +378,17 @@ function getProviderLabel(type: string): string {
370
378
  color: var(--smrt-color-on-surface-variant, #43474e);
371
379
  }
372
380
 
373
- .add-btn {
374
- padding: 0.375rem 0.75rem;
381
+ /*
382
+ * The add button now renders through smrt-ui's <Button variant="secondary">.
383
+ * The variant owns the outlined-primary look + hover; `.section-header-row
384
+ * :global(.add-btn)` only re-asserts radius and the flex-shrink so the button
385
+ * keeps its place in the header row (issue #1589).
386
+ */
387
+ .section-header-row :global(.add-btn) {
375
388
  border-radius: var(--smrt-radius-md, 8px);
376
- border: 1px solid var(--smrt-color-primary, #005ac1);
377
- background: transparent;
378
- color: var(--smrt-color-primary, #005ac1);
379
- cursor: pointer;
380
- font-size: var(--smrt-typography-label-large-size, 0.8125rem);
381
- font-family: inherit;
382
- font-weight: var(--smrt-typography-weight-medium, 500);
383
- transition: all 150ms ease;
384
389
  flex-shrink: 0;
385
390
  }
386
391
 
387
- .add-btn:hover {
388
- background: var(--smrt-color-primary, #005ac1);
389
- color: var(--smrt-color-on-primary, #fff);
390
- }
391
-
392
392
  .entry-form {
393
393
  background: var(--smrt-color-surface-container, #f0f1f9);
394
394
  border: 1px solid var(--smrt-color-primary, #005ac1);
@@ -481,42 +481,20 @@ function getProviderLabel(type: string): string {
481
481
  padding-top: 0.25rem;
482
482
  }
483
483
 
484
- .cancel-btn {
485
- padding: 0.375rem 0.75rem;
484
+ /*
485
+ * Cancel/Save now use Button's secondary/primary variants (dead bespoke CSS
486
+ * removed). `.form-actions :global(...)` only re-asserts the rounded radius so
487
+ * they match the form's other controls (issue #1589). Cancel's neutral outline
488
+ * color override keeps it from picking up secondary's primary border color.
489
+ */
490
+ .form-actions :global(.cancel-btn),
491
+ .form-actions :global(.save-btn) {
486
492
  border-radius: var(--smrt-radius-md, 8px);
487
- border: 1px solid var(--smrt-color-outline-variant, #c2c7cf);
488
- background: transparent;
489
- color: var(--smrt-color-on-surface-variant, #43474e);
490
- cursor: pointer;
491
- font-size: var(--smrt-typography-label-large-size, 0.8125rem);
492
- font-family: inherit;
493
- transition: all 150ms ease;
494
493
  }
495
494
 
496
- .cancel-btn:hover {
497
- background: var(--smrt-color-surface-container-high, #e6e7ef);
498
- }
499
-
500
- .save-btn {
501
- padding: 0.375rem 0.75rem;
502
- border-radius: var(--smrt-radius-md, 8px);
503
- border: 1px solid var(--smrt-color-primary, #005ac1);
504
- background: var(--smrt-color-primary, #005ac1);
505
- color: var(--smrt-color-on-primary, #fff);
506
- cursor: pointer;
507
- font-size: var(--smrt-typography-label-large-size, 0.8125rem);
508
- font-family: inherit;
509
- font-weight: var(--smrt-typography-weight-medium, 500);
510
- transition: all 150ms ease;
511
- }
512
-
513
- .save-btn:hover:not(:disabled) {
514
- opacity: 0.9;
515
- }
516
-
517
- .save-btn:disabled {
518
- opacity: 0.5;
519
- cursor: not-allowed;
495
+ .form-actions :global(.cancel-btn) {
496
+ border-color: var(--smrt-color-outline-variant, #c2c7cf);
497
+ color: var(--smrt-color-on-surface-variant, #43474e);
520
498
  }
521
499
 
522
500
  .test-result {
@@ -538,11 +516,16 @@ function getProviderLabel(type: string): string {
538
516
  color: var(--smrt-color-error, #ba1a1a);
539
517
  }
540
518
 
541
- .dismiss-btn {
519
+ /*
520
+ * The dismiss button now renders through smrt-ui's <Button variant="ghost">.
521
+ * `.test-result :global(.dismiss-btn)` anchors on the real `.test-result`
522
+ * element and pierces the Button child scope. `color: inherit` keeps the icon
523
+ * matching the success/failure banner color (issue #1589).
524
+ */
525
+ .test-result :global(.dismiss-btn) {
542
526
  background: transparent;
543
527
  border: none;
544
528
  font-size: var(--smrt-typography-body-large-size, 1rem);
545
- cursor: pointer;
546
529
  color: inherit;
547
530
  padding: 0 0.25rem;
548
531
  }
@@ -661,29 +644,28 @@ function getProviderLabel(type: string): string {
661
644
  flex-shrink: 0;
662
645
  }
663
646
 
664
- .test-btn {
647
+ /*
648
+ * The test and delete buttons now render through smrt-ui's <Button
649
+ * variant="ghost">. The <button> is emitted inside the Button child, so
650
+ * `.entry-actions :global(...)` anchors on the real `.entry-actions` element
651
+ * and pierces the child scope to keep the original outlined-pill styling and
652
+ * the delete button's red-on-hover affordance (issue #1589).
653
+ */
654
+ .entry-actions :global(.test-btn) {
665
655
  padding: 0.25rem 0.5rem;
666
656
  border-radius: var(--smrt-radius-sm, 4px);
667
657
  border: 1px solid var(--smrt-color-outline-variant, #c2c7cf);
668
658
  background: transparent;
669
659
  color: var(--smrt-color-on-surface-variant, #43474e);
670
- cursor: pointer;
671
660
  font-size: var(--smrt-typography-label-small-size, 0.6875rem);
672
- font-family: inherit;
673
- transition: all 150ms ease;
674
661
  }
675
662
 
676
- .test-btn:hover:not(:disabled) {
663
+ .entry-actions :global(.test-btn):hover:not(:disabled) {
677
664
  border-color: var(--smrt-color-primary, #005ac1);
678
665
  color: var(--smrt-color-primary, #005ac1);
679
666
  }
680
667
 
681
- .test-btn:disabled {
682
- opacity: 0.5;
683
- cursor: not-allowed;
684
- }
685
-
686
- .delete-btn {
668
+ .entry-actions :global(.delete-btn) {
687
669
  font-size: var(--smrt-typography-body-large-size, 1rem);
688
670
  line-height: 1;
689
671
  padding: 0.125rem 0.5rem;
@@ -691,13 +673,10 @@ function getProviderLabel(type: string): string {
691
673
  border: 1px solid transparent;
692
674
  background: transparent;
693
675
  color: var(--smrt-color-on-surface-variant, #43474e);
694
- cursor: pointer;
695
- font-family: inherit;
696
- transition: all 150ms ease;
697
676
  flex-shrink: 0;
698
677
  }
699
678
 
700
- .delete-btn:hover {
679
+ .entry-actions :global(.delete-btn):hover {
701
680
  background: var(--smrt-color-error-container, #fce4ec);
702
681
  color: var(--smrt-color-error, #ba1a1a);
703
682
  border-color: var(--smrt-color-error, #ba1a1a);
@@ -1 +1 @@
1
- {"version":3,"file":"EmailAccountManager.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/EmailAccountManager.svelte.ts"],"names":[],"mappings":"AAWA,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;AA+TD,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":"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"}