@ng-forge/dynamic-form-mcp 0.8.0-next.4 → 0.8.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.
package/bin/ng-forge-mcp.js
CHANGED
|
@@ -49,6 +49,12 @@ var FIELD_TYPES = [
|
|
|
49
49
|
description: "Number of visible text lines",
|
|
50
50
|
required: false,
|
|
51
51
|
default: 3
|
|
52
|
+
},
|
|
53
|
+
cols: {
|
|
54
|
+
name: "cols",
|
|
55
|
+
type: "number",
|
|
56
|
+
description: "Number of visible columns",
|
|
57
|
+
required: false
|
|
52
58
|
}
|
|
53
59
|
},
|
|
54
60
|
validationSupported: true,
|
|
@@ -59,6 +65,7 @@ var FIELD_TYPES = [
|
|
|
59
65
|
type: 'textarea',
|
|
60
66
|
label: 'Description',
|
|
61
67
|
placeholder: 'Enter description...',
|
|
68
|
+
maxLength: 500,
|
|
62
69
|
props: { rows: 5 }
|
|
63
70
|
}`,
|
|
64
71
|
minimalExample: `{ key: 'bio', type: 'textarea', label: 'Bio' }`
|
|
@@ -333,17 +340,20 @@ var FIELD_TYPES = [
|
|
|
333
340
|
fields: {
|
|
334
341
|
name: "fields",
|
|
335
342
|
type: "RowAllowedChildren[]",
|
|
336
|
-
description: "Child fields to render horizontally. Allowed: groups, arrays,
|
|
343
|
+
description: "Child fields to render horizontally. Allowed: groups, arrays, containers, nested rows, hidden fields, and value fields (input, select, etc). NOT ALLOWED: pages",
|
|
337
344
|
required: true
|
|
338
345
|
}
|
|
339
346
|
},
|
|
340
347
|
validationSupported: false,
|
|
341
348
|
source: "core",
|
|
342
|
-
allowedIn: ["top-level", "page", "group", "array"],
|
|
343
|
-
notAllowedIn: [
|
|
349
|
+
allowedIn: ["top-level", "page", "group", "array", "row", "container"],
|
|
350
|
+
notAllowedIn: [],
|
|
344
351
|
canContain: [
|
|
345
352
|
"group",
|
|
346
353
|
"array",
|
|
354
|
+
"container",
|
|
355
|
+
"row",
|
|
356
|
+
"hidden",
|
|
347
357
|
"input",
|
|
348
358
|
"textarea",
|
|
349
359
|
"select",
|
|
@@ -359,7 +369,7 @@ var FIELD_TYPES = [
|
|
|
359
369
|
"next",
|
|
360
370
|
"previous"
|
|
361
371
|
],
|
|
362
|
-
cannotContain: ["page"
|
|
372
|
+
cannotContain: ["page"],
|
|
363
373
|
example: `{
|
|
364
374
|
key: 'nameRow',
|
|
365
375
|
type: 'row',
|
|
@@ -371,9 +381,7 @@ var FIELD_TYPES = [
|
|
|
371
381
|
]
|
|
372
382
|
}
|
|
373
383
|
// NOT ALLOWED in rows:
|
|
374
|
-
// - type: '
|
|
375
|
-
// - type: 'page' (pages are top-level only)
|
|
376
|
-
// - type: 'row' (no nested rows)`,
|
|
384
|
+
// - type: 'page' (pages are top-level only)`,
|
|
377
385
|
minimalExample: `{ key: 'row1', type: 'row', fields: [...] }`
|
|
378
386
|
},
|
|
379
387
|
{
|
|
@@ -1105,30 +1113,12 @@ var UI_ADAPTERS = [
|
|
|
1105
1113
|
description: "Hint text below the field",
|
|
1106
1114
|
required: false
|
|
1107
1115
|
},
|
|
1108
|
-
rows: {
|
|
1109
|
-
name: "rows",
|
|
1110
|
-
type: "number",
|
|
1111
|
-
description: "Visible row count",
|
|
1112
|
-
required: false
|
|
1113
|
-
},
|
|
1114
|
-
cols: {
|
|
1115
|
-
name: "cols",
|
|
1116
|
-
type: "number",
|
|
1117
|
-
description: "Visible column count",
|
|
1118
|
-
required: false
|
|
1119
|
-
},
|
|
1120
1116
|
resize: {
|
|
1121
1117
|
name: "resize",
|
|
1122
1118
|
type: "'none' | 'both' | 'horizontal' | 'vertical'",
|
|
1123
1119
|
description: "Resize handle behavior",
|
|
1124
1120
|
required: false,
|
|
1125
1121
|
default: "vertical"
|
|
1126
|
-
},
|
|
1127
|
-
maxLength: {
|
|
1128
|
-
name: "maxLength",
|
|
1129
|
-
type: "number",
|
|
1130
|
-
description: "Maximum character length",
|
|
1131
|
-
required: false
|
|
1132
1122
|
}
|
|
1133
1123
|
}
|
|
1134
1124
|
}
|
|
@@ -5339,7 +5329,6 @@ var PrimeDatepickerPropsSchema = PrimeCommonPropsSchema.extend({
|
|
|
5339
5329
|
var PrimeTextareaPropsSchema = PrimeCommonPropsSchema.extend({
|
|
5340
5330
|
rows: z47.number().positive().optional(),
|
|
5341
5331
|
autoResize: z47.boolean().optional(),
|
|
5342
|
-
maxlength: z47.number().positive().optional(),
|
|
5343
5332
|
placeholder: DynamicTextSchema.optional()
|
|
5344
5333
|
});
|
|
5345
5334
|
var PrimeSliderPropsSchema = PrimeCommonPropsSchema.extend({
|
|
@@ -5524,9 +5513,8 @@ var IonicInputPropsSchema = z51.object({
|
|
|
5524
5513
|
hint: DynamicTextSchema.optional(),
|
|
5525
5514
|
errorText: DynamicTextSchema.optional(),
|
|
5526
5515
|
counter: z51.boolean().optional(),
|
|
5527
|
-
maxlength: z51.number().positive().optional(),
|
|
5528
5516
|
clearInput: z51.boolean().optional(),
|
|
5529
|
-
type: z51.enum(["text", "email", "password", "number", "tel", "url"]).optional(),
|
|
5517
|
+
type: z51.enum(["text", "email", "password", "number", "tel", "url", "search"]).optional(),
|
|
5530
5518
|
placeholder: DynamicTextSchema.optional()
|
|
5531
5519
|
});
|
|
5532
5520
|
var IonicCheckboxPropsSchema = z51.object({
|
|
@@ -5591,7 +5579,6 @@ var IonicSelectPropsSchema = z51.object({
|
|
|
5591
5579
|
var IonicTextareaPropsSchema = z51.object({
|
|
5592
5580
|
rows: z51.number().positive().optional(),
|
|
5593
5581
|
autoGrow: z51.boolean().optional(),
|
|
5594
|
-
maxlength: z51.number().positive().optional(),
|
|
5595
5582
|
counter: z51.boolean().optional(),
|
|
5596
5583
|
fill: z51.enum(["solid", "outline"]).optional(),
|
|
5597
5584
|
shape: z51.literal("round").optional(),
|
|
@@ -6933,10 +6920,8 @@ Included in form value but not rendered.
|
|
|
6933
6920
|
|
|
6934
6921
|
Use \`col\` (1-12) on child fields for grid width. Row is purely for layout. Supports only \`hidden\` logic type for conditional visibility.
|
|
6935
6922
|
|
|
6936
|
-
**Allowed children:** groups, arrays, value fields (input, select, checkbox, etc.)
|
|
6937
|
-
**NOT allowed:** \`
|
|
6938
|
-
|
|
6939
|
-
\u26A0\uFE0F **Common mistake:** Putting hidden fields inside rows - hidden fields should be at page or form level, not in rows.`
|
|
6923
|
+
**Allowed children:** groups, arrays, containers, nested rows, hidden fields, value fields (input, select, checkbox, etc.)
|
|
6924
|
+
**NOT allowed:** \`page\` containers`
|
|
6940
6925
|
},
|
|
6941
6926
|
array: {
|
|
6942
6927
|
brief: `**Two APIs available:**
|
|
@@ -7352,8 +7337,15 @@ logic: [{ type: 'derivation', expression: '...', stopOnUserOverride: true, reEng
|
|
|
7352
7337
|
|
|
7353
7338
|
// HTTP derivation (server-driven values)
|
|
7354
7339
|
logic: [{ type: 'derivation', source: 'http', http: { url: '/api/rate', queryParams: { from: 'formValue.currency' } }, responseExpression: 'response.rate', dependsOn: ['currency'] }]
|
|
7340
|
+
|
|
7341
|
+
// Self-dependency token: $self resolves to the field's own absolute path at collection time
|
|
7342
|
+
logic: [{ type: 'derivation', functionName: 'uppercase', dependsOn: ['$self'] }]
|
|
7343
|
+
|
|
7344
|
+
// Parent-container token: $group resolves to the field's nearest parent group/array path
|
|
7345
|
+
logic: [{ type: 'derivation', functionName: 'computeFromGroup', dependsOn: ['$group'] }]
|
|
7355
7346
|
\`\`\`
|
|
7356
7347
|
Derivation is always defined ON the field that receives the computed value (self-targeting).
|
|
7348
|
+
\`dependsOn\` paths are absolute from the form root (e.g. \`'address.state'\`). Use \`'$self'\` for the field's own absolute path and \`'$group'\` for its nearest parent group/array \u2014 both useful in factory-built fields where ancestor keys aren't known at config time.
|
|
7357
7349
|
**Variables:** \`formValue\`, \`fieldValue\`, \`fieldState\`, \`formFieldState\`, \`externalData\` (see topic: expression-variables)
|
|
7358
7350
|
**For deriving component properties** (minDate, options, label): use \`targetProperty\` (see topic \`property-derivation\`)`,
|
|
7359
7351
|
full: `# Value Derivation (Computed Fields)
|
|
@@ -7417,6 +7409,98 @@ Derivations are always defined ON the field that receives the computed value (se
|
|
|
7417
7409
|
}
|
|
7418
7410
|
\`\`\`
|
|
7419
7411
|
|
|
7412
|
+
## \`dependsOn\` Path Resolution
|
|
7413
|
+
|
|
7414
|
+
\`dependsOn\` paths are **absolute from the form root**, dotted notation. A field nested under a group has the group's key in its path:
|
|
7415
|
+
|
|
7416
|
+
\`\`\`typescript
|
|
7417
|
+
{
|
|
7418
|
+
type: 'group', key: 'address',
|
|
7419
|
+
fields: [
|
|
7420
|
+
{ key: 'state', type: 'input', logic: [{
|
|
7421
|
+
type: 'derivation',
|
|
7422
|
+
functionName: 'uppercaseState',
|
|
7423
|
+
dependsOn: ['address.state'] // absolute path from root
|
|
7424
|
+
}]}
|
|
7425
|
+
]
|
|
7426
|
+
}
|
|
7427
|
+
\`\`\`
|
|
7428
|
+
|
|
7429
|
+
Layout containers (\`page\`, \`row\`, \`container\`) do **not** contribute to the path \u2014 only \`group\` fields do. Array fields use the \`'arrayKey.$.fieldKey'\` placeholder convention.
|
|
7430
|
+
|
|
7431
|
+
### \`$self\` token
|
|
7432
|
+
|
|
7433
|
+
Use \`'$self'\` in \`dependsOn\` to refer to the field's own absolute path. Useful for self-derivations on fields built by factory helpers, where the ancestor group keys aren't known at config-authoring time:
|
|
7434
|
+
|
|
7435
|
+
\`\`\`typescript
|
|
7436
|
+
{
|
|
7437
|
+
type: 'group', key: 'address',
|
|
7438
|
+
fields: [
|
|
7439
|
+
{ key: 'state', type: 'input', logic: [{
|
|
7440
|
+
type: 'derivation',
|
|
7441
|
+
functionName: 'uppercaseState',
|
|
7442
|
+
dependsOn: ['$self'] // resolves to 'address.state' at collection time
|
|
7443
|
+
}]}
|
|
7444
|
+
]
|
|
7445
|
+
}
|
|
7446
|
+
\`\`\`
|
|
7447
|
+
|
|
7448
|
+
\`$self\` works alongside other absolute deps and inside arrays (resolves to the array placeholder form, e.g. \`'items.$.name'\`).
|
|
7449
|
+
|
|
7450
|
+
### \`$group\` token
|
|
7451
|
+
|
|
7452
|
+
Use \`'$group'\` in \`dependsOn\` to refer to the field's **nearest parent container** (group or array). The derivation fires whenever any sibling under the same parent changes \u2014 handy when you don't want to enumerate each sibling explicitly:
|
|
7453
|
+
|
|
7454
|
+
\`\`\`typescript
|
|
7455
|
+
{
|
|
7456
|
+
type: 'group', key: 'address',
|
|
7457
|
+
fields: [
|
|
7458
|
+
{ key: 'country', type: 'input' },
|
|
7459
|
+
{ key: 'state', type: 'input', logic: [{
|
|
7460
|
+
type: 'derivation',
|
|
7461
|
+
functionName: 'pickStateFromCountry',
|
|
7462
|
+
dependsOn: ['$group'] // resolves to 'address' at collection time
|
|
7463
|
+
}]}
|
|
7464
|
+
]
|
|
7465
|
+
}
|
|
7466
|
+
\`\`\`
|
|
7467
|
+
|
|
7468
|
+
Resolution rules:
|
|
7469
|
+
- Inside group(s) only \u2192 the dotted ancestor group path (\`'address'\` or \`'org.address'\`).
|
|
7470
|
+
- Directly inside an array \u2192 the array key (\`'items'\`). Fires on any item change.
|
|
7471
|
+
- Inside group(s) inside an array \u2192 \`'items.$.address'\` form.
|
|
7472
|
+
- At form root \u2192 throws \`DynamicFormError\` (no parent container exists).
|
|
7473
|
+
|
|
7474
|
+
### Token prefix substitution
|
|
7475
|
+
|
|
7476
|
+
Both \`$self\` and \`$group\` accept a dotted suffix that is appended to the resolved path:
|
|
7477
|
+
|
|
7478
|
+
\`\`\`typescript
|
|
7479
|
+
dependsOn: ['$group.country'] // resolves to 'address.country' inside group 'address'
|
|
7480
|
+
dependsOn: ['$group.contact.email'] // multi-segment suffix supported
|
|
7481
|
+
dependsOn: ['$self.flag'] // resolves to '<fieldKey>.flag' (object-valued fields)
|
|
7482
|
+
\`\`\`
|
|
7483
|
+
|
|
7484
|
+
Use this to target a specific sibling without naming the parent group key \u2014 handy in factory-built field shapes.
|
|
7485
|
+
|
|
7486
|
+
### \`groupValue\` in evaluation context
|
|
7487
|
+
|
|
7488
|
+
Custom derivation functions and expressions receive a \`groupValue\` on the \`EvaluationContext\` that mirrors the \`$group\` token at evaluation time:
|
|
7489
|
+
|
|
7490
|
+
\`\`\`typescript
|
|
7491
|
+
deriveStateFromCountry: (ctx) => {
|
|
7492
|
+
const country = ctx.groupValue?.country; // no need to know the parent key
|
|
7493
|
+
return country === 'usa' ? 'NY' : '';
|
|
7494
|
+
}
|
|
7495
|
+
\`\`\`
|
|
7496
|
+
|
|
7497
|
+
Population rules:
|
|
7498
|
+
- Inside a group: the parent group's value object.
|
|
7499
|
+
- Inside nested groups: the innermost parent group's value.
|
|
7500
|
+
- Directly inside an array item (no inner group): the array item itself (same as \`formValue\` in array context).
|
|
7501
|
+
- Inside a group inside an array item: the inner group's value within the item.
|
|
7502
|
+
- Field at form root: \`undefined\`.
|
|
7503
|
+
|
|
7420
7504
|
## HTTP Derivation (Server-Driven Values)
|
|
7421
7505
|
|
|
7422
7506
|
Fetch derived values from an HTTP endpoint. Requires \`dependsOn\` (explicit) and \`responseExpression\`.
|
|
@@ -8221,7 +8305,7 @@ provideDynamicForm({
|
|
|
8221
8305
|
| page | NO | hidden only | Nav buttons INSIDE |
|
|
8222
8306
|
| group | NO | hidden only | Creates nested object |
|
|
8223
8307
|
| array | NO | hidden only | Two APIs: \`template\`+\`value\` (simplified) or \`fields\` (full) |
|
|
8224
|
-
| row | NO | hidden only | Layout only
|
|
8308
|
+
| row | NO | hidden only | Layout only |`,
|
|
8225
8309
|
full: `# Container Rules
|
|
8226
8310
|
|
|
8227
8311
|
| Container | Label? | Logic? | Allowed Children | Notes |
|
|
@@ -8229,17 +8313,16 @@ provideDynamicForm({
|
|
|
8229
8313
|
| page | NO | YES (hidden only) | rows, groups, arrays, leaf fields, buttons | Nav buttons go INSIDE |
|
|
8230
8314
|
| group | NO | YES (hidden only) | rows, leaf fields (NOT pages, groups) | Creates nested object |
|
|
8231
8315
|
| array | NO | YES (hidden only) | rows, groups, leaf fields (NOT pages, arrays) | Two APIs: \`template\`+\`value\` (simplified) or \`fields\` (full) |
|
|
8232
|
-
| row | NO | YES (hidden only) | groups, arrays, leaf fields (NOT
|
|
8316
|
+
| row | NO | YES (hidden only) | groups, arrays, containers, nested rows, hidden fields, leaf fields (NOT pages) | Layout only |
|
|
8233
8317
|
|
|
8234
8318
|
**CRITICAL:**
|
|
8235
8319
|
- All containers (page, group, row, array) support only the \`hidden\` logic type for conditional visibility.
|
|
8236
8320
|
- For other logic types (disabled, required, readonly, derivation), apply them to child fields instead.
|
|
8237
|
-
- Hidden fields cannot be inside rows - place them at page/form level.
|
|
8238
8321
|
- Pages cannot be nested - ALL top-level fields must be pages if using multi-page mode.`
|
|
8239
8322
|
},
|
|
8240
8323
|
"field-placement": {
|
|
8241
8324
|
brief: `**Multi-page:** ALL root fields must be pages. Hidden fields go INSIDE first page.
|
|
8242
|
-
**Rows:** NO
|
|
8325
|
+
**Rows:** NO pages
|
|
8243
8326
|
**Groups:** NO nested groups, NO pages`,
|
|
8244
8327
|
full: `# Field Placement Rules
|
|
8245
8328
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ng-forge/dynamic-form-mcp",
|
|
3
|
-
"version": "0.8.0
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "MCP server for ng-forge dynamic forms - AI-assisted form schema generation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -51,11 +51,11 @@
|
|
|
51
51
|
"zod": "^3.25.76"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
|
-
"@ng-forge/dynamic-forms": "^0.8.0
|
|
55
|
-
"@ng-forge/dynamic-forms-bootstrap": "^0.8.0
|
|
56
|
-
"@ng-forge/dynamic-forms-ionic": "^0.8.0
|
|
57
|
-
"@ng-forge/dynamic-forms-material": "^0.8.0
|
|
58
|
-
"@ng-forge/dynamic-forms-primeng": "^0.8.0
|
|
54
|
+
"@ng-forge/dynamic-forms": "^0.8.0",
|
|
55
|
+
"@ng-forge/dynamic-forms-bootstrap": "^0.8.0",
|
|
56
|
+
"@ng-forge/dynamic-forms-ionic": "^0.8.0",
|
|
57
|
+
"@ng-forge/dynamic-forms-material": "^0.8.0",
|
|
58
|
+
"@ng-forge/dynamic-forms-primeng": "^0.8.0",
|
|
59
59
|
"tsx": "^4.19.0"
|
|
60
60
|
}
|
|
61
61
|
}
|
package/src/index.js
CHANGED
|
@@ -47,6 +47,12 @@ var FIELD_TYPES = [
|
|
|
47
47
|
description: "Number of visible text lines",
|
|
48
48
|
required: false,
|
|
49
49
|
default: 3
|
|
50
|
+
},
|
|
51
|
+
cols: {
|
|
52
|
+
name: "cols",
|
|
53
|
+
type: "number",
|
|
54
|
+
description: "Number of visible columns",
|
|
55
|
+
required: false
|
|
50
56
|
}
|
|
51
57
|
},
|
|
52
58
|
validationSupported: true,
|
|
@@ -57,6 +63,7 @@ var FIELD_TYPES = [
|
|
|
57
63
|
type: 'textarea',
|
|
58
64
|
label: 'Description',
|
|
59
65
|
placeholder: 'Enter description...',
|
|
66
|
+
maxLength: 500,
|
|
60
67
|
props: { rows: 5 }
|
|
61
68
|
}`,
|
|
62
69
|
minimalExample: `{ key: 'bio', type: 'textarea', label: 'Bio' }`
|
|
@@ -331,17 +338,20 @@ var FIELD_TYPES = [
|
|
|
331
338
|
fields: {
|
|
332
339
|
name: "fields",
|
|
333
340
|
type: "RowAllowedChildren[]",
|
|
334
|
-
description: "Child fields to render horizontally. Allowed: groups, arrays,
|
|
341
|
+
description: "Child fields to render horizontally. Allowed: groups, arrays, containers, nested rows, hidden fields, and value fields (input, select, etc). NOT ALLOWED: pages",
|
|
335
342
|
required: true
|
|
336
343
|
}
|
|
337
344
|
},
|
|
338
345
|
validationSupported: false,
|
|
339
346
|
source: "core",
|
|
340
|
-
allowedIn: ["top-level", "page", "group", "array"],
|
|
341
|
-
notAllowedIn: [
|
|
347
|
+
allowedIn: ["top-level", "page", "group", "array", "row", "container"],
|
|
348
|
+
notAllowedIn: [],
|
|
342
349
|
canContain: [
|
|
343
350
|
"group",
|
|
344
351
|
"array",
|
|
352
|
+
"container",
|
|
353
|
+
"row",
|
|
354
|
+
"hidden",
|
|
345
355
|
"input",
|
|
346
356
|
"textarea",
|
|
347
357
|
"select",
|
|
@@ -357,7 +367,7 @@ var FIELD_TYPES = [
|
|
|
357
367
|
"next",
|
|
358
368
|
"previous"
|
|
359
369
|
],
|
|
360
|
-
cannotContain: ["page"
|
|
370
|
+
cannotContain: ["page"],
|
|
361
371
|
example: `{
|
|
362
372
|
key: 'nameRow',
|
|
363
373
|
type: 'row',
|
|
@@ -369,9 +379,7 @@ var FIELD_TYPES = [
|
|
|
369
379
|
]
|
|
370
380
|
}
|
|
371
381
|
// NOT ALLOWED in rows:
|
|
372
|
-
// - type: '
|
|
373
|
-
// - type: 'page' (pages are top-level only)
|
|
374
|
-
// - type: 'row' (no nested rows)`,
|
|
382
|
+
// - type: 'page' (pages are top-level only)`,
|
|
375
383
|
minimalExample: `{ key: 'row1', type: 'row', fields: [...] }`
|
|
376
384
|
},
|
|
377
385
|
{
|
|
@@ -1103,30 +1111,12 @@ var UI_ADAPTERS = [
|
|
|
1103
1111
|
description: "Hint text below the field",
|
|
1104
1112
|
required: false
|
|
1105
1113
|
},
|
|
1106
|
-
rows: {
|
|
1107
|
-
name: "rows",
|
|
1108
|
-
type: "number",
|
|
1109
|
-
description: "Visible row count",
|
|
1110
|
-
required: false
|
|
1111
|
-
},
|
|
1112
|
-
cols: {
|
|
1113
|
-
name: "cols",
|
|
1114
|
-
type: "number",
|
|
1115
|
-
description: "Visible column count",
|
|
1116
|
-
required: false
|
|
1117
|
-
},
|
|
1118
1114
|
resize: {
|
|
1119
1115
|
name: "resize",
|
|
1120
1116
|
type: "'none' | 'both' | 'horizontal' | 'vertical'",
|
|
1121
1117
|
description: "Resize handle behavior",
|
|
1122
1118
|
required: false,
|
|
1123
1119
|
default: "vertical"
|
|
1124
|
-
},
|
|
1125
|
-
maxLength: {
|
|
1126
|
-
name: "maxLength",
|
|
1127
|
-
type: "number",
|
|
1128
|
-
description: "Maximum character length",
|
|
1129
|
-
required: false
|
|
1130
1120
|
}
|
|
1131
1121
|
}
|
|
1132
1122
|
}
|
|
@@ -5344,7 +5334,6 @@ var PrimeDatepickerPropsSchema = PrimeCommonPropsSchema.extend({
|
|
|
5344
5334
|
var PrimeTextareaPropsSchema = PrimeCommonPropsSchema.extend({
|
|
5345
5335
|
rows: z47.number().positive().optional(),
|
|
5346
5336
|
autoResize: z47.boolean().optional(),
|
|
5347
|
-
maxlength: z47.number().positive().optional(),
|
|
5348
5337
|
placeholder: DynamicTextSchema.optional()
|
|
5349
5338
|
});
|
|
5350
5339
|
var PrimeSliderPropsSchema = PrimeCommonPropsSchema.extend({
|
|
@@ -5529,9 +5518,8 @@ var IonicInputPropsSchema = z51.object({
|
|
|
5529
5518
|
hint: DynamicTextSchema.optional(),
|
|
5530
5519
|
errorText: DynamicTextSchema.optional(),
|
|
5531
5520
|
counter: z51.boolean().optional(),
|
|
5532
|
-
maxlength: z51.number().positive().optional(),
|
|
5533
5521
|
clearInput: z51.boolean().optional(),
|
|
5534
|
-
type: z51.enum(["text", "email", "password", "number", "tel", "url"]).optional(),
|
|
5522
|
+
type: z51.enum(["text", "email", "password", "number", "tel", "url", "search"]).optional(),
|
|
5535
5523
|
placeholder: DynamicTextSchema.optional()
|
|
5536
5524
|
});
|
|
5537
5525
|
var IonicCheckboxPropsSchema = z51.object({
|
|
@@ -5596,7 +5584,6 @@ var IonicSelectPropsSchema = z51.object({
|
|
|
5596
5584
|
var IonicTextareaPropsSchema = z51.object({
|
|
5597
5585
|
rows: z51.number().positive().optional(),
|
|
5598
5586
|
autoGrow: z51.boolean().optional(),
|
|
5599
|
-
maxlength: z51.number().positive().optional(),
|
|
5600
5587
|
counter: z51.boolean().optional(),
|
|
5601
5588
|
fill: z51.enum(["solid", "outline"]).optional(),
|
|
5602
5589
|
shape: z51.literal("round").optional(),
|
|
@@ -6982,10 +6969,8 @@ Included in form value but not rendered.
|
|
|
6982
6969
|
|
|
6983
6970
|
Use \`col\` (1-12) on child fields for grid width. Row is purely for layout. Supports only \`hidden\` logic type for conditional visibility.
|
|
6984
6971
|
|
|
6985
|
-
**Allowed children:** groups, arrays, value fields (input, select, checkbox, etc.)
|
|
6986
|
-
**NOT allowed:** \`
|
|
6987
|
-
|
|
6988
|
-
\u26A0\uFE0F **Common mistake:** Putting hidden fields inside rows - hidden fields should be at page or form level, not in rows.`
|
|
6972
|
+
**Allowed children:** groups, arrays, containers, nested rows, hidden fields, value fields (input, select, checkbox, etc.)
|
|
6973
|
+
**NOT allowed:** \`page\` containers`
|
|
6989
6974
|
},
|
|
6990
6975
|
array: {
|
|
6991
6976
|
brief: `**Two APIs available:**
|
|
@@ -7401,8 +7386,15 @@ logic: [{ type: 'derivation', expression: '...', stopOnUserOverride: true, reEng
|
|
|
7401
7386
|
|
|
7402
7387
|
// HTTP derivation (server-driven values)
|
|
7403
7388
|
logic: [{ type: 'derivation', source: 'http', http: { url: '/api/rate', queryParams: { from: 'formValue.currency' } }, responseExpression: 'response.rate', dependsOn: ['currency'] }]
|
|
7389
|
+
|
|
7390
|
+
// Self-dependency token: $self resolves to the field's own absolute path at collection time
|
|
7391
|
+
logic: [{ type: 'derivation', functionName: 'uppercase', dependsOn: ['$self'] }]
|
|
7392
|
+
|
|
7393
|
+
// Parent-container token: $group resolves to the field's nearest parent group/array path
|
|
7394
|
+
logic: [{ type: 'derivation', functionName: 'computeFromGroup', dependsOn: ['$group'] }]
|
|
7404
7395
|
\`\`\`
|
|
7405
7396
|
Derivation is always defined ON the field that receives the computed value (self-targeting).
|
|
7397
|
+
\`dependsOn\` paths are absolute from the form root (e.g. \`'address.state'\`). Use \`'$self'\` for the field's own absolute path and \`'$group'\` for its nearest parent group/array \u2014 both useful in factory-built fields where ancestor keys aren't known at config time.
|
|
7406
7398
|
**Variables:** \`formValue\`, \`fieldValue\`, \`fieldState\`, \`formFieldState\`, \`externalData\` (see topic: expression-variables)
|
|
7407
7399
|
**For deriving component properties** (minDate, options, label): use \`targetProperty\` (see topic \`property-derivation\`)`,
|
|
7408
7400
|
full: `# Value Derivation (Computed Fields)
|
|
@@ -7466,6 +7458,98 @@ Derivations are always defined ON the field that receives the computed value (se
|
|
|
7466
7458
|
}
|
|
7467
7459
|
\`\`\`
|
|
7468
7460
|
|
|
7461
|
+
## \`dependsOn\` Path Resolution
|
|
7462
|
+
|
|
7463
|
+
\`dependsOn\` paths are **absolute from the form root**, dotted notation. A field nested under a group has the group's key in its path:
|
|
7464
|
+
|
|
7465
|
+
\`\`\`typescript
|
|
7466
|
+
{
|
|
7467
|
+
type: 'group', key: 'address',
|
|
7468
|
+
fields: [
|
|
7469
|
+
{ key: 'state', type: 'input', logic: [{
|
|
7470
|
+
type: 'derivation',
|
|
7471
|
+
functionName: 'uppercaseState',
|
|
7472
|
+
dependsOn: ['address.state'] // absolute path from root
|
|
7473
|
+
}]}
|
|
7474
|
+
]
|
|
7475
|
+
}
|
|
7476
|
+
\`\`\`
|
|
7477
|
+
|
|
7478
|
+
Layout containers (\`page\`, \`row\`, \`container\`) do **not** contribute to the path \u2014 only \`group\` fields do. Array fields use the \`'arrayKey.$.fieldKey'\` placeholder convention.
|
|
7479
|
+
|
|
7480
|
+
### \`$self\` token
|
|
7481
|
+
|
|
7482
|
+
Use \`'$self'\` in \`dependsOn\` to refer to the field's own absolute path. Useful for self-derivations on fields built by factory helpers, where the ancestor group keys aren't known at config-authoring time:
|
|
7483
|
+
|
|
7484
|
+
\`\`\`typescript
|
|
7485
|
+
{
|
|
7486
|
+
type: 'group', key: 'address',
|
|
7487
|
+
fields: [
|
|
7488
|
+
{ key: 'state', type: 'input', logic: [{
|
|
7489
|
+
type: 'derivation',
|
|
7490
|
+
functionName: 'uppercaseState',
|
|
7491
|
+
dependsOn: ['$self'] // resolves to 'address.state' at collection time
|
|
7492
|
+
}]}
|
|
7493
|
+
]
|
|
7494
|
+
}
|
|
7495
|
+
\`\`\`
|
|
7496
|
+
|
|
7497
|
+
\`$self\` works alongside other absolute deps and inside arrays (resolves to the array placeholder form, e.g. \`'items.$.name'\`).
|
|
7498
|
+
|
|
7499
|
+
### \`$group\` token
|
|
7500
|
+
|
|
7501
|
+
Use \`'$group'\` in \`dependsOn\` to refer to the field's **nearest parent container** (group or array). The derivation fires whenever any sibling under the same parent changes \u2014 handy when you don't want to enumerate each sibling explicitly:
|
|
7502
|
+
|
|
7503
|
+
\`\`\`typescript
|
|
7504
|
+
{
|
|
7505
|
+
type: 'group', key: 'address',
|
|
7506
|
+
fields: [
|
|
7507
|
+
{ key: 'country', type: 'input' },
|
|
7508
|
+
{ key: 'state', type: 'input', logic: [{
|
|
7509
|
+
type: 'derivation',
|
|
7510
|
+
functionName: 'pickStateFromCountry',
|
|
7511
|
+
dependsOn: ['$group'] // resolves to 'address' at collection time
|
|
7512
|
+
}]}
|
|
7513
|
+
]
|
|
7514
|
+
}
|
|
7515
|
+
\`\`\`
|
|
7516
|
+
|
|
7517
|
+
Resolution rules:
|
|
7518
|
+
- Inside group(s) only \u2192 the dotted ancestor group path (\`'address'\` or \`'org.address'\`).
|
|
7519
|
+
- Directly inside an array \u2192 the array key (\`'items'\`). Fires on any item change.
|
|
7520
|
+
- Inside group(s) inside an array \u2192 \`'items.$.address'\` form.
|
|
7521
|
+
- At form root \u2192 throws \`DynamicFormError\` (no parent container exists).
|
|
7522
|
+
|
|
7523
|
+
### Token prefix substitution
|
|
7524
|
+
|
|
7525
|
+
Both \`$self\` and \`$group\` accept a dotted suffix that is appended to the resolved path:
|
|
7526
|
+
|
|
7527
|
+
\`\`\`typescript
|
|
7528
|
+
dependsOn: ['$group.country'] // resolves to 'address.country' inside group 'address'
|
|
7529
|
+
dependsOn: ['$group.contact.email'] // multi-segment suffix supported
|
|
7530
|
+
dependsOn: ['$self.flag'] // resolves to '<fieldKey>.flag' (object-valued fields)
|
|
7531
|
+
\`\`\`
|
|
7532
|
+
|
|
7533
|
+
Use this to target a specific sibling without naming the parent group key \u2014 handy in factory-built field shapes.
|
|
7534
|
+
|
|
7535
|
+
### \`groupValue\` in evaluation context
|
|
7536
|
+
|
|
7537
|
+
Custom derivation functions and expressions receive a \`groupValue\` on the \`EvaluationContext\` that mirrors the \`$group\` token at evaluation time:
|
|
7538
|
+
|
|
7539
|
+
\`\`\`typescript
|
|
7540
|
+
deriveStateFromCountry: (ctx) => {
|
|
7541
|
+
const country = ctx.groupValue?.country; // no need to know the parent key
|
|
7542
|
+
return country === 'usa' ? 'NY' : '';
|
|
7543
|
+
}
|
|
7544
|
+
\`\`\`
|
|
7545
|
+
|
|
7546
|
+
Population rules:
|
|
7547
|
+
- Inside a group: the parent group's value object.
|
|
7548
|
+
- Inside nested groups: the innermost parent group's value.
|
|
7549
|
+
- Directly inside an array item (no inner group): the array item itself (same as \`formValue\` in array context).
|
|
7550
|
+
- Inside a group inside an array item: the inner group's value within the item.
|
|
7551
|
+
- Field at form root: \`undefined\`.
|
|
7552
|
+
|
|
7469
7553
|
## HTTP Derivation (Server-Driven Values)
|
|
7470
7554
|
|
|
7471
7555
|
Fetch derived values from an HTTP endpoint. Requires \`dependsOn\` (explicit) and \`responseExpression\`.
|
|
@@ -8270,7 +8354,7 @@ provideDynamicForm({
|
|
|
8270
8354
|
| page | NO | hidden only | Nav buttons INSIDE |
|
|
8271
8355
|
| group | NO | hidden only | Creates nested object |
|
|
8272
8356
|
| array | NO | hidden only | Two APIs: \`template\`+\`value\` (simplified) or \`fields\` (full) |
|
|
8273
|
-
| row | NO | hidden only | Layout only
|
|
8357
|
+
| row | NO | hidden only | Layout only |`,
|
|
8274
8358
|
full: `# Container Rules
|
|
8275
8359
|
|
|
8276
8360
|
| Container | Label? | Logic? | Allowed Children | Notes |
|
|
@@ -8278,17 +8362,16 @@ provideDynamicForm({
|
|
|
8278
8362
|
| page | NO | YES (hidden only) | rows, groups, arrays, leaf fields, buttons | Nav buttons go INSIDE |
|
|
8279
8363
|
| group | NO | YES (hidden only) | rows, leaf fields (NOT pages, groups) | Creates nested object |
|
|
8280
8364
|
| array | NO | YES (hidden only) | rows, groups, leaf fields (NOT pages, arrays) | Two APIs: \`template\`+\`value\` (simplified) or \`fields\` (full) |
|
|
8281
|
-
| row | NO | YES (hidden only) | groups, arrays, leaf fields (NOT
|
|
8365
|
+
| row | NO | YES (hidden only) | groups, arrays, containers, nested rows, hidden fields, leaf fields (NOT pages) | Layout only |
|
|
8282
8366
|
|
|
8283
8367
|
**CRITICAL:**
|
|
8284
8368
|
- All containers (page, group, row, array) support only the \`hidden\` logic type for conditional visibility.
|
|
8285
8369
|
- For other logic types (disabled, required, readonly, derivation), apply them to child fields instead.
|
|
8286
|
-
- Hidden fields cannot be inside rows - place them at page/form level.
|
|
8287
8370
|
- Pages cannot be nested - ALL top-level fields must be pages if using multi-page mode.`
|
|
8288
8371
|
},
|
|
8289
8372
|
"field-placement": {
|
|
8290
8373
|
brief: `**Multi-page:** ALL root fields must be pages. Hidden fields go INSIDE first page.
|
|
8291
|
-
**Rows:** NO
|
|
8374
|
+
**Rows:** NO pages
|
|
8292
8375
|
**Groups:** NO nested groups, NO pages`,
|
|
8293
8376
|
full: `# Field Placement Rules
|
|
8294
8377
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"field-types.d.ts","sourceRoot":"","sources":["../../../../../packages/dynamic-form-mcp/src/registry/field-types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,eAAO,MAAM,WAAW,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"field-types.d.ts","sourceRoot":"","sources":["../../../../../packages/dynamic-form-mcp/src/registry/field-types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,eAAO,MAAM,WAAW,EAAE,aAAa,EA6qBtC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui-adapters.d.ts","sourceRoot":"","sources":["../../../../../packages/dynamic-form-mcp/src/registry/ui-adapters.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,eAAO,MAAM,WAAW,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"ui-adapters.d.ts","sourceRoot":"","sources":["../../../../../packages/dynamic-form-mcp/src/registry/ui-adapters.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,eAAO,MAAM,WAAW,EAAE,aAAa,EA0VtC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lookup-topics.d.ts","sourceRoot":"","sources":["../../../../../../packages/dynamic-form-mcp/src/tools/data/lookup-topics.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,
|
|
1
|
+
{"version":3,"file":"lookup-topics.d.ts","sourceRoot":"","sources":["../../../../../../packages/dynamic-form-mcp/src/tools/data/lookup-topics.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAq/ElE,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAiDrD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CA4IhD,CAAC"}
|