@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.
- package/dist/manifest.json +2 -2
- package/dist/smrt-knowledge.json +4 -4
- package/dist/svelte/ActionBar.svelte +11 -56
- package/dist/svelte/ActionBar.svelte.d.ts.map +1 -1
- package/dist/svelte/AssetDetail.svelte +15 -45
- package/dist/svelte/AssetDetail.svelte.d.ts.map +1 -1
- package/dist/svelte/AssetGrid.svelte +2 -0
- package/dist/svelte/AssetGrid.svelte.d.ts.map +1 -1
- package/dist/svelte/AssetList.svelte +20 -22
- package/dist/svelte/AssetList.svelte.d.ts.map +1 -1
- package/dist/svelte/AssetToolbar.svelte +54 -70
- package/dist/svelte/AssetToolbar.svelte.d.ts.map +1 -1
- package/dist/svelte/CreateAssetModal.svelte +12 -34
- package/dist/svelte/CreateAssetModal.svelte.d.ts.map +1 -1
- package/dist/svelte/playground/AssetDetailPreview.svelte +6 -6
- package/dist/svelte/playground/AssetDetailPreview.svelte.d.ts.map +1 -1
- package/dist/svelte/playground/CreateAssetModalPreview.svelte +6 -6
- package/dist/svelte/playground/CreateAssetModalPreview.svelte.d.ts.map +1 -1
- package/package.json +9 -8
package/dist/manifest.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": "1.0.0",
|
|
3
|
-
"timestamp":
|
|
3
|
+
"timestamp": 1782290126880,
|
|
4
4
|
"packageName": "@happyvertical/smrt-assets",
|
|
5
|
-
"packageVersion": "0.34.
|
|
5
|
+
"packageVersion": "0.34.7",
|
|
6
6
|
"objects": {
|
|
7
7
|
"@happyvertical/smrt-assets:AssetAssociation": {
|
|
8
8
|
"name": "assetassociation",
|
package/dist/smrt-knowledge.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"generatedAt": "2026-06-
|
|
3
|
+
"generatedAt": "2026-06-24T08:35:27.278Z",
|
|
4
4
|
"packageName": "@happyvertical/smrt-assets",
|
|
5
|
-
"packageVersion": "0.34.
|
|
5
|
+
"packageVersion": "0.34.7",
|
|
6
6
|
"sourceManifestPath": "dist/manifest.json",
|
|
7
7
|
"agentDocPath": "AGENTS.md",
|
|
8
8
|
"sourceHashes": {
|
|
9
|
-
"manifest": "
|
|
10
|
-
"packageJson": "
|
|
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
|
-
<
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
<Button
|
|
61
|
+
variant="ghost"
|
|
62
|
+
size="sm"
|
|
62
63
|
onclick={() => (onclearselection ?? onClearSelection)()}
|
|
63
64
|
>
|
|
64
65
|
Clear
|
|
65
|
-
</
|
|
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
|
-
<
|
|
72
|
-
|
|
73
|
-
|
|
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
|
-
</
|
|
81
|
+
</Button>
|
|
82
82
|
{/if}
|
|
83
83
|
{/each}
|
|
84
84
|
|
|
85
85
|
<!-- Default: Delete -->
|
|
86
|
-
<
|
|
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
|
-
</
|
|
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":"
|
|
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
|
-
<
|
|
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
|
-
<
|
|
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
|
-
<
|
|
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
|
-
<
|
|
265
|
+
<Button variant="ghost" size="sm" class="quick-btn" onclick={copyUrl} disabled={!asset.sourceUri}>
|
|
265
266
|
{t(M['assets.asset_detail.copy_url'])}
|
|
266
|
-
</
|
|
267
|
+
</Button>
|
|
267
268
|
{#if isImage}
|
|
268
|
-
<
|
|
269
|
+
<Button variant="ghost" size="sm" class="quick-btn" onclick={copyMarkdown} disabled={!asset.sourceUri}>
|
|
269
270
|
{t(M['assets.asset_detail.copy_markdown'])}
|
|
270
|
-
</
|
|
271
|
+
</Button>
|
|
271
272
|
{/if}
|
|
272
273
|
{#if onedit && isImage}
|
|
273
|
-
<
|
|
274
|
+
<Button variant="ghost" size="sm" class="quick-btn" onclick={handleEdit}>
|
|
274
275
|
{t(M['assets.asset_detail.edit_image'])}
|
|
275
|
-
</
|
|
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
|
-
|
|
466
|
-
|
|
467
|
-
|
|
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":"
|
|
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;
|
|
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
|
-
<
|
|
125
|
+
<Button variant="ghost" size="sm" class="sort-btn" onclick={() => handleSort('name')}>
|
|
124
126
|
Name <span class="sort-indicator">{getSortIndicator('name')}</span>
|
|
125
|
-
</
|
|
127
|
+
</Button>
|
|
126
128
|
</th>
|
|
127
129
|
<th class="col-type">Type</th>
|
|
128
130
|
<th class="col-date">
|
|
129
|
-
<
|
|
131
|
+
<Button variant="ghost" size="sm" class="sort-btn" onclick={() => handleSort('createdAt')}>
|
|
130
132
|
Created <span class="sort-indicator">{getSortIndicator('createdAt')}</span>
|
|
131
|
-
</
|
|
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
|
|
193
|
+
role="button" on the row nesting the checkbox, which avoids axe
|
|
191
194
|
nested-interactive). -->
|
|
192
|
-
<
|
|
193
|
-
|
|
195
|
+
<Button
|
|
196
|
+
variant="ghost"
|
|
194
197
|
class="row-name"
|
|
195
198
|
onclick={() => onAssetClick(asset)}
|
|
196
199
|
>
|
|
197
200
|
{asset.name || 'Untitled'}
|
|
198
|
-
</
|
|
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
|
-
|
|
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
|
-
|
|
388
|
-
|
|
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":"
|
|
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
|
-
<
|
|
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
|
-
<
|
|
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
|
-
</
|
|
126
|
+
</Button>
|
|
125
127
|
{/if}
|
|
126
128
|
</div>
|
|
127
129
|
|
|
128
130
|
<!-- Type Filter -->
|
|
129
|
-
<
|
|
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
|
-
</
|
|
137
|
+
</Select>
|
|
136
138
|
|
|
137
139
|
<!-- Sort -->
|
|
138
|
-
<
|
|
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
|
-
</
|
|
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
|
-
<
|
|
152
|
-
|
|
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
|
-
</
|
|
177
|
+
</Button>
|
|
177
178
|
{/each}
|
|
178
179
|
</div>
|
|
179
180
|
|
|
180
181
|
<!-- Upload Button -->
|
|
181
|
-
<
|
|
182
|
-
|
|
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
|
-
</
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
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
|
-
|
|
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
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
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
|
-
|
|
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
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
.
|
|
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":"
|
|
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
|
-
<
|
|
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
|
-
</
|
|
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
|
-
<
|
|
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
|
-
<
|
|
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
|
-
<
|
|
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
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
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":"
|
|
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
|
-
<
|
|
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":"
|
|
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
|
-
<
|
|
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":"
|
|
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.
|
|
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.
|
|
42
|
-
"@happyvertical/smrt-
|
|
43
|
-
"@happyvertical/smrt-
|
|
44
|
-
"@happyvertical/smrt-
|
|
45
|
-
"@happyvertical/smrt-
|
|
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.
|
|
68
|
-
"@happyvertical/smrt-vitest": "0.34.
|
|
68
|
+
"@happyvertical/smrt-playground": "0.34.7",
|
|
69
|
+
"@happyvertical/smrt-vitest": "0.34.7"
|
|
69
70
|
},
|
|
70
71
|
"keywords": [
|
|
71
72
|
"ai",
|