Skip to content

feat: expose the Form Validator in the React, Angular and Vue bindings - #2646

Draft
gigibiffi84 wants to merge 4 commits into
eclipsesource:masterfrom
gigibiffi84:feat/validator-prop-bindings
Draft

gigibiffi84 wants to merge 4 commits into
eclipsesource:masterfrom
gigibiffi84:feat/validator-prop-bindings

Conversation

@gigibiffi84

@gigibiffi84 gigibiffi84 commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Part of #1498. Stacked on #2644 (Form Validator) and #2645 (rules through the Form Validator); the diff shrinks to the last commit once those are merged.

What changed

The bindings expose the core validator option and the renderer sets evaluate rules through it.

  • React JsonForms: new validator?: FormValidatorFactory prop next to ajv, forwarded to init / updateCore.
  • Vue JsonForms: new validator prop, forwarded to init / updateCore and watched like ajv; new useValidator() returning state.validator, mirroring useAjv().
  • Angular JsonForms: new @Input() validator; JsonFormsAngularService.updateCoreState takes an optional validator argument (defaults to keeping the stored one).
  • React renderer sets: withAjvProps (material and vanilla) additionally injects ruleValidator from getRuleValidator; the categorization layouts evaluate category visibility with it.
  • Angular Material: the categorization layout and mapStateToVisible use getRuleValidator(state) instead of getAjv(state).
  • Examples: ExampleDescription gains an optional validator, passed by all five example apps. New "Custom validator" example with a dependency-free, handwritten Form Validator. Its factory validates the form schema by hand and other schemas, such as its rule condition, with the Structural Matcher.

For adopters

Nothing changes without the new prop; ajv keeps working everywhere. Known gap, left for a follow-up: vue-vuetify's AdditionalProperties passes only ajv to its nested form, so a nested form under a custom validator still validates with Ajv.

Tests

  • React: new JsonForms.test.tsx case asserting the factory reaches core and its issue renders as the control's error. React tests green (36).
  • Vue: new JsonForms.spec.ts case asserting the factory reaches core and its issue is stored as an error. Vue tests green (25).
  • 528 core tests green; all packages build.

🤖 Generated with Claude Code

@netlify

netlify Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for jsonforms-examples ready!

Name Link
🔨 Latest commit 4c9d617
🔍 Latest deploy log https://app.netlify.com/projects/jsonforms-examples/deploys/6ad4f50e5a797162be1c4d00
😎 Deploy Preview https://deploy-preview-2646--jsonforms-examples.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

gigibiffi84 added a commit to gigibiffi84/jsonforms that referenced this pull request Oct 18, 2026
Brings feat/form-validator-bridge-v2 (the eclipsesource#2644 rework on current
upstream master) into fork master and ports the stacked work to the new
API:

- core: `state.validator` holds the Form Validator, the custom factory
  is kept in `state.validatorFactory`; no default Ajv instance is
  created while a factory is set (eclipsesource#2648).
- rules (eclipsesource#2645): conditions are evaluated with the validator factory
  (one cached Form Validator per condition schema) or the Ajv instance;
  `matches` and the bound-validator branch are gone. `getRuleValidator`
  reads `validatorFactory ?? ajv`.
- bindings (eclipsesource#2646): the `validator` prop of React, Vue and Angular is a
  FormValidatorFactory; `useValidator` reads `state.validator`.
- standard-schema: `fromStandardSchema` returns a factory. For its own
  JSON Schema it validates with the library and sets `parentSchema` per
  issue (`schemaAt`, moved here from core); for other schemas, e.g. rule
  conditions, it uses core's schema matcher. No `severity`.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B36yeVG6EUUhwMCEzybGEH
@gigibiffi84
gigibiffi84 marked this pull request as draft October 18, 2026 15:04
@gigibiffi84
gigibiffi84 force-pushed the feat/validator-prop-bindings branch from f2acbc0 to e455d36 Compare October 18, 2026 15:48
@gigibiffi84

Copy link
Copy Markdown
Contributor Author

Rebased onto the reworked #2644 for context, see the overview there: #2644 (comment). Still a draft until #2644 is accepted.

gigibiffi84 and others added 4 commits October 18, 2026 18:34
Adds a `validator` init/updateCore option taking a factory
`(schema) => FormValidator`. Core calls it whenever the schema changes
and stores the result in `state.validator`; without the option, Ajv is
the default Form Validator via `createAjvValidator`. Like the other
options, `validator: undefined` keeps the current value.

- `FormValidator.validate(data)` returns `ValidationIssue`s, which
  `issuesToErrors` converts to the Ajv error objects stored in the
  state. A missing `key` becomes `custom`; a `required` issue addressed
  to the missing property is split into parent path plus
  `params.missingProperty`. Ajv errors round-trip unchanged.
- `compiledAjvValidator(validateFn)` wraps an already compiled Ajv
  function, e.g. generated via Ajv standalone code.
- `getValidator(state)` exposes the current Form Validator.
- Switching to NoValidation via setValidationMode now also drops the
  validator, so later data updates no longer reintroduce errors.

`JsonFormsCore.validator` changes from the compiled Ajv function to a
Form Validator, see MIGRATION.md.

Part of eclipsesource#1498

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B36yeVG6EUUhwMCEzybGEH
…ing them with Ajv

Combinator tab selection compiled every oneOf/anyOf/allOf branch with
Ajv and then ignored all errors except the structural keywords
required, additionalProperties, type, enum and const. The new
isStructuralMatch evaluates exactly those keywords itself, recursively
through properties, patternProperties, items, $ref, nested combinators
and if/then/else.

Tab selection therefore no longer depends on an Ajv instance or on
code generation, so it also works under a Content Security Policy
without unsafe-eval. Equivalence with the previous filtered-Ajv
behaviour is covered by tests comparing both approaches keyword by
keyword.

Part of eclipsesource#1498

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Schema based rule conditions were always evaluated with
ajv.validate(condition.schema, value), the last place where a custom
Form Validator did not apply.

- Widen the `ajv` parameter of isVisible, isEnabled, isReadonly, the
  eval* functions and Runtime.isVisible/isEnabled to RuleValidator: an
  Ajv instance (unchanged behaviour), a FormValidatorFactory (one Form
  Validator per condition schema, cached) or undefined (the Structural
  Matcher).
- Add matchesConditionSchema and the getRuleValidator selector
  (`validatorFactory`, otherwise `ajv`); core's own mappers pass
  getRuleValidator(state) instead of getAjv(state).

Part of eclipsesource#1498

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B36yeVG6EUUhwMCEzybGEH
- React, Vue and Angular JsonForms gain a `validator` prop/input next to
  `ajv`, a FormValidatorFactory forwarded to init/updateCore; Vue adds
  useValidator(); JsonFormsAngularService.updateCoreState takes an
  optional validator.
- Material and vanilla withAjvProps additionally inject `ruleValidator`
  (getRuleValidator), used by the categorization layouts; Angular
  Material evaluates category visibility with getRuleValidator too.
- ExampleDescription gains an optional `validator`, passed through by
  all five example apps; new "Custom validator" example with a
  dependency-free handwritten Form Validator. Its factory validates the
  form schema by hand and other schemas, such as the rule condition,
  with the Structural Matcher.

Part of eclipsesource#1498

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B36yeVG6EUUhwMCEzybGEH
@gigibiffi84
gigibiffi84 force-pushed the feat/validator-prop-bindings branch from e455d36 to 4c9d617 Compare October 18, 2026 16:34

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants