@happyvertical/smrt-assets 0.34.5 → 0.34.7

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": 1782261266180,
3
+ "timestamp": 1782290126880,
4
4
  "packageName": "@happyvertical/smrt-assets",
5
- "packageVersion": "0.34.5",
5
+ "packageVersion": "0.34.7",
6
6
  "objects": {
7
7
  "@happyvertical/smrt-assets:AssetAssociation": {
8
8
  "name": "assetassociation",
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "generatedAt": "2026-06-24T00:34:27.319Z",
3
+ "generatedAt": "2026-06-24T08:35:27.278Z",
4
4
  "packageName": "@happyvertical/smrt-assets",
5
- "packageVersion": "0.34.5",
5
+ "packageVersion": "0.34.7",
6
6
  "sourceManifestPath": "dist/manifest.json",
7
7
  "agentDocPath": "AGENTS.md",
8
8
  "sourceHashes": {
9
- "manifest": "ab0e3eae0ead7cb064b3c7c0ca97f06e41566cabec46c969292bfbe889f40066",
10
- "packageJson": "4c41e96836ea11748a47b472f126dda15a4f67dff18751cf4d833b45ee3fd358",
9
+ "manifest": "3eeb0753f504c9d471c1a82b87d300736bd7ce3e31f7080328cab84146365aa8",
10
+ "packageJson": "3db257c374c45bad45521f65b910648b3b41fb02b4f132fa9534702cd586681e",
11
11
  "agents": "a034545874fb7767b31168d98aa2b1b8cac205b14f2f04fb5a8e5acf33690eef"
12
12
  },
13
13
  "exports": [
@@ -8,6 +8,7 @@
8
8
 
9
9
  import { ConfirmDialog } from '@happyvertical/smrt-ui/feedback';
10
10
  import { useI18n } from '@happyvertical/smrt-ui/i18n';
11
+ import { Button } from '@happyvertical/smrt-ui/ui';
11
12
  import { M } from './i18n.js';
12
13
  import type { ActionBarProps } from './types';
13
14
 
@@ -56,34 +57,33 @@ const count = $derived(selectedAssets.length);
56
57
  <div class="action-bar">
57
58
  <div class="action-bar__left">
58
59
  <span class="action-bar__count">{count} selected</span>
59
- <button
60
- type="button"
61
- class="action-bar__clear"
60
+ <Button
61
+ variant="ghost"
62
+ size="sm"
62
63
  onclick={() => (onclearselection ?? onClearSelection)()}
63
64
  >
64
65
  Clear
65
- </button>
66
+ </Button>
66
67
  </div>
67
68
 
68
69
  <div class="action-bar__actions">
69
70
  {#each customActions as ca (ca.label)}
70
71
  {#if ca.multi !== false || count === 1}
71
- <button
72
- type="button"
73
- class="action-btn"
74
- class:action-btn--destructive={ca.destructive}
72
+ <Button
73
+ variant={ca.destructive ? 'danger' : 'secondary'}
74
+ size="sm"
75
75
  onclick={() => handleCustomAction(ca.action)}
76
76
  >
77
77
  {#if ca.icon}
78
78
  {@render ca.icon()}
79
79
  {/if}
80
80
  {ca.label}
81
- </button>
81
+ </Button>
82
82
  {/if}
83
83
  {/each}
84
84
 
85
85
  <!-- Default: Delete -->
86
- <button type="button" class="action-btn action-btn--destructive" onclick={handleDelete}>
86
+ <Button variant="danger" size="sm" onclick={handleDelete}>
87
87
  <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
88
88
  <polyline points="3 6 5 6 21 6"></polyline>
89
89
  <path d="M19 6l-2 14H7L5 6"></path>
@@ -92,7 +92,7 @@ const count = $derived(selectedAssets.length);
92
92
  <path d="M9 6V4a1 1 0 011-1h4a1 1 0 011 1v2"></path>
93
93
  </svg>
94
94
  Delete
95
- </button>
95
+ </Button>
96
96
  </div>
97
97
  </div>
98
98
 
@@ -144,57 +144,12 @@ const count = $derived(selectedAssets.length);
144
144
  color: var(--smrt-color-on-primary-container, #002d6c);
145
145
  }
146
146
 
147
- .action-bar__clear {
148
- padding: var(--smrt-spacing-1, 4px) var(--smrt-spacing-2, 8px);
149
- border: none;
150
- background: transparent;
151
- font-family: inherit;
152
- font-size: var(--smrt-typography-body-medium-size, 0.875rem);
153
- color: var(--smrt-color-primary, #005ac1);
154
- cursor: pointer;
155
- border-radius: var(--smrt-radius-small, 0.25rem);
156
- }
157
-
158
- .action-bar__clear:hover {
159
- background: color-mix(in srgb, var(--smrt-color-shadow) 5%, transparent);
160
- }
161
-
162
147
  .action-bar__actions {
163
148
  display: flex;
164
149
  align-items: center;
165
150
  gap: var(--smrt-spacing-2, 0.5rem);
166
151
  }
167
152
 
168
- .action-btn {
169
- display: inline-flex;
170
- align-items: center;
171
- gap: var(--smrt-spacing-1, 4px);
172
- height: 32px;
173
- padding: 0 var(--smrt-spacing-3, 0.75rem);
174
- font-family: inherit;
175
- font-size: var(--smrt-typography-body-medium-size, 0.875rem);
176
- font-weight: var(--smrt-typography-weight-medium, 500);
177
- border: 1px solid var(--smrt-color-outline-variant, #e5e7eb);
178
- background: var(--smrt-color-surface, #ffffff);
179
- color: var(--smrt-color-on-surface, #111827);
180
- border-radius: var(--smrt-radius-medium, 0.5rem);
181
- cursor: pointer;
182
- transition: all 150ms ease;
183
- }
184
-
185
- .action-btn:hover {
186
- box-shadow: var(--smrt-elevation-1, 0 1px 2px rgba(0,0,0,0.05));
187
- }
188
-
189
- .action-btn--destructive {
190
- border-color: var(--smrt-color-error, #dc2626);
191
- color: var(--smrt-color-error, #dc2626);
192
- }
193
-
194
- .action-btn--destructive:hover {
195
- background: var(--smrt-color-error-container, #fef2f2);
196
- }
197
-
198
153
  @media (prefers-reduced-motion: reduce) {
199
154
  .action-bar {
200
155
  animation: none;
@@ -1 +1 @@
1
- {"version":3,"file":"ActionBar.svelte.d.ts","sourceRoot":"","sources":["../../src/svelte/ActionBar.svelte.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAmG9C,QAAA,MAAM,SAAS,oDAAwC,CAAC;AACxD,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAC9C,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"ActionBar.svelte.d.ts","sourceRoot":"","sources":["../../src/svelte/ActionBar.svelte.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAoG9C,QAAA,MAAM,SAAS,oDAAwC,CAAC;AACxD,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAC9C,eAAe,SAAS,CAAC"}
@@ -7,6 +7,7 @@
7
7
  */
8
8
 
9
9
  import { Modal } from '@happyvertical/smrt-ui/feedback';
10
+ import { Input, Textarea } from '@happyvertical/smrt-ui/forms';
10
11
  import { useI18n } from '@happyvertical/smrt-ui/i18n';
11
12
  import { Button } from '@happyvertical/smrt-ui/ui';
12
13
  import type { Snippet } from 'svelte';
@@ -202,7 +203,7 @@ function formatDate(date: Date | string | undefined): string {
202
203
  <div class="detail__form">
203
204
  <div class="form-field">
204
205
  <label for="detail-name" class="form-label">Name</label>
205
- <input id="detail-name" type="text" class="form-input" bind:value={editName} />
206
+ <Input id="detail-name" type="text" bind:value={editName} />
206
207
  </div>
207
208
 
208
209
  {#if isImage}
@@ -213,13 +214,13 @@ function formatDate(date: Date | string | undefined): string {
213
214
  <span class="label-warning">{t(M['assets.asset_detail.alt_text_missing_warning'])}</span>
214
215
  {/if}
215
216
  </label>
216
- <input id="detail-alt" type="text" class="form-input" bind:value={editAlt} placeholder={t(M['assets.asset_detail.alt_text_placeholder'])} />
217
+ <Input id="detail-alt" type="text" bind:value={editAlt} placeholder={t(M['assets.asset_detail.alt_text_placeholder'])} />
217
218
  </div>
218
219
  {/if}
219
220
 
220
221
  <div class="form-field">
221
222
  <label for="detail-desc" class="form-label">Description</label>
222
- <textarea id="detail-desc" class="form-textarea" bind:value={editDescription} rows="3" placeholder={t(M['assets.asset_detail.description_placeholder'])}></textarea>
223
+ <Textarea id="detail-desc" bind:value={editDescription} rows={3} placeholder={t(M['assets.asset_detail.description_placeholder'])} />
223
224
  </div>
224
225
  </div>
225
226
  </section>
@@ -261,18 +262,18 @@ function formatDate(date: Date | string | undefined): string {
261
262
  <section class="detail__section">
262
263
  <h3 class="section-heading">{t(M['assets.asset_detail.quick_actions'])}</h3>
263
264
  <div class="quick-actions">
264
- <button type="button" class="quick-btn" onclick={copyUrl} disabled={!asset.sourceUri}>
265
+ <Button variant="ghost" size="sm" class="quick-btn" onclick={copyUrl} disabled={!asset.sourceUri}>
265
266
  {t(M['assets.asset_detail.copy_url'])}
266
- </button>
267
+ </Button>
267
268
  {#if isImage}
268
- <button type="button" class="quick-btn" onclick={copyMarkdown} disabled={!asset.sourceUri}>
269
+ <Button variant="ghost" size="sm" class="quick-btn" onclick={copyMarkdown} disabled={!asset.sourceUri}>
269
270
  {t(M['assets.asset_detail.copy_markdown'])}
270
- </button>
271
+ </Button>
271
272
  {/if}
272
273
  {#if onedit && isImage}
273
- <button type="button" class="quick-btn" onclick={handleEdit}>
274
+ <Button variant="ghost" size="sm" class="quick-btn" onclick={handleEdit}>
274
275
  {t(M['assets.asset_detail.edit_image'])}
275
- </button>
276
+ </Button>
276
277
  {/if}
277
278
  </div>
278
279
  <div class="copy-feedback" role="status" aria-live="polite">{copyFeedback}</div>
@@ -405,29 +406,6 @@ function formatDate(date: Date | string | undefined): string {
405
406
  margin-left: var(--smrt-spacing-1, 4px);
406
407
  }
407
408
 
408
- .form-input, .form-textarea {
409
- width: 100%;
410
- padding: var(--smrt-spacing-2, 0.5rem) var(--smrt-spacing-3, 0.75rem);
411
- border: 1px solid var(--smrt-color-outline-variant, #e5e7eb);
412
- border-radius: var(--smrt-radius-medium, 0.5rem);
413
- font-family: inherit;
414
- font-size: var(--smrt-typography-body-medium-size, 0.875rem);
415
- color: var(--smrt-color-on-surface, #111827);
416
- background: var(--smrt-color-surface, #ffffff);
417
- box-sizing: border-box;
418
- }
419
-
420
- .form-input:focus, .form-textarea:focus {
421
- outline: none;
422
- border-color: var(--smrt-color-primary, #005ac1);
423
- box-shadow: 0 0 0 2px var(--smrt-color-primary-container, rgba(0, 90, 193, 0.1));
424
- }
425
-
426
- .form-textarea {
427
- resize: vertical;
428
- min-height: 60px;
429
- }
430
-
431
409
  /* Metadata */
432
410
  .metadata-grid {
433
411
  display: grid;
@@ -462,33 +440,25 @@ function formatDate(date: Date | string | undefined): string {
462
440
  gap: var(--smrt-spacing-2, 0.5rem);
463
441
  }
464
442
 
465
- .quick-btn {
466
- display: inline-flex;
467
- align-items: center;
443
+ /* The quick-action buttons render via <Button> (issue #1589). They keep a
444
+ bespoke bordered-surface look (vs. the transparent ghost variant), so the
445
+ overrides reach the child-rendered <button> through :global() scoping. */
446
+ .quick-actions :global(.quick-btn) {
468
447
  gap: var(--smrt-spacing-1, 4px);
469
448
  height: 32px;
470
449
  padding: 0 var(--smrt-spacing-3, 0.75rem);
471
- font-family: inherit;
472
450
  font-size: var(--smrt-typography-label-medium-size, 0.8rem);
473
451
  font-weight: var(--smrt-typography-weight-medium, 500);
474
452
  border: 1px solid var(--smrt-color-outline-variant, #e5e7eb);
475
453
  background: var(--smrt-color-surface, #ffffff);
476
454
  color: var(--smrt-color-on-surface, #111827);
477
- border-radius: var(--smrt-radius-medium, 0.5rem);
478
- cursor: pointer;
479
- transition: all 150ms ease;
480
455
  }
481
456
 
482
- .quick-btn:hover:not(:disabled) {
457
+ .quick-actions :global(.quick-btn:hover:not(:disabled)) {
483
458
  background: var(--smrt-color-surface-container-low, #f9fafb);
484
459
  box-shadow: var(--smrt-elevation-1);
485
460
  }
486
461
 
487
- .quick-btn:disabled {
488
- opacity: 0.5;
489
- cursor: not-allowed;
490
- }
491
-
492
462
  .copy-feedback {
493
463
  margin-top: var(--smrt-spacing-2, 0.5rem);
494
464
  font-size: var(--smrt-typography-label-medium-size, 0.8rem);
@@ -1 +1 @@
1
- {"version":3,"file":"AssetDetail.svelte.d.ts","sourceRoot":"","sources":["../../src/svelte/AssetDetail.svelte.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAG9C,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,2BAA2B;IAC3B,KAAK,EAAE,cAAc,GAAG,IAAI,CAAC;IAC7B,sCAAsC;IACtC,IAAI,EAAE,OAAO,CAAC;IACd,qCAAqC;IACrC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,qDAAqD;IACrD,MAAM,CAAC,EAAE,CACP,KAAK,EAAE,cAAc,EACrB,OAAO,EAAE,kBAAkB,KACxB,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,MAAM,CAAC,EAAE,CACP,KAAK,EAAE,cAAc,EACrB,OAAO,EAAE,kBAAkB,KACxB,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,qCAAqC;IACrC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IAC3C,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IAC3C,wCAAwC;IACxC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IACzC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IACzC,4DAA4D;IAC5D,iBAAiB,CAAC,EAAE,OAAO,CAAC,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;CACpD;AAqQD,QAAA,MAAM,WAAW,sDAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"AssetDetail.svelte.d.ts","sourceRoot":"","sources":["../../src/svelte/AssetDetail.svelte.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAG9C,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,2BAA2B;IAC3B,KAAK,EAAE,cAAc,GAAG,IAAI,CAAC;IAC7B,sCAAsC;IACtC,IAAI,EAAE,OAAO,CAAC;IACd,qCAAqC;IACrC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,qDAAqD;IACrD,MAAM,CAAC,EAAE,CACP,KAAK,EAAE,cAAc,EACrB,OAAO,EAAE,kBAAkB,KACxB,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,MAAM,CAAC,EAAE,CACP,KAAK,EAAE,cAAc,EACrB,OAAO,EAAE,kBAAkB,KACxB,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,qCAAqC;IACrC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IAC3C,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IAC3C,wCAAwC;IACxC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IACzC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IACzC,4DAA4D;IAC5D,iBAAiB,CAAC,EAAE,OAAO,CAAC,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;CACpD;AAsQD,QAAA,MAAM,WAAW,sDAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
@@ -107,6 +107,7 @@ function getAltText(asset: PersistedAsset): string {
107
107
  inside an interactive control (axe nested-interactive). It sits
108
108
  above the non-interactive content but below the checkbox (z-index),
109
109
  and is keyboard-activatable natively (Enter/Space). -->
110
+ <!-- raw-primitive-allow: stretched transparent click-catching card overlay positioned absolute inset 0, layered under the checkbox by z-index; not a styled action button -->
110
111
  <button
111
112
  type="button"
112
113
  class="asset-card__open"
@@ -118,6 +119,7 @@ function getAltText(asset: PersistedAsset): string {
118
119
 
119
120
  <!-- Selection checkbox -->
120
121
  <div class="asset-card__checkbox">
122
+ <!-- raw-primitive-allow: native checkbox; no Provider-free checkbox primitive (Toggle is a switch with different semantics, CheckboxInput requires a Provider) -->
121
123
  <input
122
124
  type="checkbox"
123
125
  checked={selected}
@@ -1 +1 @@
1
- {"version":3,"file":"AssetGrid.svelte.d.ts","sourceRoot":"","sources":["../../src/svelte/AssetGrid.svelte.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,cAAc,EAAkB,MAAM,SAAS,CAAC;AA+I9D,QAAA,MAAM,SAAS,oDAAwC,CAAC;AACxD,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAC9C,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"AssetGrid.svelte.d.ts","sourceRoot":"","sources":["../../src/svelte/AssetGrid.svelte.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,cAAc,EAAkB,MAAM,SAAS,CAAC;AAiJ9D,QAAA,MAAM,SAAS,oDAAwC,CAAC;AACxD,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAC9C,eAAe,SAAS,CAAC"}
@@ -7,6 +7,7 @@
7
7
  */
8
8
 
9
9
  import { useI18n } from '@happyvertical/smrt-ui/i18n';
10
+ import { Button } from '@happyvertical/smrt-ui/ui';
10
11
  import { M } from './i18n.js';
11
12
  import type {
12
13
  AssetListProps,
@@ -110,6 +111,7 @@ function setIndeterminate(node: HTMLInputElement, value: boolean) {
110
111
  <thead class="list-table__head">
111
112
  <tr>
112
113
  <th class="col-checkbox">
114
+ <!-- raw-primitive-allow: native checkbox; no Provider-free checkbox primitive (Toggle is a switch with different semantics, CheckboxInput requires a Provider) -->
113
115
  <input
114
116
  type="checkbox"
115
117
  checked={allSelected}
@@ -120,15 +122,15 @@ function setIndeterminate(node: HTMLInputElement, value: boolean) {
120
122
  </th>
121
123
  <th class="col-thumb">Preview</th>
122
124
  <th class="col-name">
123
- <button type="button" class="sort-btn" onclick={() => handleSort('name')}>
125
+ <Button variant="ghost" size="sm" class="sort-btn" onclick={() => handleSort('name')}>
124
126
  Name <span class="sort-indicator">{getSortIndicator('name')}</span>
125
- </button>
127
+ </Button>
126
128
  </th>
127
129
  <th class="col-type">Type</th>
128
130
  <th class="col-date">
129
- <button type="button" class="sort-btn" onclick={() => handleSort('createdAt')}>
131
+ <Button variant="ghost" size="sm" class="sort-btn" onclick={() => handleSort('createdAt')}>
130
132
  Created <span class="sort-indicator">{getSortIndicator('createdAt')}</span>
131
- </button>
133
+ </Button>
132
134
  </th>
133
135
  <th class="col-status">Status</th>
134
136
  </tr>
@@ -170,6 +172,7 @@ function setIndeterminate(node: HTMLInputElement, value: boolean) {
170
172
  class:list-table__row--selected={selected}
171
173
  >
172
174
  <td class="col-checkbox">
175
+ <!-- raw-primitive-allow: native checkbox; no Provider-free checkbox primitive (Toggle is a switch with different semantics, CheckboxInput requires a Provider) -->
173
176
  <input
174
177
  type="checkbox"
175
178
  checked={selected}
@@ -187,15 +190,15 @@ function setIndeterminate(node: HTMLInputElement, value: boolean) {
187
190
  </td>
188
191
  <td class="col-name">
189
192
  <!-- The name is the row's open action (a button, not a
190
- role="button" on the <tr> nesting the checkbox avoids axe
193
+ role="button" on the row nesting the checkbox, which avoids axe
191
194
  nested-interactive). -->
192
- <button
193
- type="button"
195
+ <Button
196
+ variant="ghost"
194
197
  class="row-name"
195
198
  onclick={() => onAssetClick(asset)}
196
199
  >
197
200
  {asset.name || 'Untitled'}
198
- </button>
201
+ </Button>
199
202
  {#if asset.description}
200
203
  <span class="row-desc">{asset.description}</span>
201
204
  {/if}
@@ -308,7 +311,10 @@ function setIndeterminate(node: HTMLInputElement, value: boolean) {
308
311
  min-width: 150px;
309
312
  }
310
313
 
311
- .row-name {
314
+ /* The row name renders via <Button class="row-name"> (issue #1589). The
315
+ overrides reset it to inline name text and must reach the child-rendered
316
+ <button> through :global() scoping. */
317
+ .col-name :global(.row-name) {
312
318
  display: block;
313
319
  font-weight: var(--smrt-typography-weight-medium, 500);
314
320
  white-space: nowrap;
@@ -327,16 +333,10 @@ function setIndeterminate(node: HTMLInputElement, value: boolean) {
327
333
  cursor: pointer;
328
334
  }
329
335
 
330
- .row-name:hover {
336
+ .col-name :global(.row-name:hover) {
331
337
  text-decoration: underline;
332
338
  }
333
339
 
334
- .row-name:focus-visible {
335
- outline: 2px solid var(--smrt-color-primary, #005ac1);
336
- outline-offset: 2px;
337
- border-radius: var(--smrt-radius-small, 0.25rem);
338
- }
339
-
340
340
  .row-desc {
341
341
  display: block;
342
342
  font-size: var(--smrt-typography-body-small-size, 0.75rem);
@@ -383,10 +383,9 @@ function setIndeterminate(node: HTMLInputElement, value: boolean) {
383
383
  background: var(--smrt-color-success, #22c55e);
384
384
  }
385
385
 
386
- /* Sort */
387
- .sort-btn {
388
- display: inline-flex;
389
- align-items: center;
386
+ /* Sort — renders via <Button class="sort-btn"> (issue #1589). Overrides reset
387
+ it to an inline header-text button and reach the child <button> via :global(). */
388
+ .list-table__head :global(.sort-btn) {
390
389
  gap: var(--smrt-spacing-1, 4px);
391
390
  padding: 0;
392
391
  border: none;
@@ -394,10 +393,9 @@ function setIndeterminate(node: HTMLInputElement, value: boolean) {
394
393
  font: inherit;
395
394
  font-weight: var(--smrt-typography-weight-semibold, 600);
396
395
  color: inherit;
397
- cursor: pointer;
398
396
  }
399
397
 
400
- .sort-btn:hover {
398
+ .list-table__head :global(.sort-btn:hover) {
401
399
  color: var(--smrt-color-primary, #005ac1);
402
400
  }
403
401
 
@@ -1 +1 @@
1
- {"version":3,"file":"AssetList.svelte.d.ts","sourceRoot":"","sources":["../../src/svelte/AssetList.svelte.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EACV,cAAc,EAIf,MAAM,SAAS,CAAC;AAkMjB,QAAA,MAAM,SAAS,oDAAwC,CAAC;AACxD,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAC9C,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"AssetList.svelte.d.ts","sourceRoot":"","sources":["../../src/svelte/AssetList.svelte.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACV,cAAc,EAIf,MAAM,SAAS,CAAC;AAqMjB,QAAA,MAAM,SAAS,oDAAwC,CAAC;AACxD,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAC9C,eAAe,SAAS,CAAC"}
@@ -7,7 +7,9 @@ import { onDestroy } from 'svelte';
7
7
  * and an upload button.
8
8
  */
9
9
 
10
+ import { Input, Select } from '@happyvertical/smrt-ui/forms';
10
11
  import { useI18n } from '@happyvertical/smrt-ui/i18n';
12
+ import { Button } from '@happyvertical/smrt-ui/ui';
11
13
  import { M } from './i18n.js';
12
14
  import type {
13
15
  AssetFilters,
@@ -107,7 +109,7 @@ const views: { key: AssetViewMode; label: string; icon: string }[] = [
107
109
  <line x1="21" y1="21" x2="16.65" y2="16.65"></line>
108
110
  </svg>
109
111
  </span>
110
- <input
112
+ <Input
111
113
  type="search"
112
114
  class="search-field"
113
115
  placeholder={t(M['assets.asset_toolbar.search_placeholder'])}
@@ -116,42 +118,41 @@ const views: { key: AssetViewMode; label: string; icon: string }[] = [
116
118
  aria-label={t(M['assets.asset_toolbar.search_assets'])}
117
119
  />
118
120
  {#if searchValue}
119
- <button type="button" class="search-clear" onclick={handleClearSearch} aria-label={t(M['assets.asset_toolbar.clear_search'])}>
121
+ <Button variant="ghost" size="sm" class="search-clear" onclick={handleClearSearch} aria-label={t(M['assets.asset_toolbar.clear_search'])}>
120
122
  <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
121
123
  <line x1="18" y1="6" x2="6" y2="18"></line>
122
124
  <line x1="6" y1="6" x2="18" y2="18"></line>
123
125
  </svg>
124
- </button>
126
+ </Button>
125
127
  {/if}
126
128
  </div>
127
129
 
128
130
  <!-- Type Filter -->
129
- <select class="asset-toolbar__select" value={typeValue} onchange={handleTypeFilter} aria-label={t(M['assets.asset_toolbar.filter_by_type'])}>
131
+ <Select class="asset-toolbar__select" value={typeValue} onchange={handleTypeFilter} aria-label={t(M['assets.asset_toolbar.filter_by_type'])}>
130
132
  <option value="">{t(M['assets.asset_toolbar.all_types'])}</option>
131
133
  <option value="image">Images</option>
132
134
  <option value="video">Videos</option>
133
135
  <option value="document">Documents</option>
134
136
  <option value="audio">Audio</option>
135
- </select>
137
+ </Select>
136
138
 
137
139
  <!-- Sort -->
138
- <select class="asset-toolbar__select" value={sortValue} onchange={handleSortChange} aria-label={t(M['assets.asset_toolbar.sort_assets'])}>
140
+ <Select class="asset-toolbar__select" value={sortValue} onchange={handleSortChange} aria-label={t(M['assets.asset_toolbar.sort_assets'])}>
139
141
  <option value="createdAt:desc">{t(M['assets.asset_toolbar.newest_first'])}</option>
140
142
  <option value="createdAt:asc">{t(M['assets.asset_toolbar.oldest_first'])}</option>
141
143
  <option value="name:asc">{t(M['assets.asset_toolbar.name_a_z'])}</option>
142
144
  <option value="name:desc">{t(M['assets.asset_toolbar.name_z_a'])}</option>
143
145
  <option value="updatedAt:desc">{t(M['assets.asset_toolbar.recently_updated'])}</option>
144
- </select>
146
+ </Select>
145
147
  </div>
146
148
 
147
149
  <div class="asset-toolbar__right">
148
150
  <!-- View Toggle -->
149
151
  <div class="view-toggle" role="group" aria-label={t(M['assets.asset_toolbar.view_mode'])}>
150
152
  {#each views as v (v.key)}
151
- <button
152
- type="button"
153
+ <Button
154
+ variant={view === v.key ? 'primary' : 'ghost'}
153
155
  class="view-toggle__btn"
154
- class:view-toggle__btn--active={view === v.key}
155
156
  onclick={() => (onviewchange ?? onViewChange)(v.key)}
156
157
  aria-label={t(M['assets.asset_toolbar.view_label'], { label: v.label })}
157
158
  aria-pressed={view === v.key}
@@ -173,13 +174,13 @@ const views: { key: AssetViewMode; label: string; icon: string }[] = [
173
174
  <line x1="3" y1="18" x2="3.01" y2="18"></line>
174
175
  </svg>
175
176
  {/if}
176
- </button>
177
+ </Button>
177
178
  {/each}
178
179
  </div>
179
180
 
180
181
  <!-- Upload Button -->
181
- <button
182
- type="button"
182
+ <Button
183
+ variant="primary"
183
184
  class="upload-btn"
184
185
  onclick={() => (onupload ?? onUpload)()}
185
186
  >
@@ -189,7 +190,7 @@ const views: { key: AssetViewMode; label: string; icon: string }[] = [
189
190
  <line x1="12" y1="3" x2="12" y2="15"></line>
190
191
  </svg>
191
192
  Upload
192
- </button>
193
+ </Button>
193
194
  </div>
194
195
  </div>
195
196
 
@@ -247,10 +248,16 @@ const views: { key: AssetViewMode; label: string; icon: string }[] = [
247
248
  color: var(--smrt-color-on-surface-variant, #6b7280);
248
249
  }
249
250
 
250
- .search-field {
251
+ /* The search field renders via <Input class="search-field"> (issue #1589). It
252
+ sits inside the bordered .asset-toolbar__search shell, so the overrides strip
253
+ the primitive's own border/background/box-shadow to keep it transparent and
254
+ reach the child <input> through :global() scoping. */
255
+ .asset-toolbar__search :global(.search-field) {
251
256
  flex: 1;
252
257
  border: none;
258
+ border-radius: 0;
253
259
  background: transparent;
260
+ box-shadow: none;
254
261
  padding: var(--smrt-spacing-1, 0.25rem) var(--smrt-spacing-2, 0.5rem);
255
262
  font-family: inherit;
256
263
  font-size: var(--smrt-typography-body-medium-size, 0.875rem);
@@ -259,18 +266,23 @@ const views: { key: AssetViewMode; label: string; icon: string }[] = [
259
266
  min-width: 0;
260
267
  }
261
268
 
262
- .search-field::placeholder {
269
+ .asset-toolbar__search :global(.search-field:focus) {
270
+ border: none;
271
+ box-shadow: none;
272
+ }
273
+
274
+ .asset-toolbar__search :global(.search-field::placeholder) {
263
275
  color: var(--smrt-color-on-surface-variant, #9ca3af);
264
276
  }
265
277
 
266
- .search-field::-webkit-search-cancel-button {
278
+ .asset-toolbar__search :global(.search-field::-webkit-search-cancel-button) {
267
279
  display: none;
268
280
  }
269
281
 
270
- .search-clear {
271
- display: flex;
272
- align-items: center;
273
- justify-content: center;
282
+ /* search-clear renders via <Button class="search-clear"> (issue #1589). The
283
+ overrides shape it into a small round icon button and reach the child
284
+ <button> via :global() scoping. */
285
+ .asset-toolbar__search :global(.search-clear) {
274
286
  width: 24px;
275
287
  height: 24px;
276
288
  margin-right: var(--smrt-spacing-1, 0.25rem);
@@ -278,20 +290,23 @@ const views: { key: AssetViewMode; label: string; icon: string }[] = [
278
290
  border: none;
279
291
  background: transparent;
280
292
  color: var(--smrt-color-on-surface-variant, #6b7280);
281
- cursor: pointer;
282
293
  border-radius: var(--smrt-radius-full, 9999px);
283
294
  }
284
295
 
285
- .search-clear:hover {
296
+ .asset-toolbar__search :global(.search-clear:hover) {
286
297
  color: var(--smrt-color-on-surface, #111827);
287
298
  background: var(--smrt-color-surface-container, #f3f4f6);
288
299
  }
289
300
 
290
- /* Selects */
291
- .asset-toolbar__select {
301
+ /* Selects render via <Select class="asset-toolbar__select"> (issue #1589). The
302
+ base .select primitive owns the chevron + focus ring; these overrides pin the
303
+ toolbar-matching 36px height, container-low fill, and width, and reach the
304
+ child <select> through :global() scoping. */
305
+ .asset-toolbar__left :global(.asset-toolbar__select) {
306
+ width: auto;
292
307
  height: 36px;
293
- padding: 0 var(--smrt-spacing-3, 0.75rem);
294
- background: var(--smrt-color-surface-container-low, #f9fafb);
308
+ padding: 0 var(--smrt-spacing-8, 2rem) 0 var(--smrt-spacing-3, 0.75rem);
309
+ background-color: var(--smrt-color-surface-container-low, #f9fafb);
295
310
  border: 1px solid var(--smrt-color-outline-variant, #e5e7eb);
296
311
  border-radius: var(--smrt-radius-medium, 0.5rem);
297
312
  font-family: inherit;
@@ -300,11 +315,6 @@ const views: { key: AssetViewMode; label: string; icon: string }[] = [
300
315
  cursor: pointer;
301
316
  }
302
317
 
303
- .asset-toolbar__select:focus {
304
- outline: none;
305
- border-color: var(--smrt-color-primary, #005ac1);
306
- }
307
-
308
318
  /* View Toggle */
309
319
  .view-toggle {
310
320
  display: flex;
@@ -313,58 +323,32 @@ const views: { key: AssetViewMode; label: string; icon: string }[] = [
313
323
  overflow: hidden;
314
324
  }
315
325
 
316
- .view-toggle__btn {
317
- display: flex;
318
- align-items: center;
319
- justify-content: center;
326
+ /* view-toggle__btn renders via <Button> (issue #1589); the active state is the
327
+ `primary` variant, the inactive state the `ghost` variant. These overrides
328
+ give the buttons their square icon footprint and the segmented divider, and
329
+ reach the child <button> via :global() scoping. */
330
+ .view-toggle :global(.view-toggle__btn) {
320
331
  width: 36px;
321
332
  height: 36px;
322
333
  padding: 0;
323
334
  border: none;
324
- background: var(--smrt-color-surface, #ffffff);
325
- color: var(--smrt-color-on-surface-variant, #6b7280);
326
- cursor: pointer;
327
- transition: all 150ms ease;
335
+ border-radius: 0;
328
336
  }
329
337
 
330
- .view-toggle__btn:not(:last-child) {
338
+ .view-toggle :global(.view-toggle__btn:not(:last-child)) {
331
339
  border-right: 1px solid var(--smrt-color-outline-variant, #e5e7eb);
332
340
  }
333
341
 
334
- .view-toggle__btn:hover {
335
- background: var(--smrt-color-surface-container-low, #f9fafb);
336
- }
337
-
338
- .view-toggle__btn--active {
339
- background: var(--smrt-color-primary-container, #dbeafe);
340
- color: var(--smrt-color-on-primary-container, #002d6c);
341
- }
342
-
343
- /* Upload Button */
344
- .upload-btn {
345
- display: inline-flex;
346
- align-items: center;
342
+ /* Upload Button — renders via <Button variant="primary" class="upload-btn">
343
+ (issue #1589). The primary variant owns the fill/hover; the override only
344
+ pins the toolbar-matching 36px height and gap, reaching the child <button>
345
+ via :global() scoping. */
346
+ .asset-toolbar__right :global(.upload-btn) {
347
347
  gap: var(--smrt-spacing-1, 0.25rem);
348
348
  height: 36px;
349
349
  padding: 0 var(--smrt-spacing-3, 0.75rem);
350
- font-family: inherit;
351
350
  font-size: var(--smrt-typography-body-medium-size, 0.875rem);
352
351
  font-weight: var(--smrt-typography-weight-medium, 500);
353
- color: var(--smrt-color-on-primary, #ffffff);
354
- background: var(--smrt-color-primary, #005ac1);
355
- border: none;
356
- border-radius: var(--smrt-radius-medium, 0.5rem);
357
- cursor: pointer;
358
- transition: box-shadow 150ms ease;
359
- }
360
-
361
- .upload-btn:hover {
362
- box-shadow: var(--smrt-elevation-2, 0 1px 3px rgba(0,0,0,0.1));
363
- }
364
-
365
- .upload-btn:focus-visible {
366
- outline: 2px solid var(--smrt-color-primary, #005ac1);
367
- outline-offset: 2px;
368
352
  }
369
353
 
370
354
  @media (max-width: 640px) {
@@ -1 +1 @@
1
- {"version":3,"file":"AssetToolbar.svelte.d.ts","sourceRoot":"","sources":["../../src/svelte/AssetToolbar.svelte.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAIV,iBAAiB,EAElB,MAAM,SAAS,CAAC;AA4KjB,QAAA,MAAM,YAAY,uDAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"AssetToolbar.svelte.d.ts","sourceRoot":"","sources":["../../src/svelte/AssetToolbar.svelte.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAIV,iBAAiB,EAElB,MAAM,SAAS,CAAC;AA8KjB,QAAA,MAAM,YAAY,uDAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
@@ -12,6 +12,7 @@
12
12
  // entire smrt-svelte surface — including optional peers like smrt-agents /
13
13
  // smrt-users — just to compile this modal.
14
14
  import { Modal } from '@happyvertical/smrt-ui/feedback';
15
+ import { Input, Textarea } from '@happyvertical/smrt-ui/forms';
15
16
  import { useI18n } from '@happyvertical/smrt-ui/i18n';
16
17
  import { Button } from '@happyvertical/smrt-ui/ui';
17
18
  import { M } from './i18n.js';
@@ -167,6 +168,7 @@ const isLargeFile = $derived((file?.size ?? 0) > 2 * 1024 * 1024);
167
168
  </svg>
168
169
  <p class="dropzone__text">{t(M['assets.create_asset_modal.dropzone_text'])}</p>
169
170
  <p class="dropzone__hint">{t(M['assets.create_asset_modal.dropzone_hint'])}</p>
171
+ <!-- raw-primitive-allow: hidden native file input behind the custom drop zone, triggered programmatically; styled Input is unwanted here (visually hidden, opened via the dropzone click/keydown) -->
170
172
  <input id="file-input" type="file" class="dropzone__input" onchange={handleFileSelect} />
171
173
  </div>
172
174
  {:else}
@@ -184,20 +186,20 @@ const isLargeFile = $derived((file?.size ?? 0) > 2 * 1024 * 1024);
184
186
  <span class="file-preview__warning">{t(M['assets.create_asset_modal.large_file_warning'])}</span>
185
187
  {/if}
186
188
  </div>
187
- <button type="button" class="file-preview__remove" onclick={() => { file = null; }} aria-label={t(M['assets.create_asset_modal.remove_file'])}>
189
+ <Button variant="ghost" size="sm" class="file-preview__remove" onclick={() => { file = null; }} aria-label={t(M['assets.create_asset_modal.remove_file'])}>
188
190
  <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>
189
- </button>
191
+ </Button>
190
192
  </div>
191
193
 
192
194
  <div class="form-fields">
193
195
  <div class="form-field">
194
196
  <label for="asset-name" class="form-label">Name</label>
195
- <input id="asset-name" type="text" class="form-input" bind:value={name} placeholder={t(M['assets.create_asset_modal.name_placeholder'])} />
197
+ <Input id="asset-name" type="text" bind:value={name} placeholder={t(M['assets.create_asset_modal.name_placeholder'])} />
196
198
  </div>
197
199
 
198
200
  <div class="form-field">
199
201
  <label for="asset-desc" class="form-label">Description</label>
200
- <textarea id="asset-desc" class="form-textarea" bind:value={description} placeholder={t(M['assets.create_asset_modal.description_placeholder'])} rows="2"></textarea>
202
+ <Textarea id="asset-desc" bind:value={description} placeholder={t(M['assets.create_asset_modal.description_placeholder'])} rows={2} />
201
203
  </div>
202
204
 
203
205
  {#if isImage}
@@ -208,7 +210,7 @@ const isLargeFile = $derived((file?.size ?? 0) > 2 * 1024 * 1024);
208
210
  <span class="form-label__warning">{t(M['assets.create_asset_modal.alt_text_recommended_warning'])}</span>
209
211
  {/if}
210
212
  </label>
211
- <input id="asset-alt" type="text" class="form-input" bind:value={altText} placeholder={t(M['assets.create_asset_modal.alt_text_placeholder'])} />
213
+ <Input id="asset-alt" type="text" bind:value={altText} placeholder={t(M['assets.create_asset_modal.alt_text_placeholder'])} />
212
214
  </div>
213
215
  {/if}
214
216
  </div>
@@ -332,10 +334,10 @@ const isLargeFile = $derived((file?.size ?? 0) > 2 * 1024 * 1024);
332
334
  margin-top: var(--smrt-spacing-1, 4px);
333
335
  }
334
336
 
335
- .file-preview__remove {
336
- display: flex;
337
- align-items: center;
338
- justify-content: center;
337
+ /* file-preview__remove renders via <Button class="file-preview__remove">
338
+ (issue #1589). The overrides shape it into a small round icon button and
339
+ reach the child <button> via :global() scoping. */
340
+ .file-preview :global(.file-preview__remove) {
339
341
  width: 28px;
340
342
  height: 28px;
341
343
  flex-shrink: 0;
@@ -343,11 +345,10 @@ const isLargeFile = $derived((file?.size ?? 0) > 2 * 1024 * 1024);
343
345
  border: none;
344
346
  background: transparent;
345
347
  color: var(--smrt-color-on-surface-variant, #6b7280);
346
- cursor: pointer;
347
348
  border-radius: var(--smrt-radius-full, 9999px);
348
349
  }
349
350
 
350
- .file-preview__remove:hover {
351
+ .file-preview :global(.file-preview__remove:hover) {
351
352
  background: var(--smrt-color-surface-container, #f3f4f6);
352
353
  color: var(--smrt-color-error, #dc2626);
353
354
  }
@@ -378,27 +379,4 @@ const isLargeFile = $derived((file?.size ?? 0) > 2 * 1024 * 1024);
378
379
  margin-left: var(--smrt-spacing-1, 4px);
379
380
  }
380
381
 
381
- .form-input, .form-textarea {
382
- width: 100%;
383
- padding: var(--smrt-spacing-2, 0.5rem) var(--smrt-spacing-3, 0.75rem);
384
- border: 1px solid var(--smrt-color-outline-variant, #e5e7eb);
385
- border-radius: var(--smrt-radius-medium, 0.5rem);
386
- font-family: inherit;
387
- font-size: var(--smrt-typography-body-medium-size, 0.875rem);
388
- color: var(--smrt-color-on-surface, #111827);
389
- background: var(--smrt-color-surface, #ffffff);
390
- box-sizing: border-box;
391
- }
392
-
393
- .form-input:focus, .form-textarea:focus {
394
- outline: none;
395
- border-color: var(--smrt-color-primary, #005ac1);
396
- box-shadow: 0 0 0 2px var(--smrt-color-primary-container, rgba(0, 90, 193, 0.1));
397
- }
398
-
399
- .form-textarea {
400
- resize: vertical;
401
- min-height: 60px;
402
- }
403
-
404
382
  </style>
@@ -1 +1 @@
1
- {"version":3,"file":"CreateAssetModal.svelte.d.ts","sourceRoot":"","sources":["../../src/svelte/CreateAssetModal.svelte.ts"],"names":[],"mappings":"AAoBA,MAAM,WAAW,qBAAqB;IACpC,gCAAgC;IAChC,IAAI,EAAE,OAAO,CAAC;IACd,2CAA2C;IAC3C,WAAW,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IAC1B;4EACwE;IACxE,QAAQ,EAAE,CAAC,IAAI,EAAE;QACf,IAAI,EAAE,IAAI,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE,MAAM,CAAC;KACjB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,oCAAoC;IACpC,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAyMD,QAAA,MAAM,gBAAgB,2DAAwC,CAAC;AAC/D,KAAK,gBAAgB,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC5D,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"CreateAssetModal.svelte.d.ts","sourceRoot":"","sources":["../../src/svelte/CreateAssetModal.svelte.ts"],"names":[],"mappings":"AAqBA,MAAM,WAAW,qBAAqB;IACpC,gCAAgC;IAChC,IAAI,EAAE,OAAO,CAAC;IACd,2CAA2C;IAC3C,WAAW,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IAC1B;4EACwE;IACxE,QAAQ,EAAE,CAAC,IAAI,EAAE;QACf,IAAI,EAAE,IAAI,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE,MAAM,CAAC;KACjB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,oCAAoC;IACpC,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AA2MD,QAAA,MAAM,gBAAgB,2DAAwC,CAAC;AAC/D,KAAK,gBAAgB,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC5D,eAAe,gBAAgB,CAAC"}
@@ -1,5 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { useI18n } from '@happyvertical/smrt-ui/i18n';
3
+ import { Button } from '@happyvertical/smrt-ui/ui';
3
4
  import type { AssetDetailUpdates } from '../AssetDetail.svelte';
4
5
  import AssetDetail from '../AssetDetail.svelte';
5
6
  import { M } from '../i18n.js';
@@ -67,7 +68,7 @@ function handleEdit() {
67
68
  <p class="eyebrow">{t(M['assets.asset_detail_preview.modal_preview'])}</p>
68
69
  <h4>{previewAsset?.name ?? asset.name}</h4>
69
70
  <p>{t(M['assets.asset_detail_preview.description'])}</p>
70
- <button type="button" onclick={openPreview}>{t(M['assets.asset_detail_preview.open_asset_detail'])}</button>
71
+ <Button variant="primary" class="preview-open" onclick={openPreview}>{t(M['assets.asset_detail_preview.open_asset_detail'])}</Button>
71
72
  {#if statusMessage}
72
73
  <p class="status">{statusMessage}</p>
73
74
  {/if}
@@ -112,16 +113,15 @@ function handleEdit() {
112
113
  color: var(--smrt-color-primary, #0f766e);
113
114
  }
114
115
 
115
- button {
116
+ /* The open-preview button renders via <Button variant="primary"> (issue
117
+ #1589). The primary variant owns the fill/color; this override keeps the
118
+ pill shape and grid placement, reaching the child <button> via :global(). */
119
+ .preview-card :global(.preview-open) {
116
120
  justify-self: start;
117
121
  border: 0;
118
122
  border-radius: var(--smrt-radius-full, 9999px);
119
123
  padding: 0.75rem 1rem;
120
- font: inherit;
121
124
  font-weight: var(--smrt-typography-weight-semibold, 600);
122
- background: var(--smrt-color-primary, #0f766e);
123
- color: var(--smrt-color-on-primary, white);
124
- cursor: pointer;
125
125
  }
126
126
 
127
127
  .status {
@@ -1 +1 @@
1
- {"version":3,"file":"AssetDetailPreview.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/playground/AssetDetailPreview.svelte.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE9C,KAAK,gBAAgB,GAAI;IAAE,KAAK,EAAE,cAAc,CAAA;CAAE,CAAC;AAmFpD,QAAA,MAAM,kBAAkB,sDAAwC,CAAC;AACjE,KAAK,kBAAkB,GAAG,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAChE,eAAe,kBAAkB,CAAC"}
1
+ {"version":3,"file":"AssetDetailPreview.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/playground/AssetDetailPreview.svelte.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE9C,KAAK,gBAAgB,GAAI;IAAE,KAAK,EAAE,cAAc,CAAA;CAAE,CAAC;AAoFpD,QAAA,MAAM,kBAAkB,sDAAwC,CAAC;AACjE,KAAK,kBAAkB,GAAG,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAChE,eAAe,kBAAkB,CAAC"}
@@ -1,5 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { useI18n } from '@happyvertical/smrt-ui/i18n';
3
+ import { Button } from '@happyvertical/smrt-ui/ui';
3
4
  import CreateAssetModal from '../CreateAssetModal.svelte';
4
5
  import { M } from '../i18n.js';
5
6
 
@@ -47,7 +48,7 @@ function handleCreate(data: {
47
48
  <p class="eyebrow">{t(M['assets.create_asset_modal_preview.modal_preview'])}</p>
48
49
  <h4>{t(M['assets.create_asset_modal_preview.title'])}</h4>
49
50
  <p>{t(M['assets.create_asset_modal_preview.description'])}</p>
50
- <button type="button" onclick={openPreview}>{t(M['assets.create_asset_modal_preview.open_upload_modal'])}</button>
51
+ <Button variant="primary" class="preview-open" onclick={openPreview}>{t(M['assets.create_asset_modal_preview.open_upload_modal'])}</Button>
51
52
 
52
53
  {#if statusMessage}
53
54
  <p class="status">{statusMessage}</p>
@@ -110,16 +111,15 @@ function handleCreate(data: {
110
111
  color: var(--smrt-color-primary, #0f766e);
111
112
  }
112
113
 
113
- button {
114
+ /* The open-modal button renders via <Button variant="primary"> (issue #1589).
115
+ The primary variant owns the fill/color; this override keeps the pill shape
116
+ and grid placement, reaching the child <button> via :global(). */
117
+ .preview-card :global(.preview-open) {
114
118
  justify-self: start;
115
119
  border: 0;
116
120
  border-radius: var(--smrt-radius-full, 9999px);
117
121
  padding: 0.75rem 1rem;
118
- font: inherit;
119
122
  font-weight: var(--smrt-typography-weight-semibold, 600);
120
- background: var(--smrt-color-primary, #0f766e);
121
- color: var(--smrt-color-on-primary, white);
122
- cursor: pointer;
123
123
  }
124
124
 
125
125
  .status {
@@ -1 +1 @@
1
- {"version":3,"file":"CreateAssetModalPreview.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/playground/CreateAssetModalPreview.svelte.ts"],"names":[],"mappings":"AA2FA,QAAA,MAAM,uBAAuB,2DAAwC,CAAC;AACtE,KAAK,uBAAuB,GAAG,UAAU,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAC1E,eAAe,uBAAuB,CAAC"}
1
+ {"version":3,"file":"CreateAssetModalPreview.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/playground/CreateAssetModalPreview.svelte.ts"],"names":[],"mappings":"AA6FA,QAAA,MAAM,uBAAuB,2DAAwC,CAAC;AACtE,KAAK,uBAAuB,GAAG,UAAU,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAC1E,eAAe,uBAAuB,CAAC"}
package/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "@happyvertical/smrt-assets",
3
- "version": "0.34.5",
3
+ "version": "0.34.7",
4
4
  "description": "Asset management system with versioning, metadata, and AI-powered operations for SMRT framework",
5
5
  "type": "module",
6
+ "smrtRawPrimitives": "strict",
6
7
  "main": "./dist/index.js",
7
8
  "types": "./dist/index.d.ts",
8
9
  "files": [
@@ -38,11 +39,11 @@
38
39
  "@happyvertical/logger": "^0.74.7",
39
40
  "@happyvertical/sql": "^0.74.7",
40
41
  "@happyvertical/utils": "^0.74.7",
41
- "@happyvertical/smrt-core": "0.34.5",
42
- "@happyvertical/smrt-types": "0.34.5",
43
- "@happyvertical/smrt-ui": "0.34.5",
44
- "@happyvertical/smrt-tenancy": "0.34.5",
45
- "@happyvertical/smrt-tags": "0.34.5"
42
+ "@happyvertical/smrt-core": "0.34.7",
43
+ "@happyvertical/smrt-tags": "0.34.7",
44
+ "@happyvertical/smrt-tenancy": "0.34.7",
45
+ "@happyvertical/smrt-types": "0.34.7",
46
+ "@happyvertical/smrt-ui": "0.34.7"
46
47
  },
47
48
  "peerDependencies": {
48
49
  "svelte": "^5.18.0"
@@ -64,8 +65,8 @@
64
65
  "typescript": "^5.9.3",
65
66
  "vite": "^7.3.1",
66
67
  "vitest": "^4.0.17",
67
- "@happyvertical/smrt-playground": "0.34.5",
68
- "@happyvertical/smrt-vitest": "0.34.5"
68
+ "@happyvertical/smrt-playground": "0.34.7",
69
+ "@happyvertical/smrt-vitest": "0.34.7"
69
70
  },
70
71
  "keywords": [
71
72
  "ai",