@svadmin/lite 0.6.0 → 0.7.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 (36) hide show
  1. package/README.md +85 -9
  2. package/dist/components/LiteDynamicFormList.svelte +169 -0
  3. package/dist/components/LiteDynamicFormList.svelte.d.ts +45 -0
  4. package/dist/components/LiteFilterBuilder.svelte +205 -0
  5. package/dist/components/LiteFilterBuilder.svelte.d.ts +19 -0
  6. package/dist/components/LiteShowField.svelte +22 -0
  7. package/dist/components/LiteTransfer.svelte +185 -0
  8. package/dist/components/LiteTransfer.svelte.d.ts +18 -0
  9. package/dist/components/fields/LiteAvatarField.svelte +127 -0
  10. package/dist/components/fields/LiteAvatarField.svelte.d.ts +21 -0
  11. package/dist/components/fields/LiteCascader.svelte +119 -0
  12. package/dist/components/fields/LiteCascader.svelte.d.ts +24 -0
  13. package/dist/components/fields/LiteCodeField.svelte +71 -0
  14. package/dist/components/fields/LiteCodeField.svelte.d.ts +16 -0
  15. package/dist/components/fields/LiteCopyField.svelte +74 -0
  16. package/dist/components/fields/LiteCopyField.svelte.d.ts +18 -0
  17. package/dist/components/fields/LiteCurrencyField.svelte +126 -0
  18. package/dist/components/fields/LiteCurrencyField.svelte.d.ts +21 -0
  19. package/dist/components/fields/LiteDateRangeField.svelte +147 -0
  20. package/dist/components/fields/LiteDateRangeField.svelte.d.ts +26 -0
  21. package/dist/components/fields/LitePercentField.svelte +124 -0
  22. package/dist/components/fields/LitePercentField.svelte.d.ts +17 -0
  23. package/dist/components/fields/LitePhoneField.svelte +81 -0
  24. package/dist/components/fields/LitePhoneField.svelte.d.ts +17 -0
  25. package/dist/components/fields/LiteRatingField.svelte +105 -0
  26. package/dist/components/fields/LiteRatingField.svelte.d.ts +16 -0
  27. package/dist/components/fields/LiteTreeSelect.svelte +143 -0
  28. package/dist/components/fields/LiteTreeSelect.svelte.d.ts +23 -0
  29. package/dist/components/fields/index.d.ts +12 -0
  30. package/dist/components/fields/index.js +10 -0
  31. package/dist/components/pages/LiteListPage.svelte +14 -12
  32. package/dist/index.d.ts +5 -0
  33. package/dist/index.js +3 -0
  34. package/dist/lite.css +205 -0
  35. package/dist/schema-generator.js +15 -4
  36. package/package.json +4 -3
@@ -0,0 +1,143 @@
1
+ <script lang="ts">
2
+ import type { FieldDefinition } from '@svadmin/core';
3
+ import { t } from '@svadmin/core/i18n';
4
+
5
+ export interface TreeSelectOption {
6
+ value: string | number;
7
+ label: string;
8
+ children?: TreeSelectOption[];
9
+ disabled?: boolean;
10
+ }
11
+
12
+ interface Props {
13
+ field?: FieldDefinition;
14
+ name?: string;
15
+ label?: string;
16
+ value?: string | number | (string | number)[];
17
+ options?: TreeSelectOption[];
18
+ multiple?: boolean;
19
+ placeholder?: string;
20
+ disabled?: boolean;
21
+ required?: boolean;
22
+ error?: string[];
23
+ mode?: 'show' | 'edit' | 'create';
24
+ }
25
+
26
+ let {
27
+ field,
28
+ name = field?.key ?? 'treeSelect',
29
+ label = field?.label,
30
+ value,
31
+ options = [],
32
+ multiple = false,
33
+ placeholder,
34
+ disabled = false,
35
+ required = field?.required ?? false,
36
+ error = [],
37
+ mode = 'show',
38
+ }: Props = $props();
39
+
40
+ const hasError = $derived(error.length > 0);
41
+
42
+ interface FlatTreeOption {
43
+ value: string | number;
44
+ label: string;
45
+ level: number;
46
+ disabled?: boolean;
47
+ }
48
+
49
+ function flattenTree(nodes: TreeSelectOption[], level = 0): FlatTreeOption[] {
50
+ const list: FlatTreeOption[] = [];
51
+ for (const node of nodes) {
52
+ list.push({
53
+ value: node.value,
54
+ label: node.label,
55
+ level,
56
+ disabled: node.disabled,
57
+ });
58
+ if (node.children && node.children.length > 0) {
59
+ list.push(...flattenTree(node.children, level + 1));
60
+ }
61
+ }
62
+ return list;
63
+ }
64
+
65
+ const flattenedOptions = $derived(flattenTree(options));
66
+
67
+ function getIndentPrefix(level: number): string {
68
+ if (level === 0) return '';
69
+ return ' '.repeat(level) + '├─ ';
70
+ }
71
+
72
+ function formatDisplay(v: unknown): string {
73
+ if (v == null || v === '') return '—';
74
+ const values = Array.isArray(v) ? v.map(String) : [String(v)];
75
+ const labels = values.map((val) => {
76
+ const match = flattenedOptions.find((o) => String(o.value) === val);
77
+ return match ? match.label : val;
78
+ });
79
+ return labels.join(', ');
80
+ }
81
+
82
+ const selectedValues = $derived(
83
+ Array.isArray(value) ? value.map(String) : value != null ? [String(value)] : []
84
+ );
85
+ </script>
86
+
87
+ {#if mode === 'show'}
88
+ <span class="lite-badge">{formatDisplay(value)}</span>
89
+ {:else}
90
+ <div class="lite-form-group">
91
+ {#if label}
92
+ <label class="lite-label" for={name}>
93
+ {label}
94
+ {#if required}<span class="required">*</span>{/if}
95
+ </label>
96
+ {/if}
97
+ {#if multiple}
98
+ <select
99
+ id={name}
100
+ name="{name}[]"
101
+ multiple
102
+ class="lite-select lite-select-multiple {hasError ? 'lite-input-error' : ''}"
103
+ {disabled}
104
+ {required}
105
+ size={Math.min(8, Math.max(4, flattenedOptions.length + 1))}
106
+ >
107
+ {#each flattenedOptions as opt (opt.value)}
108
+ <option
109
+ value={String(opt.value)}
110
+ disabled={opt.disabled}
111
+ selected={selectedValues.includes(String(opt.value))}
112
+ >
113
+ {getIndentPrefix(opt.level)}{opt.label}
114
+ </option>
115
+ {/each}
116
+ </select>
117
+ {:else}
118
+ <select
119
+ id={name}
120
+ {name}
121
+ class="lite-select {hasError ? 'lite-input-error' : ''}"
122
+ {disabled}
123
+ {required}
124
+ >
125
+ <option value="">-- {placeholder || t('common.select') || 'Select'} --</option>
126
+ {#each flattenedOptions as opt (opt.value)}
127
+ <option
128
+ value={String(opt.value)}
129
+ disabled={opt.disabled}
130
+ selected={selectedValues.includes(String(opt.value))}
131
+ >
132
+ {getIndentPrefix(opt.level)}{opt.label}
133
+ </option>
134
+ {/each}
135
+ </select>
136
+ {/if}
137
+ {#if hasError}
138
+ {#each error as err, i (i)}
139
+ <div class="lite-error-text">{err}</div>
140
+ {/each}
141
+ {/if}
142
+ </div>
143
+ {/if}
@@ -0,0 +1,23 @@
1
+ import type { FieldDefinition } from '@svadmin/core';
2
+ export interface TreeSelectOption {
3
+ value: string | number;
4
+ label: string;
5
+ children?: TreeSelectOption[];
6
+ disabled?: boolean;
7
+ }
8
+ interface Props {
9
+ field?: FieldDefinition;
10
+ name?: string;
11
+ label?: string;
12
+ value?: string | number | (string | number)[];
13
+ options?: TreeSelectOption[];
14
+ multiple?: boolean;
15
+ placeholder?: string;
16
+ disabled?: boolean;
17
+ required?: boolean;
18
+ error?: string[];
19
+ mode?: 'show' | 'edit' | 'create';
20
+ }
21
+ declare const LiteTreeSelect: import("svelte").Component<Props, {}, "">;
22
+ type LiteTreeSelect = ReturnType<typeof LiteTreeSelect>;
23
+ export default LiteTreeSelect;
@@ -13,3 +13,15 @@ export { default as LiteFileField } from './LiteFileField.svelte';
13
13
  export { default as LiteRichTextField } from './LiteRichTextField.svelte';
14
14
  export { default as LiteMarkdownField } from './LiteMarkdownField.svelte';
15
15
  export { default as LiteJsonField } from './LiteJsonField.svelte';
16
+ export { default as LiteAvatarField } from './LiteAvatarField.svelte';
17
+ export { default as LiteCodeField } from './LiteCodeField.svelte';
18
+ export { default as LiteCopyField } from './LiteCopyField.svelte';
19
+ export { default as LiteCurrencyField } from './LiteCurrencyField.svelte';
20
+ export { default as LiteDateRangeField } from './LiteDateRangeField.svelte';
21
+ export { default as LitePercentField } from './LitePercentField.svelte';
22
+ export { default as LitePhoneField } from './LitePhoneField.svelte';
23
+ export { default as LiteRatingField } from './LiteRatingField.svelte';
24
+ export { default as LiteTreeSelect } from './LiteTreeSelect.svelte';
25
+ export type { TreeSelectOption } from './LiteTreeSelect.svelte';
26
+ export { default as LiteCascader } from './LiteCascader.svelte';
27
+ export type { CascaderOption } from './LiteCascader.svelte';
@@ -13,3 +13,13 @@ export { default as LiteFileField } from './LiteFileField.svelte';
13
13
  export { default as LiteRichTextField } from './LiteRichTextField.svelte';
14
14
  export { default as LiteMarkdownField } from './LiteMarkdownField.svelte';
15
15
  export { default as LiteJsonField } from './LiteJsonField.svelte';
16
+ export { default as LiteAvatarField } from './LiteAvatarField.svelte';
17
+ export { default as LiteCodeField } from './LiteCodeField.svelte';
18
+ export { default as LiteCopyField } from './LiteCopyField.svelte';
19
+ export { default as LiteCurrencyField } from './LiteCurrencyField.svelte';
20
+ export { default as LiteDateRangeField } from './LiteDateRangeField.svelte';
21
+ export { default as LitePercentField } from './LitePercentField.svelte';
22
+ export { default as LitePhoneField } from './LitePhoneField.svelte';
23
+ export { default as LiteRatingField } from './LiteRatingField.svelte';
24
+ export { default as LiteTreeSelect } from './LiteTreeSelect.svelte';
25
+ export { default as LiteCascader } from './LiteCascader.svelte';
@@ -130,18 +130,20 @@
130
130
  </span>
131
131
  </div>
132
132
 
133
- <LiteTable
134
- {records}
135
- {resource}
136
- {currentSort}
137
- {currentOrder}
138
- {currentSearch}
139
- {basePath}
140
- canShow={showView}
141
- canEdit={showEdit}
142
- canDelete={showDelete}
143
- {enableBatch}
144
- />
133
+ <div class="lite-table-scroll">
134
+ <LiteTable
135
+ {records}
136
+ {resource}
137
+ {currentSort}
138
+ {currentOrder}
139
+ {currentSearch}
140
+ {basePath}
141
+ canShow={showView}
142
+ canEdit={showEdit}
143
+ canDelete={showDelete}
144
+ {enableBatch}
145
+ />
146
+ </div>
145
147
 
146
148
  {#if total > pagination.perPage}
147
149
  <LitePagination
package/dist/index.d.ts CHANGED
@@ -15,6 +15,11 @@ export { default as LiteAlert } from './components/LiteAlert.svelte';
15
15
  export { default as LitePermissionMatrix } from './components/LitePermissionMatrix.svelte';
16
16
  export { default as LiteAuditLog } from './components/LiteAuditLog.svelte';
17
17
  export { default as LiteArrayField } from './components/LiteArrayField.svelte';
18
+ export { default as LiteDynamicFormList } from './components/LiteDynamicFormList.svelte';
19
+ export { default as LiteTransfer } from './components/LiteTransfer.svelte';
20
+ export type { TransferItem } from './components/LiteTransfer.svelte';
21
+ export { default as LiteFilterBuilder } from './components/LiteFilterBuilder.svelte';
22
+ export type { FilterRuleItem } from './components/LiteFilterBuilder.svelte';
18
23
  export { default as LiteBreadcrumbs } from './components/LiteBreadcrumbs.svelte';
19
24
  export { default as LiteStatsCard } from './components/LiteStatsCard.svelte';
20
25
  export { default as LiteConfirmDialog } from './components/LiteConfirmDialog.svelte';
package/dist/index.js CHANGED
@@ -19,6 +19,9 @@ export { default as LiteAlert } from './components/LiteAlert.svelte';
19
19
  export { default as LitePermissionMatrix } from './components/LitePermissionMatrix.svelte';
20
20
  export { default as LiteAuditLog } from './components/LiteAuditLog.svelte';
21
21
  export { default as LiteArrayField } from './components/LiteArrayField.svelte';
22
+ export { default as LiteDynamicFormList } from './components/LiteDynamicFormList.svelte';
23
+ export { default as LiteTransfer } from './components/LiteTransfer.svelte';
24
+ export { default as LiteFilterBuilder } from './components/LiteFilterBuilder.svelte';
22
25
  export { default as LiteBreadcrumbs } from './components/LiteBreadcrumbs.svelte';
23
26
  export { default as LiteStatsCard } from './components/LiteStatsCard.svelte';
24
27
  export { default as LiteConfirmDialog } from './components/LiteConfirmDialog.svelte';
package/dist/lite.css CHANGED
@@ -1066,6 +1066,211 @@ textarea.lite-input {
1066
1066
  .lite-mt-0 { margin-top: 0; }
1067
1067
  .lite-mb-lg { margin-bottom: 24px; }
1068
1068
 
1069
+ /* ─── Avatar ───────────────────────────────────────────────── */
1070
+ .lite-avatar-wrapper {
1071
+ display: inline-flex;
1072
+ align-items: center;
1073
+ }
1074
+ .lite-avatar-container {
1075
+ position: relative;
1076
+ display: inline-block;
1077
+ vertical-align: middle;
1078
+ flex-shrink: 0;
1079
+ }
1080
+ .lite-avatar {
1081
+ display: inline-flex;
1082
+ align-items: center;
1083
+ justify-content: center;
1084
+ background: #f1f5f9;
1085
+ color: #64748b;
1086
+ font-weight: 500;
1087
+ overflow: hidden;
1088
+ vertical-align: middle;
1089
+ }
1090
+ .lite-avatar-circle { border-radius: 50%; }
1091
+ .lite-avatar-square { border-radius: 6px; }
1092
+
1093
+ .lite-avatar-xs { width: 20px; height: 20px; font-size: 10px; }
1094
+ .lite-avatar-sm { width: 28px; height: 28px; font-size: 12px; }
1095
+ .lite-avatar-default { width: 36px; height: 36px; font-size: 14px; }
1096
+ .lite-avatar-lg { width: 44px; height: 44px; font-size: 16px; }
1097
+
1098
+ .lite-avatar-img {
1099
+ width: 100%;
1100
+ height: 100%;
1101
+ object-fit: cover;
1102
+ }
1103
+ .lite-avatar-dot {
1104
+ position: absolute;
1105
+ bottom: 0;
1106
+ right: 0;
1107
+ border-radius: 50%;
1108
+ border: 2px solid #ffffff;
1109
+ }
1110
+ .lite-avatar-dot-xs { width: 6px; height: 6px; }
1111
+ .lite-avatar-dot-sm { width: 8px; height: 8px; }
1112
+ .lite-avatar-dot-default { width: 10px; height: 10px; }
1113
+ .lite-avatar-dot-lg { width: 12px; height: 12px; }
1114
+
1115
+ .lite-avatar-status-online, .lite-avatar-status-success { background: #22c55e; }
1116
+ .lite-avatar-status-busy, .lite-avatar-status-error { background: #ef4444; }
1117
+ .lite-avatar-status-warning, .lite-avatar-status-away { background: #f59e0b; }
1118
+ .lite-avatar-status-offline, .lite-avatar-status-neutral { background: #94a3b8; }
1119
+
1120
+ .lite-avatar-text-block {
1121
+ display: inline-flex;
1122
+ flex-direction: column;
1123
+ margin-left: 10px;
1124
+ text-align: left;
1125
+ vertical-align: middle;
1126
+ }
1127
+ .lite-avatar-name {
1128
+ font-size: 13px;
1129
+ font-weight: 500;
1130
+ color: #0f172a;
1131
+ line-height: 1.2;
1132
+ }
1133
+ .lite-avatar-subtitle {
1134
+ font-size: 11px;
1135
+ color: #64748b;
1136
+ line-height: 1.2;
1137
+ margin-top: 2px;
1138
+ }
1139
+
1140
+ /* ─── Code Block ───────────────────────────────────────────── */
1141
+ .lite-code-block {
1142
+ border: 1px solid #e2e8f0;
1143
+ border-radius: 6px;
1144
+ background: #f8fafc;
1145
+ overflow: hidden;
1146
+ margin: 4px 0;
1147
+ }
1148
+ .lite-code-header {
1149
+ padding: 4px 10px;
1150
+ background: #f1f5f9;
1151
+ border-bottom: 1px solid #e2e8f0;
1152
+ font-size: 11px;
1153
+ }
1154
+ .lite-code-pre {
1155
+ margin: 0;
1156
+ padding: 10px 12px;
1157
+ font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
1158
+ font-size: 12px;
1159
+ line-height: 1.5;
1160
+ overflow-x: auto;
1161
+ overflow-y: auto;
1162
+ color: #0f172a;
1163
+ }
1164
+
1165
+ /* ─── Copy Field ───────────────────────────────────────────── */
1166
+ .lite-copy-field {
1167
+ display: inline-flex;
1168
+ align-items: center;
1169
+ }
1170
+ .lite-copy-text {
1171
+ font-size: 13px;
1172
+ color: #0f172a;
1173
+ }
1174
+
1175
+ /* ─── Currency & Numbers ───────────────────────────────────── */
1176
+ .lite-currency-field {
1177
+ display: inline-flex;
1178
+ align-items: center;
1179
+ font-size: 13px;
1180
+ }
1181
+
1182
+ /* ─── Date Range ───────────────────────────────────────────── */
1183
+ .lite-date-range {
1184
+ display: inline-flex;
1185
+ align-items: center;
1186
+ font-size: 13px;
1187
+ }
1188
+
1189
+ /* ─── Percentage & Progress ────────────────────────────────── */
1190
+ .lite-percent-container {
1191
+ display: inline-flex;
1192
+ align-items: center;
1193
+ }
1194
+ .lite-progress-track {
1195
+ display: inline-block;
1196
+ width: 64px;
1197
+ height: 6px;
1198
+ background: #e2e8f0;
1199
+ border-radius: 3px;
1200
+ overflow: hidden;
1201
+ margin-left: 8px;
1202
+ vertical-align: middle;
1203
+ }
1204
+ .lite-progress-fill {
1205
+ display: block;
1206
+ height: 100%;
1207
+ background: #4f46e5;
1208
+ border-radius: 3px;
1209
+ }
1210
+ .lite-progress-success { background: #22c55e; }
1211
+ .lite-progress-warning { background: #f59e0b; }
1212
+ .lite-progress-danger { background: #ef4444; }
1213
+ .lite-progress-info { background: #3b82f6; }
1214
+
1215
+ /* ─── Phone Field ──────────────────────────────────────────── */
1216
+ .lite-phone-container {
1217
+ display: inline-flex;
1218
+ align-items: center;
1219
+ font-size: 13px;
1220
+ }
1221
+ .lite-phone-icon {
1222
+ margin-right: 6px;
1223
+ font-size: 12px;
1224
+ }
1225
+ .lite-phone-link {
1226
+ color: #4f46e5;
1227
+ font-weight: 500;
1228
+ text-decoration: none;
1229
+ }
1230
+ .lite-phone-link:hover {
1231
+ text-decoration: underline;
1232
+ }
1233
+
1234
+ /* ─── Rating Field ─────────────────────────────────────────── */
1235
+ .lite-rating-container {
1236
+ display: inline-flex;
1237
+ align-items: center;
1238
+ }
1239
+ .lite-rating {
1240
+ display: inline-flex;
1241
+ align-items: center;
1242
+ }
1243
+ .lite-rating-star {
1244
+ display: inline-block;
1245
+ margin-right: 2px;
1246
+ line-height: 1;
1247
+ }
1248
+ .lite-rating-star-full, .lite-rating-star-half {
1249
+ color: #f59e0b;
1250
+ }
1251
+ .lite-rating-star-empty {
1252
+ color: #cbd5e1;
1253
+ }
1254
+ .lite-rating-sm { font-size: 12px; }
1255
+ .lite-rating-default { font-size: 14px; }
1256
+ .lite-rating-lg { font-size: 18px; }
1257
+ .lite-rating-value {
1258
+ margin-left: 6px;
1259
+ font-size: 13px;
1260
+ color: #0f172a;
1261
+ font-weight: 500;
1262
+ }
1263
+
1264
+ /* ─── Semantic Tone Utilities ──────────────────────────────── */
1265
+ .lite-font-mono {
1266
+ font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
1267
+ }
1268
+ .lite-text-success { color: #16a34a; font-weight: 500; }
1269
+ .lite-text-warning { color: #d97706; font-weight: 500; }
1270
+ .lite-text-danger { color: #dc2626; font-weight: 500; }
1271
+ .lite-text-info { color: #2563eb; font-weight: 500; }
1272
+ .lite-text-primary { color: #4f46e5; font-weight: 500; }
1273
+
1069
1274
  /* ─── Responsive ───────────────────────────────────────────── */
1070
1275
  @media (max-width: 768px) {
1071
1276
  .lite-wrapper {
@@ -49,6 +49,7 @@ function coerceAndValidateField(field, value, mode, withinArray = false, path =
49
49
  const issues = [];
50
50
  let coerced = value;
51
51
  switch (field.type) {
52
+ case "currency":
52
53
  case "number": {
53
54
  if (coerced === undefined || coerced === null || coerced === "") {
54
55
  coerced = undefined;
@@ -57,7 +58,7 @@ function coerceAndValidateField(field, value, mode, withinArray = false, path =
57
58
  }
58
59
  }
59
60
  else if (typeof coerced === "string") {
60
- const trimmed = coerced.trim();
61
+ const trimmed = coerced.trim().replace(/^[$€£¥₹]/u, "");
61
62
  if (trimmed === "") {
62
63
  coerced = undefined;
63
64
  if (field.required) {
@@ -251,7 +252,7 @@ function coerceAndValidateField(field, value, mode, withinArray = false, path =
251
252
  }
252
253
  case "phone": {
253
254
  if (typeof coerced === "string" && coerced.length > 0) {
254
- if (!/^[+\d\s()-]*$/.test(coerced)) {
255
+ if (!/^[+\d\s()-]*$/u.test(coerced)) {
255
256
  issues.push({ path, message: `${field.label} must be a valid phone number` });
256
257
  }
257
258
  }
@@ -309,7 +310,13 @@ function coerceAndValidateField(field, value, mode, withinArray = false, path =
309
310
  break;
310
311
  }
311
312
  // Check required
312
- if (field.type !== "number" && field.type !== "boolean" && field.type !== "array" && field.type !== "file" && field.type !== "image" && field.type !== "images") {
313
+ if (field.type !== "number"
314
+ && field.type !== "currency"
315
+ && field.type !== "boolean"
316
+ && field.type !== "array"
317
+ && field.type !== "file"
318
+ && field.type !== "image"
319
+ && field.type !== "images") {
313
320
  if (field.required && !hasRequiredValue(coerced)) {
314
321
  issues.push({ path, message: `${field.label} is required` });
315
322
  }
@@ -339,6 +346,7 @@ export function fieldsToTypeBoxSchema(fields, mode = "create") {
339
346
  activeFields.push(field);
340
347
  switch (field.type) {
341
348
  case "number":
349
+ case "currency":
342
350
  shape[field.key] = field.required ? Type.Number() : Type.Optional(Type.Number());
343
351
  break;
344
352
  case "boolean":
@@ -434,7 +442,9 @@ export const resourceToZodSchema = resourceToTypeBoxSchema;
434
442
  */
435
443
  export function fieldToInputType(field) {
436
444
  switch (field.type) {
437
- case "number": return "text";
445
+ case "number":
446
+ case "currency": return "text";
447
+ case "color": return "color";
438
448
  case "email": return "text";
439
449
  case "url": return "text";
440
450
  case "phone": return "tel";
@@ -464,6 +474,7 @@ export function fieldToPlaceholder(field) {
464
474
  case "url": return "https://example.com";
465
475
  case "phone": return "+1 (555) 000-0000";
466
476
  case "number": return "0";
477
+ case "currency": return "0.00";
467
478
  default: return "";
468
479
  }
469
480
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@svadmin/lite",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "SSR-first lightweight admin UI for @svadmin with optional progressive enhancement",
5
5
  "type": "module",
6
6
  "sideEffects": [
@@ -49,7 +49,7 @@
49
49
  },
50
50
  "peerDependencies": {
51
51
  "svelte": "^5.56.10",
52
- "@svadmin/core": ">=0.34.2 <0.46.0",
52
+ "@svadmin/core": ">=0.34.2 <0.47.0",
53
53
  "@sveltejs/kit": "^2.70.3"
54
54
  },
55
55
  "dependencies": {
@@ -70,7 +70,8 @@
70
70
  "test": "bun run test:components && bun run test:server && bun run test:security",
71
71
  "test:components": "vitest run --config ./vitest.config.ts",
72
72
  "test:server": "bun test ./src/schema-generator.test.ts ./src/server-adapter.test.ts ./src/fragment-id.test.ts ./src/compatibility.test.ts ./src/ie11-ssr-contract.test.ts",
73
- "test:security": "vitest run --config ./src/security.test.config.ts"
73
+ "test:security": "vitest run --config ./src/security.test.config.ts",
74
+ "check:parity": "bun ../../scripts/check-parity.ts --write"
74
75
  },
75
76
  "license": "MIT",
76
77
  "publishConfig": {