@happyvertical/smrt-assets 0.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/AGENTS.md +78 -0
  2. package/CLAUDE.md +1 -0
  3. package/LICENSE +7 -0
  4. package/README.md +136 -0
  5. package/dist/__smrt-register__.d.ts +2 -0
  6. package/dist/__smrt-register__.d.ts.map +1 -0
  7. package/dist/asset-association.d.ts +16 -0
  8. package/dist/asset-association.d.ts.map +1 -0
  9. package/dist/asset-associations.d.ts +27 -0
  10. package/dist/asset-associations.d.ts.map +1 -0
  11. package/dist/asset-capabilities.d.ts +137 -0
  12. package/dist/asset-capabilities.d.ts.map +1 -0
  13. package/dist/asset-conventions.d.ts +76 -0
  14. package/dist/asset-conventions.d.ts.map +1 -0
  15. package/dist/asset-metafield.d.ts +27 -0
  16. package/dist/asset-metafield.d.ts.map +1 -0
  17. package/dist/asset-metafields.d.ts +27 -0
  18. package/dist/asset-metafields.d.ts.map +1 -0
  19. package/dist/asset-runtime.d.ts +218 -0
  20. package/dist/asset-runtime.d.ts.map +1 -0
  21. package/dist/asset-serving.d.ts +146 -0
  22. package/dist/asset-serving.d.ts.map +1 -0
  23. package/dist/asset-status.d.ts +15 -0
  24. package/dist/asset-status.d.ts.map +1 -0
  25. package/dist/asset-statuses.d.ts +25 -0
  26. package/dist/asset-statuses.d.ts.map +1 -0
  27. package/dist/asset-store.d.ts +200 -0
  28. package/dist/asset-store.d.ts.map +1 -0
  29. package/dist/asset-type.d.ts +15 -0
  30. package/dist/asset-type.d.ts.map +1 -0
  31. package/dist/asset-types.d.ts +28 -0
  32. package/dist/asset-types.d.ts.map +1 -0
  33. package/dist/asset.d.ts +158 -0
  34. package/dist/asset.d.ts.map +1 -0
  35. package/dist/assets.d.ts +125 -0
  36. package/dist/assets.d.ts.map +1 -0
  37. package/dist/folder.d.ts +16 -0
  38. package/dist/folder.d.ts.map +1 -0
  39. package/dist/folders.d.ts +45 -0
  40. package/dist/folders.d.ts.map +1 -0
  41. package/dist/index.d.ts +21 -0
  42. package/dist/index.d.ts.map +1 -0
  43. package/dist/index.js +2285 -0
  44. package/dist/index.js.map +1 -0
  45. package/dist/manifest.json +4079 -0
  46. package/dist/media-bundle-persistence.d.ts +99 -0
  47. package/dist/media-bundle-persistence.d.ts.map +1 -0
  48. package/dist/owned-asset-helpers.d.ts +20 -0
  49. package/dist/owned-asset-helpers.d.ts.map +1 -0
  50. package/dist/playground.d.ts +2 -0
  51. package/dist/playground.d.ts.map +1 -0
  52. package/dist/playground.js +127 -0
  53. package/dist/playground.js.map +1 -0
  54. package/dist/smrt-knowledge.json +1922 -0
  55. package/dist/svelte/ActionBar.svelte +203 -0
  56. package/dist/svelte/ActionBar.svelte.d.ts +5 -0
  57. package/dist/svelte/ActionBar.svelte.d.ts.map +1 -0
  58. package/dist/svelte/AssetDetail.svelte +521 -0
  59. package/dist/svelte/AssetDetail.svelte.d.ts +35 -0
  60. package/dist/svelte/AssetDetail.svelte.d.ts.map +1 -0
  61. package/dist/svelte/AssetGrid.svelte +351 -0
  62. package/dist/svelte/AssetGrid.svelte.d.ts +5 -0
  63. package/dist/svelte/AssetGrid.svelte.d.ts.map +1 -0
  64. package/dist/svelte/AssetList.svelte +436 -0
  65. package/dist/svelte/AssetList.svelte.d.ts +5 -0
  66. package/dist/svelte/AssetList.svelte.d.ts.map +1 -0
  67. package/dist/svelte/AssetManager.svelte +381 -0
  68. package/dist/svelte/AssetManager.svelte.d.ts +5 -0
  69. package/dist/svelte/AssetManager.svelte.d.ts.map +1 -0
  70. package/dist/svelte/AssetToolbar.svelte +388 -0
  71. package/dist/svelte/AssetToolbar.svelte.d.ts +5 -0
  72. package/dist/svelte/AssetToolbar.svelte.d.ts.map +1 -0
  73. package/dist/svelte/CreateAssetModal.svelte +373 -0
  74. package/dist/svelte/CreateAssetModal.svelte.d.ts +19 -0
  75. package/dist/svelte/CreateAssetModal.svelte.d.ts.map +1 -0
  76. package/dist/svelte/__tests__/ActionBar.test.js +72 -0
  77. package/dist/svelte/__tests__/AssetDetail.test.js +57 -0
  78. package/dist/svelte/__tests__/AssetGrid.test.js +69 -0
  79. package/dist/svelte/__tests__/AssetList.test.js +72 -0
  80. package/dist/svelte/__tests__/AssetManager.test.js +21 -0
  81. package/dist/svelte/__tests__/AssetManagerRoute.test.js +16 -0
  82. package/dist/svelte/__tests__/AssetToolbar.test.js +39 -0
  83. package/dist/svelte/__tests__/CreateAssetModal.test.js +42 -0
  84. package/dist/svelte/i18n.d.ts +76 -0
  85. package/dist/svelte/i18n.d.ts.map +1 -0
  86. package/dist/svelte/i18n.js +87 -0
  87. package/dist/svelte/index.d.ts +19 -0
  88. package/dist/svelte/index.d.ts.map +1 -0
  89. package/dist/svelte/index.js +30 -0
  90. package/dist/svelte/playground/AssetDetailPreview.svelte +131 -0
  91. package/dist/svelte/playground/AssetDetailPreview.svelte.d.ts +8 -0
  92. package/dist/svelte/playground/AssetDetailPreview.svelte.d.ts.map +1 -0
  93. package/dist/svelte/playground/CreateAssetModalPreview.svelte +151 -0
  94. package/dist/svelte/playground/CreateAssetModalPreview.svelte.d.ts +4 -0
  95. package/dist/svelte/playground/CreateAssetModalPreview.svelte.d.ts.map +1 -0
  96. package/dist/svelte/playground.d.ts +60 -0
  97. package/dist/svelte/playground.d.ts.map +1 -0
  98. package/dist/svelte/playground.js +93 -0
  99. package/dist/svelte/routes/AssetManagerRoute.svelte +209 -0
  100. package/dist/svelte/routes/AssetManagerRoute.svelte.d.ts +4 -0
  101. package/dist/svelte/routes/AssetManagerRoute.svelte.d.ts.map +1 -0
  102. package/dist/svelte/routes/index.d.ts +2 -0
  103. package/dist/svelte/routes/index.d.ts.map +1 -0
  104. package/dist/svelte/routes/index.js +1 -0
  105. package/dist/svelte/routes/shared.d.ts +25 -0
  106. package/dist/svelte/routes/shared.d.ts.map +1 -0
  107. package/dist/svelte/routes/shared.js +31 -0
  108. package/dist/svelte/types.d.ts +179 -0
  109. package/dist/svelte/types.d.ts.map +1 -0
  110. package/dist/svelte/types.js +6 -0
  111. package/dist/types.d.ts +80 -0
  112. package/dist/types.d.ts.map +1 -0
  113. package/dist/types.js +2 -0
  114. package/dist/types.js.map +1 -0
  115. package/dist/ui.d.ts +10 -0
  116. package/dist/ui.d.ts.map +1 -0
  117. package/dist/ui.js +85 -0
  118. package/dist/ui.js.map +1 -0
  119. package/package.json +102 -0
@@ -0,0 +1,16 @@
1
+ // @vitest-environment jsdom
2
+ /**
3
+ * Component coverage for the package route surface via the shared S11 harness
4
+ * (#1416) — it composes AssetManager with a custom action.
5
+ */
6
+ import { render, screen } from '@happyvertical/smrt-vitest/svelte';
7
+ import { describe, expect, it } from 'vitest';
8
+ import AssetManagerRoute from '../routes/AssetManagerRoute.svelte';
9
+ describe('AssetManagerRoute', () => {
10
+ it('renders the route surface with an embedded asset manager', () => {
11
+ render(AssetManagerRoute);
12
+ expect(screen.getByText('Package Route Surface')).toBeInTheDocument();
13
+ // AssetManager's toolbar renders inside the route.
14
+ expect(screen.getByLabelText('Search assets')).toBeInTheDocument();
15
+ });
16
+ });
@@ -0,0 +1,39 @@
1
+ // @vitest-environment jsdom
2
+ /**
3
+ * Component coverage for AssetToolbar via the shared S11 harness (#1416).
4
+ */
5
+ import { expectNoA11yViolations, render, screen, userEvent, } from '@happyvertical/smrt-vitest/svelte';
6
+ import { describe, expect, it, vi } from 'vitest';
7
+ import AssetToolbar from '../AssetToolbar.svelte';
8
+ const baseProps = (over = {}) => ({
9
+ view: 'grid',
10
+ filters: { search: '', types: [], tags: [], mimePatterns: [] },
11
+ sort: { field: 'name', direction: 'asc' },
12
+ onViewChange: vi.fn(),
13
+ onFilterChange: vi.fn(),
14
+ onSortChange: vi.fn(),
15
+ ...over,
16
+ });
17
+ describe('AssetToolbar', () => {
18
+ it('renders search, filter, sort, and view controls', () => {
19
+ render(AssetToolbar, { props: baseProps() });
20
+ expect(screen.getByLabelText('Search assets')).toBeInTheDocument();
21
+ expect(screen.getByLabelText('Sort assets')).toBeInTheDocument();
22
+ expect(screen.getByRole('group', { name: 'View mode' })).toBeInTheDocument();
23
+ });
24
+ it('clears the active search', async () => {
25
+ const onFilterChange = vi.fn();
26
+ render(AssetToolbar, {
27
+ props: baseProps({
28
+ filters: { search: 'photo', types: [], tags: [], mimePatterns: [] },
29
+ onFilterChange,
30
+ }),
31
+ });
32
+ await userEvent.click(screen.getByLabelText('Clear search'));
33
+ expect(onFilterChange).toHaveBeenCalledWith(expect.objectContaining({ search: '' }));
34
+ });
35
+ it('is axe-clean', async () => {
36
+ const { container } = render(AssetToolbar, { props: baseProps() });
37
+ await expectNoA11yViolations(container);
38
+ });
39
+ });
@@ -0,0 +1,42 @@
1
+ // @vitest-environment jsdom
2
+ /**
3
+ * Component coverage for CreateAssetModal via the shared S11 harness (#1416).
4
+ * The jsdom `<dialog>` showModal/close polyfill comes from the shared setup.
5
+ */
6
+ import { render, screen, userEvent } from '@happyvertical/smrt-vitest/svelte';
7
+ import { describe, expect, it, vi } from 'vitest';
8
+ import CreateAssetModal from '../CreateAssetModal.svelte';
9
+ const baseProps = (over = {}) => ({
10
+ open: true,
11
+ oncreate: vi.fn(),
12
+ onclose: vi.fn(),
13
+ ...over,
14
+ });
15
+ describe('CreateAssetModal', () => {
16
+ it('renders the upload dialog with a dropzone when open and empty', () => {
17
+ render(CreateAssetModal, { props: baseProps() });
18
+ expect(screen.getByRole('heading', { name: 'Upload Asset', hidden: true })).toBeInTheDocument();
19
+ expect(screen.getByText(/Drag & drop/, { hidden: true })).toBeTruthy();
20
+ });
21
+ it('pre-loads an initial file into the metadata form', () => {
22
+ // A non-image file avoids URL.createObjectURL (unimplemented in jsdom).
23
+ const file = new File(['x'], 'notes.txt', { type: 'text/plain' });
24
+ render(CreateAssetModal, { props: baseProps({ initialFile: file }) });
25
+ expect(screen.getByText('notes.txt', { hidden: true })).toBeInTheDocument();
26
+ });
27
+ it('closes via Cancel', async () => {
28
+ const onclose = vi.fn();
29
+ render(CreateAssetModal, { props: baseProps({ onclose }) });
30
+ await userEvent.click(screen.getByRole('button', { name: 'Cancel', hidden: true }));
31
+ expect(onclose).toHaveBeenCalled();
32
+ });
33
+ it('submits the pre-loaded file', async () => {
34
+ const oncreate = vi.fn();
35
+ const file = new File(['x'], 'notes.txt', { type: 'text/plain' });
36
+ render(CreateAssetModal, {
37
+ props: baseProps({ initialFile: file, oncreate }),
38
+ });
39
+ await userEvent.click(screen.getByRole('button', { name: /Upload/, hidden: true }));
40
+ expect(oncreate).toHaveBeenCalledWith(expect.objectContaining({ file: expect.any(File) }));
41
+ });
42
+ });
@@ -0,0 +1,76 @@
1
+ export declare const M: {
2
+ readonly 'assets.action_bar.delete_confirm_title': "assets.action_bar.delete_confirm_title";
3
+ readonly 'assets.action_bar.delete_confirm_message_one': "assets.action_bar.delete_confirm_message_one";
4
+ readonly 'assets.action_bar.delete_confirm_message_other': "assets.action_bar.delete_confirm_message_other";
5
+ readonly 'assets.action_bar.delete': "assets.action_bar.delete";
6
+ readonly 'assets.action_bar.cancel': "assets.action_bar.cancel";
7
+ readonly 'assets.asset_detail.open_pdf_in_new_tab': "assets.asset_detail.open_pdf_in_new_tab";
8
+ readonly 'assets.asset_detail.alt_text': "assets.asset_detail.alt_text";
9
+ readonly 'assets.asset_detail.alt_text_missing_warning': "assets.asset_detail.alt_text_missing_warning";
10
+ readonly 'assets.asset_detail.quick_actions': "assets.asset_detail.quick_actions";
11
+ readonly 'assets.asset_detail.copy_url': "assets.asset_detail.copy_url";
12
+ readonly 'assets.asset_detail.copy_markdown': "assets.asset_detail.copy_markdown";
13
+ readonly 'assets.asset_detail.edit_image': "assets.asset_detail.edit_image";
14
+ readonly 'assets.asset_detail.used_in': "assets.asset_detail.used_in";
15
+ readonly 'assets.asset_detail.alt_text_placeholder': "assets.asset_detail.alt_text_placeholder";
16
+ readonly 'assets.asset_detail.description_placeholder': "assets.asset_detail.description_placeholder";
17
+ readonly 'assets.asset_grid.loading': "assets.asset_grid.loading";
18
+ readonly 'assets.asset_grid.no_assets_found': "assets.asset_grid.no_assets_found";
19
+ readonly 'assets.asset_grid.empty_hint': "assets.asset_grid.empty_hint";
20
+ readonly 'assets.asset_grid.no_alt': "assets.asset_grid.no_alt";
21
+ readonly 'assets.asset_grid.missing_alt_text': "assets.asset_grid.missing_alt_text";
22
+ readonly 'assets.asset_grid.open_named': "assets.asset_grid.open_named";
23
+ readonly 'assets.asset_grid.select_named': "assets.asset_grid.select_named";
24
+ readonly 'assets.asset_grid.select_named_checkbox': "assets.asset_grid.select_named_checkbox";
25
+ readonly 'assets.asset_list.loading': "assets.asset_list.loading";
26
+ readonly 'assets.asset_list.no_assets_found': "assets.asset_list.no_assets_found";
27
+ readonly 'assets.asset_list.empty_hint': "assets.asset_list.empty_hint";
28
+ readonly 'assets.asset_list.select_all': "assets.asset_list.select_all";
29
+ readonly 'assets.asset_list.select_named': "assets.asset_list.select_named";
30
+ readonly 'assets.asset_manager.drop_file_to_upload': "assets.asset_manager.drop_file_to_upload";
31
+ readonly 'assets.asset_toolbar.all_types': "assets.asset_toolbar.all_types";
32
+ readonly 'assets.asset_toolbar.newest_first': "assets.asset_toolbar.newest_first";
33
+ readonly 'assets.asset_toolbar.oldest_first': "assets.asset_toolbar.oldest_first";
34
+ readonly 'assets.asset_toolbar.name_a_z': "assets.asset_toolbar.name_a_z";
35
+ readonly 'assets.asset_toolbar.name_z_a': "assets.asset_toolbar.name_z_a";
36
+ readonly 'assets.asset_toolbar.recently_updated': "assets.asset_toolbar.recently_updated";
37
+ readonly 'assets.asset_toolbar.search_placeholder': "assets.asset_toolbar.search_placeholder";
38
+ readonly 'assets.asset_toolbar.search_assets': "assets.asset_toolbar.search_assets";
39
+ readonly 'assets.asset_toolbar.clear_search': "assets.asset_toolbar.clear_search";
40
+ readonly 'assets.asset_toolbar.filter_by_type': "assets.asset_toolbar.filter_by_type";
41
+ readonly 'assets.asset_toolbar.sort_assets': "assets.asset_toolbar.sort_assets";
42
+ readonly 'assets.asset_toolbar.view_mode': "assets.asset_toolbar.view_mode";
43
+ readonly 'assets.asset_toolbar.view_label': "assets.asset_toolbar.view_label";
44
+ readonly 'assets.create_asset_modal.dropzone_text': "assets.create_asset_modal.dropzone_text";
45
+ readonly 'assets.create_asset_modal.dropzone_hint': "assets.create_asset_modal.dropzone_hint";
46
+ readonly 'assets.create_asset_modal.large_file_warning': "assets.create_asset_modal.large_file_warning";
47
+ readonly 'assets.create_asset_modal.alt_text': "assets.create_asset_modal.alt_text";
48
+ readonly 'assets.create_asset_modal.alt_text_recommended_warning': "assets.create_asset_modal.alt_text_recommended_warning";
49
+ readonly 'assets.create_asset_modal.name_placeholder': "assets.create_asset_modal.name_placeholder";
50
+ readonly 'assets.create_asset_modal.description_placeholder': "assets.create_asset_modal.description_placeholder";
51
+ readonly 'assets.create_asset_modal.alt_text_placeholder': "assets.create_asset_modal.alt_text_placeholder";
52
+ readonly 'assets.create_asset_modal.upload_asset': "assets.create_asset_modal.upload_asset";
53
+ readonly 'assets.create_asset_modal.preview_alt': "assets.create_asset_modal.preview_alt";
54
+ readonly 'assets.create_asset_modal.remove_file': "assets.create_asset_modal.remove_file";
55
+ readonly 'assets.asset_detail_preview.modal_preview': "assets.asset_detail_preview.modal_preview";
56
+ readonly 'assets.asset_detail_preview.description': "assets.asset_detail_preview.description";
57
+ readonly 'assets.asset_detail_preview.open_asset_detail': "assets.asset_detail_preview.open_asset_detail";
58
+ readonly 'assets.create_asset_modal_preview.modal_preview': "assets.create_asset_modal_preview.modal_preview";
59
+ readonly 'assets.create_asset_modal_preview.title': "assets.create_asset_modal_preview.title";
60
+ readonly 'assets.create_asset_modal_preview.description': "assets.create_asset_modal_preview.description";
61
+ readonly 'assets.create_asset_modal_preview.open_upload_modal': "assets.create_asset_modal_preview.open_upload_modal";
62
+ readonly 'assets.create_asset_modal_preview.alt_text': "assets.create_asset_modal_preview.alt_text";
63
+ readonly 'assets.asset_manager_route.eyebrow': "assets.asset_manager_route.eyebrow";
64
+ readonly 'assets.asset_manager_route.title': "assets.asset_manager_route.title";
65
+ readonly 'assets.asset_manager_route.lede': "assets.asset_manager_route.lede";
66
+ readonly 'assets.asset_manager_route.selection_state': "assets.asset_manager_route.selection_state";
67
+ readonly 'assets.asset_manager_route.no_assets_selected': "assets.asset_manager_route.no_assets_selected";
68
+ readonly 'assets.asset_manager_route.assets_selected': "assets.asset_manager_route.assets_selected";
69
+ readonly 'assets.asset_manager_route.custom_action_example': "assets.asset_manager_route.custom_action_example";
70
+ readonly 'assets.asset_manager_route.custom_action_description': "assets.asset_manager_route.custom_action_description";
71
+ readonly 'assets.asset_manager_route.queue_review': "assets.asset_manager_route.queue_review";
72
+ readonly 'assets.asset_manager_route.queue_review_hint': "assets.asset_manager_route.queue_review_hint";
73
+ readonly 'assets.asset_manager_route.surface_label': "assets.asset_manager_route.surface_label";
74
+ readonly 'assets.asset_manager_route.route_state_label': "assets.asset_manager_route.route_state_label";
75
+ };
76
+ //# sourceMappingURL=i18n.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../../src/svelte/i18n.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8GZ,CAAC"}
@@ -0,0 +1,87 @@
1
+ import { defineMessages } from '@happyvertical/smrt-ui/i18n';
2
+ export const M = defineMessages({
3
+ // ActionBar
4
+ 'assets.action_bar.delete_confirm_title': 'Delete {count} asset{plural}?',
5
+ // Separate singular/plural messages (an English `{plural}` suffix doesn't translate).
6
+ 'assets.action_bar.delete_confirm_message_one': 'This action cannot be undone. The asset and its file data will be permanently removed.',
7
+ 'assets.action_bar.delete_confirm_message_other': 'This action cannot be undone. The assets and their file data will be permanently removed.',
8
+ 'assets.action_bar.delete': 'Delete',
9
+ 'assets.action_bar.cancel': 'Cancel',
10
+ // AssetDetail
11
+ 'assets.asset_detail.open_pdf_in_new_tab': 'Open PDF in new tab',
12
+ 'assets.asset_detail.alt_text': 'Alt Text',
13
+ 'assets.asset_detail.alt_text_missing_warning': '⚠️ Missing — required for accessibility',
14
+ 'assets.asset_detail.quick_actions': 'Quick Actions',
15
+ 'assets.asset_detail.copy_url': '📋 Copy URL',
16
+ 'assets.asset_detail.copy_markdown': '📝 Copy Markdown',
17
+ 'assets.asset_detail.edit_image': '✏️ Edit Image',
18
+ 'assets.asset_detail.used_in': 'Used In',
19
+ 'assets.asset_detail.alt_text_placeholder': 'Describe this image for screen readers',
20
+ 'assets.asset_detail.description_placeholder': 'Optional description',
21
+ // AssetGrid
22
+ 'assets.asset_grid.loading': 'Loading assets...',
23
+ 'assets.asset_grid.no_assets_found': 'No assets found',
24
+ 'assets.asset_grid.empty_hint': 'Upload an asset or change your search filters to see results.',
25
+ 'assets.asset_grid.no_alt': '⚠️ No alt',
26
+ 'assets.asset_grid.missing_alt_text': 'Missing alt text',
27
+ 'assets.asset_grid.open_named': 'Open {name}',
28
+ 'assets.asset_grid.select_named': 'Select {name}',
29
+ 'assets.asset_grid.select_named_checkbox': 'Select {name}',
30
+ // AssetList
31
+ 'assets.asset_list.loading': 'Loading assets...',
32
+ 'assets.asset_list.no_assets_found': 'No assets found',
33
+ 'assets.asset_list.empty_hint': 'Upload an asset or change your search filters to see results.',
34
+ 'assets.asset_list.select_all': 'Select all',
35
+ 'assets.asset_list.select_named': 'Select {name}',
36
+ // AssetManager
37
+ 'assets.asset_manager.drop_file_to_upload': 'Drop file to upload',
38
+ // AssetToolbar
39
+ 'assets.asset_toolbar.all_types': 'All types',
40
+ 'assets.asset_toolbar.newest_first': 'Newest first',
41
+ 'assets.asset_toolbar.oldest_first': 'Oldest first',
42
+ 'assets.asset_toolbar.name_a_z': 'Name A–Z',
43
+ 'assets.asset_toolbar.name_z_a': 'Name Z–A',
44
+ 'assets.asset_toolbar.recently_updated': 'Recently updated',
45
+ 'assets.asset_toolbar.search_placeholder': 'Search assets...',
46
+ 'assets.asset_toolbar.search_assets': 'Search assets',
47
+ 'assets.asset_toolbar.clear_search': 'Clear search',
48
+ 'assets.asset_toolbar.filter_by_type': 'Filter by type',
49
+ 'assets.asset_toolbar.sort_assets': 'Sort assets',
50
+ 'assets.asset_toolbar.view_mode': 'View mode',
51
+ 'assets.asset_toolbar.view_label': '{label} view',
52
+ // CreateAssetModal
53
+ 'assets.create_asset_modal.dropzone_text': 'Drag & drop a file here, or click to browse',
54
+ 'assets.create_asset_modal.dropzone_hint': 'You can also paste an image from your clipboard',
55
+ 'assets.create_asset_modal.large_file_warning': '⚠️ Large file — may slow page loads',
56
+ 'assets.create_asset_modal.alt_text': 'Alt Text',
57
+ 'assets.create_asset_modal.alt_text_recommended_warning': '⚠️ Recommended for accessibility',
58
+ 'assets.create_asset_modal.name_placeholder': 'Asset name',
59
+ 'assets.create_asset_modal.description_placeholder': 'Optional description',
60
+ 'assets.create_asset_modal.alt_text_placeholder': 'Describe this image for screen readers',
61
+ 'assets.create_asset_modal.upload_asset': 'Upload Asset',
62
+ 'assets.create_asset_modal.preview_alt': 'Preview',
63
+ 'assets.create_asset_modal.remove_file': 'Remove file',
64
+ // AssetDetailPreview (playground)
65
+ 'assets.asset_detail_preview.modal_preview': 'Modal Preview',
66
+ 'assets.asset_detail_preview.description': 'Launch the asset detail dialog from inside the preview stage so the shared\n playground stays navigable.',
67
+ 'assets.asset_detail_preview.open_asset_detail': 'Open Asset Detail',
68
+ // CreateAssetModalPreview (playground)
69
+ 'assets.create_asset_modal_preview.modal_preview': 'Modal Preview',
70
+ 'assets.create_asset_modal_preview.title': 'Create Asset Modal',
71
+ 'assets.create_asset_modal_preview.description': 'Open the upload dialog from inside the preview stage to exercise the real\n modal flow without covering the host navigation.',
72
+ 'assets.create_asset_modal_preview.open_upload_modal': 'Open Upload Modal',
73
+ 'assets.create_asset_modal_preview.alt_text': 'Alt Text',
74
+ // AssetManagerRoute (route)
75
+ 'assets.asset_manager_route.eyebrow': 'Package Route Surface',
76
+ 'assets.asset_manager_route.title': 'Asset Manager',
77
+ 'assets.asset_manager_route.lede': 'The reference route for browsing, selecting, and reviewing uploaded\n assets with the package-owned asset manager UI.',
78
+ 'assets.asset_manager_route.selection_state': 'Selection State',
79
+ 'assets.asset_manager_route.no_assets_selected': 'No assets selected.',
80
+ 'assets.asset_manager_route.assets_selected': 'asset{plural} selected.',
81
+ 'assets.asset_manager_route.custom_action_example': 'Custom Action Example',
82
+ 'assets.asset_manager_route.custom_action_description': 'This route keeps package-owned defaults while leaving room for app\n specific actions.',
83
+ 'assets.asset_manager_route.queue_review': 'Queue Review',
84
+ 'assets.asset_manager_route.queue_review_hint': 'from the selection action bar to see\n the package route feedback.',
85
+ 'assets.asset_manager_route.surface_label': 'Asset manager surface',
86
+ 'assets.asset_manager_route.route_state_label': 'Asset route state',
87
+ });
@@ -0,0 +1,19 @@
1
+ /**
2
+ * smrt-assets Svelte components
3
+ *
4
+ * Reusable Asset Manager UI for embedding in downstream SMRT sites.
5
+ * Auto-registers components with ModuleUIRegistry on import so chat
6
+ * (and other registry-driven consumers) can discover them.
7
+ *
8
+ * @packageDocumentation
9
+ */
10
+ import ActionBar from './ActionBar.svelte';
11
+ import AssetDetail from './AssetDetail.svelte';
12
+ import AssetGrid from './AssetGrid.svelte';
13
+ import AssetList from './AssetList.svelte';
14
+ import AssetManager from './AssetManager.svelte';
15
+ import AssetToolbar from './AssetToolbar.svelte';
16
+ import CreateAssetModal from './CreateAssetModal.svelte';
17
+ export { ActionBar, AssetDetail, AssetGrid, AssetList, AssetManager, AssetToolbar, CreateAssetModal, };
18
+ export type { ActionBarProps, AssetAction, AssetFilters, AssetGridProps, AssetListProps, AssetManagerMode, AssetManagerProps, AssetSort, AssetSortDirection, AssetSortField, AssetToolbarProps, AssetViewMode, } from './types';
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/svelte/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,OAAO,SAAS,MAAM,oBAAoB,CAAC;AAC3C,OAAO,WAAW,MAAM,sBAAsB,CAAC;AAC/C,OAAO,SAAS,MAAM,oBAAoB,CAAC;AAC3C,OAAO,SAAS,MAAM,oBAAoB,CAAC;AAC3C,OAAO,YAAY,MAAM,uBAAuB,CAAC;AACjD,OAAO,YAAY,MAAM,uBAAuB,CAAC;AACjD,OAAO,gBAAgB,MAAM,2BAA2B,CAAC;AAGzD,OAAO,EACL,SAAS,EACT,WAAW,EACX,SAAS,EACT,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,gBAAgB,GACjB,CAAC;AAGF,YAAY,EACV,cAAc,EACd,WAAW,EACX,YAAY,EACZ,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,SAAS,EACT,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,aAAa,GACd,MAAM,SAAS,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * smrt-assets Svelte components
3
+ *
4
+ * Reusable Asset Manager UI for embedding in downstream SMRT sites.
5
+ * Auto-registers components with ModuleUIRegistry on import so chat
6
+ * (and other registry-driven consumers) can discover them.
7
+ *
8
+ * @packageDocumentation
9
+ */
10
+ import { ModuleUIRegistry } from '@happyvertical/smrt-ui/registry';
11
+ import { ASSETS_MODULE_META } from '../ui.js';
12
+ // Import components
13
+ import ActionBar from './ActionBar.svelte';
14
+ import AssetDetail from './AssetDetail.svelte';
15
+ import AssetGrid from './AssetGrid.svelte';
16
+ import AssetList from './AssetList.svelte';
17
+ import AssetManager from './AssetManager.svelte';
18
+ import AssetToolbar from './AssetToolbar.svelte';
19
+ import CreateAssetModal from './CreateAssetModal.svelte';
20
+ // Components
21
+ export { ActionBar, AssetDetail, AssetGrid, AssetList, AssetManager, AssetToolbar, CreateAssetModal, };
22
+ // Auto-register with ModuleUIRegistry
23
+ ModuleUIRegistry.registerModule(ASSETS_MODULE_META);
24
+ ModuleUIRegistry.register('@happyvertical/smrt-assets', 'asset-manager', AssetManager);
25
+ ModuleUIRegistry.register('@happyvertical/smrt-assets', 'asset-grid', AssetGrid);
26
+ ModuleUIRegistry.register('@happyvertical/smrt-assets', 'asset-list', AssetList);
27
+ ModuleUIRegistry.register('@happyvertical/smrt-assets', 'asset-detail', AssetDetail);
28
+ ModuleUIRegistry.register('@happyvertical/smrt-assets', 'asset-toolbar', AssetToolbar);
29
+ ModuleUIRegistry.register('@happyvertical/smrt-assets', 'asset-action-bar', ActionBar);
30
+ ModuleUIRegistry.register('@happyvertical/smrt-assets', 'asset-create-modal', CreateAssetModal);
@@ -0,0 +1,131 @@
1
+ <script lang="ts">
2
+ import { useI18n } from '@happyvertical/smrt-ui/i18n';
3
+ import type { AssetDetailUpdates } from '../AssetDetail.svelte';
4
+ import AssetDetail from '../AssetDetail.svelte';
5
+ import { M } from '../i18n.js';
6
+ import type { PersistedAsset } from '../types';
7
+
8
+ const { t } = useI18n();
9
+
10
+ let { asset }: { asset: PersistedAsset } = $props();
11
+
12
+ let isOpen = $state(false);
13
+ let previewAsset = $state<PersistedAsset | null>(null);
14
+ let statusMessage = $state<string | null>(null);
15
+ let lastAsset: PersistedAsset | null = null;
16
+
17
+ function clonePersistedAsset(
18
+ source: PersistedAsset,
19
+ updates: AssetDetailUpdates = {},
20
+ ): PersistedAsset {
21
+ return Object.assign(
22
+ Object.create(Object.getPrototypeOf(source)) as PersistedAsset,
23
+ source,
24
+ updates,
25
+ );
26
+ }
27
+
28
+ $effect(() => {
29
+ if (asset !== lastAsset) {
30
+ lastAsset = asset;
31
+ previewAsset = clonePersistedAsset(asset);
32
+ statusMessage = null;
33
+ isOpen = false;
34
+ }
35
+ });
36
+
37
+ function openPreview() {
38
+ statusMessage = null;
39
+ isOpen = true;
40
+ }
41
+
42
+ function closePreview() {
43
+ isOpen = false;
44
+ }
45
+
46
+ function handleSave(_asset: PersistedAsset, updates: AssetDetailUpdates) {
47
+ if (!previewAsset) {
48
+ return;
49
+ }
50
+
51
+ previewAsset = clonePersistedAsset(previewAsset, updates);
52
+ statusMessage = 'Saved changes in the preview harness.';
53
+ }
54
+
55
+ function handleDelete() {
56
+ statusMessage = 'Delete requested from the preview harness.';
57
+ isOpen = false;
58
+ }
59
+
60
+ function handleEdit() {
61
+ statusMessage = 'Edit requested from the preview harness.';
62
+ }
63
+ </script>
64
+
65
+ <div class="preview-shell">
66
+ <div class="preview-card">
67
+ <p class="eyebrow">{t(M['assets.asset_detail_preview.modal_preview'])}</p>
68
+ <h4>{previewAsset?.name ?? asset.name}</h4>
69
+ <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
+ {#if statusMessage}
72
+ <p class="status">{statusMessage}</p>
73
+ {/if}
74
+ </div>
75
+
76
+ <AssetDetail
77
+ asset={previewAsset ?? asset}
78
+ open={isOpen}
79
+ onclose={closePreview}
80
+ onsave={handleSave}
81
+ ondelete={handleDelete}
82
+ onedit={handleEdit}
83
+ />
84
+ </div>
85
+
86
+ <style>
87
+ .preview-shell {
88
+ display: grid;
89
+ gap: 1rem;
90
+ }
91
+
92
+ .preview-card {
93
+ display: grid;
94
+ gap: 0.75rem;
95
+ max-width: 32rem;
96
+ padding: 1.25rem;
97
+ border-radius: 1rem;
98
+ background: color-mix(in srgb, var(--smrt-color-surface) 92%, transparent);
99
+ border: 1px solid var(--smrt-color-outline-variant, rgba(15, 23, 34, 0.08));
100
+ box-shadow: var(--smrt-elevation-5, 0 18px 38px color-mix(in srgb, var(--smrt-color-shadow) 8%, transparent));
101
+ }
102
+
103
+ .preview-card h4,
104
+ .preview-card p {
105
+ margin: 0;
106
+ }
107
+
108
+ .eyebrow {
109
+ font-size: var(--smrt-typography-label-medium-size, 0.75rem);
110
+ letter-spacing: var(--smrt-typography-label-medium-tracking, 0.12em);
111
+ text-transform: uppercase;
112
+ color: var(--smrt-color-primary, #0f766e);
113
+ }
114
+
115
+ button {
116
+ justify-self: start;
117
+ border: 0;
118
+ border-radius: var(--smrt-radius-full, 9999px);
119
+ padding: 0.75rem 1rem;
120
+ font: inherit;
121
+ 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
+ }
126
+
127
+ .status {
128
+ color: var(--smrt-color-primary, #0f766e);
129
+ font-size: var(--smrt-typography-body-large-size, 0.95rem);
130
+ }
131
+ </style>
@@ -0,0 +1,8 @@
1
+ import type { PersistedAsset } from '../types';
2
+ type $$ComponentProps = {
3
+ asset: PersistedAsset;
4
+ };
5
+ declare const AssetDetailPreview: import("svelte").Component<$$ComponentProps, {}, "">;
6
+ type AssetDetailPreview = ReturnType<typeof AssetDetailPreview>;
7
+ export default AssetDetailPreview;
8
+ //# sourceMappingURL=AssetDetailPreview.svelte.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,151 @@
1
+ <script lang="ts">
2
+ import { useI18n } from '@happyvertical/smrt-ui/i18n';
3
+ import CreateAssetModal from '../CreateAssetModal.svelte';
4
+ import { M } from '../i18n.js';
5
+
6
+ const { t } = useI18n();
7
+
8
+ interface CreatedAssetSummary {
9
+ name: string;
10
+ description: string;
11
+ altText: string;
12
+ fileName: string;
13
+ }
14
+
15
+ let isOpen = $state(false);
16
+ let statusMessage = $state<string | null>(null);
17
+ let lastCreated = $state<CreatedAssetSummary | null>(null);
18
+
19
+ function openPreview() {
20
+ statusMessage = null;
21
+ isOpen = true;
22
+ }
23
+
24
+ function closePreview() {
25
+ isOpen = false;
26
+ }
27
+
28
+ function handleCreate(data: {
29
+ file: File;
30
+ name: string;
31
+ description: string;
32
+ altText: string;
33
+ }) {
34
+ lastCreated = {
35
+ name: data.name,
36
+ description: data.description,
37
+ altText: data.altText,
38
+ fileName: data.file.name,
39
+ };
40
+ statusMessage = 'Captured a create request in the preview harness.';
41
+ isOpen = false;
42
+ }
43
+ </script>
44
+
45
+ <div class="preview-shell">
46
+ <div class="preview-card">
47
+ <p class="eyebrow">{t(M['assets.create_asset_modal_preview.modal_preview'])}</p>
48
+ <h4>{t(M['assets.create_asset_modal_preview.title'])}</h4>
49
+ <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
+
52
+ {#if statusMessage}
53
+ <p class="status">{statusMessage}</p>
54
+ {/if}
55
+
56
+ {#if lastCreated}
57
+ <dl class="summary">
58
+ <div>
59
+ <dt>File</dt>
60
+ <dd>{lastCreated.fileName}</dd>
61
+ </div>
62
+ <div>
63
+ <dt>Name</dt>
64
+ <dd>{lastCreated.name || 'Untitled'}</dd>
65
+ </div>
66
+ <div>
67
+ <dt>Description</dt>
68
+ <dd>{lastCreated.description || '—'}</dd>
69
+ </div>
70
+ <div>
71
+ <dt>{t(M['assets.create_asset_modal_preview.alt_text'])}</dt>
72
+ <dd>{lastCreated.altText || '—'}</dd>
73
+ </div>
74
+ </dl>
75
+ {/if}
76
+ </div>
77
+
78
+ <CreateAssetModal open={isOpen} onclose={closePreview} oncreate={handleCreate} />
79
+ </div>
80
+
81
+ <style>
82
+ .preview-shell {
83
+ display: grid;
84
+ gap: 1rem;
85
+ }
86
+
87
+ .preview-card {
88
+ display: grid;
89
+ gap: 0.75rem;
90
+ max-width: 32rem;
91
+ padding: 1.25rem;
92
+ border-radius: 1rem;
93
+ background: color-mix(in srgb, var(--smrt-color-surface) 92%, transparent);
94
+ border: 1px solid var(--smrt-color-outline-variant, rgba(15, 23, 34, 0.08));
95
+ box-shadow: var(--smrt-elevation-5, 0 18px 38px color-mix(in srgb, var(--smrt-color-shadow) 8%, transparent));
96
+ }
97
+
98
+ .preview-card h4,
99
+ .preview-card p,
100
+ .summary,
101
+ .summary dt,
102
+ .summary dd {
103
+ margin: 0;
104
+ }
105
+
106
+ .eyebrow {
107
+ font-size: var(--smrt-typography-label-medium-size, 0.75rem);
108
+ letter-spacing: var(--smrt-typography-label-medium-tracking, 0.12em);
109
+ text-transform: uppercase;
110
+ color: var(--smrt-color-primary, #0f766e);
111
+ }
112
+
113
+ button {
114
+ justify-self: start;
115
+ border: 0;
116
+ border-radius: var(--smrt-radius-full, 9999px);
117
+ padding: 0.75rem 1rem;
118
+ font: inherit;
119
+ 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
+ }
124
+
125
+ .status {
126
+ color: var(--smrt-color-primary, #0f766e);
127
+ font-size: var(--smrt-typography-body-large-size, 0.95rem);
128
+ }
129
+
130
+ .summary {
131
+ display: grid;
132
+ gap: 0.5rem;
133
+ padding-top: 0.5rem;
134
+ }
135
+
136
+ .summary div {
137
+ display: grid;
138
+ gap: 0.1rem;
139
+ }
140
+
141
+ .summary dt {
142
+ font-size: var(--smrt-typography-label-medium-size, 0.75rem);
143
+ letter-spacing: var(--smrt-typography-label-medium-tracking, 0.08em);
144
+ text-transform: uppercase;
145
+ color: var(--smrt-color-on-surface-variant, #5b6574);
146
+ }
147
+
148
+ .summary dd {
149
+ color: var(--smrt-color-on-surface, #172033);
150
+ }
151
+ </style>
@@ -0,0 +1,4 @@
1
+ declare const CreateAssetModalPreview: import("svelte").Component<Record<string, never>, {}, "">;
2
+ type CreateAssetModalPreview = ReturnType<typeof CreateAssetModalPreview>;
3
+ export default CreateAssetModalPreview;
4
+ //# sourceMappingURL=CreateAssetModalPreview.svelte.d.ts.map
@@ -0,0 +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"}