@type32/yaml-editor-form 0.1.4 → 0.1.5

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/README.md CHANGED
@@ -112,6 +112,7 @@ const customTypes: YamlFieldType[] = [
112
112
  label: 'Image',
113
113
  icon: 'i-lucide-image',
114
114
  defaultValue: '',
115
+ baseType: 'string',
115
116
  component: 'image'
116
117
  }
117
118
  ]
@@ -477,6 +478,7 @@ export const DEFAULT_FIELD_TYPES: YamlFieldType[] = [
477
478
  label: 'Email',
478
479
  icon: 'i-lucide-mail',
479
480
  defaultValue: '',
481
+ baseType: 'string',
480
482
  detect: (value) => typeof value === 'string' && /^[^@]+@[^@]+/.test(value)
481
483
  }
482
484
  ]
@@ -497,6 +499,7 @@ const customTypes: YamlFieldType[] = [
497
499
  label: 'URL',
498
500
  icon: 'i-lucide-link',
499
501
  defaultValue: 'https://',
502
+ baseType: 'string',
500
503
  detect: (value) => typeof value === 'string' && value.startsWith('http')
501
504
  }
502
505
  ]
@@ -545,6 +548,7 @@ const customTypes: YamlFieldType[] = [
545
548
  label: 'Rich Text',
546
549
  icon: 'i-lucide-file-text',
547
550
  defaultValue: '',
551
+ baseType: 'string',
548
552
  component: 'richtext' // Now uses custom component
549
553
  }
550
554
  ]
@@ -693,6 +697,7 @@ const customTypes: YamlFieldType[] = [
693
697
  label: 'Image',
694
698
  icon: 'i-lucide-image',
695
699
  defaultValue: '',
700
+ baseType: 'string',
696
701
  component: 'image'
697
702
  },
698
703
  {
@@ -700,6 +705,7 @@ const customTypes: YamlFieldType[] = [
700
705
  label: 'Markdown',
701
706
  icon: 'i-lucide-file-text',
702
707
  defaultValue: '',
708
+ baseType: 'string',
703
709
  component: 'markdown'
704
710
  }
705
711
  ]
@@ -744,13 +750,15 @@ const customTypes: YamlFieldType[] = [
744
750
  label: 'UUID',
745
751
  icon: 'i-lucide-fingerprint',
746
752
  defaultValue: () => crypto.randomUUID(), // Function called each time
753
+ baseType: 'string',
747
754
  detect: (v) => /^[0-9a-f]{8}-[0-9a-f]{4}-/.test(v)
748
755
  },
749
756
  {
750
757
  type: 'timestamp',
751
758
  label: 'Timestamp',
752
759
  icon: 'i-lucide-clock',
753
- defaultValue: () => new Date().toISOString()
760
+ defaultValue: () => new Date().toISOString(),
761
+ baseType: 'string'
754
762
  }
755
763
  ]
756
764
  </script>
@@ -834,6 +842,7 @@ types/
834
842
  label: 'My Type',
835
843
  icon: 'i-lucide-my-icon',
836
844
  defaultValue: 'default',
845
+ baseType: 'string', // Required: specify base type for conversions
837
846
  detect: (value) => /* detection logic */
838
847
  }
839
848
  ```
@@ -1169,6 +1178,320 @@ Requires:
1169
1178
  - reka-ui (via Nuxt UI)
1170
1179
  - tailwindcss (via Nuxt)
1171
1180
 
1181
+ ## Advanced Examples
1182
+
1183
+ ### Custom String Array Type
1184
+
1185
+ Here's an example of a custom string array type with autocomplete suggestions:
1186
+
1187
+ ```vue
1188
+ <script setup lang="ts">
1189
+ import type { YamlFieldType } from '@type32/yaml-editor-form'
1190
+
1191
+ const customTypes: YamlFieldType[] = [
1192
+ {
1193
+ type: 'skills',
1194
+ label: 'Skills',
1195
+ icon: 'i-lucide-sparkles',
1196
+ defaultValue: [],
1197
+ baseType: 'string-array', // Inherits array conversions
1198
+ component: 'skills',
1199
+ detect: (value) => {
1200
+ // Auto-detect arrays with skill-like strings
1201
+ return Array.isArray(value) &&
1202
+ value.length > 0 &&
1203
+ value.every(v => typeof v === 'string' && v.length < 30)
1204
+ }
1205
+ }
1206
+ ]
1207
+
1208
+ const profile = ref({
1209
+ name: 'John Doe',
1210
+ skills: ['Vue.js', 'TypeScript', 'Nuxt']
1211
+ })
1212
+
1213
+ // Predefined skill suggestions
1214
+ const skillSuggestions = [
1215
+ 'Vue.js', 'React', 'Angular', 'TypeScript', 'JavaScript',
1216
+ 'Node.js', 'Python', 'Nuxt', 'Next.js', 'Tailwind CSS'
1217
+ ]
1218
+ </script>
1219
+
1220
+ <template>
1221
+ <YamlFormEditor v-model="profile" :field-types="customTypes">
1222
+ <!-- Custom skills input with autocomplete -->
1223
+ <template #field-skills="{ modelValue, readonly, updateModelValue }">
1224
+ <div class="space-y-2">
1225
+ <!-- Display current skills as badges -->
1226
+ <div class="flex flex-wrap gap-2">
1227
+ <UBadge
1228
+ v-for="(skill, index) in (modelValue as string[])"
1229
+ :key="index"
1230
+ color="primary"
1231
+ variant="soft"
1232
+ >
1233
+ {{ skill }}
1234
+ <UButton
1235
+ v-if="!readonly"
1236
+ icon="i-lucide-x"
1237
+ size="2xs"
1238
+ variant="ghost"
1239
+ :padded="false"
1240
+ @click="updateModelValue((modelValue as string[]).filter((_, i) => i !== index))"
1241
+ />
1242
+ </UBadge>
1243
+ </div>
1244
+
1245
+ <!-- Add new skill with autocomplete -->
1246
+ <UInputMenu
1247
+ v-if="!readonly"
1248
+ :options="skillSuggestions"
1249
+ placeholder="Add skill..."
1250
+ @update:model-value="(newSkill: string) => {
1251
+ if (newSkill && !(modelValue as string[]).includes(newSkill)) {
1252
+ updateModelValue([...(modelValue as string[]), newSkill])
1253
+ }
1254
+ }"
1255
+ />
1256
+ </div>
1257
+ </template>
1258
+ </YamlFormEditor>
1259
+ </template>
1260
+ ```
1261
+
1262
+ ### Custom Object Array Type
1263
+
1264
+ Here's an example of a custom object array type with card-based rendering:
1265
+
1266
+ ```vue
1267
+ <script setup lang="ts">
1268
+ import type { YamlFieldType } from '@type32/yaml-editor-form'
1269
+
1270
+ const customTypes: YamlFieldType[] = [
1271
+ {
1272
+ type: 'contacts',
1273
+ label: 'Contacts',
1274
+ icon: 'i-lucide-users',
1275
+ defaultValue: [],
1276
+ baseType: 'array', // Inherits array conversions
1277
+ component: 'contacts',
1278
+ detect: (value) => {
1279
+ // Auto-detect arrays of contact-like objects
1280
+ return Array.isArray(value) &&
1281
+ value.length > 0 &&
1282
+ value.every(v =>
1283
+ v && typeof v === 'object' &&
1284
+ ('name' in v || 'email' in v)
1285
+ )
1286
+ }
1287
+ }
1288
+ ]
1289
+
1290
+ const data = ref({
1291
+ projectName: 'My Project',
1292
+ contacts: [
1293
+ { name: 'Alice Johnson', email: 'alice@example.com', role: 'Designer' },
1294
+ { name: 'Bob Smith', email: 'bob@example.com', role: 'Developer' }
1295
+ ]
1296
+ })
1297
+ </script>
1298
+
1299
+ <template>
1300
+ <YamlFormEditor v-model="data" :field-types="customTypes">
1301
+ <!-- Custom contacts list with card UI -->
1302
+ <template #field-contacts="{ modelValue, readonly, updateModelValue }">
1303
+ <div class="space-y-3">
1304
+ <!-- Contact cards -->
1305
+ <UCard
1306
+ v-for="(contact, index) in (modelValue as any[])"
1307
+ :key="index"
1308
+ :ui="{ body: { padding: 'p-4' } }"
1309
+ >
1310
+ <div class="flex items-start justify-between gap-3">
1311
+ <div class="flex-1 space-y-2">
1312
+ <!-- Name -->
1313
+ <UInput
1314
+ :model-value="contact.name"
1315
+ placeholder="Name"
1316
+ :disabled="readonly"
1317
+ @update:model-value="(val: string) => {
1318
+ const updated = [...(modelValue as any[])]
1319
+ updated[index] = { ...contact, name: val }
1320
+ updateModelValue(updated)
1321
+ }"
1322
+ />
1323
+
1324
+ <!-- Email -->
1325
+ <UInput
1326
+ :model-value="contact.email"
1327
+ type="email"
1328
+ placeholder="Email"
1329
+ icon="i-lucide-mail"
1330
+ :disabled="readonly"
1331
+ @update:model-value="(val: string) => {
1332
+ const updated = [...(modelValue as any[])]
1333
+ updated[index] = { ...contact, email: val }
1334
+ updateModelValue(updated)
1335
+ }"
1336
+ />
1337
+
1338
+ <!-- Role -->
1339
+ <UInput
1340
+ :model-value="contact.role"
1341
+ placeholder="Role"
1342
+ icon="i-lucide-briefcase"
1343
+ :disabled="readonly"
1344
+ @update:model-value="(val: string) => {
1345
+ const updated = [...(modelValue as any[])]
1346
+ updated[index] = { ...contact, role: val }
1347
+ updateModelValue(updated)
1348
+ }"
1349
+ />
1350
+ </div>
1351
+
1352
+ <!-- Remove button -->
1353
+ <UButton
1354
+ v-if="!readonly"
1355
+ icon="i-lucide-trash-2"
1356
+ color="red"
1357
+ variant="ghost"
1358
+ size="sm"
1359
+ @click="updateModelValue((modelValue as any[]).filter((_, i) => i !== index))"
1360
+ />
1361
+ </div>
1362
+ </UCard>
1363
+
1364
+ <!-- Add contact button -->
1365
+ <UButton
1366
+ v-if="!readonly"
1367
+ icon="i-lucide-plus"
1368
+ label="Add Contact"
1369
+ variant="outline"
1370
+ block
1371
+ @click="updateModelValue([
1372
+ ...(modelValue as any[]),
1373
+ { name: '', email: '', role: '' }
1374
+ ])"
1375
+ />
1376
+ </div>
1377
+ </template>
1378
+ </YamlFormEditor>
1379
+ </template>
1380
+ ```
1381
+
1382
+ ### Combined Example
1383
+
1384
+ You can use both custom array types together:
1385
+
1386
+ ```vue
1387
+ <script setup lang="ts">
1388
+ import type { YamlFieldType } from '@type32/yaml-editor-form'
1389
+
1390
+ const customTypes: YamlFieldType[] = [
1391
+ // Custom string array
1392
+ {
1393
+ type: 'tags',
1394
+ label: 'Tags',
1395
+ icon: 'i-lucide-tag',
1396
+ defaultValue: [],
1397
+ baseType: 'string-array',
1398
+ component: 'tags',
1399
+ detect: (v) => Array.isArray(v) && v.every(i => typeof i === 'string')
1400
+ },
1401
+ // Custom object array
1402
+ {
1403
+ type: 'team',
1404
+ label: 'Team Members',
1405
+ icon: 'i-lucide-users',
1406
+ defaultValue: [],
1407
+ baseType: 'array',
1408
+ component: 'team',
1409
+ detect: (v) => Array.isArray(v) && v.every(i => i?.name || i?.email)
1410
+ }
1411
+ ]
1412
+
1413
+ const project = ref({
1414
+ name: 'Website Redesign',
1415
+ tags: ['frontend', 'design', 'urgent'],
1416
+ team: [
1417
+ { name: 'Alice', email: 'alice@example.com' },
1418
+ { name: 'Bob', email: 'bob@example.com' }
1419
+ ]
1420
+ })
1421
+ </script>
1422
+
1423
+ <template>
1424
+ <YamlFormEditor v-model="project" :field-types="customTypes">
1425
+ <!-- String array implementation -->
1426
+ <template #field-tags="{ modelValue, readonly, updateModelValue }">
1427
+ <UInputTags
1428
+ :model-value="modelValue as string[]"
1429
+ :disabled="readonly"
1430
+ placeholder="Add tags..."
1431
+ @update:model-value="updateModelValue"
1432
+ />
1433
+ </template>
1434
+
1435
+ <!-- Object array implementation -->
1436
+ <template #field-team="{ modelValue, readonly, updateModelValue }">
1437
+ <!-- Your custom team member UI here -->
1438
+ <div class="space-y-2">
1439
+ <div
1440
+ v-for="(member, idx) in (modelValue as any[])"
1441
+ :key="idx"
1442
+ class="flex gap-2"
1443
+ >
1444
+ <UInput
1445
+ :model-value="member.name"
1446
+ placeholder="Name"
1447
+ :disabled="readonly"
1448
+ @update:model-value="(val: string) => {
1449
+ const updated = [...(modelValue as any[])]
1450
+ updated[idx] = { ...member, name: val }
1451
+ updateModelValue(updated)
1452
+ }"
1453
+ />
1454
+ <UButton
1455
+ v-if="!readonly"
1456
+ icon="i-lucide-x"
1457
+ color="red"
1458
+ variant="ghost"
1459
+ @click="updateModelValue((modelValue as any[]).filter((_, i) => i !== idx))"
1460
+ />
1461
+ </div>
1462
+ <UButton
1463
+ v-if="!readonly"
1464
+ icon="i-lucide-plus"
1465
+ label="Add Member"
1466
+ size="sm"
1467
+ @click="updateModelValue([...(modelValue as any[]), { name: '', email: '' }])"
1468
+ />
1469
+ </div>
1470
+ </template>
1471
+ </YamlFormEditor>
1472
+ </template>
1473
+ ```
1474
+
1475
+ ### Key Patterns for Array Types
1476
+
1477
+ **String Arrays (`baseType: 'string-array'`):**
1478
+ - Use for specialized tag inputs, category lists, etc.
1479
+ - Can convert to/from regular arrays and strings
1480
+ - Good for: skills, tags, categories, keywords
1481
+
1482
+ **Object Arrays (`baseType: 'array'`):**
1483
+ - Use for collections with structured data
1484
+ - Provide custom UI for adding/editing/removing items
1485
+ - Good for: contacts, team members, products, events
1486
+
1487
+ **Important Notes:**
1488
+ 1. **Type Assertions**: Use `(modelValue as string[])` or `(modelValue as any[])` for type safety
1489
+ 2. **Immutability**: Always create new arrays when updating (spread operator `[...]`)
1490
+ 3. **Index Management**: Track items by index for updates/deletions
1491
+ 4. **Add Operations**: Spread existing array and add new items
1492
+ 5. **Remove Operations**: Use `filter()` to remove by index
1493
+ 6. **Update Operations**: Clone array, modify specific index, update entire array
1494
+
1172
1495
  ## License
1173
1496
 
1174
1497
  This component is part of the Vertex project.
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@type32/yaml-editor-form",
3
3
  "configKey": "yamlEditorForm",
4
- "version": "0.1.4",
4
+ "version": "0.1.5",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "3.6.1"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@type32/yaml-editor-form",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "YAML Editor Form Component for Nuxt.",
5
5
  "repository": "https://github.com/CTRL-Neo-Studios/yaml-editor-form",
6
6
  "license": "MIT",