Skip to content

Add ErrorIndicator glyph component (#358)#360

Merged
CarlosNZ merged 5 commits into
v2.0-devfrom
358-error-indicator-component
Jun 15, 2026
Merged

Add ErrorIndicator glyph component (#358)#360
CarlosNZ merged 5 commits into
v2.0-devfrom
358-error-indicator-component

Conversation

@CarlosNZ

Copy link
Copy Markdown
Owner

Summary

Adds ErrorIndicator to @json-edit-react/components — a custom-node component that wraps the built-in node (originalNode) and adds a glyph (default ⚠️) beside it, to flag the nodes you target. Rewires the "Validation flagging" demo example to use it instead of the red-background theme, making it the first example combining @json-edit-react/utils and @json-edit-react/components. Implements #358.

Stacked on #359 (base 357-use-validation-state). The demo example and the cross-branch test consume useValidationState, which lands in #359. Retarget this to v2.0-dev once #359 merges.

How the validation state reaches the component

It doesn't — the component is a pure presentational wrapper that only knows errorGlyph / position. Which nodes it decorates is the definition's condition, which the factory (createDefinitionFactory) ANDs with the component's guard. The consumer wires validity there and memoizes on [validation]:

const validation = useValidationState(data, validate)
const customNodeDefinitions = useMemo(
  () => [errorIndicatorDefinition({ condition: (nd) => validation.hasErrorAt(nd.path) })],
  [validation]
)

So @json-edit-react/components takes no dependency on @json-edit-react/utils (it accepts a FilterFunction, not a ValidationState). The customNodeDefinitions array — Object.is-compared as a node prop, memoized on [validation] — pierces the node memo when validity flips, so the marker appears/clears correctly even cross-branch. With condition = validity, only invalid nodes pay the passOriginalNode cost.

Guarded to value nodes

The definition's guard is ({ value }) => value === null || typeof value !== 'object'. ANDed with any consumer condition, it ensures the glyph never lands on a collection — important because AJV's if/then reports an error at the parent object's path as well as the leaf, which would otherwise wrap (and visually break) the whole collection. Override guard to opt collections back in; for collection-level marking use validationStyles({ within }) from @json-edit-react/utils.

Details

  • Props via componentProps: errorGlyph (any ReactNode, default ⚠️), position ('before' | 'after', default 'after'). No condition → flags nothing (the default targeting is a deliberate no-op).
  • Layout in ErrorIndicator/style.css (inline-flex + align-items: center + gap), injected via rollup-plugin-styles and imported in both component.tsx and definition.ts (as DatePicker does) so sideEffects: false can't tree-shake it. A class, not inline styles, so consumers can override it.
  • Dependency-free — imports only React and core types.

Testing

test/error-indicator.test.tsx (imported from the component's subtree, not the barrel, to avoid the barrel's ESM-only deps in Jest):

  • default no-op; condition targeting; value-node guard (a broad condition never decorates a collection); errorGlyph / position props (glyph content + DOM order).
  • Cross-branch integration (renders a real JsonEditor with useValidationState): editing one node flips a different-branch node's validity and the glyph appears/clears there. Verified sharp — freezing the memo dep makes both cases fail with stale glyphs.

Full suite green (487 passed / 2 todo, +7); components tsc + build clean; demo typecheck 0 errors; core lint + compile unaffected. Changeset: @json-edit-react/components minor.

🤖 Generated with Claude Code

@github-actions

github-actions Bot commented Jun 14, 2026

Copy link
Copy Markdown

Bundle size impact

@json-edit-react/components

Format Base raw PR raw Δ raw Base gzip PR gzip Δ gzip
esm 13.22 KB 13.75 KB 🔺 +539 B (+3.98%) 4.49 KB 4.67 KB 🔺 +178 B (+3.87%)
cjs 13.91 KB 14.45 KB 🔺 +553 B (+3.88%) 4.36 KB 4.54 KB 🔺 +183 B (+4.10%)

Measured from build/index.{cjs,esm}.js. Gzip at level 9.

Base automatically changed from 357-use-validation-state to v2.0-dev June 15, 2026 05:25
@CarlosNZ CarlosNZ merged commit 70167c4 into v2.0-dev Jun 15, 2026
2 checks passed
@CarlosNZ CarlosNZ deleted the 358-error-indicator-component branch June 15, 2026 05:43
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.

1 participant