@happyvertical/smrt-products 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/lib/chunks/{ProductForm-p4-xbubZ.js → ProductForm-BLRguem5.js} +268 -148
- package/dist/lib/chunks/ProductForm-BLRguem5.js.map +1 -0
- package/dist/lib/components.js +1 -1
- package/dist/lib/index.js +1 -1
- package/dist/lib/lib/components/ProductCard.svelte +6 -35
- package/dist/lib/lib/components/ProductCard.svelte.d.ts.map +1 -1
- package/dist/lib/lib/components/ProductForm.svelte +96 -148
- package/dist/lib/lib/components/ProductForm.svelte.d.ts.map +1 -1
- package/dist/lib/lib/components/auto-generated/AutoForm.svelte +30 -56
- package/dist/lib/lib/components/auto-generated/AutoForm.svelte.d.ts.map +1 -1
- package/dist/lib/lib/components/auto-generated/FieldRenderer.svelte +8 -37
- package/dist/lib/lib/components/auto-generated/FieldRenderer.svelte.d.ts.map +1 -1
- package/dist/lib/lib/features/ProductCatalog.svelte +27 -45
- package/dist/lib/lib/features/ProductCatalog.svelte.d.ts.map +1 -1
- package/dist/lib/manifest.json +2 -2
- package/dist/lib/smrt-knowledge.json +4 -4
- package/dist/lib/smrt-products.css +9 -91
- package/package.json +8 -7
- package/dist/lib/chunks/ProductForm-p4-xbubZ.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProductCatalog.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/features/ProductCatalog.svelte"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ProductCatalog.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/features/ProductCatalog.svelte"],"names":[],"mappings":"AAcA,UAAU,KAAK;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAqKD,QAAA,MAAM,cAAc,2CAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}
|
package/dist/lib/manifest.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": "1.0.0",
|
|
3
|
-
"timestamp":
|
|
3
|
+
"timestamp": 1782290137787,
|
|
4
4
|
"packageName": "@happyvertical/smrt-products",
|
|
5
|
-
"packageVersion": "0.34.
|
|
5
|
+
"packageVersion": "0.34.7",
|
|
6
6
|
"objects": {
|
|
7
7
|
"@happyvertical/smrt-products:CategoryCollection": {
|
|
8
8
|
"name": "categorycollection",
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"generatedAt": "2026-06-
|
|
3
|
+
"generatedAt": "2026-06-24T08:35:38.290Z",
|
|
4
4
|
"packageName": "@happyvertical/smrt-products",
|
|
5
|
-
"packageVersion": "0.34.
|
|
5
|
+
"packageVersion": "0.34.7",
|
|
6
6
|
"sourceManifestPath": "dist/lib/manifest.json",
|
|
7
7
|
"agentDocPath": "AGENTS.md",
|
|
8
8
|
"sourceHashes": {
|
|
9
|
-
"manifest": "
|
|
10
|
-
"packageJson": "
|
|
9
|
+
"manifest": "30f0edb5a8238da237d80fb012c320c04b2b4ac78e68481089a647961cfc66c4",
|
|
10
|
+
"packageJson": "393552fb22b0e6b9bbd15ef79cb29ab70be32c531d3ee31f357d1bab751cdc55",
|
|
11
11
|
"agents": "4ca8837df73cf8b966b65cea639a058baa8f92ae536f3cd5036546fcbfeb37c8"
|
|
12
12
|
},
|
|
13
13
|
"exports": [
|
|
@@ -83,55 +83,25 @@
|
|
|
83
83
|
padding-top: 0.75rem;
|
|
84
84
|
border-top: 1px solid var(--smrt-color-outline-variant, #f3f4f6);
|
|
85
85
|
}
|
|
86
|
-
|
|
87
|
-
.edit-btn.svelte-11ja2cl, .delete-btn.svelte-11ja2cl {
|
|
88
|
-
padding: 0.375rem 0.75rem;
|
|
89
|
-
border-radius: var(--smrt-radius-sm, 4px);
|
|
90
|
-
font-size: var(--smrt-typography-label-large-size, 0.875rem);
|
|
91
|
-
font-weight: var(--smrt-typography-weight-medium, 500);
|
|
92
|
-
border: 1px solid;
|
|
93
|
-
cursor: pointer;
|
|
94
|
-
transition: all 0.2s;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
.edit-btn.svelte-11ja2cl {
|
|
98
|
-
background: var(--smrt-color-surface-container-low, #f9fafb);
|
|
99
|
-
border-color: var(--smrt-color-outline-variant, #d1d5db);
|
|
100
|
-
color: var(--smrt-color-on-surface, #374151);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
.edit-btn.svelte-11ja2cl:hover {
|
|
104
|
-
background: var(--smrt-color-surface-container, #f3f4f6);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
.delete-btn.svelte-11ja2cl {
|
|
108
|
-
background: var(--smrt-color-error-container, #fef2f2);
|
|
109
|
-
border-color: var(--smrt-color-error, #fecaca);
|
|
110
|
-
color: var(--smrt-color-error, #dc2626);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
.delete-btn.svelte-11ja2cl:hover {
|
|
114
|
-
background: var(--smrt-color-error-container, #fee2e2);
|
|
115
|
-
}
|
|
116
86
|
|
|
117
|
-
.product-form.svelte-1hh5ovx {
|
|
87
|
+
.product-form-shell.svelte-1hh5ovx .product-form {
|
|
118
88
|
max-width: 500px;
|
|
119
89
|
padding: 1.5rem;
|
|
120
90
|
background: var(--smrt-color-surface, #fff);
|
|
121
91
|
border-radius: var(--smrt-radius-md, 8px);
|
|
122
92
|
border: 1px solid var(--smrt-color-outline-variant, #e2e8f0);
|
|
123
93
|
}
|
|
124
|
-
|
|
94
|
+
|
|
125
95
|
.form-group.svelte-1hh5ovx {
|
|
126
96
|
margin-bottom: 1rem;
|
|
127
97
|
}
|
|
128
|
-
|
|
98
|
+
|
|
129
99
|
.form-row.svelte-1hh5ovx {
|
|
130
100
|
display: grid;
|
|
131
101
|
grid-template-columns: 1fr 1fr;
|
|
132
102
|
gap: 1rem;
|
|
133
103
|
}
|
|
134
|
-
|
|
104
|
+
|
|
135
105
|
label.svelte-1hh5ovx {
|
|
136
106
|
display: block;
|
|
137
107
|
margin-bottom: 0.25rem;
|
|
@@ -140,30 +110,13 @@
|
|
|
140
110
|
font-size: var(--smrt-typography-label-large-size, 0.875rem);
|
|
141
111
|
}
|
|
142
112
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
border-radius: var(--smrt-radius-sm, 4px);
|
|
148
|
-
font-size: var(--smrt-typography-body-medium-size, 0.875rem);
|
|
149
|
-
transition: border-color 0.2s;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
.form-input.svelte-1hh5ovx:focus, .form-textarea.svelte-1hh5ovx:focus {
|
|
153
|
-
outline: none;
|
|
154
|
-
border-color: var(--smrt-color-primary, #3b82f6);
|
|
155
|
-
box-shadow: 0 0 0 3px color-mix(in srgb, var(--smrt-color-primary, #3b82f6) 10%, transparent);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
.form-input.error.svelte-1hh5ovx {
|
|
113
|
+
/* Error border on the migrated <Input>. The primitive renders the inner
|
|
114
|
+
<input class="input error"> inside its own component, so the scoped class
|
|
115
|
+
can't reach it without :global (#1589). */
|
|
116
|
+
.product-form-shell.svelte-1hh5ovx .input.error {
|
|
159
117
|
border-color: var(--smrt-color-error, #dc2626);
|
|
160
118
|
}
|
|
161
|
-
|
|
162
|
-
.form-textarea.svelte-1hh5ovx {
|
|
163
|
-
resize: vertical;
|
|
164
|
-
min-height: 80px;
|
|
165
|
-
}
|
|
166
|
-
|
|
119
|
+
|
|
167
120
|
.checkbox-label.svelte-1hh5ovx {
|
|
168
121
|
display: flex;
|
|
169
122
|
align-items: center;
|
|
@@ -196,38 +149,3 @@
|
|
|
196
149
|
padding-top: 1rem;
|
|
197
150
|
border-top: 1px solid var(--smrt-color-outline-variant, #f3f4f6);
|
|
198
151
|
}
|
|
199
|
-
|
|
200
|
-
.cancel-btn.svelte-1hh5ovx, .submit-btn.svelte-1hh5ovx {
|
|
201
|
-
padding: 0.5rem 1rem;
|
|
202
|
-
border-radius: var(--smrt-radius-sm, 4px);
|
|
203
|
-
font-size: var(--smrt-typography-label-large-size, 0.875rem);
|
|
204
|
-
font-weight: var(--smrt-typography-weight-medium, 500);
|
|
205
|
-
cursor: pointer;
|
|
206
|
-
border: 1px solid;
|
|
207
|
-
transition: all 0.2s;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
.cancel-btn.svelte-1hh5ovx {
|
|
211
|
-
background: var(--smrt-color-surface, #fff);
|
|
212
|
-
border-color: var(--smrt-color-outline-variant, #d1d5db);
|
|
213
|
-
color: var(--smrt-color-on-surface, #374151);
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
.cancel-btn.svelte-1hh5ovx:hover:not(:disabled) {
|
|
217
|
-
background: var(--smrt-color-surface-container-low, #f9fafb);
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
.submit-btn.svelte-1hh5ovx {
|
|
221
|
-
background: var(--smrt-color-primary, #3b82f6);
|
|
222
|
-
border-color: var(--smrt-color-primary, #3b82f6);
|
|
223
|
-
color: var(--smrt-color-on-primary, white);
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
.submit-btn.svelte-1hh5ovx:hover:not(:disabled) {
|
|
227
|
-
background: var(--smrt-color-primary, #2563eb);
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
.submit-btn.svelte-1hh5ovx:disabled, .cancel-btn.svelte-1hh5ovx:disabled {
|
|
231
|
-
opacity: 0.5;
|
|
232
|
-
cursor: not-allowed;
|
|
233
|
-
}
|
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@happyvertical/smrt-products",
|
|
3
|
-
"version": "0.34.
|
|
3
|
+
"version": "0.34.7",
|
|
4
4
|
"description": "SMRT products module: triple-purpose microservice template for standalone apps, federated modules, and NPM libraries",
|
|
5
5
|
"author": "HappyVertical",
|
|
6
6
|
"type": "module",
|
|
7
|
+
"smrtRawPrimitives": "strict",
|
|
7
8
|
"main": "dist/lib/index.js",
|
|
8
9
|
"types": "dist/lib/index.d.ts",
|
|
9
10
|
"files": [
|
|
@@ -54,11 +55,11 @@
|
|
|
54
55
|
"@happyvertical/utils": "^0.74.7",
|
|
55
56
|
"cors": "^2.8.5",
|
|
56
57
|
"express": "^5.2.1",
|
|
57
|
-
"@happyvertical/smrt-assets": "0.34.
|
|
58
|
-
"@happyvertical/smrt-
|
|
59
|
-
"@happyvertical/smrt-
|
|
60
|
-
"@happyvertical/smrt-tenancy": "0.34.
|
|
61
|
-
"@happyvertical/smrt-
|
|
58
|
+
"@happyvertical/smrt-assets": "0.34.7",
|
|
59
|
+
"@happyvertical/smrt-core": "0.34.7",
|
|
60
|
+
"@happyvertical/smrt-scanner": "0.34.7",
|
|
61
|
+
"@happyvertical/smrt-tenancy": "0.34.7",
|
|
62
|
+
"@happyvertical/smrt-ui": "0.34.7"
|
|
62
63
|
},
|
|
63
64
|
"peerDependencies": {
|
|
64
65
|
"svelte": "^5.46.4"
|
|
@@ -81,7 +82,7 @@
|
|
|
81
82
|
"typescript": "^5.9.3",
|
|
82
83
|
"vite": "^7.3.1",
|
|
83
84
|
"vitest": "^4.0.17",
|
|
84
|
-
"@happyvertical/smrt-vitest": "0.34.
|
|
85
|
+
"@happyvertical/smrt-vitest": "0.34.7"
|
|
85
86
|
},
|
|
86
87
|
"keywords": [
|
|
87
88
|
"smrt",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ProductForm-p4-xbubZ.js","sources":["../../../src/lib/components/ProductCard.svelte","../../../src/lib/i18n.ts","../../../src/lib/components/ProductForm.svelte"],"sourcesContent":["<script lang=\"ts\">\nimport type { ProductData } from '../types';\n\ninterface Props {\n product: ProductData;\n onEdit?: (product: ProductData) => void;\n onDelete?: (id: string) => void;\n}\n\nconst { product, onEdit, onDelete }: Props = $props();\n</script>\n\n<div class=\"product-card\">\n <div class=\"product-header\">\n <h3 class=\"product-name\">{product.name}</h3>\n {#if product.manufacturer}\n <div class=\"product-manufacturer\">{product.manufacturer}</div>\n {/if}\n </div>\n\n {#if product.model}\n <div class=\"product-model\">Model: {product.model}</div>\n {/if}\n\n {#if product.description}\n <p class=\"product-description\">{product.description}</p>\n {/if}\n\n <div class=\"product-meta\">\n {#if product.category}\n <div class=\"product-category\">Category: {product.category}</div>\n {/if}\n \n {#if product.tags && product.tags.length > 0}\n <div class=\"product-tags\">\n {#each product.tags as tag}\n <span class=\"tag\">{tag}</span>\n {/each}\n </div>\n {/if}\n </div>\n \n <div class=\"product-actions\">\n {#if onEdit}\n <button type=\"button\" onclick={() => onEdit?.(product)} class=\"edit-btn\">\n Edit\n </button>\n {/if}\n \n {#if onDelete}\n <button type=\"button\" onclick={() => onDelete?.(product.id)} class=\"delete-btn\">\n Delete\n </button>\n {/if}\n </div>\n</div>\n\n<style>\n .product-card {\n border: 1px solid var(--smrt-color-outline-variant, #e2e8f0);\n border-radius: var(--smrt-radius-md, 8px);\n padding: 1rem;\n background: var(--smrt-color-surface, #fff);\n box-shadow: var(--smrt-elevation-1, 0 1px 3px color-mix(in srgb, var(--smrt-color-shadow, #000) 10%, transparent));\n transition: box-shadow 0.2s;\n }\n\n .product-card:hover {\n box-shadow: var(--smrt-elevation-2, 0 4px 6px color-mix(in srgb, var(--smrt-color-shadow, #000) 10%, transparent));\n }\n \n .product-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 0.5rem;\n }\n \n .product-name {\n margin: 0;\n font-size: var(--smrt-typography-title-medium-size, 1.125rem);\n font-weight: var(--smrt-typography-weight-semibold, 600);\n color: var(--smrt-color-on-surface, #1f2937);\n }\n\n .product-manufacturer {\n font-size: var(--smrt-typography-title-small-size, 0.875rem);\n font-weight: var(--smrt-typography-weight-medium, 500);\n color: var(--smrt-color-on-surface-variant, #6b7280);\n }\n\n .product-model {\n font-size: var(--smrt-typography-body-medium-size, 0.875rem);\n color: var(--smrt-color-on-surface-variant, #6b7280);\n margin-bottom: 0.5rem;\n }\n\n .product-category {\n font-size: var(--smrt-typography-label-medium-size, 0.75rem);\n font-weight: var(--smrt-typography-weight-medium, 500);\n color: var(--smrt-color-on-surface, #374151);\n background: var(--smrt-color-surface-container, #f3f4f6);\n padding: 0.25rem 0.5rem;\n border-radius: var(--smrt-radius-sm, 4px);\n display: inline-block;\n margin-bottom: 0.5rem;\n }\n \n .product-description {\n margin: 0.5rem 0;\n color: var(--smrt-color-on-surface-variant, #6b7280);\n font-size: var(--smrt-typography-body-medium-size, 0.875rem);\n line-height: var(--smrt-typography-body-medium-line-height, 1.4);\n }\n \n .product-meta {\n margin: 0.75rem 0;\n }\n \n \n .product-tags {\n margin-top: 0.5rem;\n display: flex;\n flex-wrap: wrap;\n gap: 0.25rem;\n }\n \n .tag {\n background: var(--smrt-color-surface-container, #f3f4f6);\n color: var(--smrt-color-on-surface, #374151);\n padding: 0.125rem 0.5rem;\n border-radius: var(--smrt-radius-full, 9999px);\n font-size: var(--smrt-typography-label-medium-size, 0.75rem);\n }\n\n .product-actions {\n display: flex;\n gap: 0.5rem;\n margin-top: 1rem;\n padding-top: 0.75rem;\n border-top: 1px solid var(--smrt-color-outline-variant, #f3f4f6);\n }\n \n .edit-btn, .delete-btn {\n padding: 0.375rem 0.75rem;\n border-radius: var(--smrt-radius-sm, 4px);\n font-size: var(--smrt-typography-label-large-size, 0.875rem);\n font-weight: var(--smrt-typography-weight-medium, 500);\n border: 1px solid;\n cursor: pointer;\n transition: all 0.2s;\n }\n \n .edit-btn {\n background: var(--smrt-color-surface-container-low, #f9fafb);\n border-color: var(--smrt-color-outline-variant, #d1d5db);\n color: var(--smrt-color-on-surface, #374151);\n }\n\n .edit-btn:hover {\n background: var(--smrt-color-surface-container, #f3f4f6);\n }\n\n .delete-btn {\n background: var(--smrt-color-error-container, #fef2f2);\n border-color: var(--smrt-color-error, #fecaca);\n color: var(--smrt-color-error, #dc2626);\n }\n\n .delete-btn:hover {\n background: var(--smrt-color-error-container, #fee2e2);\n }\n</style>","import { defineMessages } from '@happyvertical/smrt-ui/i18n';\n\nexport const M = defineMessages({\n // App\n 'products.app.categories_coming_soon': 'Category management coming soon...',\n 'products.app.analytics_coming_soon': 'Analytics dashboard coming soon...',\n\n // AppLayout\n 'products.app_layout.service_title': 'Product Service',\n 'products.app_layout.footer_copyright':\n '2024 SMRT Product Service - Auto-generated with ❤️',\n 'products.app_layout.api_docs': 'API Docs',\n 'products.app_layout.mcp_tools': 'MCP Tools',\n\n // DemoPage\n 'products.demo_page.title': 'SMRT Framework Demo',\n 'products.demo_page.subtitle':\n 'Define Once, Consume Everywhere - Progressive Customization',\n 'products.demo_page.custom_components_tab': 'Custom Components',\n 'products.demo_page.auto_generated_heading':\n 'Auto-Generated UI from SMRT Object',\n 'products.demo_page.auto_generated_description':\n 'This form is automatically generated from the Product class definition.\\n The field types, labels, and validation rules are inferred from the TypeScript schema.',\n 'products.demo_page.generated_form_heading': 'Generated Form',\n 'products.demo_page.auto_form_title': 'Auto-Generated Product Form',\n 'products.demo_page.generated_display_heading': 'Generated Display',\n 'products.demo_page.custom_components_heading':\n 'Custom Components with SMRT Integration',\n 'products.demo_page.custom_components_description':\n 'These are hand-crafted components that still leverage the SMRT data structure\\n but provide custom UI/UX for specific business requirements.',\n 'products.demo_page.custom_form_heading': 'Custom Form',\n 'products.demo_page.custom_display_heading': 'Custom Display',\n 'products.demo_page.progressive_heading': 'Progressive Customization',\n 'products.demo_page.progressive_description':\n 'Start with auto-generated components, then progressively customize as needed.\\n Both approaches use the same underlying SMRT Product model.',\n 'products.demo_page.feature_zero_config': '✅ Zero configuration',\n 'products.demo_page.feature_instant_ui': '✅ Instant UI from schema',\n 'products.demo_page.feature_type_safe': '✅ Type-safe by default',\n 'products.demo_page.feature_prototyping': '⚡ Perfect for prototyping',\n 'products.demo_page.custom_components_label': '🎨 Custom Components',\n 'products.demo_page.feature_tailored_ux': '✅ Tailored UX',\n 'products.demo_page.feature_business_workflows':\n '✅ Business-specific workflows',\n 'products.demo_page.feature_advanced_interactions':\n '✅ Advanced interactions',\n 'products.demo_page.simple_auto_form_title': 'Auto Form',\n 'products.demo_page.benefits_heading': 'SMRT Framework Benefits',\n 'products.demo_page.benefit_define_once_label': 'Define Once:',\n 'products.demo_page.benefit_define_once_text':\n 'Product class with @smrt decorator',\n 'products.demo_page.benefit_auto_generate_label': 'Auto-Generate:',\n 'products.demo_page.benefit_auto_generate_text':\n 'REST APIs, MCP tools, TypeScript clients, default UI',\n 'products.demo_page.benefit_progressive_label': 'Progressive Enhancement:',\n 'products.demo_page.benefit_progressive_text':\n 'Start with defaults, customize as needed',\n 'products.demo_page.benefit_type_safety_label': 'Type Safety:',\n 'products.demo_page.benefit_type_safety_text':\n 'End-to-end TypeScript integration',\n 'products.demo_page.benefit_multiple_consumption_label':\n 'Multiple Consumption:',\n 'products.demo_page.benefit_multiple_consumption_text':\n 'Library, federation, standalone',\n\n // ProductsPage\n 'products.products_page.description':\n 'Manage your product catalog with auto-generated CRUD operations, \\n real-time updates, and AI-powered tools via MCP.',\n 'products.products_page.auto_generated_text':\n 'REST API endpoints automatically created from @smrt() decorated Product class',\n 'products.products_page.ai_ready_heading': '🤖 AI Ready',\n 'products.products_page.ai_ready_text':\n 'MCP tools available for Claude and other AI models to interact with products',\n 'products.products_page.federatable_text':\n 'Components can be consumed by other applications via module federation',\n 'products.products_page.library_text':\n 'Install as NPM package: npm install @have/smrt-template',\n\n // ProductForm\n 'products.product_form.name_label': 'Product Name *',\n 'products.product_form.name_placeholder': 'Enter product name',\n 'products.product_form.description_placeholder':\n 'Product description (optional)',\n 'products.product_form.category_placeholder': 'Product category',\n 'products.product_form.tags_placeholder': 'tag1, tag2, tag3',\n 'products.product_form.tags_hint': 'Separate tags with commas',\n 'products.product_form.in_stock_label': 'In Stock',\n\n // TestComponent\n 'products.test_component.title': 'Test Component',\n\n // AutoForm\n 'products.auto_form.subtitle': 'Auto-generated from SMRT Product model',\n 'products.auto_form.debug_summary': 'Form Data (Debug)',\n\n // FieldRenderer\n 'products.field_renderer.array_hint': 'Enter values separated by commas',\n 'products.field_renderer.object_hint': 'Enter valid JSON',\n\n // CategoryManager\n 'products.category_manager.title': 'Category Manager',\n 'products.category_manager.subtitle': 'Manage product categories',\n 'products.category_manager.coming_soon':\n 'Category management feature coming soon...',\n 'products.category_manager.will_include': 'This will include:',\n 'products.category_manager.create_edit': 'Create and edit categories',\n 'products.category_manager.organize_hierarchy': 'Organize category hierarchy',\n 'products.category_manager.manage_permissions': 'Manage category permissions',\n 'products.category_manager.analytics': 'Category analytics',\n\n // ProductCatalog\n 'products.product_catalog.title': 'Product Catalog',\n 'products.product_catalog.in_stock': 'in stock',\n 'products.product_catalog.total_value': 'Total value:',\n 'products.product_catalog.search_placeholder': 'Search products...',\n 'products.product_catalog.all_categories': 'All Categories',\n 'products.product_catalog.add_product': 'Add Product',\n 'products.product_catalog.loading': 'Loading products...',\n 'products.product_catalog.empty':\n 'No products yet. Create your first product to get started!',\n 'products.product_catalog.create_first': 'Create First Product',\n 'products.product_catalog.no_match':\n 'No products match your search criteria.',\n});\n","<script lang=\"ts\">\nimport { useI18n } from '@happyvertical/smrt-ui/i18n';\nimport { M } from '../i18n.js';\nimport type { ProductData } from '../types';\n\nconst { t } = useI18n();\n\ninterface Props {\n product?: Partial<ProductData>;\n onSubmit: (product: Partial<ProductData>) => void;\n onCancel?: () => void;\n loading?: boolean;\n}\n\nconst { product = {}, onSubmit, onCancel, loading = false }: Props = $props();\n\nconst formData = $state({\n name: product.name || '',\n description: product.description || '',\n price: product.price || 0,\n inStock: product.inStock ?? true,\n category: product.category || '',\n tags: product.tags?.join(', ') || '',\n});\n\nlet errors = $state<Record<string, string>>({});\n\nfunction validateForm() {\n errors = {};\n\n if (!formData.name.trim()) {\n errors.name = 'Product name is required';\n }\n\n if (formData.price < 0) {\n errors.price = 'Price must be non-negative';\n }\n\n return Object.keys(errors).length === 0;\n}\n\nfunction handleSubmit(event: Event) {\n event.preventDefault();\n\n if (!validateForm()) {\n return;\n }\n\n const productData: Partial<ProductData> = {\n ...product,\n name: formData.name.trim(),\n description: formData.description.trim() || undefined,\n price: formData.price,\n inStock: formData.inStock,\n category: formData.category.trim(),\n tags: formData.tags\n ? formData.tags\n .split(',')\n .map((tag) => tag.trim())\n .filter(Boolean)\n : [],\n };\n\n onSubmit(productData);\n}\n</script>\n\n<form onsubmit={handleSubmit} class=\"product-form\">\n <div class=\"form-group\">\n <label for=\"name\">{t(M['products.product_form.name_label'])}</label>\n <input\n id=\"name\"\n type=\"text\"\n bind:value={formData.name}\n disabled={loading}\n class=\"form-input\"\n class:error={errors.name}\n placeholder={t(M['products.product_form.name_placeholder'])}\n />\n {#if errors.name}\n <span class=\"error-message\">{errors.name}</span>\n {/if}\n </div>\n\n <div class=\"form-group\">\n <label for=\"description\">Description</label>\n <textarea\n id=\"description\"\n bind:value={formData.description}\n disabled={loading}\n class=\"form-textarea\"\n placeholder={t(M['products.product_form.description_placeholder'])}\n rows=\"3\"\n ></textarea>\n </div>\n\n <div class=\"form-row\">\n <div class=\"form-group\">\n <label for=\"price\">Price *</label>\n <input\n id=\"price\"\n type=\"number\"\n step=\"0.01\"\n min=\"0\"\n bind:value={formData.price}\n disabled={loading}\n class=\"form-input\"\n class:error={errors.price}\n placeholder=\"0.00\"\n />\n {#if errors.price}\n <span class=\"error-message\">{errors.price}</span>\n {/if}\n </div>\n\n <div class=\"form-group\">\n <label for=\"category\">Category</label>\n <input\n id=\"category\"\n type=\"text\"\n bind:value={formData.category}\n disabled={loading}\n class=\"form-input\"\n placeholder={t(M['products.product_form.category_placeholder'])}\n />\n </div>\n </div>\n\n <div class=\"form-group\">\n <label for=\"tags\">Tags</label>\n <input\n id=\"tags\"\n type=\"text\"\n bind:value={formData.tags}\n disabled={loading}\n class=\"form-input\"\n placeholder={t(M['products.product_form.tags_placeholder'])}\n />\n <small class=\"form-hint\">{t(M['products.product_form.tags_hint'])}</small>\n </div>\n\n <div class=\"form-group\">\n <label class=\"checkbox-label\">\n <input\n type=\"checkbox\"\n bind:checked={formData.inStock}\n disabled={loading}\n class=\"form-checkbox\"\n />\n {t(M['products.product_form.in_stock_label'])}\n </label>\n </div>\n\n <div class=\"form-actions\">\n {#if onCancel}\n <button type=\"button\" onclick={onCancel} disabled={loading} class=\"cancel-btn\">\n Cancel\n </button>\n {/if}\n \n <button type=\"submit\" disabled={loading} class=\"submit-btn\">\n {#if loading}\n Saving...\n {:else}\n {product.id ? 'Update Product' : 'Create Product'}\n {/if}\n </button>\n </div>\n</form>\n\n<style>\n .product-form {\n max-width: 500px;\n padding: 1.5rem;\n background: var(--smrt-color-surface, #fff);\n border-radius: var(--smrt-radius-md, 8px);\n border: 1px solid var(--smrt-color-outline-variant, #e2e8f0);\n }\n \n .form-group {\n margin-bottom: 1rem;\n }\n \n .form-row {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 1rem;\n }\n \n label {\n display: block;\n margin-bottom: 0.25rem;\n font-weight: var(--smrt-typography-weight-medium, 500);\n color: var(--smrt-color-on-surface, #374151);\n font-size: var(--smrt-typography-label-large-size, 0.875rem);\n }\n\n .form-input, .form-textarea {\n width: 100%;\n padding: 0.5rem;\n border: 1px solid var(--smrt-color-outline-variant, #d1d5db);\n border-radius: var(--smrt-radius-sm, 4px);\n font-size: var(--smrt-typography-body-medium-size, 0.875rem);\n transition: border-color 0.2s;\n }\n\n .form-input:focus, .form-textarea:focus {\n outline: none;\n border-color: var(--smrt-color-primary, #3b82f6);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--smrt-color-primary, #3b82f6) 10%, transparent);\n }\n\n .form-input.error {\n border-color: var(--smrt-color-error, #dc2626);\n }\n \n .form-textarea {\n resize: vertical;\n min-height: 80px;\n }\n \n .checkbox-label {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n cursor: pointer;\n }\n \n .form-checkbox {\n width: auto;\n }\n \n .form-hint {\n color: var(--smrt-color-on-surface-variant, #6b7280);\n font-size: var(--smrt-typography-body-small-size, 0.75rem);\n margin-top: 0.25rem;\n }\n\n .error-message {\n color: var(--smrt-color-error, #dc2626);\n font-size: var(--smrt-typography-label-medium-size, 0.75rem);\n margin-top: 0.25rem;\n display: block;\n }\n\n .form-actions {\n display: flex;\n gap: 0.75rem;\n justify-content: flex-end;\n margin-top: 1.5rem;\n padding-top: 1rem;\n border-top: 1px solid var(--smrt-color-outline-variant, #f3f4f6);\n }\n \n .cancel-btn, .submit-btn {\n padding: 0.5rem 1rem;\n border-radius: var(--smrt-radius-sm, 4px);\n font-size: var(--smrt-typography-label-large-size, 0.875rem);\n font-weight: var(--smrt-typography-weight-medium, 500);\n cursor: pointer;\n border: 1px solid;\n transition: all 0.2s;\n }\n \n .cancel-btn {\n background: var(--smrt-color-surface, #fff);\n border-color: var(--smrt-color-outline-variant, #d1d5db);\n color: var(--smrt-color-on-surface, #374151);\n }\n\n .cancel-btn:hover:not(:disabled) {\n background: var(--smrt-color-surface-container-low, #f9fafb);\n }\n\n .submit-btn {\n background: var(--smrt-color-primary, #3b82f6);\n border-color: var(--smrt-color-primary, #3b82f6);\n color: var(--smrt-color-on-primary, white);\n }\n\n .submit-btn:hover:not(:disabled) {\n background: var(--smrt-color-primary, #2563eb);\n }\n \n .submit-btn:disabled, .cancel-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n</style>"],"names":["root","root_1","root_2","root_3","$$anchor"],"mappings":"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"}
|