@ng-forge/dynamic-form-mcp 0.6.1 → 0.8.0-next.1

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.
@@ -20,12 +20,6 @@ var FIELD_TYPES = [
20
20
  description: "HTML input type",
21
21
  required: false,
22
22
  default: "text"
23
- },
24
- placeholder: {
25
- name: "placeholder",
26
- type: "DynamicText",
27
- description: "Placeholder text displayed when field is empty",
28
- required: false
29
23
  }
30
24
  },
31
25
  validationSupported: true,
@@ -37,7 +31,8 @@ var FIELD_TYPES = [
37
31
  label: 'Email Address',
38
32
  required: true,
39
33
  email: true,
40
- props: { type: 'email', placeholder: 'user@example.com' }
34
+ placeholder: 'user@example.com',
35
+ props: { type: 'email' }
41
36
  }`,
42
37
  minimalExample: `{ key: 'name', type: 'input', label: 'Name' }`
43
38
  },
@@ -54,12 +49,6 @@ var FIELD_TYPES = [
54
49
  description: "Number of visible text lines",
55
50
  required: false,
56
51
  default: 3
57
- },
58
- placeholder: {
59
- name: "placeholder",
60
- type: "DynamicText",
61
- description: "Placeholder text displayed when field is empty",
62
- required: false
63
52
  }
64
53
  },
65
54
  validationSupported: true,
@@ -69,7 +58,8 @@ var FIELD_TYPES = [
69
58
  key: 'description',
70
59
  type: 'textarea',
71
60
  label: 'Description',
72
- props: { rows: 5, placeholder: 'Enter description...' }
61
+ placeholder: 'Enter description...',
62
+ props: { rows: 5 }
73
63
  }`,
74
64
  minimalExample: `{ key: 'bio', type: 'textarea', label: 'Bio' }`
75
65
  },
@@ -92,12 +82,6 @@ var FIELD_TYPES = [
92
82
  description: "Allow multiple selections",
93
83
  required: false,
94
84
  default: false
95
- },
96
- placeholder: {
97
- name: "placeholder",
98
- type: "DynamicText",
99
- description: "Placeholder text for empty selection",
100
- required: false
101
85
  }
102
86
  },
103
87
  validationSupported: true,
@@ -858,54 +842,6 @@ var VALIDATORS = [
858
842
  example: `{
859
843
  type: 'async',
860
844
  functionName: 'checkUsernameAvailability'
861
- }`
862
- },
863
- {
864
- type: "customAsync",
865
- category: "async",
866
- description: "DEPRECATED \u2014 use type: 'async' instead. Async validator using registered async function.",
867
- parameters: {
868
- functionName: {
869
- name: "functionName",
870
- type: "string",
871
- description: "Name of registered async validator function",
872
- required: true
873
- },
874
- params: {
875
- name: "params",
876
- type: "Record<string, unknown>",
877
- description: "Parameters to pass to validator function",
878
- required: false
879
- }
880
- },
881
- example: `// DEPRECATED \u2014 use type: 'async' instead
882
- {
883
- type: 'customAsync',
884
- functionName: 'checkUsernameAvailability'
885
- }`
886
- },
887
- {
888
- type: "customHttp",
889
- category: "http",
890
- description: "DEPRECATED \u2014 use type: 'http' with functionName instead. HTTP-based validator with automatic request cancellation.",
891
- parameters: {
892
- functionName: {
893
- name: "functionName",
894
- type: "string",
895
- description: "Name of registered HTTP validator configuration",
896
- required: true
897
- },
898
- params: {
899
- name: "params",
900
- type: "Record<string, unknown>",
901
- description: "Parameters to pass to HTTP validator",
902
- required: false
903
- }
904
- },
905
- example: `// DEPRECATED \u2014 use type: 'http' with functionName instead
906
- {
907
- type: 'customHttp',
908
- functionName: 'validateEmailExists'
909
845
  }`
910
846
  },
911
847
  {
@@ -1009,6 +945,20 @@ var UI_ADAPTERS = [
1009
945
  required: false,
1010
946
  default: "dynamic"
1011
947
  },
948
+ floatLabel: {
949
+ name: "floatLabel",
950
+ type: "'auto' | 'always' | 'never'",
951
+ description: "Label float behavior",
952
+ required: false,
953
+ default: "auto"
954
+ },
955
+ hideRequiredMarker: {
956
+ name: "hideRequiredMarker",
957
+ type: "boolean",
958
+ description: "Hide the required asterisk",
959
+ required: false,
960
+ default: false
961
+ },
1012
962
  hint: {
1013
963
  name: "hint",
1014
964
  type: "DynamicText",
@@ -1027,6 +977,26 @@ var UI_ADAPTERS = [
1027
977
  description: "Material form field appearance",
1028
978
  required: false,
1029
979
  default: "outline"
980
+ },
981
+ floatLabel: {
982
+ name: "floatLabel",
983
+ type: "'auto' | 'always' | 'never'",
984
+ description: "Label float behavior",
985
+ required: false,
986
+ default: "auto"
987
+ },
988
+ hideRequiredMarker: {
989
+ name: "hideRequiredMarker",
990
+ type: "boolean",
991
+ description: "Hide the required asterisk",
992
+ required: false,
993
+ default: false
994
+ },
995
+ hint: {
996
+ name: "hint",
997
+ type: "DynamicText",
998
+ description: "Hint text below the field",
999
+ required: false
1030
1000
  }
1031
1001
  }
1032
1002
  },
@@ -1047,12 +1017,118 @@ var UI_ADAPTERS = [
1047
1017
  type: "datepicker",
1048
1018
  componentName: "MatDatepickerFieldComponent",
1049
1019
  additionalProps: {
1020
+ appearance: {
1021
+ name: "appearance",
1022
+ type: "'fill' | 'outline'",
1023
+ description: "Material form field appearance",
1024
+ required: false,
1025
+ default: "outline"
1026
+ },
1027
+ subscriptSizing: {
1028
+ name: "subscriptSizing",
1029
+ type: "'fixed' | 'dynamic'",
1030
+ description: "Error/hint text sizing",
1031
+ required: false,
1032
+ default: "dynamic"
1033
+ },
1034
+ floatLabel: {
1035
+ name: "floatLabel",
1036
+ type: "'auto' | 'always' | 'never'",
1037
+ description: "Label float behavior",
1038
+ required: false,
1039
+ default: "auto"
1040
+ },
1041
+ hideRequiredMarker: {
1042
+ name: "hideRequiredMarker",
1043
+ type: "boolean",
1044
+ description: "Hide the required asterisk",
1045
+ required: false,
1046
+ default: false
1047
+ },
1050
1048
  startView: {
1051
1049
  name: "startView",
1052
1050
  type: "'month' | 'year' | 'multi-year'",
1053
1051
  description: "Initial calendar view",
1054
1052
  required: false,
1055
1053
  default: "month"
1054
+ },
1055
+ touchUi: {
1056
+ name: "touchUi",
1057
+ type: "boolean",
1058
+ description: "Use touch-friendly calendar UI",
1059
+ required: false,
1060
+ default: false
1061
+ },
1062
+ hint: {
1063
+ name: "hint",
1064
+ type: "DynamicText",
1065
+ description: "Hint text below the field",
1066
+ required: false
1067
+ }
1068
+ }
1069
+ },
1070
+ {
1071
+ type: "textarea",
1072
+ componentName: "MatTextareaFieldComponent",
1073
+ additionalProps: {
1074
+ appearance: {
1075
+ name: "appearance",
1076
+ type: "'fill' | 'outline'",
1077
+ description: "Material form field appearance",
1078
+ required: false,
1079
+ default: "outline"
1080
+ },
1081
+ subscriptSizing: {
1082
+ name: "subscriptSizing",
1083
+ type: "'fixed' | 'dynamic'",
1084
+ description: "Error/hint text sizing",
1085
+ required: false,
1086
+ default: "dynamic"
1087
+ },
1088
+ floatLabel: {
1089
+ name: "floatLabel",
1090
+ type: "'auto' | 'always' | 'never'",
1091
+ description: "Label float behavior",
1092
+ required: false,
1093
+ default: "auto"
1094
+ },
1095
+ hideRequiredMarker: {
1096
+ name: "hideRequiredMarker",
1097
+ type: "boolean",
1098
+ description: "Hide the required asterisk",
1099
+ required: false,
1100
+ default: false
1101
+ },
1102
+ hint: {
1103
+ name: "hint",
1104
+ type: "DynamicText",
1105
+ description: "Hint text below the field",
1106
+ required: false
1107
+ },
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
+ resize: {
1121
+ name: "resize",
1122
+ type: "'none' | 'both' | 'horizontal' | 'vertical'",
1123
+ description: "Resize handle behavior",
1124
+ required: false,
1125
+ default: "vertical"
1126
+ },
1127
+ maxLength: {
1128
+ name: "maxLength",
1129
+ type: "number",
1130
+ description: "Maximum character length",
1131
+ required: false
1056
1132
  }
1057
1133
  }
1058
1134
  }
@@ -1327,6 +1403,160 @@ var DOCUMENTATION = [
1327
1403
  { id: "example-array", title: "Complete Array Form", category: "examples", url: `${BASE_URL}/examples/array-form` }
1328
1404
  ];
1329
1405
 
1406
+ // packages/dynamic-form-mcp/src/registry/wrappers.ts
1407
+ var WRAPPER_AUTHORING_CONTRACT = `All wrapper components MUST:
1408
+
1409
+ 1. Implement \`FieldWrapperContract\` from \`@ng-forge/dynamic-forms\`.
1410
+ 2. Expose \`readonly fieldComponent = viewChild.required('fieldComponent', { read: ViewContainerRef });\`
1411
+ \u2014 this is the slot where the inner wrapper (or the field) is rendered
1412
+ imperatively by the outlet.
1413
+ 3. Place the \`#fieldComponent\` template ref UNCONDITIONALLY. It cannot
1414
+ live inside \`@if\`, \`@defer\`, \`@for\`, \`@switch\`, \`<ng-template>\`,
1415
+ or any structural directive that delays view creation. The outlet reads
1416
+ the \`ViewContainerRef\` immediately after creation \u2014 if the slot isn't
1417
+ materialised yet, \`viewChild.required\` throws \`NG0951\`
1418
+ (REQUIRED_QUERY_NO_VALUE), the wrapper chain is torn down, and the field
1419
+ renders bare.
1420
+ 4. Declare every config key the wrapper consumes as an Angular \`input()\`.
1421
+ Unknown keys are silently dropped \u2014 the outlet probes
1422
+ \`reflectComponentType(...).inputs\` before calling \`setInput()\`.
1423
+ Runtime typos in config will NOT throw; rely on TypeScript (via
1424
+ \`FieldRegistryWrappers\` module augmentation) to catch them.
1425
+ 5. Optionally accept \`fieldInputs: input<WrapperFieldInputs>()\` to read
1426
+ the wrapped field's mapper outputs and read-only form state.`;
1427
+ var WRAPPERS = [
1428
+ {
1429
+ type: "css",
1430
+ category: "core",
1431
+ availability: "shipping",
1432
+ package: "@ng-forge/dynamic-forms",
1433
+ description: "Invisible wrapper that applies CSS classes to the host element via a `DynamicText` input. Useful for decorating any field (or container) with styling without authoring a custom wrapper. Resolves `Signal<string>` / `Observable<string>` / `string` uniformly.",
1434
+ props: {
1435
+ cssClasses: {
1436
+ name: "cssClasses",
1437
+ type: "DynamicText",
1438
+ description: "Space-separated CSS class names to apply to the wrapper host element. Accepts a literal string, a Signal<string>, or an Observable<string> \u2014 the wrapper subscribes and updates the host [class] binding reactively.",
1439
+ required: false
1440
+ }
1441
+ },
1442
+ autoAppliesTo: [],
1443
+ componentName: "CssWrapperComponent",
1444
+ contract: WRAPPER_AUTHORING_CONTRACT,
1445
+ example: `// Field-level CSS wrapper (scoped to a single field)
1446
+ {
1447
+ key: 'email',
1448
+ type: 'input',
1449
+ label: 'Email',
1450
+ wrappers: [{ type: 'css', cssClasses: 'field--highlight' }]
1451
+ }
1452
+
1453
+ // Dynamic classes via Signal<string>
1454
+ {
1455
+ key: 'amount',
1456
+ type: 'input',
1457
+ label: 'Amount',
1458
+ wrappers: [{ type: 'css', cssClasses: highlightClass }] // highlightClass: Signal<string>
1459
+ }
1460
+
1461
+ // Chained with other wrappers (outer-most first)
1462
+ {
1463
+ key: 'contact',
1464
+ type: 'group',
1465
+ wrappers: [
1466
+ { type: 'section', title: 'Contact' }, // outer
1467
+ { type: 'css', cssClasses: 'pad-lg' } // inner
1468
+ ],
1469
+ fields: [...]
1470
+ }`,
1471
+ minimalExample: `{ type: 'css', cssClasses: 'my-class' }`
1472
+ },
1473
+ {
1474
+ type: "arraySection",
1475
+ category: "demo",
1476
+ availability: "demo-only",
1477
+ package: "@internal/examples-shared-ui",
1478
+ description: 'Demo wrapper used by the docs sandbox. Wraps an array field in a titled card whose header contains an "Add" button \u2014 the wrapper owns the append behaviour, dispatching `arrayEvent(key).append(itemTemplate)` on click via the `EventBus`. Lets the consumer config drop the separate `addArrayItem` button field. NOT a shipping primitive; copy the component out of `internal/examples-shared-ui/src/lib/demo-wrappers/` or author your own if you want this pattern in production.',
1479
+ props: {
1480
+ title: {
1481
+ name: "title",
1482
+ type: "string",
1483
+ description: "Card header text rendered above the array.",
1484
+ required: false
1485
+ },
1486
+ addLabel: {
1487
+ name: "addLabel",
1488
+ type: "string",
1489
+ description: 'Text for the Add button in the header. Defaults to "Add" when omitted.',
1490
+ required: false
1491
+ },
1492
+ itemTemplate: {
1493
+ name: "itemTemplate",
1494
+ type: "FieldDef<unknown> | readonly FieldDef<unknown>[]",
1495
+ description: "Template passed to `arrayEvent(key).append(template)` when the Add button is clicked. Should match the array's `fields` shape.",
1496
+ required: true
1497
+ }
1498
+ },
1499
+ autoAppliesTo: [],
1500
+ componentName: "ArraySectionWrapperComponent",
1501
+ contract: WRAPPER_AUTHORING_CONTRACT,
1502
+ example: `// Array wrapped with arraySection \u2014 the wrapper owns the Add button
1503
+ import { arrayEvent } from '@ng-forge/dynamic-forms';
1504
+
1505
+ const tagItemTemplate = { key: 'tag', type: 'input', label: 'Tag' } as const satisfies FieldDef;
1506
+
1507
+ {
1508
+ key: 'tags',
1509
+ type: 'array',
1510
+ wrappers: [{
1511
+ type: 'arraySection',
1512
+ title: 'Tags',
1513
+ addLabel: 'Add tag',
1514
+ itemTemplate: tagItemTemplate,
1515
+ }],
1516
+ fields: [tagItemTemplate],
1517
+ }
1518
+ // Clicking the header button dispatches arrayEvent('tags').append(tagItemTemplate)`,
1519
+ minimalExample: `{ type: 'arraySection', title: 'Items', itemTemplate: { key: 'item', type: 'input', label: 'Item' } }`
1520
+ },
1521
+ {
1522
+ type: "section",
1523
+ category: "demo",
1524
+ availability: "demo-only",
1525
+ package: "@internal/examples-shared-ui",
1526
+ description: "Demo wrapper used by the docs sandbox. Renders a titled card around the wrapped content and is registered with every sandbox adapter so the Writing-a-Wrapper docs can demonstrate an end-to-end custom wrapper. NOT a shipping primitive \u2014 use as a pattern/template, not a dependency.",
1527
+ props: {
1528
+ title: {
1529
+ name: "title",
1530
+ type: "string",
1531
+ description: "Card header text. Omit to render a header-less card.",
1532
+ required: false
1533
+ }
1534
+ },
1535
+ autoAppliesTo: [],
1536
+ componentName: "SectionWrapperComponent",
1537
+ contract: WRAPPER_AUTHORING_CONTRACT,
1538
+ example: `// Section wrapper around a group
1539
+ {
1540
+ key: 'address',
1541
+ type: 'group',
1542
+ wrappers: [{ type: 'section', title: 'Shipping address' }],
1543
+ fields: [
1544
+ { key: 'street', type: 'input', label: 'Street' },
1545
+ { key: 'city', type: 'input', label: 'City' }
1546
+ ]
1547
+ }
1548
+
1549
+ // Header-less card (title omitted)
1550
+ {
1551
+ key: 'details',
1552
+ type: 'group',
1553
+ wrappers: [{ type: 'section' }],
1554
+ fields: [...]
1555
+ }`,
1556
+ minimalExample: `{ type: 'section', title: 'Section title' }`
1557
+ }
1558
+ ];
1559
+
1330
1560
  // packages/dynamic-form-mcp/src/registry/index.ts
1331
1561
  function getFieldTypes() {
1332
1562
  return FIELD_TYPES;
@@ -1352,6 +1582,15 @@ function getUIAdapters() {
1352
1582
  function getUIAdapter(library) {
1353
1583
  return UI_ADAPTERS.find((a) => a.library === library);
1354
1584
  }
1585
+ function getWrappers() {
1586
+ return WRAPPERS;
1587
+ }
1588
+ function getWrapper(type) {
1589
+ return WRAPPERS.find((w) => w.type === type);
1590
+ }
1591
+ function getWrappersByCategory(category) {
1592
+ return WRAPPERS.filter((w) => w.category === category);
1593
+ }
1355
1594
  function getDocPages() {
1356
1595
  return DOCUMENTATION;
1357
1596
  }
@@ -1922,13 +2161,13 @@ For fields that collect user input (\`input\`, \`textarea\`, \`select\`, \`check
1922
2161
  label: 'Email Address',
1923
2162
  required: true, // Shorthand validator
1924
2163
  email: true, // Shorthand validator
2164
+ placeholder: 'user@example.com', // Field-level, not inside props
1925
2165
  validationMessages: { // Always provide clear messages
1926
2166
  required: 'Email is required',
1927
2167
  email: 'Please enter a valid email'
1928
2168
  },
1929
2169
  props: {
1930
2170
  type: 'email', // HTML input type
1931
- placeholder: 'user@example.com',
1932
2171
  hint: 'We will never share your email' // UI library specific
1933
2172
  }
1934
2173
  }
@@ -1944,11 +2183,11 @@ MUST include \`options\` array:
1944
2183
  type: 'select',
1945
2184
  label: 'Country',
1946
2185
  required: true,
2186
+ placeholder: 'Select a country',
1947
2187
  options: [
1948
2188
  { value: 'us', label: 'United States' },
1949
2189
  { value: 'uk', label: 'United Kingdom' }
1950
- ],
1951
- props: { placeholder: 'Select a country' }
2190
+ ]
1952
2191
  }
1953
2192
  \`\`\`
1954
2193
 
@@ -2062,6 +2301,27 @@ Use shorthand properties directly on field definitions:
2062
2301
 
2063
2302
  Available shorthands: \`required\`, \`email\`, \`min\`, \`max\`, \`minLength\`, \`maxLength\`, \`pattern\`
2064
2303
 
2304
+ ### Nullable Values
2305
+
2306
+ Value fields accept a \`nullable?: boolean\` flag. When \`true\`:
2307
+
2308
+ - \`value\` accepts \`null\` in addition to the field's normal value type.
2309
+ - An omitted \`value\` resolves to \`null\` (instead of the type-specific empty default like \`''\`, \`NaN\`, or \`[]\`).
2310
+ - Orthogonal to \`required\`. \`nullable\` declares that the **model** accepts \`null\`; \`required\` is a **validation** constraint. Angular's \`Validators.required\` treats \`null\` as invalid, so a field that is both \`nullable\` and \`required\` will fail required-validation when the value is \`null\` \u2014 the two flags describe different layers (data shape vs. validation), not conflicting semantics.
2311
+ - Map OpenAPI \`nullable: true\` (3.0) or \`type: [T, null]\` (3.1) to this flag.
2312
+
2313
+ \`\`\`typescript
2314
+ {
2315
+ key: 'middleName',
2316
+ type: 'input',
2317
+ label: 'Middle Name',
2318
+ nullable: true,
2319
+ value: null, // valid; default-resolves to null
2320
+ }
2321
+ \`\`\`
2322
+
2323
+ Read-side caveat: a user clearing a text input reads back as \`""\`, not \`null\` \u2014 this is a DOM/Web IDL contract, identical to classic Reactive Forms. \`nullable\` is a contract for accepted values, not a guarantee of emitted ones.
2324
+
2065
2325
  ### Validation Messages
2066
2326
 
2067
2327
  ALWAYS provide validation messages. Use template variables:
@@ -2276,7 +2536,8 @@ Different UI libraries support different properties. Always validate against the
2276
2536
  |----------|----------|-----------|---------|-------|
2277
2537
  | \`appearance\` | \u2713 (fill, outline) | \u2717 | \u2717 | \u2713 (fill, outline) |
2278
2538
  | \`subscriptSizing\` | \u2713 | \u2717 | \u2717 | \u2717 |
2279
- | \`floatLabel\` | \u2713 | \u2717 | \u2713 | \u2717 |
2539
+ | \`floatLabel\` | \u2713 (auto, always, never) | \u2717 | \u2717 | \u2717 |
2540
+ | \`hideRequiredMarker\` | \u2713 | \u2717 | \u2717 | \u2717 |
2280
2541
  | \`hint\` | \u2713 | \u2713 (as \`helpText\`) | \u2713 | \u2713 |
2281
2542
 
2282
2543
  ### Container Fields
@@ -2363,7 +2624,9 @@ var examples_default = [
2363
2624
  key: "title",
2364
2625
  type: "text",
2365
2626
  label: "Sign In",
2366
- props: { elementType: "h2" }
2627
+ props: {
2628
+ elementType: "h2"
2629
+ }
2367
2630
  },
2368
2631
  {
2369
2632
  key: "email",
@@ -2371,8 +2634,13 @@ var examples_default = [
2371
2634
  label: "Email Address",
2372
2635
  required: true,
2373
2636
  email: true,
2374
- validationMessages: { email: "Please enter a valid email address" },
2375
- props: { type: "email", placeholder: "your@email.com" }
2637
+ validationMessages: {
2638
+ email: "Please enter a valid email address"
2639
+ },
2640
+ props: {
2641
+ type: "email"
2642
+ },
2643
+ placeholder: "your@email.com"
2376
2644
  },
2377
2645
  {
2378
2646
  key: "password",
@@ -2380,7 +2648,10 @@ var examples_default = [
2380
2648
  label: "Password",
2381
2649
  required: true,
2382
2650
  minLength: 8,
2383
- props: { type: "password", placeholder: "Enter your password" }
2651
+ props: {
2652
+ type: "password"
2653
+ },
2654
+ placeholder: "Enter your password"
2384
2655
  },
2385
2656
  {
2386
2657
  key: "remember",
@@ -2391,7 +2662,9 @@ var examples_default = [
2391
2662
  key: "submit",
2392
2663
  type: "submit",
2393
2664
  label: "Sign In",
2394
- props: { color: "primary" }
2665
+ props: {
2666
+ color: "primary"
2667
+ }
2395
2668
  }
2396
2669
  ]
2397
2670
  }
@@ -2413,7 +2686,7 @@ var examples_default = [
2413
2686
  required: "First name is required",
2414
2687
  minLength: "Must be at least {{requiredLength}} characters"
2415
2688
  },
2416
- props: { placeholder: "Enter your first name" }
2689
+ placeholder: "Enter your first name"
2417
2690
  },
2418
2691
  {
2419
2692
  key: "lastName",
@@ -2425,7 +2698,7 @@ var examples_default = [
2425
2698
  required: "Last name is required",
2426
2699
  minLength: "Must be at least {{requiredLength}} characters"
2427
2700
  },
2428
- props: { placeholder: "Enter your last name" }
2701
+ placeholder: "Enter your last name"
2429
2702
  },
2430
2703
  {
2431
2704
  key: "email",
@@ -2437,7 +2710,10 @@ var examples_default = [
2437
2710
  required: "Email is required",
2438
2711
  email: "Please enter a valid email address"
2439
2712
  },
2440
- props: { type: "email", placeholder: "user@example.com" }
2713
+ props: {
2714
+ type: "email"
2715
+ },
2716
+ placeholder: "user@example.com"
2441
2717
  },
2442
2718
  {
2443
2719
  key: "age",
@@ -2451,22 +2727,42 @@ var examples_default = [
2451
2727
  min: "Must be at least {{min}}",
2452
2728
  max: "Must not exceed {{max}}"
2453
2729
  },
2454
- props: { type: "number", placeholder: "18" }
2730
+ props: {
2731
+ type: "number"
2732
+ },
2733
+ placeholder: "18"
2455
2734
  },
2456
2735
  {
2457
2736
  key: "country",
2458
2737
  type: "select",
2459
2738
  label: "Country",
2460
2739
  required: true,
2461
- validationMessages: { required: "Please select a country" },
2740
+ validationMessages: {
2741
+ required: "Please select a country"
2742
+ },
2462
2743
  options: [
2463
- { value: "us", label: "United States" },
2464
- { value: "uk", label: "United Kingdom" },
2465
- { value: "ca", label: "Canada" },
2466
- { value: "au", label: "Australia" },
2467
- { value: "de", label: "Germany" }
2744
+ {
2745
+ value: "us",
2746
+ label: "United States"
2747
+ },
2748
+ {
2749
+ value: "uk",
2750
+ label: "United Kingdom"
2751
+ },
2752
+ {
2753
+ value: "ca",
2754
+ label: "Canada"
2755
+ },
2756
+ {
2757
+ value: "au",
2758
+ label: "Australia"
2759
+ },
2760
+ {
2761
+ value: "de",
2762
+ label: "Germany"
2763
+ }
2468
2764
  ],
2469
- props: { placeholder: "Select your country" }
2765
+ placeholder: "Select your country"
2470
2766
  },
2471
2767
  {
2472
2768
  key: "newsletter",
@@ -2478,13 +2774,17 @@ var examples_default = [
2478
2774
  type: "checkbox",
2479
2775
  label: "I agree to the terms and conditions",
2480
2776
  required: true,
2481
- validationMessages: { required: "You must accept the terms" }
2777
+ validationMessages: {
2778
+ required: "You must accept the terms"
2779
+ }
2482
2780
  },
2483
2781
  {
2484
2782
  key: "submit",
2485
2783
  type: "submit",
2486
2784
  label: "Create Account",
2487
- props: { color: "primary" }
2785
+ props: {
2786
+ color: "primary"
2787
+ }
2488
2788
  }
2489
2789
  ]
2490
2790
  }
@@ -2509,7 +2809,7 @@ var examples_default = [
2509
2809
  label: "First Name",
2510
2810
  required: true,
2511
2811
  col: 6,
2512
- props: { placeholder: "Your first name" }
2812
+ placeholder: "Your first name"
2513
2813
  },
2514
2814
  {
2515
2815
  key: "lastName",
@@ -2517,7 +2817,7 @@ var examples_default = [
2517
2817
  label: "Last Name",
2518
2818
  required: true,
2519
2819
  col: 6,
2520
- props: { placeholder: "Your last name" }
2820
+ placeholder: "Your last name"
2521
2821
  }
2522
2822
  ]
2523
2823
  },
@@ -2527,8 +2827,13 @@ var examples_default = [
2527
2827
  label: "Email Address",
2528
2828
  required: true,
2529
2829
  email: true,
2530
- validationMessages: { email: "Please enter a valid email" },
2531
- props: { type: "email", placeholder: "email@example.com" }
2830
+ validationMessages: {
2831
+ email: "Please enter a valid email"
2832
+ },
2833
+ props: {
2834
+ type: "email"
2835
+ },
2836
+ placeholder: "email@example.com"
2532
2837
  },
2533
2838
  {
2534
2839
  key: "subject",
@@ -2536,12 +2841,24 @@ var examples_default = [
2536
2841
  label: "Subject",
2537
2842
  required: true,
2538
2843
  options: [
2539
- { value: "general", label: "General Inquiry" },
2540
- { value: "support", label: "Technical Support" },
2541
- { value: "billing", label: "Billing Question" },
2542
- { value: "feedback", label: "Feedback" }
2844
+ {
2845
+ value: "general",
2846
+ label: "General Inquiry"
2847
+ },
2848
+ {
2849
+ value: "support",
2850
+ label: "Technical Support"
2851
+ },
2852
+ {
2853
+ value: "billing",
2854
+ label: "Billing Question"
2855
+ },
2856
+ {
2857
+ value: "feedback",
2858
+ label: "Feedback"
2859
+ }
2543
2860
  ],
2544
- props: { placeholder: "Select a subject" }
2861
+ placeholder: "Select a subject"
2545
2862
  },
2546
2863
  {
2547
2864
  key: "message",
@@ -2554,13 +2871,18 @@ var examples_default = [
2554
2871
  minLength: "Message must be at least {{requiredLength}} characters",
2555
2872
  maxLength: "Message cannot exceed {{requiredLength}} characters"
2556
2873
  },
2557
- props: { rows: 5, placeholder: "How can we help you?" }
2874
+ props: {
2875
+ rows: 5
2876
+ },
2877
+ placeholder: "How can we help you?"
2558
2878
  },
2559
2879
  {
2560
2880
  key: "submit",
2561
2881
  type: "submit",
2562
2882
  label: "Send Message",
2563
- props: { color: "primary" }
2883
+ props: {
2884
+ color: "primary"
2885
+ }
2564
2886
  }
2565
2887
  ]
2566
2888
  }
@@ -2587,13 +2909,17 @@ var examples_default = [
2587
2909
  label: "Email",
2588
2910
  required: true,
2589
2911
  email: true,
2590
- props: { type: "email" }
2912
+ props: {
2913
+ type: "email"
2914
+ }
2591
2915
  },
2592
2916
  {
2593
2917
  key: "addressTitle",
2594
2918
  type: "text",
2595
2919
  label: "Shipping Address",
2596
- props: { elementType: "h4" }
2920
+ props: {
2921
+ elementType: "h4"
2922
+ }
2597
2923
  },
2598
2924
  {
2599
2925
  key: "address",
@@ -2609,8 +2935,20 @@ var examples_default = [
2609
2935
  key: "cityStateRow",
2610
2936
  type: "row",
2611
2937
  fields: [
2612
- { key: "city", type: "input", label: "City", required: true, col: 6 },
2613
- { key: "state", type: "input", label: "State", required: true, col: 3 },
2938
+ {
2939
+ key: "city",
2940
+ type: "input",
2941
+ label: "City",
2942
+ required: true,
2943
+ col: 6
2944
+ },
2945
+ {
2946
+ key: "state",
2947
+ type: "input",
2948
+ label: "State",
2949
+ required: true,
2950
+ col: 3
2951
+ },
2614
2952
  {
2615
2953
  key: "zip",
2616
2954
  type: "input",
@@ -2618,7 +2956,9 @@ var examples_default = [
2618
2956
  required: true,
2619
2957
  col: 3,
2620
2958
  pattern: "^\\d{5}$",
2621
- validationMessages: { pattern: "ZIP must be 5 digits" }
2959
+ validationMessages: {
2960
+ pattern: "ZIP must be 5 digits"
2961
+ }
2622
2962
  }
2623
2963
  ]
2624
2964
  },
@@ -2628,8 +2968,14 @@ var examples_default = [
2628
2968
  label: "Country",
2629
2969
  required: true,
2630
2970
  options: [
2631
- { value: "us", label: "United States" },
2632
- { value: "ca", label: "Canada" }
2971
+ {
2972
+ value: "us",
2973
+ label: "United States"
2974
+ },
2975
+ {
2976
+ value: "ca",
2977
+ label: "Canada"
2978
+ }
2633
2979
  ]
2634
2980
  }
2635
2981
  ]
@@ -2660,12 +3006,37 @@ var examples_default = [
2660
3006
  key: "stepTitle1",
2661
3007
  type: "text",
2662
3008
  label: "Step 1: Personal Information",
2663
- props: { elementType: "h3" }
3009
+ props: {
3010
+ elementType: "h3"
3011
+ }
3012
+ },
3013
+ {
3014
+ key: "firstName",
3015
+ type: "input",
3016
+ label: "First Name",
3017
+ required: true
3018
+ },
3019
+ {
3020
+ key: "lastName",
3021
+ type: "input",
3022
+ label: "Last Name",
3023
+ required: true
3024
+ },
3025
+ {
3026
+ key: "email",
3027
+ type: "input",
3028
+ label: "Email",
3029
+ required: true,
3030
+ email: true,
3031
+ props: {
3032
+ type: "email"
3033
+ }
2664
3034
  },
2665
- { key: "firstName", type: "input", label: "First Name", required: true },
2666
- { key: "lastName", type: "input", label: "Last Name", required: true },
2667
- { key: "email", type: "input", label: "Email", required: true, email: true, props: { type: "email" } },
2668
- { key: "next1", type: "next", label: "Continue" }
3035
+ {
3036
+ key: "next1",
3037
+ type: "next",
3038
+ label: "Continue"
3039
+ }
2669
3040
  ]
2670
3041
  },
2671
3042
  {
@@ -2676,17 +3047,44 @@ var examples_default = [
2676
3047
  key: "stepTitle2",
2677
3048
  type: "text",
2678
3049
  label: "Step 2: Address",
2679
- props: { elementType: "h3" }
3050
+ props: {
3051
+ elementType: "h3"
3052
+ }
3053
+ },
3054
+ {
3055
+ key: "street",
3056
+ type: "input",
3057
+ label: "Street Address",
3058
+ required: true
3059
+ },
3060
+ {
3061
+ key: "city",
3062
+ type: "input",
3063
+ label: "City",
3064
+ required: true
3065
+ },
3066
+ {
3067
+ key: "state",
3068
+ type: "input",
3069
+ label: "State",
3070
+ required: true
2680
3071
  },
2681
- { key: "street", type: "input", label: "Street Address", required: true },
2682
- { key: "city", type: "input", label: "City", required: true },
2683
- { key: "state", type: "input", label: "State", required: true },
2684
3072
  {
2685
3073
  key: "navRow2",
2686
3074
  type: "row",
2687
3075
  fields: [
2688
- { key: "prev2", type: "previous", label: "Back", col: 6 },
2689
- { key: "next2", type: "next", label: "Continue", col: 6 }
3076
+ {
3077
+ key: "prev2",
3078
+ type: "previous",
3079
+ label: "Back",
3080
+ col: 6
3081
+ },
3082
+ {
3083
+ key: "next2",
3084
+ type: "next",
3085
+ label: "Continue",
3086
+ col: 6
3087
+ }
2690
3088
  ]
2691
3089
  }
2692
3090
  ]
@@ -2699,21 +3097,35 @@ var examples_default = [
2699
3097
  key: "stepTitle3",
2700
3098
  type: "text",
2701
3099
  label: "Step 3: Review & Submit",
2702
- props: { elementType: "h3" }
3100
+ props: {
3101
+ elementType: "h3"
3102
+ }
2703
3103
  },
2704
3104
  {
2705
3105
  key: "confirm",
2706
3106
  type: "checkbox",
2707
3107
  label: "I confirm all information is correct",
2708
3108
  required: true,
2709
- validationMessages: { required: "Please confirm before submitting" }
3109
+ validationMessages: {
3110
+ required: "Please confirm before submitting"
3111
+ }
2710
3112
  },
2711
3113
  {
2712
3114
  key: "navRow3",
2713
3115
  type: "row",
2714
3116
  fields: [
2715
- { key: "prev3", type: "previous", label: "Back", col: 6 },
2716
- { key: "submit", type: "submit", label: "Submit", col: 6 }
3117
+ {
3118
+ key: "prev3",
3119
+ type: "previous",
3120
+ label: "Back",
3121
+ col: 6
3122
+ },
3123
+ {
3124
+ key: "submit",
3125
+ type: "submit",
3126
+ label: "Submit",
3127
+ col: 6
3128
+ }
2717
3129
  ]
2718
3130
  }
2719
3131
  ]
@@ -2734,8 +3146,14 @@ var examples_default = [
2734
3146
  label: "Account Type",
2735
3147
  required: true,
2736
3148
  options: [
2737
- { value: "personal", label: "Personal" },
2738
- { value: "business", label: "Business" }
3149
+ {
3150
+ value: "personal",
3151
+ label: "Personal"
3152
+ },
3153
+ {
3154
+ value: "business",
3155
+ label: "Business"
3156
+ }
2739
3157
  ]
2740
3158
  },
2741
3159
  {
@@ -2762,7 +3180,9 @@ var examples_default = [
2762
3180
  }
2763
3181
  }
2764
3182
  ],
2765
- validationMessages: { required: "Business name is required" }
3183
+ validationMessages: {
3184
+ required: "Business name is required"
3185
+ }
2766
3186
  },
2767
3187
  {
2768
3188
  key: "taxId",
@@ -2779,7 +3199,7 @@ var examples_default = [
2779
3199
  }
2780
3200
  }
2781
3201
  ],
2782
- props: { placeholder: "XX-XXXXXXX" }
3202
+ placeholder: "XX-XXXXXXX"
2783
3203
  },
2784
3204
  {
2785
3205
  key: "newsletter",
@@ -2791,9 +3211,18 @@ var examples_default = [
2791
3211
  type: "select",
2792
3212
  label: "Email Frequency",
2793
3213
  options: [
2794
- { value: "daily", label: "Daily" },
2795
- { value: "weekly", label: "Weekly" },
2796
- { value: "monthly", label: "Monthly" }
3214
+ {
3215
+ value: "daily",
3216
+ label: "Daily"
3217
+ },
3218
+ {
3219
+ value: "weekly",
3220
+ label: "Weekly"
3221
+ },
3222
+ {
3223
+ value: "monthly",
3224
+ label: "Monthly"
3225
+ }
2797
3226
  ],
2798
3227
  logic: [
2799
3228
  {
@@ -2835,7 +3264,9 @@ var examples_default = [
2835
3264
  key: "contactsTitle",
2836
3265
  type: "text",
2837
3266
  label: "Emergency Contacts",
2838
- props: { elementType: "h4" }
3267
+ props: {
3268
+ elementType: "h4"
3269
+ }
2839
3270
  },
2840
3271
  {
2841
3272
  key: "contacts",
@@ -2850,19 +3281,49 @@ var examples_default = [
2850
3281
  key: "contactRow",
2851
3282
  type: "row",
2852
3283
  fields: [
2853
- { key: "name", type: "input", label: "Contact Name", required: true, col: 4 },
2854
- { key: "phone", type: "input", label: "Phone", required: true, col: 4, props: { type: "tel" } },
3284
+ {
3285
+ key: "name",
3286
+ type: "input",
3287
+ label: "Contact Name",
3288
+ required: true,
3289
+ col: 4
3290
+ },
3291
+ {
3292
+ key: "phone",
3293
+ type: "input",
3294
+ label: "Phone",
3295
+ required: true,
3296
+ col: 4,
3297
+ props: {
3298
+ type: "tel"
3299
+ }
3300
+ },
2855
3301
  {
2856
3302
  key: "relationship",
2857
3303
  type: "select",
2858
3304
  label: "Relationship",
2859
3305
  col: 4,
2860
3306
  options: [
2861
- { value: "spouse", label: "Spouse" },
2862
- { value: "parent", label: "Parent" },
2863
- { value: "sibling", label: "Sibling" },
2864
- { value: "friend", label: "Friend" },
2865
- { value: "other", label: "Other" }
3307
+ {
3308
+ value: "spouse",
3309
+ label: "Spouse"
3310
+ },
3311
+ {
3312
+ value: "parent",
3313
+ label: "Parent"
3314
+ },
3315
+ {
3316
+ value: "sibling",
3317
+ label: "Sibling"
3318
+ },
3319
+ {
3320
+ value: "friend",
3321
+ label: "Friend"
3322
+ },
3323
+ {
3324
+ value: "other",
3325
+ label: "Other"
3326
+ }
2866
3327
  ]
2867
3328
  }
2868
3329
  ]
@@ -2890,15 +3351,23 @@ var examples_default = [
2890
3351
  key: "title",
2891
3352
  type: "text",
2892
3353
  label: "Customer Feedback",
2893
- props: { elementType: "h2" }
3354
+ props: {
3355
+ elementType: "h2"
3356
+ }
2894
3357
  },
2895
3358
  {
2896
3359
  key: "satisfaction",
2897
3360
  type: "slider",
2898
3361
  label: "Overall Satisfaction (1-10)",
2899
3362
  required: true,
2900
- props: { min: 1, max: 10, step: 1 },
2901
- validationMessages: { required: "Please rate your satisfaction" }
3363
+ props: {
3364
+ min: 1,
3365
+ max: 10,
3366
+ step: 1
3367
+ },
3368
+ validationMessages: {
3369
+ required: "Please rate your satisfaction"
3370
+ }
2902
3371
  },
2903
3372
  {
2904
3373
  key: "recommend",
@@ -2906,30 +3375,62 @@ var examples_default = [
2906
3375
  label: "Would you recommend us?",
2907
3376
  required: true,
2908
3377
  options: [
2909
- { value: "yes", label: "Yes, definitely" },
2910
- { value: "maybe", label: "Maybe" },
2911
- { value: "no", label: "No" }
3378
+ {
3379
+ value: "yes",
3380
+ label: "Yes, definitely"
3381
+ },
3382
+ {
3383
+ value: "maybe",
3384
+ label: "Maybe"
3385
+ },
3386
+ {
3387
+ value: "no",
3388
+ label: "No"
3389
+ }
2912
3390
  ],
2913
- validationMessages: { required: "Please select an option" }
3391
+ validationMessages: {
3392
+ required: "Please select an option"
3393
+ }
2914
3394
  },
2915
3395
  {
2916
3396
  key: "improvements",
2917
3397
  type: "select",
2918
3398
  label: "What could we improve?",
2919
- props: { multiple: true, placeholder: "Select all that apply" },
3399
+ props: {
3400
+ multiple: true
3401
+ },
2920
3402
  options: [
2921
- { value: "speed", label: "Response Time" },
2922
- { value: "quality", label: "Product Quality" },
2923
- { value: "price", label: "Pricing" },
2924
- { value: "support", label: "Customer Support" },
2925
- { value: "ui", label: "User Interface" }
2926
- ]
3403
+ {
3404
+ value: "speed",
3405
+ label: "Response Time"
3406
+ },
3407
+ {
3408
+ value: "quality",
3409
+ label: "Product Quality"
3410
+ },
3411
+ {
3412
+ value: "price",
3413
+ label: "Pricing"
3414
+ },
3415
+ {
3416
+ value: "support",
3417
+ label: "Customer Support"
3418
+ },
3419
+ {
3420
+ value: "ui",
3421
+ label: "User Interface"
3422
+ }
3423
+ ],
3424
+ placeholder: "Select all that apply"
2927
3425
  },
2928
3426
  {
2929
3427
  key: "comments",
2930
3428
  type: "textarea",
2931
3429
  label: "Additional Comments",
2932
- props: { rows: 4, placeholder: "Share any additional feedback..." }
3430
+ props: {
3431
+ rows: 4
3432
+ },
3433
+ placeholder: "Share any additional feedback..."
2933
3434
  },
2934
3435
  {
2935
3436
  key: "followUp",
@@ -2941,7 +3442,9 @@ var examples_default = [
2941
3442
  type: "input",
2942
3443
  label: "Email Address",
2943
3444
  email: true,
2944
- props: { type: "email", placeholder: "your@email.com" },
3445
+ props: {
3446
+ type: "email"
3447
+ },
2945
3448
  logic: [
2946
3449
  {
2947
3450
  type: "hidden",
@@ -2965,7 +3468,8 @@ var examples_default = [
2965
3468
  validationMessages: {
2966
3469
  required: "Email required for follow-up",
2967
3470
  email: "Please enter a valid email"
2968
- }
3471
+ },
3472
+ placeholder: "your@email.com"
2969
3473
  },
2970
3474
  {
2971
3475
  key: "submit",
@@ -3414,7 +3918,7 @@ var MatButtonPropsSchema = z12.object({
3414
3918
  });
3415
3919
 
3416
3920
  // internal/dynamic-forms-zod/material/src/fields/mat-input-field.schema.ts
3417
- import { z as z22 } from "zod";
3921
+ import { z as z23 } from "zod";
3418
3922
 
3419
3923
  // internal/dynamic-forms-zod/src/lib/schemas/field/field-def.schema.ts
3420
3924
  import { z as z14 } from "zod";
@@ -3517,16 +4021,12 @@ var FieldValueConditionSchema = BaseComparisonConditionSchema.extend({
3517
4021
  */
3518
4022
  fieldPath: z15.string()
3519
4023
  });
3520
- var FormValueConditionSchema = BaseComparisonConditionSchema.extend({
3521
- type: z15.literal("formValue")
3522
- });
3523
4024
  var CustomConditionSchema = z15.object({
3524
4025
  type: z15.literal("custom"),
3525
4026
  /**
3526
- * JavaScript expression to evaluate.
3527
- * Has access to: fieldValue, formValue, fieldPath
4027
+ * Name of a registered custom function to invoke.
3528
4028
  */
3529
- expression: z15.string()
4029
+ functionName: z15.string()
3530
4030
  });
3531
4031
  var JavaScriptConditionSchema = z15.object({
3532
4032
  type: z15.literal("javascript"),
@@ -3539,7 +4039,6 @@ var JavaScriptConditionSchema = z15.object({
3539
4039
  var ConditionalExpressionSchema = z15.lazy(
3540
4040
  () => z15.discriminatedUnion("type", [
3541
4041
  FieldValueConditionSchema,
3542
- FormValueConditionSchema,
3543
4042
  CustomConditionSchema,
3544
4043
  JavaScriptConditionSchema,
3545
4044
  AndConditionSchema,
@@ -3628,7 +4127,7 @@ var ValidatorConfigSchema = z16.discriminatedUnion("type", [
3628
4127
  }),
3629
4128
  // Async validators
3630
4129
  BaseValidatorSchema.extend({
3631
- type: z16.literal("customAsync"),
4130
+ type: z16.literal("async"),
3632
4131
  /**
3633
4132
  * Name of a registered async validator function. Required.
3634
4133
  */
@@ -3640,7 +4139,7 @@ var ValidatorConfigSchema = z16.discriminatedUnion("type", [
3640
4139
  }),
3641
4140
  // HTTP validators
3642
4141
  BaseValidatorSchema.extend({
3643
- type: z16.literal("customHttp"),
4142
+ type: z16.literal("http"),
3644
4143
  /**
3645
4144
  * Name of a registered HTTP validator config function. Required.
3646
4145
  */
@@ -3881,16 +4380,31 @@ var FieldWithValidationSchema = z21.object({
3881
4380
  schemas: z21.array(SchemaApplicationConfigSchema).optional()
3882
4381
  });
3883
4382
 
4383
+ // internal/dynamic-forms-zod/src/lib/schemas/field/nullable-value.refinement.ts
4384
+ import { z as z22 } from "zod";
4385
+ var nullableValueRefine = (data, ctx) => {
4386
+ if (!data || typeof data !== "object") return;
4387
+ const field = data;
4388
+ if (field.value === null && field.nullable !== true) {
4389
+ ctx.addIssue({
4390
+ code: z22.ZodIssueCode.custom,
4391
+ path: ["value"],
4392
+ message: "value: null is only allowed when nullable is true. Add `nullable: true` or remove the null value."
4393
+ });
4394
+ }
4395
+ };
4396
+
3884
4397
  // internal/dynamic-forms-zod/material/src/fields/mat-input-field.schema.ts
3885
- var MatInputFieldSchema = BaseFieldDefSchema.merge(FieldWithValidationSchema).extend({
4398
+ var MatInputFieldSchemaObject = BaseFieldDefSchema.merge(FieldWithValidationSchema).extend({
3886
4399
  /**
3887
4400
  * Field type discriminant.
3888
4401
  */
3889
- type: z22.literal("input"),
4402
+ type: z23.literal("input"),
4403
+ nullable: z23.boolean().optional(),
3890
4404
  /**
3891
4405
  * Initial value for the input.
3892
4406
  */
3893
- value: z22.string().optional(),
4407
+ value: z23.string().nullable().optional(),
3894
4408
  /**
3895
4409
  * Placeholder text (can also be in props).
3896
4410
  */
@@ -3900,18 +4414,20 @@ var MatInputFieldSchema = BaseFieldDefSchema.merge(FieldWithValidationSchema).ex
3900
4414
  */
3901
4415
  props: MatInputPropsSchema.optional()
3902
4416
  });
4417
+ var MatInputFieldSchema = MatInputFieldSchemaObject.superRefine(nullableValueRefine);
3903
4418
 
3904
4419
  // internal/dynamic-forms-zod/material/src/fields/mat-textarea-field.schema.ts
3905
- import { z as z23 } from "zod";
3906
- var MatTextareaFieldSchema = BaseFieldDefSchema.merge(FieldWithValidationSchema).extend({
4420
+ import { z as z24 } from "zod";
4421
+ var MatTextareaFieldSchemaObject = BaseFieldDefSchema.merge(FieldWithValidationSchema).extend({
3907
4422
  /**
3908
4423
  * Field type discriminant.
3909
4424
  */
3910
- type: z23.literal("textarea"),
4425
+ type: z24.literal("textarea"),
4426
+ nullable: z24.boolean().optional(),
3911
4427
  /**
3912
4428
  * Initial value for the textarea.
3913
4429
  */
3914
- value: z23.string().optional(),
4430
+ value: z24.string().nullable().optional(),
3915
4431
  /**
3916
4432
  * Placeholder text (can also be in props).
3917
4433
  */
@@ -3921,13 +4437,14 @@ var MatTextareaFieldSchema = BaseFieldDefSchema.merge(FieldWithValidationSchema)
3921
4437
  */
3922
4438
  props: MatTextareaPropsSchema.optional()
3923
4439
  });
4440
+ var MatTextareaFieldSchema = MatTextareaFieldSchemaObject.superRefine(nullableValueRefine);
3924
4441
 
3925
4442
  // internal/dynamic-forms-zod/material/src/fields/mat-select-field.schema.ts
3926
- import { z as z25 } from "zod";
4443
+ import { z as z26 } from "zod";
3927
4444
 
3928
4445
  // internal/dynamic-forms-zod/src/lib/schemas/common/field-option.schema.ts
3929
- import { z as z24 } from "zod";
3930
- var FieldOptionSchema = z24.object({
4446
+ import { z as z25 } from "zod";
4447
+ var FieldOptionSchema = z25.object({
3931
4448
  /**
3932
4449
  * Display text for the option.
3933
4450
  */
@@ -3936,25 +4453,26 @@ var FieldOptionSchema = z24.object({
3936
4453
  * The actual value stored when this option is selected.
3937
4454
  * Can be any JSON-serializable value.
3938
4455
  */
3939
- value: z24.unknown(),
4456
+ value: z25.unknown(),
3940
4457
  /**
3941
4458
  * Whether this option is disabled and cannot be selected.
3942
4459
  */
3943
- disabled: z24.boolean().optional()
4460
+ disabled: z25.boolean().optional()
3944
4461
  }).passthrough();
3945
- var FieldOptionsSchema = z24.array(FieldOptionSchema);
4462
+ var FieldOptionsSchema = z25.array(FieldOptionSchema);
3946
4463
 
3947
4464
  // internal/dynamic-forms-zod/material/src/fields/mat-select-field.schema.ts
3948
- var MatSelectFieldSchema = BaseFieldDefSchema.merge(FieldWithValidationSchema).extend({
4465
+ var MatSelectFieldSchemaObject = BaseFieldDefSchema.merge(FieldWithValidationSchema).extend({
3949
4466
  /**
3950
4467
  * Field type discriminant.
3951
4468
  */
3952
- type: z25.literal("select"),
4469
+ type: z26.literal("select"),
4470
+ nullable: z26.boolean().optional(),
3953
4471
  /**
3954
4472
  * Initial value for the select.
3955
4473
  * Can be single value or array if multiple is enabled.
3956
4474
  */
3957
- value: z25.unknown().optional(),
4475
+ value: z26.unknown().nullable().optional(),
3958
4476
  /**
3959
4477
  * Placeholder text (can also be in props).
3960
4478
  */
@@ -3968,18 +4486,19 @@ var MatSelectFieldSchema = BaseFieldDefSchema.merge(FieldWithValidationSchema).e
3968
4486
  */
3969
4487
  props: MatSelectPropsSchema.optional()
3970
4488
  });
4489
+ var MatSelectFieldSchema = MatSelectFieldSchemaObject.superRefine(nullableValueRefine);
3971
4490
 
3972
4491
  // internal/dynamic-forms-zod/material/src/fields/mat-checkbox-field.schema.ts
3973
- import { z as z26 } from "zod";
4492
+ import { z as z27 } from "zod";
3974
4493
  var MatCheckboxFieldSchema = BaseFieldDefSchema.merge(FieldWithValidationSchema).extend({
3975
4494
  /**
3976
4495
  * Field type discriminant.
3977
4496
  */
3978
- type: z26.literal("checkbox"),
4497
+ type: z27.literal("checkbox"),
3979
4498
  /**
3980
4499
  * Initial checked state.
3981
4500
  */
3982
- value: z26.boolean().optional(),
4501
+ value: z27.boolean().optional(),
3983
4502
  /**
3984
4503
  * Placeholder/helper text.
3985
4504
  */
@@ -3991,16 +4510,17 @@ var MatCheckboxFieldSchema = BaseFieldDefSchema.merge(FieldWithValidationSchema)
3991
4510
  });
3992
4511
 
3993
4512
  // internal/dynamic-forms-zod/material/src/fields/mat-radio-field.schema.ts
3994
- import { z as z27 } from "zod";
3995
- var MatRadioFieldSchema = BaseFieldDefSchema.merge(FieldWithValidationSchema).extend({
4513
+ import { z as z28 } from "zod";
4514
+ var MatRadioFieldSchemaObject = BaseFieldDefSchema.merge(FieldWithValidationSchema).extend({
3996
4515
  /**
3997
4516
  * Field type discriminant.
3998
4517
  */
3999
- type: z27.literal("radio"),
4518
+ type: z28.literal("radio"),
4519
+ nullable: z28.boolean().optional(),
4000
4520
  /**
4001
4521
  * Initial selected value.
4002
4522
  */
4003
- value: z27.unknown().optional(),
4523
+ value: z28.unknown().nullable().optional(),
4004
4524
  /**
4005
4525
  * Placeholder/helper text.
4006
4526
  */
@@ -4014,18 +4534,20 @@ var MatRadioFieldSchema = BaseFieldDefSchema.merge(FieldWithValidationSchema).ex
4014
4534
  */
4015
4535
  props: MatRadioPropsSchema.optional()
4016
4536
  });
4537
+ var MatRadioFieldSchema = MatRadioFieldSchemaObject.superRefine(nullableValueRefine);
4017
4538
 
4018
4539
  // internal/dynamic-forms-zod/material/src/fields/mat-multi-checkbox-field.schema.ts
4019
- import { z as z28 } from "zod";
4020
- var MatMultiCheckboxFieldSchema = BaseFieldDefSchema.merge(FieldWithValidationSchema).extend({
4540
+ import { z as z29 } from "zod";
4541
+ var MatMultiCheckboxFieldSchemaObject = BaseFieldDefSchema.merge(FieldWithValidationSchema).extend({
4021
4542
  /**
4022
4543
  * Field type discriminant.
4023
4544
  */
4024
- type: z28.literal("multi-checkbox"),
4545
+ type: z29.literal("multi-checkbox"),
4546
+ nullable: z29.boolean().optional(),
4025
4547
  /**
4026
4548
  * Initial selected values (array).
4027
4549
  */
4028
- value: z28.array(z28.unknown()).optional(),
4550
+ value: z29.array(z29.unknown()).nullable().optional(),
4029
4551
  /**
4030
4552
  * Placeholder/helper text.
4031
4553
  */
@@ -4039,18 +4561,19 @@ var MatMultiCheckboxFieldSchema = BaseFieldDefSchema.merge(FieldWithValidationSc
4039
4561
  */
4040
4562
  props: MatMultiCheckboxPropsSchema.optional()
4041
4563
  });
4564
+ var MatMultiCheckboxFieldSchema = MatMultiCheckboxFieldSchemaObject.superRefine(nullableValueRefine);
4042
4565
 
4043
4566
  // internal/dynamic-forms-zod/material/src/fields/mat-toggle-field.schema.ts
4044
- import { z as z29 } from "zod";
4567
+ import { z as z30 } from "zod";
4045
4568
  var MatToggleFieldSchema = BaseFieldDefSchema.merge(FieldWithValidationSchema).extend({
4046
4569
  /**
4047
4570
  * Field type discriminant.
4048
4571
  */
4049
- type: z29.literal("toggle"),
4572
+ type: z30.literal("toggle"),
4050
4573
  /**
4051
4574
  * Initial toggle state.
4052
4575
  */
4053
- value: z29.boolean().optional(),
4576
+ value: z30.boolean().optional(),
4054
4577
  /**
4055
4578
  * Placeholder/helper text.
4056
4579
  */
@@ -4062,28 +4585,29 @@ var MatToggleFieldSchema = BaseFieldDefSchema.merge(FieldWithValidationSchema).e
4062
4585
  });
4063
4586
 
4064
4587
  // internal/dynamic-forms-zod/material/src/fields/mat-slider-field.schema.ts
4065
- import { z as z30 } from "zod";
4066
- var MatSliderFieldSchema = BaseFieldDefSchema.merge(FieldWithValidationSchema).extend({
4588
+ import { z as z31 } from "zod";
4589
+ var MatSliderFieldSchemaObject = BaseFieldDefSchema.merge(FieldWithValidationSchema).extend({
4067
4590
  /**
4068
4591
  * Field type discriminant.
4069
4592
  */
4070
- type: z30.literal("slider"),
4593
+ type: z31.literal("slider"),
4594
+ nullable: z31.boolean().optional(),
4071
4595
  /**
4072
4596
  * Initial slider value.
4073
4597
  */
4074
- value: z30.number().optional(),
4598
+ value: z31.number().nullable().optional(),
4075
4599
  /**
4076
4600
  * Minimum slider value.
4077
4601
  */
4078
- minValue: z30.number().optional(),
4602
+ minValue: z31.number().optional(),
4079
4603
  /**
4080
4604
  * Maximum slider value.
4081
4605
  */
4082
- maxValue: z30.number().optional(),
4606
+ maxValue: z31.number().optional(),
4083
4607
  /**
4084
4608
  * Step increment.
4085
4609
  */
4086
- step: z30.number().positive().optional(),
4610
+ step: z31.number().positive().optional(),
4087
4611
  /**
4088
4612
  * Placeholder/helper text.
4089
4613
  */
@@ -4093,19 +4617,21 @@ var MatSliderFieldSchema = BaseFieldDefSchema.merge(FieldWithValidationSchema).e
4093
4617
  */
4094
4618
  props: MatSliderPropsSchema.optional()
4095
4619
  });
4620
+ var MatSliderFieldSchema = MatSliderFieldSchemaObject.superRefine(nullableValueRefine);
4096
4621
 
4097
4622
  // internal/dynamic-forms-zod/material/src/fields/mat-datepicker-field.schema.ts
4098
- import { z as z31 } from "zod";
4099
- var DateValueSchema = z31.union([z31.string(), z31.null()]);
4100
- var MatDatepickerFieldSchema = BaseFieldDefSchema.merge(FieldWithValidationSchema).extend({
4623
+ import { z as z32 } from "zod";
4624
+ var DateValueSchema = z32.union([z32.string(), z32.null()]);
4625
+ var MatDatepickerFieldSchemaObject = BaseFieldDefSchema.merge(FieldWithValidationSchema).extend({
4101
4626
  /**
4102
4627
  * Field type discriminant.
4103
4628
  */
4104
- type: z31.literal("datepicker"),
4629
+ type: z32.literal("datepicker"),
4630
+ nullable: z32.boolean().optional(),
4105
4631
  /**
4106
4632
  * Initial date value (ISO string in JSON configs).
4107
4633
  */
4108
- value: DateValueSchema.optional(),
4634
+ value: DateValueSchema.nullable().optional(),
4109
4635
  /**
4110
4636
  * Minimum selectable date.
4111
4637
  */
@@ -4127,24 +4653,25 @@ var MatDatepickerFieldSchema = BaseFieldDefSchema.merge(FieldWithValidationSchem
4127
4653
  */
4128
4654
  props: MatDatepickerPropsSchema.optional()
4129
4655
  });
4656
+ var MatDatepickerFieldSchema = MatDatepickerFieldSchemaObject.superRefine(nullableValueRefine);
4130
4657
 
4131
4658
  // internal/dynamic-forms-zod/material/src/fields/mat-button-field.schema.ts
4132
- import { z as z32 } from "zod";
4133
- var EventArgSchema = z32.union([z32.string(), z32.number(), z32.boolean(), z32.null(), z32.undefined()]);
4659
+ import { z as z33 } from "zod";
4660
+ var EventArgSchema = z33.union([z33.string(), z33.number(), z33.boolean(), z33.null(), z33.undefined()]);
4134
4661
  var MatButtonFieldSchema = BaseFieldDefSchema.extend({
4135
4662
  /**
4136
4663
  * Field type discriminant.
4137
4664
  */
4138
- type: z32.literal("button"),
4665
+ type: z33.literal("button"),
4139
4666
  /**
4140
4667
  * Event type name (string reference to registered event).
4141
4668
  * Note: Full event configuration requires runtime setup.
4142
4669
  */
4143
- event: z32.string().optional(),
4670
+ event: z33.string().optional(),
4144
4671
  /**
4145
4672
  * Arguments passed to the event constructor.
4146
4673
  */
4147
- eventArgs: z32.array(EventArgSchema).optional(),
4674
+ eventArgs: z33.array(EventArgSchema).optional(),
4148
4675
  /**
4149
4676
  * Material-specific button properties.
4150
4677
  */
@@ -4155,45 +4682,45 @@ var MatButtonFieldSchema = BaseFieldDefSchema.extend({
4155
4682
  logic: LogicArraySchema.optional()
4156
4683
  });
4157
4684
  var MatSubmitButtonFieldSchema = BaseFieldDefSchema.extend({
4158
- type: z32.literal("submit"),
4685
+ type: z33.literal("submit"),
4159
4686
  props: MatButtonPropsSchema.optional(),
4160
4687
  logic: LogicArraySchema.optional()
4161
4688
  });
4162
4689
  var MatNextButtonFieldSchema = BaseFieldDefSchema.extend({
4163
- type: z32.literal("next"),
4690
+ type: z33.literal("next"),
4164
4691
  props: MatButtonPropsSchema.optional(),
4165
4692
  logic: LogicArraySchema.optional()
4166
4693
  });
4167
4694
  var MatPreviousButtonFieldSchema = BaseFieldDefSchema.extend({
4168
- type: z32.literal("previous"),
4695
+ type: z33.literal("previous"),
4169
4696
  props: MatButtonPropsSchema.optional()
4170
4697
  });
4171
4698
  var MatAddArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
4172
- type: z32.literal("addArrayItem"),
4699
+ type: z33.literal("addArrayItem"),
4173
4700
  /**
4174
4701
  * Key of the array field to add items to.
4175
4702
  * If omitted, uses the parent array context.
4176
4703
  */
4177
- arrayKey: z32.string().optional(),
4704
+ arrayKey: z33.string().optional(),
4178
4705
  props: MatButtonPropsSchema.optional()
4179
4706
  });
4180
4707
  var MatRemoveArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
4181
- type: z32.literal("removeArrayItem"),
4708
+ type: z33.literal("removeArrayItem"),
4182
4709
  /**
4183
4710
  * Key of the array field to remove items from.
4184
4711
  * If omitted, uses the parent array context.
4185
4712
  */
4186
- arrayKey: z32.string().optional(),
4713
+ arrayKey: z33.string().optional(),
4187
4714
  props: MatButtonPropsSchema.optional()
4188
4715
  });
4189
4716
 
4190
4717
  // internal/dynamic-forms-zod/material/src/mat-leaf-field.schema.ts
4191
- import { z as z35 } from "zod";
4718
+ import { z as z36 } from "zod";
4192
4719
 
4193
4720
  // internal/dynamic-forms-zod/src/lib/schemas/leaves/text-field.schema.ts
4194
- import { z as z33 } from "zod";
4195
- var TextElementTypeSchema = z33.enum(["p", "h1", "h2", "h3", "h4", "h5", "h6", "span"]);
4196
- var TextPropsSchema = z33.object({
4721
+ import { z as z34 } from "zod";
4722
+ var TextElementTypeSchema = z34.enum(["p", "h1", "h2", "h3", "h4", "h5", "h6", "span"]);
4723
+ var TextPropsSchema = z34.object({
4197
4724
  /**
4198
4725
  * HTML element type to render the text.
4199
4726
  */
@@ -4203,7 +4730,7 @@ var TextFieldSchema = BaseFieldDefSchema.extend({
4203
4730
  /**
4204
4731
  * Field type discriminant.
4205
4732
  */
4206
- type: z33.literal("text"),
4733
+ type: z34.literal("text"),
4207
4734
  /**
4208
4735
  * Text-specific properties.
4209
4736
  */
@@ -4215,9 +4742,9 @@ var TextFieldSchema = BaseFieldDefSchema.extend({
4215
4742
  });
4216
4743
 
4217
4744
  // internal/dynamic-forms-zod/src/lib/schemas/leaves/hidden-field.schema.ts
4218
- import { z as z34 } from "zod";
4219
- var HiddenScalarSchema = z34.union([z34.string(), z34.number(), z34.boolean()]);
4220
- var HiddenValueSchema = z34.union([HiddenScalarSchema, z34.array(HiddenScalarSchema)]);
4745
+ import { z as z35 } from "zod";
4746
+ var HiddenScalarSchema = z35.union([z35.string(), z35.number(), z35.boolean()]);
4747
+ var HiddenValueSchema = z35.union([HiddenScalarSchema, z35.array(HiddenScalarSchema)]);
4221
4748
  var HiddenFieldSchema = BaseFieldDefSchema.omit({
4222
4749
  label: true,
4223
4750
  meta: true,
@@ -4233,7 +4760,7 @@ var HiddenFieldSchema = BaseFieldDefSchema.omit({
4233
4760
  /**
4234
4761
  * Field type discriminant.
4235
4762
  */
4236
- type: z34.literal("hidden"),
4763
+ type: z35.literal("hidden"),
4237
4764
  /**
4238
4765
  * The value to store. Required for hidden fields.
4239
4766
  */
@@ -4241,20 +4768,20 @@ var HiddenFieldSchema = BaseFieldDefSchema.omit({
4241
4768
  });
4242
4769
 
4243
4770
  // internal/dynamic-forms-zod/material/src/mat-leaf-field.schema.ts
4244
- var MatLeafFieldSchema = z35.discriminatedUnion("type", [
4771
+ var MatLeafFieldSchema = z36.discriminatedUnion("type", [
4245
4772
  // Default fields
4246
4773
  TextFieldSchema,
4247
4774
  HiddenFieldSchema,
4248
4775
  // Material value fields
4249
- MatInputFieldSchema,
4250
- MatTextareaFieldSchema,
4251
- MatSelectFieldSchema,
4776
+ MatInputFieldSchemaObject,
4777
+ MatTextareaFieldSchemaObject,
4778
+ MatSelectFieldSchemaObject,
4252
4779
  MatCheckboxFieldSchema,
4253
- MatRadioFieldSchema,
4254
- MatMultiCheckboxFieldSchema,
4780
+ MatRadioFieldSchemaObject,
4781
+ MatMultiCheckboxFieldSchemaObject,
4255
4782
  MatToggleFieldSchema,
4256
- MatSliderFieldSchema,
4257
- MatDatepickerFieldSchema,
4783
+ MatSliderFieldSchemaObject,
4784
+ MatDatepickerFieldSchemaObject,
4258
4785
  // Material button fields
4259
4786
  MatButtonFieldSchema,
4260
4787
  MatSubmitButtonFieldSchema,
@@ -4262,18 +4789,18 @@ var MatLeafFieldSchema = z35.discriminatedUnion("type", [
4262
4789
  MatPreviousButtonFieldSchema,
4263
4790
  MatAddArrayItemButtonFieldSchema,
4264
4791
  MatRemoveArrayItemButtonFieldSchema
4265
- ]);
4792
+ ]).superRefine(nullableValueRefine);
4266
4793
 
4267
4794
  // internal/dynamic-forms-zod/src/lib/schemas/containers/factories.ts
4268
- import { z as z36 } from "zod";
4269
- var ContainerLogicSchema = z36.object({
4270
- type: z36.literal("hidden"),
4271
- condition: z36.union([ConditionalExpressionSchema, z36.boolean()])
4795
+ import { z as z37 } from "zod";
4796
+ var ContainerLogicSchema = z37.object({
4797
+ type: z37.literal("hidden"),
4798
+ condition: z37.union([ConditionalExpressionSchema, z37.boolean()])
4272
4799
  });
4273
4800
  function createContainerSchemas(options) {
4274
4801
  const { leafFieldSchema } = options;
4275
- const AnyFieldSchema = z36.lazy(
4276
- () => z36.union([
4802
+ const AnyFieldSchema = z37.lazy(
4803
+ () => z37.union([
4277
4804
  leafFieldSchema,
4278
4805
  PageFieldSchema,
4279
4806
  RowFieldSchema,
@@ -4287,67 +4814,67 @@ function createContainerSchemas(options) {
4287
4814
  }).extend({
4288
4815
  // Explicitly forbid label on container fields
4289
4816
  // This makes Zod reject any value for these properties
4290
- label: z36.never().optional(),
4291
- meta: z36.never().optional()
4817
+ label: z37.never().optional(),
4818
+ meta: z37.never().optional()
4292
4819
  });
4293
4820
  const PageFieldSchema = ContainerBaseSchema.extend({
4294
- type: z36.literal("page"),
4295
- fields: z36.array(AnyFieldSchema),
4296
- logic: z36.array(ContainerLogicSchema).optional(),
4821
+ type: z37.literal("page"),
4822
+ fields: z37.array(AnyFieldSchema),
4823
+ logic: z37.array(ContainerLogicSchema).optional(),
4297
4824
  // Also forbid title (common mistake)
4298
- title: z36.never().optional()
4825
+ title: z37.never().optional()
4299
4826
  });
4300
4827
  const RowFieldSchema = ContainerBaseSchema.extend({
4301
- type: z36.literal("row"),
4302
- fields: z36.array(AnyFieldSchema),
4828
+ type: z37.literal("row"),
4829
+ fields: z37.array(AnyFieldSchema),
4303
4830
  // Container logic - only 'hidden' type allowed (same as pages)
4304
- logic: z36.array(ContainerLogicSchema).optional()
4831
+ logic: z37.array(ContainerLogicSchema).optional()
4305
4832
  });
4306
4833
  const GroupFieldSchema = ContainerBaseSchema.extend({
4307
- type: z36.literal("group"),
4308
- fields: z36.array(AnyFieldSchema),
4834
+ type: z37.literal("group"),
4835
+ fields: z37.array(AnyFieldSchema),
4309
4836
  // Container logic - only 'hidden' type allowed (same as pages)
4310
- logic: z36.array(ContainerLogicSchema).optional()
4837
+ logic: z37.array(ContainerLogicSchema).optional()
4311
4838
  });
4312
- const ArrayButtonConfigSchema = z36.object({
4313
- label: z36.string().optional(),
4314
- props: z36.record(z36.unknown()).optional()
4839
+ const ArrayButtonConfigSchema = z37.object({
4840
+ label: z37.string().optional(),
4841
+ props: z37.record(z37.unknown()).optional()
4315
4842
  });
4316
4843
  const FullArrayFieldSchema = ContainerBaseSchema.extend({
4317
- type: z36.literal("array"),
4318
- fields: z36.array(AnyFieldSchema),
4319
- logic: z36.array(ContainerLogicSchema).optional(),
4844
+ type: z37.literal("array"),
4845
+ fields: z37.array(AnyFieldSchema),
4846
+ logic: z37.array(ContainerLogicSchema).optional(),
4320
4847
  // Full API does not use template
4321
- template: z36.never().optional(),
4848
+ template: z37.never().optional(),
4322
4849
  // Array length validation
4323
- minLength: z36.number().int().min(0).optional(),
4324
- maxLength: z36.number().int().min(0).optional()
4850
+ minLength: z37.number().int().min(0).optional(),
4851
+ maxLength: z37.number().int().min(0).optional()
4325
4852
  });
4326
- const ArrayAllowedChildSchema = z36.lazy(
4853
+ const ArrayAllowedChildSchema = z37.lazy(
4327
4854
  () => AnyFieldSchema.refine((field) => field.type !== "page" && field.type !== "array", {
4328
4855
  message: "Array templates cannot contain page or array fields. Only leaf fields, rows, and groups are allowed."
4329
4856
  })
4330
4857
  );
4331
4858
  const SimplifiedArrayFieldSchema = ContainerBaseSchema.extend({
4332
- type: z36.literal("array"),
4859
+ type: z37.literal("array"),
4333
4860
  // Template: single field (primitive array) or array of fields (object array)
4334
4861
  // Only ArrayAllowedChildren (leaf fields, rows, groups) are valid — no pages or nested arrays.
4335
- template: z36.union([ArrayAllowedChildSchema, z36.array(ArrayAllowedChildSchema)]),
4862
+ template: z37.union([ArrayAllowedChildSchema, z37.array(ArrayAllowedChildSchema)]),
4336
4863
  // Initial values for the array
4337
- value: z36.array(z36.unknown()).optional(),
4864
+ value: z37.array(z37.unknown()).optional(),
4338
4865
  // Button customization or opt-out (false to disable)
4339
- addButton: z36.union([ArrayButtonConfigSchema, z36.literal(false)]).optional(),
4340
- removeButton: z36.union([ArrayButtonConfigSchema, z36.literal(false)]).optional(),
4341
- logic: z36.array(ContainerLogicSchema).optional(),
4866
+ addButton: z37.union([ArrayButtonConfigSchema, z37.literal(false)]).optional(),
4867
+ removeButton: z37.union([ArrayButtonConfigSchema, z37.literal(false)]).optional(),
4868
+ logic: z37.array(ContainerLogicSchema).optional(),
4342
4869
  // Array length validation
4343
- minLength: z36.number().int().min(0).optional(),
4344
- maxLength: z36.number().int().min(0).optional(),
4870
+ minLength: z37.number().int().min(0).optional(),
4871
+ maxLength: z37.number().int().min(0).optional(),
4345
4872
  // Simplified API does not use fields
4346
- fields: z36.never().optional(),
4347
- minItems: z36.never().optional(),
4348
- maxItems: z36.never().optional()
4873
+ fields: z37.never().optional(),
4874
+ minItems: z37.never().optional(),
4875
+ maxItems: z37.never().optional()
4349
4876
  });
4350
- const ArrayFieldSchema = z36.union([FullArrayFieldSchema, SimplifiedArrayFieldSchema]);
4877
+ const ArrayFieldSchema = z37.union([FullArrayFieldSchema, SimplifiedArrayFieldSchema]);
4351
4878
  const AllFieldsSchema = AnyFieldSchema;
4352
4879
  return {
4353
4880
  PageFieldSchema,
@@ -4369,48 +4896,48 @@ var MatArrayFieldSchema = containerSchemas.ArrayFieldSchema;
4369
4896
  var MatFieldSchema = containerSchemas.AllFieldsSchema;
4370
4897
 
4371
4898
  // internal/dynamic-forms-zod/material/src/mat-form-config.schema.ts
4372
- import { z as z40 } from "zod";
4899
+ import { z as z41 } from "zod";
4373
4900
 
4374
4901
  // internal/dynamic-forms-zod/src/lib/schemas/form/form-config.schema.ts
4375
- import { z as z39 } from "zod";
4902
+ import { z as z40 } from "zod";
4376
4903
 
4377
4904
  // internal/dynamic-forms-zod/src/lib/schemas/form/form-options.schema.ts
4378
- import { z as z37 } from "zod";
4379
- var SubmitButtonOptionsSchema = z37.object({
4905
+ import { z as z38 } from "zod";
4906
+ var SubmitButtonOptionsSchema = z38.object({
4380
4907
  /**
4381
4908
  * Whether to disable the submit button when the form is invalid.
4382
4909
  * Defaults to true.
4383
4910
  */
4384
- disableWhenInvalid: z37.boolean().optional(),
4911
+ disableWhenInvalid: z38.boolean().optional(),
4385
4912
  /**
4386
4913
  * Whether to disable the submit button while the form is submitting.
4387
4914
  * Defaults to true.
4388
4915
  */
4389
- disableWhileSubmitting: z37.boolean().optional()
4916
+ disableWhileSubmitting: z38.boolean().optional()
4390
4917
  });
4391
- var NextButtonOptionsSchema = z37.object({
4918
+ var NextButtonOptionsSchema = z38.object({
4392
4919
  /**
4393
4920
  * Whether to disable the next button when the current page is invalid.
4394
4921
  * Defaults to true.
4395
4922
  */
4396
- disableWhenPageInvalid: z37.boolean().optional(),
4923
+ disableWhenPageInvalid: z38.boolean().optional(),
4397
4924
  /**
4398
4925
  * Whether to disable the next button while the form is submitting.
4399
4926
  * Defaults to true.
4400
4927
  */
4401
- disableWhileSubmitting: z37.boolean().optional()
4928
+ disableWhileSubmitting: z38.boolean().optional()
4402
4929
  });
4403
- var FormOptionsSchema = z37.object({
4930
+ var FormOptionsSchema = z38.object({
4404
4931
  /**
4405
4932
  * Whether the entire form is disabled.
4406
4933
  */
4407
- disabled: z37.boolean().optional(),
4934
+ disabled: z38.boolean().optional(),
4408
4935
  /**
4409
4936
  * Maximum number of derivation iterations before stopping.
4410
4937
  * Prevents infinite loops in circular derivations.
4411
4938
  * Defaults to 10.
4412
4939
  */
4413
- maxDerivationIterations: z37.number().positive().optional(),
4940
+ maxDerivationIterations: z38.number().positive().optional(),
4414
4941
  /**
4415
4942
  * Options for the submit button behavior.
4416
4943
  */
@@ -4423,36 +4950,36 @@ var FormOptionsSchema = z37.object({
4423
4950
  * Whether to exclude values of hidden fields from submission output.
4424
4951
  * Overrides the global withValueExclusionDefaults() setting for this form.
4425
4952
  */
4426
- excludeValueIfHidden: z37.boolean().optional(),
4953
+ excludeValueIfHidden: z38.boolean().optional(),
4427
4954
  /**
4428
4955
  * Whether to exclude values of disabled fields from submission output.
4429
4956
  * Overrides the global withValueExclusionDefaults() setting for this form.
4430
4957
  */
4431
- excludeValueIfDisabled: z37.boolean().optional(),
4958
+ excludeValueIfDisabled: z38.boolean().optional(),
4432
4959
  /**
4433
4960
  * Whether to exclude values of readonly fields from submission output.
4434
4961
  * Overrides the global withValueExclusionDefaults() setting for this form.
4435
4962
  */
4436
- excludeValueIfReadonly: z37.boolean().optional()
4963
+ excludeValueIfReadonly: z38.boolean().optional()
4437
4964
  });
4438
4965
 
4439
4966
  // internal/dynamic-forms-zod/src/lib/schemas/form/schema-definition.schema.ts
4440
- import { z as z38 } from "zod";
4441
- var SchemaDefinitionSchema = z38.object({
4967
+ import { z as z39 } from "zod";
4968
+ var SchemaDefinitionSchema = z39.object({
4442
4969
  /**
4443
4970
  * Unique identifier for the schema.
4444
4971
  * Used to reference the schema in SchemaApplicationConfig.
4445
4972
  */
4446
- name: z38.string(),
4973
+ name: z39.string(),
4447
4974
  /**
4448
4975
  * Human-readable description of what this schema validates.
4449
4976
  */
4450
- description: z38.string().optional(),
4977
+ description: z39.string().optional(),
4451
4978
  /**
4452
4979
  * Field path pattern for automatic schema application.
4453
4980
  * Supports glob-like patterns.
4454
4981
  */
4455
- pathPattern: z38.string().optional(),
4982
+ pathPattern: z39.string().optional(),
4456
4983
  /**
4457
4984
  * Validators to apply to fields using this schema.
4458
4985
  */
@@ -4464,17 +4991,17 @@ var SchemaDefinitionSchema = z38.object({
4464
4991
  /**
4465
4992
  * Nested schema applications for composing schemas.
4466
4993
  */
4467
- subSchemas: z38.array(SchemaApplicationConfigSchema).optional()
4994
+ subSchemas: z39.array(SchemaApplicationConfigSchema).optional()
4468
4995
  });
4469
- var SchemaDefinitionsArraySchema = z38.array(SchemaDefinitionSchema);
4996
+ var SchemaDefinitionsArraySchema = z39.array(SchemaDefinitionSchema);
4470
4997
 
4471
4998
  // internal/dynamic-forms-zod/src/lib/schemas/form/form-config.schema.ts
4472
4999
  function createFormConfigSchema(fieldSchema, propsSchema) {
4473
- const baseSchema = z39.object({
5000
+ const baseSchema = z40.object({
4474
5001
  /**
4475
5002
  * Array of field definitions that make up the form.
4476
5003
  */
4477
- fields: z39.array(fieldSchema),
5004
+ fields: z40.array(fieldSchema),
4478
5005
  /**
4479
5006
  * Form-level options controlling behavior.
4480
5007
  */
@@ -4514,15 +5041,15 @@ function createFormConfigSchema(fieldSchema, propsSchema) {
4514
5041
  }
4515
5042
  return baseSchema;
4516
5043
  }
4517
- var BaseFormConfigSchema = z39.object({
4518
- fields: z39.array(z39.any()),
5044
+ var BaseFormConfigSchema = z40.object({
5045
+ fields: z40.array(z40.any()),
4519
5046
  options: FormOptionsSchema.optional(),
4520
5047
  schemas: SchemaDefinitionsArraySchema.optional(),
4521
5048
  defaultValidationMessages: ValidationMessagesSchema.optional()
4522
5049
  });
4523
5050
 
4524
5051
  // internal/dynamic-forms-zod/material/src/mat-form-config.schema.ts
4525
- var MatFormDefaultPropsSchema = z40.object({
5052
+ var MatFormDefaultPropsSchema = z41.object({
4526
5053
  /**
4527
5054
  * Default form field appearance for all fields.
4528
5055
  */
@@ -4539,15 +5066,15 @@ var MatFormDefaultPropsSchema = z40.object({
4539
5066
  var MatFormConfigSchema = createFormConfigSchema(MatFieldSchema, MatFormDefaultPropsSchema);
4540
5067
 
4541
5068
  // internal/dynamic-forms-zod/bootstrap/src/props/index.ts
4542
- import { z as z42 } from "zod";
5069
+ import { z as z43 } from "zod";
4543
5070
 
4544
5071
  // internal/dynamic-forms-zod/bootstrap/src/props/bs-common-props.schema.ts
4545
- import { z as z41 } from "zod";
4546
- var BsSizeSchema = z41.enum(["sm", "lg"]);
4547
- var BsButtonVariantSchema = z41.enum(["primary", "secondary", "success", "danger", "warning", "info", "light", "dark", "link"]);
4548
- var BsFormFieldPropsSchema = z41.object({
5072
+ import { z as z42 } from "zod";
5073
+ var BsSizeSchema = z42.enum(["sm", "lg"]);
5074
+ var BsButtonVariantSchema = z42.enum(["primary", "secondary", "success", "danger", "warning", "info", "light", "dark", "link"]);
5075
+ var BsFormFieldPropsSchema = z42.object({
4549
5076
  size: BsSizeSchema.optional(),
4550
- floatingLabel: z41.boolean().optional(),
5077
+ floatingLabel: z42.boolean().optional(),
4551
5078
  hint: DynamicTextSchema.optional(),
4552
5079
  validFeedback: DynamicTextSchema.optional(),
4553
5080
  invalidFeedback: DynamicTextSchema.optional()
@@ -4555,194 +5082,208 @@ var BsFormFieldPropsSchema = z41.object({
4555
5082
 
4556
5083
  // internal/dynamic-forms-zod/bootstrap/src/props/index.ts
4557
5084
  var BsInputPropsSchema = BsFormFieldPropsSchema.extend({
4558
- type: z42.enum(["text", "email", "password", "number", "tel", "url"]).optional(),
5085
+ type: z43.enum(["text", "email", "password", "number", "tel", "url"]).optional(),
4559
5086
  placeholder: DynamicTextSchema.optional(),
4560
- plaintext: z42.boolean().optional()
5087
+ plaintext: z43.boolean().optional()
4561
5088
  });
4562
5089
  var BsTextareaPropsSchema = BsFormFieldPropsSchema.extend({
4563
- rows: z42.number().positive().optional(),
5090
+ rows: z43.number().positive().optional(),
4564
5091
  placeholder: DynamicTextSchema.optional()
4565
5092
  });
4566
5093
  var BsSelectPropsSchema = BsFormFieldPropsSchema.extend({
4567
- multiple: z42.boolean().optional(),
4568
- htmlSize: z42.number().positive().optional(),
5094
+ multiple: z43.boolean().optional(),
5095
+ htmlSize: z43.number().positive().optional(),
4569
5096
  placeholder: DynamicTextSchema.optional()
4570
5097
  });
4571
- var BsCheckboxPropsSchema = z42.object({
4572
- switch: z42.boolean().optional(),
4573
- inline: z42.boolean().optional(),
4574
- reverse: z42.boolean().optional(),
4575
- indeterminate: z42.boolean().optional(),
5098
+ var BsCheckboxPropsSchema = z43.object({
5099
+ switch: z43.boolean().optional(),
5100
+ inline: z43.boolean().optional(),
5101
+ reverse: z43.boolean().optional(),
5102
+ indeterminate: z43.boolean().optional(),
4576
5103
  hint: DynamicTextSchema.optional()
4577
5104
  });
4578
- var BsRadioPropsSchema = z42.object({
4579
- inline: z42.boolean().optional(),
4580
- reverse: z42.boolean().optional(),
4581
- buttonGroup: z42.boolean().optional(),
5105
+ var BsRadioPropsSchema = z43.object({
5106
+ inline: z43.boolean().optional(),
5107
+ reverse: z43.boolean().optional(),
5108
+ buttonGroup: z43.boolean().optional(),
4582
5109
  buttonSize: BsSizeSchema.optional(),
4583
5110
  hint: DynamicTextSchema.optional()
4584
5111
  });
4585
- var BsMultiCheckboxPropsSchema = z42.object({
4586
- switch: z42.boolean().optional(),
4587
- inline: z42.boolean().optional(),
4588
- reverse: z42.boolean().optional(),
5112
+ var BsMultiCheckboxPropsSchema = z43.object({
5113
+ switch: z43.boolean().optional(),
5114
+ inline: z43.boolean().optional(),
5115
+ reverse: z43.boolean().optional(),
4589
5116
  hint: DynamicTextSchema.optional()
4590
5117
  });
4591
- var BsTogglePropsSchema = z42.object({
5118
+ var BsTogglePropsSchema = z43.object({
4592
5119
  size: BsSizeSchema.optional(),
4593
- reverse: z42.boolean().optional(),
4594
- inline: z42.boolean().optional(),
5120
+ reverse: z43.boolean().optional(),
5121
+ inline: z43.boolean().optional(),
4595
5122
  hint: DynamicTextSchema.optional()
4596
5123
  });
4597
5124
  var BsDatepickerPropsSchema = BsFormFieldPropsSchema.extend({
4598
- useNgBootstrap: z42.boolean().optional(),
4599
- displayMonths: z42.number().positive().optional(),
4600
- navigation: z42.enum(["select", "arrows", "none"]).optional(),
4601
- outsideDays: z42.enum(["visible", "collapsed", "hidden"]).optional(),
4602
- showWeekNumbers: z42.boolean().optional(),
5125
+ useNgBootstrap: z43.boolean().optional(),
5126
+ displayMonths: z43.number().positive().optional(),
5127
+ navigation: z43.enum(["select", "arrows", "none"]).optional(),
5128
+ outsideDays: z43.enum(["visible", "collapsed", "hidden"]).optional(),
5129
+ showWeekNumbers: z43.boolean().optional(),
4603
5130
  placeholder: DynamicTextSchema.optional()
4604
5131
  });
4605
- var BsSliderPropsSchema = z42.object({
4606
- showValue: z42.boolean().optional(),
4607
- valuePrefix: z42.string().optional(),
4608
- valueSuffix: z42.string().optional(),
5132
+ var BsSliderPropsSchema = z43.object({
5133
+ showValue: z43.boolean().optional(),
5134
+ valuePrefix: z43.string().optional(),
5135
+ valueSuffix: z43.string().optional(),
4609
5136
  hint: DynamicTextSchema.optional(),
4610
- min: z42.number().optional(),
4611
- max: z42.number().optional(),
4612
- step: z42.number().positive().optional()
5137
+ min: z43.number().optional(),
5138
+ max: z43.number().optional(),
5139
+ step: z43.number().positive().optional()
4613
5140
  });
4614
- var BsButtonPropsSchema = z42.object({
5141
+ var BsButtonPropsSchema = z43.object({
4615
5142
  variant: BsButtonVariantSchema.optional(),
4616
- outline: z42.boolean().optional(),
5143
+ outline: z43.boolean().optional(),
4617
5144
  size: BsSizeSchema.optional(),
4618
- block: z42.boolean().optional(),
4619
- active: z42.boolean().optional(),
4620
- type: z42.enum(["button", "submit", "reset"]).optional()
5145
+ block: z43.boolean().optional(),
5146
+ active: z43.boolean().optional(),
5147
+ type: z43.enum(["button", "submit", "reset"]).optional()
4621
5148
  });
4622
5149
 
4623
5150
  // internal/dynamic-forms-zod/bootstrap/src/fields/index.ts
4624
- import { z as z43 } from "zod";
5151
+ import { z as z44 } from "zod";
4625
5152
  var BsValueFieldBase = BaseFieldDefSchema.merge(FieldWithValidationSchema);
4626
- var BsInputFieldSchema = BsValueFieldBase.extend({
4627
- type: z43.literal("input"),
4628
- value: z43.string().optional(),
5153
+ var BsInputFieldSchemaObject = BsValueFieldBase.extend({
5154
+ type: z44.literal("input"),
5155
+ nullable: z44.boolean().optional(),
5156
+ value: z44.string().nullable().optional(),
4629
5157
  placeholder: DynamicTextSchema.optional(),
4630
5158
  props: BsInputPropsSchema.optional()
4631
5159
  });
4632
- var BsTextareaFieldSchema = BsValueFieldBase.extend({
4633
- type: z43.literal("textarea"),
4634
- value: z43.string().optional(),
5160
+ var BsInputFieldSchema = BsInputFieldSchemaObject.superRefine(nullableValueRefine);
5161
+ var BsTextareaFieldSchemaObject = BsValueFieldBase.extend({
5162
+ type: z44.literal("textarea"),
5163
+ nullable: z44.boolean().optional(),
5164
+ value: z44.string().nullable().optional(),
4635
5165
  placeholder: DynamicTextSchema.optional(),
4636
5166
  props: BsTextareaPropsSchema.optional()
4637
5167
  });
4638
- var BsSelectFieldSchema = BsValueFieldBase.extend({
4639
- type: z43.literal("select"),
4640
- value: z43.string().optional(),
5168
+ var BsTextareaFieldSchema = BsTextareaFieldSchemaObject.superRefine(nullableValueRefine);
5169
+ var BsSelectFieldSchemaObject = BsValueFieldBase.extend({
5170
+ type: z44.literal("select"),
5171
+ nullable: z44.boolean().optional(),
5172
+ value: z44.string().nullable().optional(),
4641
5173
  // Bootstrap select only supports strings
4642
5174
  placeholder: DynamicTextSchema.optional(),
4643
5175
  options: FieldOptionsSchema,
4644
5176
  props: BsSelectPropsSchema.optional()
4645
5177
  });
5178
+ var BsSelectFieldSchema = BsSelectFieldSchemaObject.superRefine(nullableValueRefine);
4646
5179
  var BsCheckboxFieldSchema = BsValueFieldBase.extend({
4647
- type: z43.literal("checkbox"),
4648
- value: z43.boolean().optional(),
5180
+ type: z44.literal("checkbox"),
5181
+ value: z44.boolean().optional(),
4649
5182
  placeholder: DynamicTextSchema.optional(),
4650
5183
  props: BsCheckboxPropsSchema.optional()
4651
5184
  });
4652
- var BsRadioFieldSchema = BsValueFieldBase.extend({
4653
- type: z43.literal("radio"),
4654
- value: z43.unknown().optional(),
5185
+ var BsRadioFieldSchemaObject = BsValueFieldBase.extend({
5186
+ type: z44.literal("radio"),
5187
+ nullable: z44.boolean().optional(),
5188
+ value: z44.unknown().nullable().optional(),
4655
5189
  placeholder: DynamicTextSchema.optional(),
4656
5190
  options: FieldOptionsSchema,
4657
5191
  props: BsRadioPropsSchema.optional()
4658
5192
  });
4659
- var BsMultiCheckboxFieldSchema = BsValueFieldBase.extend({
4660
- type: z43.literal("multi-checkbox"),
4661
- value: z43.array(z43.unknown()).optional(),
5193
+ var BsRadioFieldSchema = BsRadioFieldSchemaObject.superRefine(nullableValueRefine);
5194
+ var BsMultiCheckboxFieldSchemaObject = BsValueFieldBase.extend({
5195
+ type: z44.literal("multi-checkbox"),
5196
+ nullable: z44.boolean().optional(),
5197
+ value: z44.array(z44.unknown()).nullable().optional(),
4662
5198
  placeholder: DynamicTextSchema.optional(),
4663
5199
  options: FieldOptionsSchema,
4664
5200
  props: BsMultiCheckboxPropsSchema.optional()
4665
5201
  });
5202
+ var BsMultiCheckboxFieldSchema = BsMultiCheckboxFieldSchemaObject.superRefine(nullableValueRefine);
4666
5203
  var BsToggleFieldSchema = BsValueFieldBase.extend({
4667
- type: z43.literal("toggle"),
4668
- value: z43.boolean().optional(),
5204
+ type: z44.literal("toggle"),
5205
+ value: z44.boolean().optional(),
4669
5206
  placeholder: DynamicTextSchema.optional(),
4670
5207
  props: BsTogglePropsSchema.optional()
4671
5208
  });
4672
- var BsDatepickerFieldSchema = BsValueFieldBase.extend({
4673
- type: z43.literal("datepicker"),
4674
- value: z43.union([z43.string(), z43.null()]).optional(),
4675
- minDate: z43.union([z43.string(), z43.null()]).optional(),
4676
- maxDate: z43.union([z43.string(), z43.null()]).optional(),
4677
- startAt: z43.union([z43.string(), z43.null()]).optional(),
5209
+ var BsDatepickerFieldSchemaObject = BsValueFieldBase.extend({
5210
+ type: z44.literal("datepicker"),
5211
+ nullable: z44.boolean().optional(),
5212
+ value: z44.union([z44.string(), z44.null()]).optional(),
5213
+ minDate: z44.union([z44.string(), z44.null()]).optional(),
5214
+ maxDate: z44.union([z44.string(), z44.null()]).optional(),
5215
+ startAt: z44.union([z44.string(), z44.null()]).optional(),
4678
5216
  placeholder: DynamicTextSchema.optional(),
4679
5217
  props: BsDatepickerPropsSchema.optional()
4680
5218
  });
4681
- var BsSliderFieldSchema = BsValueFieldBase.extend({
4682
- type: z43.literal("slider"),
4683
- value: z43.number().optional(),
4684
- minValue: z43.number().optional(),
4685
- maxValue: z43.number().optional(),
4686
- step: z43.number().positive().optional(),
5219
+ var BsDatepickerFieldSchema = BsDatepickerFieldSchemaObject.superRefine(nullableValueRefine);
5220
+ var BsSliderFieldSchemaObject = BsValueFieldBase.extend({
5221
+ type: z44.literal("slider"),
5222
+ nullable: z44.boolean().optional(),
5223
+ value: z44.number().nullable().optional(),
5224
+ minValue: z44.number().optional(),
5225
+ maxValue: z44.number().optional(),
5226
+ step: z44.number().positive().optional(),
4687
5227
  placeholder: DynamicTextSchema.optional(),
4688
5228
  props: BsSliderPropsSchema.optional()
4689
5229
  });
5230
+ var BsSliderFieldSchema = BsSliderFieldSchemaObject.superRefine(nullableValueRefine);
4690
5231
  var BsButtonFieldSchema = BaseFieldDefSchema.extend({
4691
- type: z43.literal("button"),
4692
- event: z43.string().optional(),
4693
- eventArgs: z43.array(z43.union([z43.string(), z43.number(), z43.boolean(), z43.null(), z43.undefined()])).optional(),
5232
+ type: z44.literal("button"),
5233
+ event: z44.string().optional(),
5234
+ eventArgs: z44.array(z44.union([z44.string(), z44.number(), z44.boolean(), z44.null(), z44.undefined()])).optional(),
4694
5235
  props: BsButtonPropsSchema.optional(),
4695
5236
  logic: LogicArraySchema.optional()
4696
5237
  });
4697
5238
  var BsSubmitButtonFieldSchema = BaseFieldDefSchema.extend({
4698
- type: z43.literal("submit"),
5239
+ type: z44.literal("submit"),
4699
5240
  props: BsButtonPropsSchema.optional(),
4700
5241
  logic: LogicArraySchema.optional()
4701
5242
  });
4702
5243
  var BsNextButtonFieldSchema = BaseFieldDefSchema.extend({
4703
- type: z43.literal("next"),
5244
+ type: z44.literal("next"),
4704
5245
  props: BsButtonPropsSchema.optional(),
4705
5246
  logic: LogicArraySchema.optional()
4706
5247
  });
4707
5248
  var BsPreviousButtonFieldSchema = BaseFieldDefSchema.extend({
4708
- type: z43.literal("previous"),
5249
+ type: z44.literal("previous"),
4709
5250
  props: BsButtonPropsSchema.optional()
4710
5251
  });
4711
5252
  var BsAddArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
4712
- type: z43.literal("addArrayItem"),
4713
- arrayKey: z43.string().optional(),
5253
+ type: z44.literal("addArrayItem"),
5254
+ arrayKey: z44.string().optional(),
4714
5255
  props: BsButtonPropsSchema.optional()
4715
5256
  });
4716
5257
  var BsRemoveArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
4717
- type: z43.literal("removeArrayItem"),
4718
- arrayKey: z43.string().optional(),
5258
+ type: z44.literal("removeArrayItem"),
5259
+ arrayKey: z44.string().optional(),
4719
5260
  props: BsButtonPropsSchema.optional()
4720
5261
  });
4721
5262
 
4722
5263
  // internal/dynamic-forms-zod/bootstrap/src/bs-leaf-field.schema.ts
4723
- import { z as z44 } from "zod";
4724
- var BsLeafFieldSchema = z44.discriminatedUnion("type", [
5264
+ import { z as z45 } from "zod";
5265
+ var BsLeafFieldSchema = z45.discriminatedUnion("type", [
4725
5266
  TextFieldSchema,
4726
5267
  HiddenFieldSchema,
4727
- BsInputFieldSchema,
4728
- BsTextareaFieldSchema,
4729
- BsSelectFieldSchema,
5268
+ BsInputFieldSchemaObject,
5269
+ BsTextareaFieldSchemaObject,
5270
+ BsSelectFieldSchemaObject,
4730
5271
  BsCheckboxFieldSchema,
4731
- BsRadioFieldSchema,
4732
- BsMultiCheckboxFieldSchema,
5272
+ BsRadioFieldSchemaObject,
5273
+ BsMultiCheckboxFieldSchemaObject,
4733
5274
  BsToggleFieldSchema,
4734
- BsDatepickerFieldSchema,
4735
- BsSliderFieldSchema,
5275
+ BsDatepickerFieldSchemaObject,
5276
+ BsSliderFieldSchemaObject,
4736
5277
  BsButtonFieldSchema,
4737
5278
  BsSubmitButtonFieldSchema,
4738
5279
  BsNextButtonFieldSchema,
4739
5280
  BsPreviousButtonFieldSchema,
4740
5281
  BsAddArrayItemButtonFieldSchema,
4741
5282
  BsRemoveArrayItemButtonFieldSchema
4742
- ]);
5283
+ ]).superRefine(nullableValueRefine);
4743
5284
 
4744
5285
  // internal/dynamic-forms-zod/bootstrap/src/bs-form-config.schema.ts
4745
- import { z as z45 } from "zod";
5286
+ import { z as z46 } from "zod";
4746
5287
  var containerSchemas2 = createContainerSchemas({
4747
5288
  leafFieldSchema: BsLeafFieldSchema
4748
5289
  });
@@ -4751,186 +5292,200 @@ var BsRowFieldSchema = containerSchemas2.RowFieldSchema;
4751
5292
  var BsGroupFieldSchema = containerSchemas2.GroupFieldSchema;
4752
5293
  var BsArrayFieldSchema = containerSchemas2.ArrayFieldSchema;
4753
5294
  var BsFieldSchema = containerSchemas2.AllFieldsSchema;
4754
- var BsFormDefaultPropsSchema = z45.object({
5295
+ var BsFormDefaultPropsSchema = z46.object({
4755
5296
  size: BsSizeSchema.optional(),
4756
- floatingLabel: z45.boolean().optional()
5297
+ floatingLabel: z46.boolean().optional()
4757
5298
  });
4758
5299
  var BsFormConfigSchema = createFormConfigSchema(BsFieldSchema, BsFormDefaultPropsSchema);
4759
5300
 
4760
5301
  // internal/dynamic-forms-zod/primeng/src/props/index.ts
4761
- import { z as z46 } from "zod";
4762
- var PrimeSeveritySchema = z46.enum(["primary", "secondary", "success", "info", "warn", "danger", "help", "contrast"]);
4763
- var PrimeCommonPropsSchema = z46.object({
4764
- styleClass: z46.string().optional(),
5302
+ import { z as z47 } from "zod";
5303
+ var PrimeSeveritySchema = z47.enum(["primary", "secondary", "success", "info", "warn", "danger", "help", "contrast"]);
5304
+ var PrimeCommonPropsSchema = z47.object({
5305
+ styleClass: z47.string().optional(),
4765
5306
  hint: DynamicTextSchema.optional()
4766
5307
  });
4767
5308
  var PrimeInputPropsSchema = PrimeCommonPropsSchema.extend({
4768
- type: z46.enum(["text", "email", "password", "number", "tel", "url"]).optional(),
5309
+ type: z47.enum(["text", "email", "password", "number", "tel", "url"]).optional(),
4769
5310
  placeholder: DynamicTextSchema.optional(),
4770
- size: z46.enum(["small", "large"]).optional(),
4771
- variant: z46.enum(["outlined", "filled"]).optional()
5311
+ size: z47.enum(["small", "large"]).optional(),
5312
+ variant: z47.enum(["outlined", "filled"]).optional()
4772
5313
  });
4773
5314
  var PrimeCheckboxPropsSchema = PrimeCommonPropsSchema.extend({
4774
- binary: z46.boolean().optional(),
4775
- trueValue: z46.unknown().optional(),
4776
- falseValue: z46.unknown().optional()
5315
+ binary: z47.boolean().optional(),
5316
+ trueValue: z47.unknown().optional(),
5317
+ falseValue: z47.unknown().optional()
4777
5318
  });
4778
5319
  var PrimeRadioPropsSchema = PrimeCommonPropsSchema.extend({
4779
- name: z46.string().optional()
5320
+ name: z47.string().optional()
4780
5321
  });
4781
5322
  var PrimeSelectPropsSchema = PrimeCommonPropsSchema.extend({
4782
- multiple: z46.boolean().optional(),
4783
- filter: z46.boolean().optional(),
5323
+ multiple: z47.boolean().optional(),
5324
+ filter: z47.boolean().optional(),
4784
5325
  placeholder: DynamicTextSchema.optional(),
4785
- showClear: z46.boolean().optional()
5326
+ showClear: z47.boolean().optional()
4786
5327
  });
4787
5328
  var PrimeMultiCheckboxPropsSchema = PrimeCommonPropsSchema;
4788
5329
  var PrimeDatepickerPropsSchema = PrimeCommonPropsSchema.extend({
4789
- dateFormat: z46.string().optional(),
4790
- inline: z46.boolean().optional(),
4791
- showIcon: z46.boolean().optional(),
4792
- showButtonBar: z46.boolean().optional(),
4793
- selectionMode: z46.enum(["single", "multiple", "range"]).optional(),
4794
- touchUI: z46.boolean().optional(),
4795
- view: z46.enum(["date", "month", "year"]).optional(),
5330
+ dateFormat: z47.string().optional(),
5331
+ inline: z47.boolean().optional(),
5332
+ showIcon: z47.boolean().optional(),
5333
+ showButtonBar: z47.boolean().optional(),
5334
+ selectionMode: z47.enum(["single", "multiple", "range"]).optional(),
5335
+ touchUI: z47.boolean().optional(),
5336
+ view: z47.enum(["date", "month", "year"]).optional(),
4796
5337
  placeholder: DynamicTextSchema.optional()
4797
5338
  });
4798
5339
  var PrimeTextareaPropsSchema = PrimeCommonPropsSchema.extend({
4799
- rows: z46.number().positive().optional(),
4800
- autoResize: z46.boolean().optional(),
4801
- maxlength: z46.number().positive().optional(),
5340
+ rows: z47.number().positive().optional(),
5341
+ autoResize: z47.boolean().optional(),
5342
+ maxlength: z47.number().positive().optional(),
4802
5343
  placeholder: DynamicTextSchema.optional()
4803
5344
  });
4804
5345
  var PrimeSliderPropsSchema = PrimeCommonPropsSchema.extend({
4805
- min: z46.number().optional(),
4806
- max: z46.number().optional(),
4807
- step: z46.number().positive().optional(),
4808
- range: z46.boolean().optional(),
4809
- orientation: z46.enum(["horizontal", "vertical"]).optional()
5346
+ min: z47.number().optional(),
5347
+ max: z47.number().optional(),
5348
+ step: z47.number().positive().optional(),
5349
+ range: z47.boolean().optional(),
5350
+ orientation: z47.enum(["horizontal", "vertical"]).optional()
4810
5351
  });
4811
5352
  var PrimeTogglePropsSchema = PrimeCommonPropsSchema;
4812
- var PrimeButtonPropsSchema = z46.object({
5353
+ var PrimeButtonPropsSchema = z47.object({
4813
5354
  severity: PrimeSeveritySchema.optional(),
4814
- text: z46.boolean().optional(),
4815
- outlined: z46.boolean().optional(),
4816
- raised: z46.boolean().optional(),
4817
- rounded: z46.boolean().optional(),
4818
- icon: z46.string().optional(),
4819
- iconPos: z46.enum(["left", "right", "top", "bottom"]).optional(),
4820
- type: z46.enum(["button", "submit", "reset"]).optional()
5355
+ text: z47.boolean().optional(),
5356
+ outlined: z47.boolean().optional(),
5357
+ raised: z47.boolean().optional(),
5358
+ rounded: z47.boolean().optional(),
5359
+ icon: z47.string().optional(),
5360
+ iconPos: z47.enum(["left", "right", "top", "bottom"]).optional(),
5361
+ type: z47.enum(["button", "submit", "reset"]).optional()
4821
5362
  });
4822
5363
 
4823
5364
  // internal/dynamic-forms-zod/primeng/src/fields/index.ts
4824
- import { z as z47 } from "zod";
5365
+ import { z as z48 } from "zod";
4825
5366
  var PrimeValueFieldBase = BaseFieldDefSchema.merge(FieldWithValidationSchema);
4826
- var PrimeInputFieldSchema = PrimeValueFieldBase.extend({
4827
- type: z47.literal("input"),
4828
- value: z47.string().optional(),
5367
+ var PrimeInputFieldSchemaObject = PrimeValueFieldBase.extend({
5368
+ type: z48.literal("input"),
5369
+ nullable: z48.boolean().optional(),
5370
+ value: z48.string().nullable().optional(),
4829
5371
  placeholder: DynamicTextSchema.optional(),
4830
5372
  props: PrimeInputPropsSchema.optional()
4831
5373
  });
5374
+ var PrimeInputFieldSchema = PrimeInputFieldSchemaObject.superRefine(nullableValueRefine);
4832
5375
  var PrimeCheckboxFieldSchema = PrimeValueFieldBase.extend({
4833
- type: z47.literal("checkbox"),
4834
- value: z47.boolean().optional(),
5376
+ type: z48.literal("checkbox"),
5377
+ value: z48.boolean().optional(),
4835
5378
  placeholder: DynamicTextSchema.optional(),
4836
5379
  props: PrimeCheckboxPropsSchema.optional()
4837
5380
  });
4838
- var PrimeRadioFieldSchema = PrimeValueFieldBase.extend({
4839
- type: z47.literal("radio"),
4840
- value: z47.unknown().optional(),
5381
+ var PrimeRadioFieldSchemaObject = PrimeValueFieldBase.extend({
5382
+ type: z48.literal("radio"),
5383
+ nullable: z48.boolean().optional(),
5384
+ value: z48.unknown().nullable().optional(),
4841
5385
  placeholder: DynamicTextSchema.optional(),
4842
5386
  options: FieldOptionsSchema,
4843
5387
  props: PrimeRadioPropsSchema.optional()
4844
5388
  });
4845
- var PrimeSelectFieldSchema = PrimeValueFieldBase.extend({
4846
- type: z47.literal("select"),
4847
- value: z47.unknown().optional(),
5389
+ var PrimeRadioFieldSchema = PrimeRadioFieldSchemaObject.superRefine(nullableValueRefine);
5390
+ var PrimeSelectFieldSchemaObject = PrimeValueFieldBase.extend({
5391
+ type: z48.literal("select"),
5392
+ nullable: z48.boolean().optional(),
5393
+ value: z48.unknown().nullable().optional(),
4848
5394
  placeholder: DynamicTextSchema.optional(),
4849
5395
  options: FieldOptionsSchema,
4850
5396
  props: PrimeSelectPropsSchema.optional()
4851
5397
  });
4852
- var PrimeMultiCheckboxFieldSchema = PrimeValueFieldBase.extend({
4853
- type: z47.literal("multi-checkbox"),
4854
- value: z47.array(z47.unknown()).optional(),
5398
+ var PrimeSelectFieldSchema = PrimeSelectFieldSchemaObject.superRefine(nullableValueRefine);
5399
+ var PrimeMultiCheckboxFieldSchemaObject = PrimeValueFieldBase.extend({
5400
+ type: z48.literal("multi-checkbox"),
5401
+ nullable: z48.boolean().optional(),
5402
+ value: z48.array(z48.unknown()).nullable().optional(),
4855
5403
  placeholder: DynamicTextSchema.optional(),
4856
5404
  options: FieldOptionsSchema,
4857
5405
  props: PrimeMultiCheckboxPropsSchema.optional()
4858
5406
  });
4859
- var PrimeDatepickerFieldSchema = PrimeValueFieldBase.extend({
4860
- type: z47.literal("datepicker"),
4861
- value: z47.union([z47.string(), z47.null()]).optional(),
4862
- minDate: z47.union([z47.string(), z47.null()]).optional(),
4863
- maxDate: z47.union([z47.string(), z47.null()]).optional(),
4864
- startAt: z47.union([z47.string(), z47.null()]).optional(),
5407
+ var PrimeMultiCheckboxFieldSchema = PrimeMultiCheckboxFieldSchemaObject.superRefine(nullableValueRefine);
5408
+ var PrimeDatepickerFieldSchemaObject = PrimeValueFieldBase.extend({
5409
+ type: z48.literal("datepicker"),
5410
+ nullable: z48.boolean().optional(),
5411
+ value: z48.union([z48.string(), z48.null()]).optional(),
5412
+ minDate: z48.union([z48.string(), z48.null()]).optional(),
5413
+ maxDate: z48.union([z48.string(), z48.null()]).optional(),
5414
+ startAt: z48.union([z48.string(), z48.null()]).optional(),
4865
5415
  placeholder: DynamicTextSchema.optional(),
4866
5416
  props: PrimeDatepickerPropsSchema.optional()
4867
5417
  });
4868
- var PrimeTextareaFieldSchema = PrimeValueFieldBase.extend({
4869
- type: z47.literal("textarea"),
4870
- value: z47.string().optional(),
5418
+ var PrimeDatepickerFieldSchema = PrimeDatepickerFieldSchemaObject.superRefine(nullableValueRefine);
5419
+ var PrimeTextareaFieldSchemaObject = PrimeValueFieldBase.extend({
5420
+ type: z48.literal("textarea"),
5421
+ nullable: z48.boolean().optional(),
5422
+ value: z48.string().nullable().optional(),
4871
5423
  placeholder: DynamicTextSchema.optional(),
4872
5424
  props: PrimeTextareaPropsSchema.optional()
4873
5425
  });
4874
- var PrimeSliderFieldSchema = PrimeValueFieldBase.extend({
4875
- type: z47.literal("slider"),
4876
- value: z47.number().optional(),
4877
- minValue: z47.number().optional(),
4878
- maxValue: z47.number().optional(),
4879
- step: z47.number().positive().optional(),
5426
+ var PrimeTextareaFieldSchema = PrimeTextareaFieldSchemaObject.superRefine(nullableValueRefine);
5427
+ var PrimeSliderFieldSchemaObject = PrimeValueFieldBase.extend({
5428
+ type: z48.literal("slider"),
5429
+ nullable: z48.boolean().optional(),
5430
+ value: z48.number().nullable().optional(),
5431
+ minValue: z48.number().optional(),
5432
+ maxValue: z48.number().optional(),
5433
+ step: z48.number().positive().optional(),
4880
5434
  placeholder: DynamicTextSchema.optional(),
4881
5435
  props: PrimeSliderPropsSchema.optional()
4882
5436
  });
5437
+ var PrimeSliderFieldSchema = PrimeSliderFieldSchemaObject.superRefine(nullableValueRefine);
4883
5438
  var PrimeToggleFieldSchema = PrimeValueFieldBase.extend({
4884
- type: z47.literal("toggle"),
4885
- value: z47.boolean().optional(),
5439
+ type: z48.literal("toggle"),
5440
+ value: z48.boolean().optional(),
4886
5441
  placeholder: DynamicTextSchema.optional(),
4887
5442
  props: PrimeTogglePropsSchema.optional()
4888
5443
  });
4889
5444
  var PrimeButtonFieldSchema = BaseFieldDefSchema.extend({
4890
- type: z47.literal("button"),
4891
- event: z47.string().optional(),
4892
- eventArgs: z47.array(z47.union([z47.string(), z47.number(), z47.boolean(), z47.null(), z47.undefined()])).optional(),
5445
+ type: z48.literal("button"),
5446
+ event: z48.string().optional(),
5447
+ eventArgs: z48.array(z48.union([z48.string(), z48.number(), z48.boolean(), z48.null(), z48.undefined()])).optional(),
4893
5448
  props: PrimeButtonPropsSchema.optional(),
4894
5449
  logic: LogicArraySchema.optional()
4895
5450
  });
4896
5451
  var PrimeSubmitButtonFieldSchema = BaseFieldDefSchema.extend({
4897
- type: z47.literal("submit"),
5452
+ type: z48.literal("submit"),
4898
5453
  props: PrimeButtonPropsSchema.optional(),
4899
5454
  logic: LogicArraySchema.optional()
4900
5455
  });
4901
5456
  var PrimeNextButtonFieldSchema = BaseFieldDefSchema.extend({
4902
- type: z47.literal("next"),
5457
+ type: z48.literal("next"),
4903
5458
  props: PrimeButtonPropsSchema.optional(),
4904
5459
  logic: LogicArraySchema.optional()
4905
5460
  });
4906
5461
  var PrimePreviousButtonFieldSchema = BaseFieldDefSchema.extend({
4907
- type: z47.literal("previous"),
5462
+ type: z48.literal("previous"),
4908
5463
  props: PrimeButtonPropsSchema.optional()
4909
5464
  });
4910
5465
  var PrimeAddArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
4911
- type: z47.literal("addArrayItem"),
4912
- arrayKey: z47.string().optional(),
5466
+ type: z48.literal("addArrayItem"),
5467
+ arrayKey: z48.string().optional(),
4913
5468
  props: PrimeButtonPropsSchema.optional()
4914
5469
  });
4915
5470
  var PrimeRemoveArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
4916
- type: z47.literal("removeArrayItem"),
4917
- arrayKey: z47.string().optional(),
5471
+ type: z48.literal("removeArrayItem"),
5472
+ arrayKey: z48.string().optional(),
4918
5473
  props: PrimeButtonPropsSchema.optional()
4919
5474
  });
4920
5475
 
4921
5476
  // internal/dynamic-forms-zod/primeng/src/prime-leaf-field.schema.ts
4922
- import { z as z48 } from "zod";
4923
- var PrimeLeafFieldSchema = z48.discriminatedUnion("type", [
5477
+ import { z as z49 } from "zod";
5478
+ var PrimeLeafFieldSchema = z49.discriminatedUnion("type", [
4924
5479
  TextFieldSchema,
4925
5480
  HiddenFieldSchema,
4926
- PrimeInputFieldSchema,
5481
+ PrimeInputFieldSchemaObject,
4927
5482
  PrimeCheckboxFieldSchema,
4928
- PrimeRadioFieldSchema,
4929
- PrimeSelectFieldSchema,
4930
- PrimeMultiCheckboxFieldSchema,
4931
- PrimeDatepickerFieldSchema,
4932
- PrimeTextareaFieldSchema,
4933
- PrimeSliderFieldSchema,
5483
+ PrimeRadioFieldSchemaObject,
5484
+ PrimeSelectFieldSchemaObject,
5485
+ PrimeMultiCheckboxFieldSchemaObject,
5486
+ PrimeDatepickerFieldSchemaObject,
5487
+ PrimeTextareaFieldSchemaObject,
5488
+ PrimeSliderFieldSchemaObject,
4934
5489
  PrimeToggleFieldSchema,
4935
5490
  PrimeButtonFieldSchema,
4936
5491
  PrimeSubmitButtonFieldSchema,
@@ -4938,10 +5493,10 @@ var PrimeLeafFieldSchema = z48.discriminatedUnion("type", [
4938
5493
  PrimePreviousButtonFieldSchema,
4939
5494
  PrimeAddArrayItemButtonFieldSchema,
4940
5495
  PrimeRemoveArrayItemButtonFieldSchema
4941
- ]);
5496
+ ]).superRefine(nullableValueRefine);
4942
5497
 
4943
5498
  // internal/dynamic-forms-zod/primeng/src/prime-form-config.schema.ts
4944
- import { z as z49 } from "zod";
5499
+ import { z as z50 } from "zod";
4945
5500
  var containerSchemas3 = createContainerSchemas({
4946
5501
  leafFieldSchema: PrimeLeafFieldSchema
4947
5502
  });
@@ -4950,240 +5505,254 @@ var PrimeRowFieldSchema = containerSchemas3.RowFieldSchema;
4950
5505
  var PrimeGroupFieldSchema = containerSchemas3.GroupFieldSchema;
4951
5506
  var PrimeArrayFieldSchema = containerSchemas3.ArrayFieldSchema;
4952
5507
  var PrimeFieldSchema = containerSchemas3.AllFieldsSchema;
4953
- var PrimeFormDefaultPropsSchema = z49.object({
4954
- styleClass: z49.string().optional()
5508
+ var PrimeFormDefaultPropsSchema = z50.object({
5509
+ styleClass: z50.string().optional()
4955
5510
  });
4956
5511
  var PrimeFormConfigSchema = createFormConfigSchema(PrimeFieldSchema, PrimeFormDefaultPropsSchema);
4957
5512
 
4958
5513
  // internal/dynamic-forms-zod/ionic/src/props/index.ts
4959
- import { z as z50 } from "zod";
4960
- var IonicColorSchema = z50.enum(["primary", "secondary", "tertiary", "success", "warning", "danger", "light", "medium", "dark"]);
4961
- var IonicLabelPlacementSchema = z50.enum(["start", "end", "fixed", "stacked", "floating"]);
4962
- var IonicJustifySchema = z50.enum(["start", "end", "space-between"]);
4963
- var IonicFillSchema = z50.enum(["solid", "outline", "clear", "default"]);
4964
- var IonicInputPropsSchema = z50.object({
4965
- fill: z50.enum(["solid", "outline"]).optional(),
4966
- shape: z50.literal("round").optional(),
5514
+ import { z as z51 } from "zod";
5515
+ var IonicColorSchema = z51.enum(["primary", "secondary", "tertiary", "success", "warning", "danger", "light", "medium", "dark"]);
5516
+ var IonicLabelPlacementSchema = z51.enum(["start", "end", "fixed", "stacked", "floating"]);
5517
+ var IonicJustifySchema = z51.enum(["start", "end", "space-between"]);
5518
+ var IonicFillSchema = z51.enum(["solid", "outline", "clear", "default"]);
5519
+ var IonicInputPropsSchema = z51.object({
5520
+ fill: z51.enum(["solid", "outline"]).optional(),
5521
+ shape: z51.literal("round").optional(),
4967
5522
  labelPlacement: IonicLabelPlacementSchema.optional(),
4968
5523
  color: IonicColorSchema.optional(),
4969
5524
  hint: DynamicTextSchema.optional(),
4970
5525
  errorText: DynamicTextSchema.optional(),
4971
- counter: z50.boolean().optional(),
4972
- maxlength: z50.number().positive().optional(),
4973
- clearInput: z50.boolean().optional(),
4974
- type: z50.enum(["text", "email", "password", "number", "tel", "url"]).optional(),
5526
+ counter: z51.boolean().optional(),
5527
+ maxlength: z51.number().positive().optional(),
5528
+ clearInput: z51.boolean().optional(),
5529
+ type: z51.enum(["text", "email", "password", "number", "tel", "url"]).optional(),
4975
5530
  placeholder: DynamicTextSchema.optional()
4976
5531
  });
4977
- var IonicCheckboxPropsSchema = z50.object({
4978
- labelPlacement: z50.enum(["start", "end", "fixed", "stacked"]).optional(),
5532
+ var IonicCheckboxPropsSchema = z51.object({
5533
+ labelPlacement: z51.enum(["start", "end", "fixed", "stacked"]).optional(),
4979
5534
  justify: IonicJustifySchema.optional(),
4980
- color: z50.enum(["primary", "secondary", "tertiary", "success", "warning", "danger"]).optional(),
4981
- indeterminate: z50.boolean().optional(),
5535
+ color: z51.enum(["primary", "secondary", "tertiary", "success", "warning", "danger"]).optional(),
5536
+ indeterminate: z51.boolean().optional(),
4982
5537
  hint: DynamicTextSchema.optional()
4983
5538
  });
4984
- var IonicRadioPropsSchema = z50.object({
4985
- labelPlacement: z50.enum(["start", "end", "fixed", "stacked"]).optional(),
5539
+ var IonicRadioPropsSchema = z51.object({
5540
+ labelPlacement: z51.enum(["start", "end", "fixed", "stacked"]).optional(),
4986
5541
  justify: IonicJustifySchema.optional(),
4987
- color: z50.enum(["primary", "secondary", "tertiary", "success", "warning", "danger"]).optional(),
5542
+ color: z51.enum(["primary", "secondary", "tertiary", "success", "warning", "danger"]).optional(),
4988
5543
  hint: DynamicTextSchema.optional()
4989
5544
  });
4990
- var IonicTogglePropsSchema = z50.object({
4991
- labelPlacement: z50.enum(["start", "end", "fixed", "stacked"]).optional(),
5545
+ var IonicTogglePropsSchema = z51.object({
5546
+ labelPlacement: z51.enum(["start", "end", "fixed", "stacked"]).optional(),
4992
5547
  justify: IonicJustifySchema.optional(),
4993
- color: z50.enum(["primary", "secondary", "tertiary", "success", "warning", "danger"]).optional(),
4994
- enableOnOffLabels: z50.boolean().optional(),
5548
+ color: z51.enum(["primary", "secondary", "tertiary", "success", "warning", "danger"]).optional(),
5549
+ enableOnOffLabels: z51.boolean().optional(),
4995
5550
  hint: DynamicTextSchema.optional()
4996
5551
  });
4997
- var IonicSliderPropsSchema = z50.object({
4998
- min: z50.number().optional(),
4999
- max: z50.number().optional(),
5000
- step: z50.number().positive().optional(),
5001
- dualKnobs: z50.boolean().optional(),
5002
- pin: z50.boolean().optional(),
5003
- ticks: z50.boolean().optional(),
5004
- snaps: z50.boolean().optional(),
5005
- color: z50.enum(["primary", "secondary", "tertiary", "success", "warning", "danger"]).optional(),
5006
- labelPlacement: z50.enum(["start", "end", "fixed", "stacked"]).optional(),
5552
+ var IonicSliderPropsSchema = z51.object({
5553
+ min: z51.number().optional(),
5554
+ max: z51.number().optional(),
5555
+ step: z51.number().positive().optional(),
5556
+ dualKnobs: z51.boolean().optional(),
5557
+ pin: z51.boolean().optional(),
5558
+ ticks: z51.boolean().optional(),
5559
+ snaps: z51.boolean().optional(),
5560
+ color: z51.enum(["primary", "secondary", "tertiary", "success", "warning", "danger"]).optional(),
5561
+ labelPlacement: z51.enum(["start", "end", "fixed", "stacked"]).optional(),
5007
5562
  hint: DynamicTextSchema.optional()
5008
5563
  });
5009
- var IonicDatepickerPropsSchema = z50.object({
5010
- presentation: z50.enum(["date", "date-time", "time", "time-date", "month", "month-year", "year"]).optional(),
5011
- multiple: z50.boolean().optional(),
5012
- preferWheel: z50.boolean().optional(),
5013
- showDefaultButtons: z50.boolean().optional(),
5014
- showDefaultTitle: z50.boolean().optional(),
5015
- showDefaultTimeLabel: z50.boolean().optional(),
5016
- showClearButton: z50.boolean().optional(),
5017
- doneText: z50.string().optional(),
5018
- cancelText: z50.string().optional(),
5019
- size: z50.enum(["cover", "fixed"]).optional(),
5020
- color: z50.enum(["primary", "secondary", "tertiary", "success", "warning", "danger"]).optional(),
5564
+ var IonicDatepickerPropsSchema = z51.object({
5565
+ presentation: z51.enum(["date", "date-time", "time", "time-date", "month", "month-year", "year"]).optional(),
5566
+ multiple: z51.boolean().optional(),
5567
+ preferWheel: z51.boolean().optional(),
5568
+ showDefaultButtons: z51.boolean().optional(),
5569
+ showDefaultTitle: z51.boolean().optional(),
5570
+ showDefaultTimeLabel: z51.boolean().optional(),
5571
+ showClearButton: z51.boolean().optional(),
5572
+ doneText: z51.string().optional(),
5573
+ cancelText: z51.string().optional(),
5574
+ size: z51.enum(["cover", "fixed"]).optional(),
5575
+ color: z51.enum(["primary", "secondary", "tertiary", "success", "warning", "danger"]).optional(),
5021
5576
  hint: DynamicTextSchema.optional(),
5022
5577
  placeholder: DynamicTextSchema.optional()
5023
5578
  });
5024
- var IonicSelectPropsSchema = z50.object({
5025
- multiple: z50.boolean().optional(),
5026
- interface: z50.enum(["action-sheet", "popover", "alert"]).optional(),
5027
- cancelText: z50.string().optional(),
5028
- okText: z50.string().optional(),
5579
+ var IonicSelectPropsSchema = z51.object({
5580
+ multiple: z51.boolean().optional(),
5581
+ interface: z51.enum(["action-sheet", "popover", "alert"]).optional(),
5582
+ cancelText: z51.string().optional(),
5583
+ okText: z51.string().optional(),
5029
5584
  placeholder: DynamicTextSchema.optional(),
5030
- fill: z50.enum(["solid", "outline"]).optional(),
5031
- shape: z50.literal("round").optional(),
5585
+ fill: z51.enum(["solid", "outline"]).optional(),
5586
+ shape: z51.literal("round").optional(),
5032
5587
  labelPlacement: IonicLabelPlacementSchema.optional(),
5033
- color: z50.enum(["primary", "secondary", "tertiary", "success", "warning", "danger"]).optional(),
5588
+ color: z51.enum(["primary", "secondary", "tertiary", "success", "warning", "danger"]).optional(),
5034
5589
  hint: DynamicTextSchema.optional()
5035
5590
  });
5036
- var IonicTextareaPropsSchema = z50.object({
5037
- rows: z50.number().positive().optional(),
5038
- autoGrow: z50.boolean().optional(),
5039
- maxlength: z50.number().positive().optional(),
5040
- counter: z50.boolean().optional(),
5041
- fill: z50.enum(["solid", "outline"]).optional(),
5042
- shape: z50.literal("round").optional(),
5591
+ var IonicTextareaPropsSchema = z51.object({
5592
+ rows: z51.number().positive().optional(),
5593
+ autoGrow: z51.boolean().optional(),
5594
+ maxlength: z51.number().positive().optional(),
5595
+ counter: z51.boolean().optional(),
5596
+ fill: z51.enum(["solid", "outline"]).optional(),
5597
+ shape: z51.literal("round").optional(),
5043
5598
  labelPlacement: IonicLabelPlacementSchema.optional(),
5044
5599
  hint: DynamicTextSchema.optional(),
5045
5600
  errorText: DynamicTextSchema.optional(),
5046
5601
  color: IonicColorSchema.optional(),
5047
5602
  placeholder: DynamicTextSchema.optional()
5048
5603
  });
5049
- var IonicMultiCheckboxPropsSchema = z50.object({
5050
- labelPlacement: z50.enum(["start", "end", "fixed", "stacked"]).optional(),
5604
+ var IonicMultiCheckboxPropsSchema = z51.object({
5605
+ labelPlacement: z51.enum(["start", "end", "fixed", "stacked"]).optional(),
5051
5606
  justify: IonicJustifySchema.optional(),
5052
- color: z50.enum(["primary", "secondary", "tertiary", "success", "warning", "danger"]).optional(),
5607
+ color: z51.enum(["primary", "secondary", "tertiary", "success", "warning", "danger"]).optional(),
5053
5608
  hint: DynamicTextSchema.optional()
5054
5609
  });
5055
- var IonicButtonPropsSchema = z50.object({
5056
- expand: z50.enum(["full", "block"]).optional(),
5610
+ var IonicButtonPropsSchema = z51.object({
5611
+ expand: z51.enum(["full", "block"]).optional(),
5057
5612
  fill: IonicFillSchema.optional(),
5058
- shape: z50.literal("round").optional(),
5059
- size: z50.enum(["small", "default", "large"]).optional(),
5613
+ shape: z51.literal("round").optional(),
5614
+ size: z51.enum(["small", "default", "large"]).optional(),
5060
5615
  color: IonicColorSchema.optional(),
5061
- strong: z50.boolean().optional(),
5062
- type: z50.enum(["button", "submit", "reset"]).optional()
5616
+ strong: z51.boolean().optional(),
5617
+ type: z51.enum(["button", "submit", "reset"]).optional()
5063
5618
  });
5064
5619
 
5065
5620
  // internal/dynamic-forms-zod/ionic/src/fields/index.ts
5066
- import { z as z51 } from "zod";
5621
+ import { z as z52 } from "zod";
5067
5622
  var IonicValueFieldBase = BaseFieldDefSchema.merge(FieldWithValidationSchema);
5068
- var IonicInputFieldSchema = IonicValueFieldBase.extend({
5069
- type: z51.literal("input"),
5070
- value: z51.string().optional(),
5623
+ var IonicInputFieldSchemaObject = IonicValueFieldBase.extend({
5624
+ type: z52.literal("input"),
5625
+ nullable: z52.boolean().optional(),
5626
+ value: z52.string().nullable().optional(),
5071
5627
  placeholder: DynamicTextSchema.optional(),
5072
5628
  props: IonicInputPropsSchema.optional()
5073
5629
  });
5630
+ var IonicInputFieldSchema = IonicInputFieldSchemaObject.superRefine(nullableValueRefine);
5074
5631
  var IonicCheckboxFieldSchema = IonicValueFieldBase.extend({
5075
- type: z51.literal("checkbox"),
5076
- value: z51.boolean().optional(),
5632
+ type: z52.literal("checkbox"),
5633
+ value: z52.boolean().optional(),
5077
5634
  placeholder: DynamicTextSchema.optional(),
5078
5635
  props: IonicCheckboxPropsSchema.optional()
5079
5636
  });
5080
- var IonicRadioFieldSchema = IonicValueFieldBase.extend({
5081
- type: z51.literal("radio"),
5082
- value: z51.unknown().optional(),
5637
+ var IonicRadioFieldSchemaObject = IonicValueFieldBase.extend({
5638
+ type: z52.literal("radio"),
5639
+ nullable: z52.boolean().optional(),
5640
+ value: z52.unknown().nullable().optional(),
5083
5641
  placeholder: DynamicTextSchema.optional(),
5084
5642
  options: FieldOptionsSchema,
5085
5643
  props: IonicRadioPropsSchema.optional()
5086
5644
  });
5645
+ var IonicRadioFieldSchema = IonicRadioFieldSchemaObject.superRefine(nullableValueRefine);
5087
5646
  var IonicToggleFieldSchema = IonicValueFieldBase.extend({
5088
- type: z51.literal("toggle"),
5089
- value: z51.boolean().optional(),
5647
+ type: z52.literal("toggle"),
5648
+ value: z52.boolean().optional(),
5090
5649
  placeholder: DynamicTextSchema.optional(),
5091
5650
  props: IonicTogglePropsSchema.optional()
5092
5651
  });
5093
- var IonicSliderFieldSchema = IonicValueFieldBase.extend({
5094
- type: z51.literal("slider"),
5095
- value: z51.number().optional(),
5096
- minValue: z51.number().optional(),
5097
- maxValue: z51.number().optional(),
5098
- step: z51.number().positive().optional(),
5652
+ var IonicSliderFieldSchemaObject = IonicValueFieldBase.extend({
5653
+ type: z52.literal("slider"),
5654
+ nullable: z52.boolean().optional(),
5655
+ value: z52.number().nullable().optional(),
5656
+ minValue: z52.number().optional(),
5657
+ maxValue: z52.number().optional(),
5658
+ step: z52.number().positive().optional(),
5099
5659
  placeholder: DynamicTextSchema.optional(),
5100
5660
  props: IonicSliderPropsSchema.optional()
5101
5661
  });
5102
- var IonicDatepickerFieldSchema = IonicValueFieldBase.extend({
5103
- type: z51.literal("datepicker"),
5104
- value: z51.union([z51.string(), z51.null()]).optional(),
5105
- minDate: z51.union([z51.string(), z51.null()]).optional(),
5106
- maxDate: z51.union([z51.string(), z51.null()]).optional(),
5107
- startAt: z51.union([z51.string(), z51.null()]).optional(),
5662
+ var IonicSliderFieldSchema = IonicSliderFieldSchemaObject.superRefine(nullableValueRefine);
5663
+ var IonicDatepickerFieldSchemaObject = IonicValueFieldBase.extend({
5664
+ type: z52.literal("datepicker"),
5665
+ nullable: z52.boolean().optional(),
5666
+ value: z52.union([z52.string(), z52.null()]).optional(),
5667
+ minDate: z52.union([z52.string(), z52.null()]).optional(),
5668
+ maxDate: z52.union([z52.string(), z52.null()]).optional(),
5669
+ startAt: z52.union([z52.string(), z52.null()]).optional(),
5108
5670
  placeholder: DynamicTextSchema.optional(),
5109
5671
  props: IonicDatepickerPropsSchema.optional()
5110
5672
  });
5111
- var IonicSelectFieldSchema = IonicValueFieldBase.extend({
5112
- type: z51.literal("select"),
5113
- value: z51.unknown().optional(),
5673
+ var IonicDatepickerFieldSchema = IonicDatepickerFieldSchemaObject.superRefine(nullableValueRefine);
5674
+ var IonicSelectFieldSchemaObject = IonicValueFieldBase.extend({
5675
+ type: z52.literal("select"),
5676
+ nullable: z52.boolean().optional(),
5677
+ value: z52.unknown().nullable().optional(),
5114
5678
  placeholder: DynamicTextSchema.optional(),
5115
5679
  options: FieldOptionsSchema,
5116
5680
  props: IonicSelectPropsSchema.optional()
5117
5681
  });
5118
- var IonicTextareaFieldSchema = IonicValueFieldBase.extend({
5119
- type: z51.literal("textarea"),
5120
- value: z51.string().optional(),
5682
+ var IonicSelectFieldSchema = IonicSelectFieldSchemaObject.superRefine(nullableValueRefine);
5683
+ var IonicTextareaFieldSchemaObject = IonicValueFieldBase.extend({
5684
+ type: z52.literal("textarea"),
5685
+ nullable: z52.boolean().optional(),
5686
+ value: z52.string().nullable().optional(),
5121
5687
  placeholder: DynamicTextSchema.optional(),
5122
5688
  props: IonicTextareaPropsSchema.optional()
5123
5689
  });
5124
- var IonicMultiCheckboxFieldSchema = IonicValueFieldBase.extend({
5125
- type: z51.literal("multi-checkbox"),
5126
- value: z51.array(z51.unknown()).optional(),
5690
+ var IonicTextareaFieldSchema = IonicTextareaFieldSchemaObject.superRefine(nullableValueRefine);
5691
+ var IonicMultiCheckboxFieldSchemaObject = IonicValueFieldBase.extend({
5692
+ type: z52.literal("multi-checkbox"),
5693
+ nullable: z52.boolean().optional(),
5694
+ value: z52.array(z52.unknown()).nullable().optional(),
5127
5695
  placeholder: DynamicTextSchema.optional(),
5128
5696
  options: FieldOptionsSchema,
5129
5697
  props: IonicMultiCheckboxPropsSchema.optional()
5130
5698
  });
5699
+ var IonicMultiCheckboxFieldSchema = IonicMultiCheckboxFieldSchemaObject.superRefine(nullableValueRefine);
5131
5700
  var IonicButtonFieldSchema = BaseFieldDefSchema.extend({
5132
- type: z51.literal("button"),
5133
- event: z51.string().optional(),
5134
- eventArgs: z51.array(z51.union([z51.string(), z51.number(), z51.boolean(), z51.null(), z51.undefined()])).optional(),
5701
+ type: z52.literal("button"),
5702
+ event: z52.string().optional(),
5703
+ eventArgs: z52.array(z52.union([z52.string(), z52.number(), z52.boolean(), z52.null(), z52.undefined()])).optional(),
5135
5704
  props: IonicButtonPropsSchema.optional(),
5136
5705
  logic: LogicArraySchema.optional()
5137
5706
  });
5138
5707
  var IonicSubmitButtonFieldSchema = BaseFieldDefSchema.extend({
5139
- type: z51.literal("submit"),
5708
+ type: z52.literal("submit"),
5140
5709
  props: IonicButtonPropsSchema.optional(),
5141
5710
  logic: LogicArraySchema.optional()
5142
5711
  });
5143
5712
  var IonicNextButtonFieldSchema = BaseFieldDefSchema.extend({
5144
- type: z51.literal("next"),
5713
+ type: z52.literal("next"),
5145
5714
  props: IonicButtonPropsSchema.optional(),
5146
5715
  logic: LogicArraySchema.optional()
5147
5716
  });
5148
5717
  var IonicPreviousButtonFieldSchema = BaseFieldDefSchema.extend({
5149
- type: z51.literal("previous"),
5718
+ type: z52.literal("previous"),
5150
5719
  props: IonicButtonPropsSchema.optional()
5151
5720
  });
5152
5721
  var IonicAddArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
5153
- type: z51.literal("addArrayItem"),
5154
- arrayKey: z51.string().optional(),
5722
+ type: z52.literal("addArrayItem"),
5723
+ arrayKey: z52.string().optional(),
5155
5724
  props: IonicButtonPropsSchema.optional()
5156
5725
  });
5157
5726
  var IonicRemoveArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
5158
- type: z51.literal("removeArrayItem"),
5159
- arrayKey: z51.string().optional(),
5727
+ type: z52.literal("removeArrayItem"),
5728
+ arrayKey: z52.string().optional(),
5160
5729
  props: IonicButtonPropsSchema.optional()
5161
5730
  });
5162
5731
 
5163
5732
  // internal/dynamic-forms-zod/ionic/src/ionic-leaf-field.schema.ts
5164
- import { z as z52 } from "zod";
5165
- var IonicLeafFieldSchema = z52.discriminatedUnion("type", [
5733
+ import { z as z53 } from "zod";
5734
+ var IonicLeafFieldSchema = z53.discriminatedUnion("type", [
5166
5735
  TextFieldSchema,
5167
5736
  HiddenFieldSchema,
5168
- IonicInputFieldSchema,
5737
+ IonicInputFieldSchemaObject,
5169
5738
  IonicCheckboxFieldSchema,
5170
- IonicRadioFieldSchema,
5739
+ IonicRadioFieldSchemaObject,
5171
5740
  IonicToggleFieldSchema,
5172
- IonicSliderFieldSchema,
5173
- IonicDatepickerFieldSchema,
5174
- IonicSelectFieldSchema,
5175
- IonicTextareaFieldSchema,
5176
- IonicMultiCheckboxFieldSchema,
5741
+ IonicSliderFieldSchemaObject,
5742
+ IonicDatepickerFieldSchemaObject,
5743
+ IonicSelectFieldSchemaObject,
5744
+ IonicTextareaFieldSchemaObject,
5745
+ IonicMultiCheckboxFieldSchemaObject,
5177
5746
  IonicButtonFieldSchema,
5178
5747
  IonicSubmitButtonFieldSchema,
5179
5748
  IonicNextButtonFieldSchema,
5180
5749
  IonicPreviousButtonFieldSchema,
5181
5750
  IonicAddArrayItemButtonFieldSchema,
5182
5751
  IonicRemoveArrayItemButtonFieldSchema
5183
- ]);
5752
+ ]).superRefine(nullableValueRefine);
5184
5753
 
5185
5754
  // internal/dynamic-forms-zod/ionic/src/ionic-form-config.schema.ts
5186
- import { z as z53 } from "zod";
5755
+ import { z as z54 } from "zod";
5187
5756
  var containerSchemas4 = createContainerSchemas({
5188
5757
  leafFieldSchema: IonicLeafFieldSchema
5189
5758
  });
@@ -5192,7 +5761,7 @@ var IonicRowFieldSchema = containerSchemas4.RowFieldSchema;
5192
5761
  var IonicGroupFieldSchema = containerSchemas4.GroupFieldSchema;
5193
5762
  var IonicArrayFieldSchema = containerSchemas4.ArrayFieldSchema;
5194
5763
  var IonicFieldSchema = containerSchemas4.AllFieldsSchema;
5195
- var IonicFormDefaultPropsSchema = z53.object({
5764
+ var IonicFormDefaultPropsSchema = z54.object({
5196
5765
  color: IonicColorSchema.optional(),
5197
5766
  labelPlacement: IonicLabelPlacementSchema.optional()
5198
5767
  });
@@ -5923,6 +6492,110 @@ ${fieldTypes.map((ft) => `- ${ft}`).join("\n")}
5923
6492
  });
5924
6493
  }
5925
6494
 
6495
+ // packages/dynamic-form-mcp/src/resources/wrappers.resource.ts
6496
+ function registerWrappersResource(server) {
6497
+ server.resource("ng-forge Wrappers", "ng-forge://wrappers", async () => {
6498
+ const wrappers = getWrappers();
6499
+ return {
6500
+ contents: [
6501
+ {
6502
+ uri: "ng-forge://wrappers",
6503
+ mimeType: "application/json",
6504
+ text: JSON.stringify(
6505
+ {
6506
+ description: 'Available ng-forge field wrappers. Wrappers decorate the rendered output of a field or container without changing form data. Compose via `wrappers: [{ type: "...", ...props }]`.',
6507
+ categories: {
6508
+ core: "Ships from @ng-forge/dynamic-forms \u2014 always importable.",
6509
+ demo: "Ships from @internal/examples-shared-ui for the docs sandbox \u2014 NOT a library primitive.",
6510
+ adapter: "Ships from a UI adapter library (reserved)."
6511
+ },
6512
+ authoringContract: WRAPPER_AUTHORING_CONTRACT,
6513
+ wrappers: wrappers.map((w) => ({
6514
+ type: w.type,
6515
+ category: w.category,
6516
+ availability: w.availability,
6517
+ package: w.package,
6518
+ description: w.description,
6519
+ autoAppliesTo: w.autoAppliesTo
6520
+ }))
6521
+ },
6522
+ null,
6523
+ 2
6524
+ )
6525
+ }
6526
+ ]
6527
+ };
6528
+ });
6529
+ server.resource("Wrapper Details", "ng-forge://wrappers/{type}", async (uri) => {
6530
+ const match = uri.href.match(/ng-forge:\/\/wrappers\/(.+)/);
6531
+ const typeName = match?.[1];
6532
+ if (!typeName) {
6533
+ return {
6534
+ contents: [
6535
+ {
6536
+ uri: uri.href,
6537
+ mimeType: "text/plain",
6538
+ text: "Wrapper type not specified in URI"
6539
+ }
6540
+ ]
6541
+ };
6542
+ }
6543
+ const wrapper = getWrapper(typeName);
6544
+ if (!wrapper) {
6545
+ return {
6546
+ contents: [
6547
+ {
6548
+ uri: uri.href,
6549
+ mimeType: "text/plain",
6550
+ text: `Wrapper type '${typeName}' not found. Available types: ${getWrappers().map((w) => w.type).join(", ")}`
6551
+ }
6552
+ ]
6553
+ };
6554
+ }
6555
+ return {
6556
+ contents: [
6557
+ {
6558
+ uri: uri.href,
6559
+ mimeType: "application/json",
6560
+ text: JSON.stringify(wrapper, null, 2)
6561
+ }
6562
+ ]
6563
+ };
6564
+ });
6565
+ server.resource("Wrappers by Category", "ng-forge://wrappers/category/{category}", async (uri) => {
6566
+ const match = uri.href.match(/ng-forge:\/\/wrappers\/category\/(.+)/);
6567
+ const category = match?.[1];
6568
+ if (!category || !["core", "demo", "adapter"].includes(category)) {
6569
+ return {
6570
+ contents: [
6571
+ {
6572
+ uri: uri.href,
6573
+ mimeType: "text/plain",
6574
+ text: "Valid categories: core, demo, adapter"
6575
+ }
6576
+ ]
6577
+ };
6578
+ }
6579
+ const wrappers = getWrappersByCategory(category);
6580
+ return {
6581
+ contents: [
6582
+ {
6583
+ uri: uri.href,
6584
+ mimeType: "application/json",
6585
+ text: JSON.stringify(
6586
+ {
6587
+ category,
6588
+ wrappers
6589
+ },
6590
+ null,
6591
+ 2
6592
+ )
6593
+ }
6594
+ ]
6595
+ };
6596
+ });
6597
+ }
6598
+
5926
6599
  // packages/dynamic-form-mcp/src/resources/index.ts
5927
6600
  function registerResources(server) {
5928
6601
  registerInstructionsResource(server);
@@ -5930,22 +6603,24 @@ function registerResources(server) {
5930
6603
  registerFieldTypesResource(server);
5931
6604
  registerValidatorsResource(server);
5932
6605
  registerUIAdaptersResource(server);
6606
+ registerWrappersResource(server);
5933
6607
  registerDocumentationResource(server);
5934
6608
  registerSchemasResource(server);
5935
6609
  }
5936
6610
 
5937
6611
  // packages/dynamic-form-mcp/src/tools/lookup.tool.ts
5938
- import { z as z54 } from "zod";
6612
+ import { z as z55 } from "zod";
5939
6613
 
5940
6614
  // packages/dynamic-form-mcp/src/tools/data/lookup-topics.ts
5941
6615
  var TOPICS = {
5942
6616
  // ========== FIELD TYPES ==========
5943
6617
  input: {
5944
6618
  brief: `\`\`\`typescript
5945
- { key: 'email', type: 'input', label: 'Email', required: true, email: true, props: { type: 'email', placeholder: 'you@example.com' } }
6619
+ { key: 'email', type: 'input', label: 'Email', required: true, email: true, placeholder: 'you@example.com', props: { type: 'email' } }
5946
6620
  \`\`\`
5947
6621
  **Shorthand:** required, email, min, max, minLength, maxLength, pattern
5948
- **Props:** type (text|email|password|number|tel|url), placeholder, appearance (Material)`,
6622
+ **Field-level:** placeholder
6623
+ **Props:** type (text|email|password|number|tel|url), appearance (Material)`,
5949
6624
  full: `# Input Field
5950
6625
 
5951
6626
  \`\`\`typescript
@@ -5955,9 +6630,9 @@ var TOPICS = {
5955
6630
  label: 'Email',
5956
6631
  required: true,
5957
6632
  email: true,
6633
+ placeholder: 'you@example.com',
5958
6634
  props: {
5959
6635
  type: 'email', // 'text' | 'email' | 'password' | 'number' | 'tel' | 'url'
5960
- placeholder: 'you@example.com',
5961
6636
  appearance: 'outline' // Material: 'outline' | 'fill'
5962
6637
  }
5963
6638
  }
@@ -5965,7 +6640,8 @@ var TOPICS = {
5965
6640
 
5966
6641
  **Validation shorthand:** \`required\`, \`email\`, \`min\`, \`max\`, \`minLength\`, \`maxLength\`, \`pattern\`
5967
6642
 
5968
- **Props:** \`type\`, \`placeholder\`, \`appearance\` (Material), \`hint\` (Material)
6643
+ **Field-level:** \`placeholder\`
6644
+ **Props:** \`type\`, \`appearance\` (Material), \`hint\` (Material)
5969
6645
 
5970
6646
  **Value Type:** \`string | number\`
5971
6647
 
@@ -5973,7 +6649,7 @@ var TOPICS = {
5973
6649
  },
5974
6650
  select: {
5975
6651
  brief: `\`\`\`typescript
5976
- { key: 'country', type: 'select', label: 'Country', options: [{ label: 'USA', value: 'us' }], props: { placeholder: 'Choose...' } }
6652
+ { key: 'country', type: 'select', label: 'Country', placeholder: 'Choose...', options: [{ label: 'USA', value: 'us' }] }
5977
6653
  \`\`\`
5978
6654
  \u26A0\uFE0F **options at FIELD level, NOT in props!**`,
5979
6655
  full: `# Select Field
@@ -5988,8 +6664,8 @@ var TOPICS = {
5988
6664
  { label: 'USA', value: 'us' },
5989
6665
  { label: 'Canada', value: 'ca' }
5990
6666
  ],
6667
+ placeholder: 'Choose...',
5991
6668
  props: {
5992
- placeholder: 'Choose...',
5993
6669
  multiple: false // Allow multiple selection
5994
6670
  }
5995
6671
  }
@@ -6082,7 +6758,7 @@ For multiple selections, use **multi-checkbox** type.`,
6082
6758
  },
6083
6759
  textarea: {
6084
6760
  brief: `\`\`\`typescript
6085
- { key: 'bio', type: 'textarea', label: 'Bio', maxLength: 500, props: { rows: 4, placeholder: 'Tell us about yourself...' } }
6761
+ { key: 'bio', type: 'textarea', label: 'Bio', maxLength: 500, placeholder: 'Tell us about yourself...', props: { rows: 4 } }
6086
6762
  \`\`\``,
6087
6763
  full: `# Textarea Field
6088
6764
 
@@ -6092,9 +6768,9 @@ For multiple selections, use **multi-checkbox** type.`,
6092
6768
  type: 'textarea',
6093
6769
  label: 'Biography',
6094
6770
  maxLength: 500,
6771
+ placeholder: 'Tell us about yourself...',
6095
6772
  props: {
6096
6773
  rows: 4,
6097
- placeholder: 'Tell us about yourself...'
6098
6774
  }
6099
6775
  }
6100
6776
  \`\`\`
@@ -8002,18 +8678,33 @@ logic: [{ type: 'disabled', condition: 'formSubmitting' }]
8002
8678
  Copy-paste ready expressions for derivations and conditions.
8003
8679
 
8004
8680
  ## Age from Birthdate
8681
+ Complex calculations like age should use a custom function, not an expression:
8005
8682
  \`\`\`typescript
8006
- expression: \`(() => {
8007
- if (!formValue.birthDate) return '';
8008
- const birth = new Date(formValue.birthDate);
8009
- const today = new Date();
8010
- let age = today.getFullYear() - birth.getFullYear();
8011
- const monthDiff = today.getMonth() - birth.getMonth();
8012
- if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birth.getDate())) {
8013
- age--;
8014
- }
8015
- return age;
8016
- })()\`
8683
+ // In your FormConfig:
8684
+ {
8685
+ key: 'age',
8686
+ type: 'input',
8687
+ derivation: {
8688
+ type: 'custom',
8689
+ functionName: 'calculateAge',
8690
+ },
8691
+ }
8692
+
8693
+ // In customFnConfig:
8694
+ customFnConfig: {
8695
+ derivations: {
8696
+ calculateAge: (ctx) => {
8697
+ const birthDate = ctx.formValue().birthDate;
8698
+ if (!birthDate) return '';
8699
+ const birth = new Date(birthDate);
8700
+ const today = new Date();
8701
+ let age = today.getFullYear() - birth.getFullYear();
8702
+ const m = today.getMonth() - birth.getMonth();
8703
+ if (m < 0 || (m === 0 && today.getDate() < birth.getDate())) age--;
8704
+ return age;
8705
+ },
8706
+ },
8707
+ }
8017
8708
  \`\`\`
8018
8709
 
8019
8710
  ## Array Count / Length
@@ -8342,7 +9033,13 @@ var TOPIC_DESCRIPTIONS = {
8342
9033
  conditions: "Condition operators and types for logic rules",
8343
9034
  "common-expressions": "Frequently used derivation expressions (age, math, concatenation)",
8344
9035
  "type-narrowing": "TypeScript type safety with as const satisfies FormConfig",
8345
- workflow: "Recommended tool usage guide \u2014 start here"
9036
+ workflow: "Recommended tool usage guide \u2014 start here",
9037
+ // Wrappers
9038
+ wrappers: "Overview of the wrapper chain: how to apply, compose, and author wrappers",
9039
+ wrapper: "Overview of the wrapper chain (alias of `wrappers`)",
9040
+ css: "Built-in CSS wrapper \u2014 applies DynamicText class names to the host element",
9041
+ arraySection: "Demo wrapper \u2014 array card whose header owns the Add button (examples-shared-ui)",
9042
+ section: "Demo wrapper \u2014 titled card around any field or container (examples-shared-ui)"
8346
9043
  };
8347
9044
  var TOPIC_ALIASES = {
8348
9045
  // Field type aliases
@@ -8469,7 +9166,21 @@ var TOPIC_ALIASES = {
8469
9166
  // Workflow aliases
8470
9167
  "how-to": "workflow",
8471
9168
  guide: "workflow",
8472
- "getting-started": "workflow"
9169
+ "getting-started": "workflow",
9170
+ // Wrapper aliases
9171
+ wrapper: "wrappers",
9172
+ "field-wrapper": "wrappers",
9173
+ "field-wrappers": "wrappers",
9174
+ decorator: "wrappers",
9175
+ decorators: "wrappers",
9176
+ "wrapper-chain": "wrappers",
9177
+ "css-wrapper": "css",
9178
+ csswrapper: "css",
9179
+ cssclasses: "css",
9180
+ "array-section": "arraySection",
9181
+ arraysection: "arraySection",
9182
+ "section-wrapper": "section",
9183
+ sectionwrapper: "section"
8473
9184
  };
8474
9185
 
8475
9186
  // packages/dynamic-form-mcp/src/services/topic-mapper.ts
@@ -8566,6 +9277,7 @@ function formatTopicItem(key) {
8566
9277
  function getTopicList() {
8567
9278
  const fieldTypes = ["input", "select", "slider", "radio", "checkbox", "textarea", "datepicker", "toggle", "text", "hidden"];
8568
9279
  const containers = ["group", "row", "array", "simplified-array", "page"];
9280
+ const wrappers = ["wrappers", ...getWrappers().map((w) => w.type)];
8569
9281
  const concepts = [
8570
9282
  "validation",
8571
9283
  "validation-messages",
@@ -8601,6 +9313,9 @@ ${fieldTypes.map(formatTopicItem).join("\n")}
8601
9313
  ## Containers
8602
9314
  ${containers.map(formatTopicItem).join("\n")}
8603
9315
 
9316
+ ## Wrappers
9317
+ ${wrappers.map(formatTopicItem).join("\n")}
9318
+
8604
9319
  ## Concepts
8605
9320
  ${concepts.map(formatTopicItem).join("\n")}
8606
9321
 
@@ -8667,7 +9382,144 @@ function formatFieldInfoFull(field, uiFieldType) {
8667
9382
  lines.push("```");
8668
9383
  return lines.join("\n");
8669
9384
  }
9385
+ function formatWrapperInfo(wrapper) {
9386
+ const lines = [];
9387
+ lines.push(`# ${wrapper.type} wrapper`);
9388
+ lines.push("");
9389
+ lines.push(`**Category:** ${wrapper.category}`);
9390
+ lines.push(`**Availability:** ${wrapper.availability}`);
9391
+ lines.push(`**Package:** \`${wrapper.package}\``);
9392
+ lines.push(`**Component:** \`${wrapper.componentName}\``);
9393
+ lines.push(`**Description:** ${wrapper.description}`);
9394
+ if (wrapper.availability === "demo-only") {
9395
+ lines.push("");
9396
+ lines.push(
9397
+ "> **Note:** This is a demo wrapper that ships with the docs sandbox, not a library primitive. Use it as a pattern/template and author your own wrapper (or copy the component out of `internal/examples-shared-ui/src/lib/demo-wrappers/`) when adopting the idea in production."
9398
+ );
9399
+ }
9400
+ if (wrapper.autoAppliesTo.length > 0) {
9401
+ lines.push("");
9402
+ lines.push(`**Auto-applies to:** ${wrapper.autoAppliesTo.join(", ")}`);
9403
+ lines.push(
9404
+ "_(Injected automatically into these field types. Can be overridden via `FormConfig.defaultWrappers` or per-field `wrappers: [...]`; clear entirely with `wrappers: null`.)_"
9405
+ );
9406
+ } else {
9407
+ lines.push("");
9408
+ lines.push("**Auto-applies to:** _(none \u2014 opt-in via the field's `wrappers` array)_");
9409
+ }
9410
+ if (Object.keys(wrapper.props).length > 0) {
9411
+ lines.push("");
9412
+ lines.push("### Config Props");
9413
+ for (const prop of Object.values(wrapper.props)) {
9414
+ const req = prop.required ? " **(required)**" : "";
9415
+ const def = prop.default !== void 0 ? ` (default: ${JSON.stringify(prop.default)})` : "";
9416
+ lines.push(`- \`${prop.name}\`: ${prop.type}${req}${def} \u2014 ${prop.description}`);
9417
+ }
9418
+ } else {
9419
+ lines.push("");
9420
+ lines.push("### Config Props");
9421
+ lines.push("_(none \u2014 no configurable inputs on this wrapper)_");
9422
+ }
9423
+ if (wrapper.minimalExample) {
9424
+ lines.push("");
9425
+ lines.push("### Minimal Config");
9426
+ lines.push("```typescript");
9427
+ lines.push(wrapper.minimalExample);
9428
+ lines.push("```");
9429
+ }
9430
+ lines.push("");
9431
+ lines.push("### Full Example");
9432
+ lines.push("```typescript");
9433
+ lines.push(wrapper.example);
9434
+ lines.push("```");
9435
+ lines.push("");
9436
+ lines.push("### Authoring Contract");
9437
+ lines.push(wrapper.contract);
9438
+ return lines.join("\n");
9439
+ }
9440
+ function formatWrappersOverview() {
9441
+ const wrappers = getWrappers();
9442
+ const lines = [];
9443
+ lines.push("# Wrappers");
9444
+ lines.push("");
9445
+ lines.push(
9446
+ "Wrappers decorate the rendered output of a field (or container) without changing the form data structure. They are composed as a chain: each wrapper exposes a `#fieldComponent` `ViewContainerRef` slot where the next wrapper \u2014 or the field itself \u2014 is rendered."
9447
+ );
9448
+ lines.push("");
9449
+ lines.push("## Applying a wrapper");
9450
+ lines.push("");
9451
+ lines.push("```typescript");
9452
+ lines.push(`// Per-field wrapper chain (outer-most first)
9453
+ {
9454
+ key: 'email',
9455
+ type: 'input',
9456
+ label: 'Email',
9457
+ wrappers: [
9458
+ { type: 'section', title: 'Account' }, // outer
9459
+ { type: 'css', cssClasses: 'pad-lg' } // inner
9460
+ ]
9461
+ }
9462
+
9463
+ // Form-level defaults applied to every field
9464
+ const config = {
9465
+ defaultWrappers: [{ type: 'css', cssClasses: 'field-default' }],
9466
+ fields: [...]
9467
+ } as const satisfies FormConfig;
9468
+
9469
+ // Clear all wrappers on a specific field (overrides defaults + auto)
9470
+ { key: 'id', type: 'hidden', value: 'abc', wrappers: null }`);
9471
+ lines.push("```");
9472
+ lines.push("");
9473
+ lines.push("## Registered Wrappers");
9474
+ lines.push("");
9475
+ for (const w of wrappers) {
9476
+ const flag = w.availability === "demo-only" ? " _(demo-only)_" : "";
9477
+ lines.push(`- **${w.type}** (${w.category}, \`${w.package}\`)${flag} \u2014 ${w.description.split(".")[0]}.`);
9478
+ }
9479
+ lines.push("");
9480
+ lines.push('Use `ngforge_lookup topic="<name>"` for full details on any individual wrapper.');
9481
+ lines.push("");
9482
+ lines.push("## Authoring Contract");
9483
+ lines.push("");
9484
+ lines.push(wrappers[0]?.contract ?? "");
9485
+ return lines.join("\n");
9486
+ }
8670
9487
  async function resolveTopicContent(resolvedTopic, depth, uiIntegration) {
9488
+ if (resolvedTopic === "wrappers" || resolvedTopic === "wrapper") {
9489
+ if (depth === "brief") {
9490
+ const wrappers = getWrappers();
9491
+ return [
9492
+ "**Wrappers** decorate a field's rendered output without changing form data.",
9493
+ "",
9494
+ "Registered:",
9495
+ ...wrappers.map((w) => `- \`${w.type}\` (${w.category}${w.availability === "demo-only" ? ", demo-only" : ""})`),
9496
+ "",
9497
+ 'Use `wrappers: [{ type: "css", cssClasses: "..." }]` on any field. See `ngforge_lookup topic="wrappers"` for the full overview.'
9498
+ ].join("\n");
9499
+ }
9500
+ return formatWrappersOverview();
9501
+ }
9502
+ const wrapperInfo = getWrapper(resolvedTopic);
9503
+ if (wrapperInfo) {
9504
+ const formatted = formatWrapperInfo(wrapperInfo);
9505
+ if (depth === "brief") {
9506
+ const lines = [
9507
+ `# ${wrapperInfo.type} wrapper`,
9508
+ "",
9509
+ `${wrapperInfo.description.split(".")[0]}.`,
9510
+ "",
9511
+ "```typescript",
9512
+ wrapperInfo.minimalExample ?? `{ type: '${wrapperInfo.type}' }`,
9513
+ "```"
9514
+ ];
9515
+ if (wrapperInfo.availability === "demo-only") {
9516
+ lines.push("");
9517
+ lines.push(`**Demo-only** \u2014 ships from \`${wrapperInfo.package}\`, not \`@ng-forge/dynamic-forms\`.`);
9518
+ }
9519
+ return lines.join("\n");
9520
+ }
9521
+ return formatted;
9522
+ }
8671
9523
  if (depth === "brief") {
8672
9524
  const topicContent2 = TOPICS[resolvedTopic];
8673
9525
  if (topicContent2) {
@@ -8755,7 +9607,12 @@ var NEXT_STEPS = {
8755
9607
  "logic-matrix": '**Next:** `ngforge_lookup topic="conditional"` for condition syntax \xB7 `ngforge_lookup topic="derivation"` for derivation syntax',
8756
9608
  "field-placement": '**Next:** `ngforge_lookup topic="containers"` for container overview',
8757
9609
  conditions: '**Next:** `ngforge_lookup topic="conditional"` for full conditional logic docs \xB7 `ngforge_examples pattern="minimal-conditional"` for working example',
8758
- workflow: '**Next:** `ngforge_lookup topic="golden-path"` for form structure templates \xB7 `ngforge_examples pattern="complete"` for a full working example'
9610
+ workflow: '**Next:** `ngforge_lookup topic="golden-path"` for form structure templates \xB7 `ngforge_examples pattern="complete"` for a full working example',
9611
+ // Wrappers
9612
+ wrappers: '**Next:** `ngforge_lookup topic="css"` for the shipping CSS wrapper \xB7 `ngforge_lookup topic="section"` or `ngforge_lookup topic="arraySection"` for demo wrappers \xB7 `ngforge_examples pattern="wrapper-array-actions"` for a working array-section example',
9613
+ css: '**Next:** `ngforge_lookup topic="wrappers"` for the full wrapper overview \xB7 `ngforge_lookup topic="field-placement"` for where wrappers can apply',
9614
+ arraySection: '**Next:** `ngforge_lookup topic="wrappers"` for the wrapper overview \xB7 `ngforge_lookup topic="array"` for array field docs \xB7 `ngforge_lookup topic="array-buttons"` for the button-field alternative',
9615
+ section: '**Next:** `ngforge_lookup topic="wrappers"` for the wrapper overview \xB7 `ngforge_lookup topic="css"` for the shipping CSS wrapper'
8759
9616
  };
8760
9617
  function getNextSteps(topic) {
8761
9618
  return NEXT_STEPS[topic];
@@ -8776,6 +9633,8 @@ Field types: input, select, slider, radio, checkbox, textarea, datepicker, toggl
8776
9633
 
8777
9634
  Containers: group, row, array, simplified-array, page
8778
9635
 
9636
+ Wrappers: wrappers (overview), css (shipping), section, arraySection (demo-only)
9637
+
8779
9638
  Concepts: validation, conditional, derivation, property-derivation, options-format, expression-variables, async-validators
8780
9639
 
8781
9640
  Patterns: field-placement, logic-matrix, context-api, containers, multi-page-gotchas
@@ -8783,11 +9642,11 @@ Patterns: field-placement, logic-matrix, context-api, containers, multi-page-got
8783
9642
  Use topic="list" to see all available topics with descriptions.
8784
9643
  Use ngforge_search query="your question" to find topics by keyword.`,
8785
9644
  {
8786
- topic: z54.string().describe(
8787
- 'Topic to look up: field types (input, select, hidden, group, row, array, page), concepts (validation, conditional, derivation, property-derivation, options-format), patterns (golden-path, pitfalls, multi-page-gotchas), or "list" to see all topics'
9645
+ topic: z55.string().describe(
9646
+ 'Topic to look up: field types (input, select, hidden, group, row, array, page), wrappers (wrappers, css, section, arraySection), concepts (validation, conditional, derivation, property-derivation, options-format), patterns (golden-path, pitfalls, multi-page-gotchas), or "list" to see all topics'
8788
9647
  ),
8789
- depth: z54.enum(["brief", "full", "schema"]).default("full").describe("brief=quick syntax (~20 lines), full=complete docs with examples, schema=include JSON schema"),
8790
- uiIntegration: z54.enum(UI_INTEGRATIONS2).optional().describe("Filter UI-specific info (only with depth=schema). material, bootstrap, primeng, ionic")
9648
+ depth: z55.enum(["brief", "full", "schema"]).default("full").describe("brief=quick syntax (~20 lines), full=complete docs with examples, schema=include JSON schema"),
9649
+ uiIntegration: z55.enum(UI_INTEGRATIONS2).optional().describe("Filter UI-specific info (only with depth=schema). material, bootstrap, primeng, ionic")
8791
9650
  },
8792
9651
  async ({ topic, depth, uiIntegration }) => {
8793
9652
  const normalizedTopic = topic.toLowerCase().trim();
@@ -8835,7 +9694,7 @@ ${nextSteps}`;
8835
9694
  }
8836
9695
 
8837
9696
  // packages/dynamic-form-mcp/src/tools/examples.tool.ts
8838
- import { z as z55 } from "zod";
9697
+ import { z as z56 } from "zod";
8839
9698
  var PATTERNS = {
8840
9699
  // ========== MINIMAL PATTERNS (NEW) ==========
8841
9700
  "minimal-multipage": {
@@ -10818,7 +11677,7 @@ const megaFormConfig = {
10818
11677
  { key: 'pageHeader', type: 'text', label: 'All Field Types Demo', props: { elementType: 'h1' } },
10819
11678
 
10820
11679
  // TEXT INPUTS
10821
- { key: 'textInput', type: 'input', label: 'Text Input', props: { placeholder: 'Type here' } },
11680
+ { key: 'textInput', type: 'input', label: 'Text Input', placeholder: 'Type here' },
10822
11681
  { key: 'emailInput', type: 'input', label: 'Email', email: true, props: { type: 'email' } },
10823
11682
  { key: 'passwordInput', type: 'input', label: 'Password', minLength: 8, props: { type: 'password' } },
10824
11683
  { key: 'numberInput', type: 'input', label: 'Number', min: 0, max: 100, props: { type: 'number' } },
@@ -11061,10 +11920,10 @@ Standard patterns: derivation, property-derivation, multi-page, conditional, val
11061
11920
  Use pattern="list" to see all available patterns.
11062
11921
  Use depth="minimal" for code-only output (no markdown).`,
11063
11922
  {
11064
- pattern: z55.string().optional().describe(
11923
+ pattern: z56.string().optional().describe(
11065
11924
  'Pattern to get: minimal-multipage, minimal-array, minimal-simplified-array, minimal-conditional, minimal-validation, minimal-hidden, derivation, property-derivation, multi-page, conditional, validation, complete, mega. Use "list" to see all.'
11066
11925
  ),
11067
- depth: z55.enum(["minimal", "brief", "full", "explained"]).default("full").describe(
11926
+ depth: z56.enum(["minimal", "brief", "full", "explained"]).default("full").describe(
11068
11927
  "minimal=code only (~20-50 lines), brief=code+summary, full=code+comments (default), explained=code+detailed explanation"
11069
11928
  )
11070
11929
  },
@@ -11141,7 +12000,7 @@ function extractCode(markdown) {
11141
12000
  }
11142
12001
 
11143
12002
  // packages/dynamic-form-mcp/src/tools/validate.tool.ts
11144
- import { z as z56 } from "zod";
12003
+ import { z as z57 } from "zod";
11145
12004
  import { readFile } from "fs/promises";
11146
12005
 
11147
12006
  // packages/dynamic-form-mcp/src/utils/ast-extractor.ts
@@ -11755,10 +12614,10 @@ Example errors you'll see:
11755
12614
  - "options MUST be at FIELD level, NOT inside props"
11756
12615
  - "containers only support 'hidden' logic type"`,
11757
12616
  {
11758
- config: z56.union([z56.string(), z56.object({}).passthrough()]).describe(
12617
+ config: z57.union([z57.string(), z57.object({}).passthrough()]).describe(
11759
12618
  "File path (.ts/.js) OR JSON string OR JSON object. Auto-detects: paths ending in .ts/.js or starting with / are treated as files."
11760
12619
  ),
11761
- uiIntegration: z56.enum(UI_INTEGRATIONS3).default("material").describe("UI library to validate against (material, bootstrap, primeng, ionic). Defaults to material.")
12620
+ uiIntegration: z57.enum(UI_INTEGRATIONS3).default("material").describe("UI library to validate against (material, bootstrap, primeng, ionic). Defaults to material.")
11762
12621
  },
11763
12622
  async ({ config, uiIntegration }) => {
11764
12623
  try {
@@ -11864,7 +12723,7 @@ If validating JSON, ensure:
11864
12723
  }
11865
12724
 
11866
12725
  // packages/dynamic-form-mcp/src/tools/scaffold.tool.ts
11867
- import { z as z57 } from "zod";
12726
+ import { z as z58 } from "zod";
11868
12727
  var UI_INTEGRATIONS4 = ["material", "bootstrap", "primeng", "ionic"];
11869
12728
  function parseFieldDefs(fields) {
11870
12729
  return fields.map((f) => {
@@ -12119,12 +12978,12 @@ Examples:
12119
12978
  - With groups: pages=0 groups=["address","billing"]
12120
12979
  - With hidden: hidden=["userId:abc123","source:web"]`,
12121
12980
  {
12122
- pages: z57.number().min(0).max(10).default(0).describe("Number of pages (0 = single-page form, 1-10 = multi-page wizard)"),
12123
- arrays: z57.array(z57.string()).optional().describe('Array field names for dynamic lists, e.g., ["contacts", "addresses"]'),
12124
- groups: z57.array(z57.string()).optional().describe('Group field names for nested objects, e.g., ["address", "billing"]'),
12125
- hidden: z57.array(z57.string()).optional().describe('Hidden fields as "name:value" pairs, e.g., ["userId:abc", "version:1"]'),
12126
- fields: z57.array(z57.string()).optional().describe('Basic fields as "name:type" pairs, e.g., ["email:input", "country:select", "age:slider"]'),
12127
- uiIntegration: z57.enum(UI_INTEGRATIONS4).default("material").describe("UI library (for future UI-specific props). Defaults to material.")
12981
+ pages: z58.number().min(0).max(10).default(0).describe("Number of pages (0 = single-page form, 1-10 = multi-page wizard)"),
12982
+ arrays: z58.array(z58.string()).optional().describe('Array field names for dynamic lists, e.g., ["contacts", "addresses"]'),
12983
+ groups: z58.array(z58.string()).optional().describe('Group field names for nested objects, e.g., ["address", "billing"]'),
12984
+ hidden: z58.array(z58.string()).optional().describe('Hidden fields as "name:value" pairs, e.g., ["userId:abc", "version:1"]'),
12985
+ fields: z58.array(z58.string()).optional().describe('Basic fields as "name:type" pairs, e.g., ["email:input", "country:select", "age:slider"]'),
12986
+ uiIntegration: z58.enum(UI_INTEGRATIONS4).default("material").describe("UI library (for future UI-specific props). Defaults to material.")
12128
12987
  },
12129
12988
  async ({ pages, arrays = [], groups = [], hidden = [], fields = [] }) => {
12130
12989
  const fieldDefs = parseFieldDefs(fields);
@@ -12166,7 +13025,7 @@ Examples:
12166
13025
  }
12167
13026
 
12168
13027
  // packages/dynamic-form-mcp/src/tools/search.tool.ts
12169
- import { z as z58 } from "zod";
13028
+ import { z as z59 } from "zod";
12170
13029
  var searchIndex = null;
12171
13030
  function getTopicSubcategory(key) {
12172
13031
  const fieldTypes = ["input", "select", "slider", "radio", "checkbox", "textarea", "datepicker", "toggle", "text", "hidden"];
@@ -12221,6 +13080,18 @@ function buildIndex() {
12221
13080
  toolCall: `ngforge_examples pattern="${key}"`
12222
13081
  });
12223
13082
  }
13083
+ for (const wrapper of getWrappers()) {
13084
+ const subcategory = wrapper.availability === "demo-only" ? `Wrapper (demo, ${wrapper.category})` : `Wrapper (${wrapper.category})`;
13085
+ entries.push({
13086
+ id: wrapper.type,
13087
+ category: "wrapper",
13088
+ subcategory,
13089
+ description: wrapper.description,
13090
+ aliases: [],
13091
+ content: `${wrapper.type} wrapper ${wrapper.description} ${wrapper.package}`.toLowerCase(),
13092
+ toolCall: `ngforge_lookup topic="${wrapper.type}"`
13093
+ });
13094
+ }
12224
13095
  searchIndex = entries;
12225
13096
  return entries;
12226
13097
  }
@@ -12263,7 +13134,7 @@ Try broader terms or check available topics:
12263
13134
  const lines = ["# Search Results", ""];
12264
13135
  for (let i = 0; i < results.length; i++) {
12265
13136
  const { entry } = results[i];
12266
- const categoryLabel = entry.category === "topic" ? `Topic \xB7 ${entry.subcategory}` : `Example \xB7 ${entry.subcategory}`;
13137
+ const categoryLabel = entry.category === "topic" ? `Topic \xB7 ${entry.subcategory}` : entry.category === "wrapper" ? entry.subcategory : `Example \xB7 ${entry.subcategory}`;
12267
13138
  lines.push(`${i + 1}. **${entry.id}** (${categoryLabel})`);
12268
13139
  lines.push(` ${entry.description}`);
12269
13140
  lines.push(` \u2192 \`${entry.toolCall}\``);
@@ -12290,7 +13161,7 @@ Use this when you don't know the exact topic name.
12290
13161
 
12291
13162
  New to ng-forge? Start with: ngforge_lookup topic="workflow"`,
12292
13163
  {
12293
- query: z58.string().describe("Natural language or keywords to search for")
13164
+ query: z59.string().describe("Natural language or keywords to search for")
12294
13165
  },
12295
13166
  async ({ query }) => {
12296
13167
  const index = buildIndex();