Skip to content

Edit Lifecycle — Hierarchical Composition

How editable components compose in a hierarchy, how data flows between levels, and how the Edit Lifecycle relates to the typed data provider pattern (FD-01). See Edit Lifecycle for the pattern overview.

In Arda, domain entities are nested: an Order contains a Supplier, which contains an Address. Each level is an editable component that manages its own draft. The framework composes these into a hierarchy where:

  • initialValue flows down from parent to child.
  • onConfirm flows up from child to parent.
  • contextErrors flow down from parent to child after parent-level validation.

PlantUML diagram

Downward: initial values and contextual errors

Section titled “Downward: initial values and contextual errors”
  1. The top-level component receives data from a data provider (TanStack Query, Redux, or props).
  2. It passes the relevant slice to each child as initialValue.
  3. After the child reports its validation via onChange, the parent runs its own contextual validation.
  4. Any contextual errors are injected into the child as contextErrors.
  1. The child calls onChange(value, validation) on every draft change.
  2. The parent incorporates the child’s value into its own draft.
  3. When the child confirms, it calls onConfirm(value).
  4. The parent updates its draft with the confirmed child value.
  5. The parent may then confirm its own draft, propagating further up.

When a parent composes errors for a child, it prefixes the child’s field path with the child’s position in the parent. For example:

  • Child AddressEditor reports error on field postalCode.
  • Parent SupplierEditor namespaces it as address.postalCode.
  • Grandparent OrderEditor sees it as supplier.address.postalCode.

The errorsFor() prefix matching automatically routes each error to the correct level.

Relationship to FD-01 (Typed Data Providers)

Section titled “Relationship to FD-01 (Typed Data Providers)”

The Edit Lifecycle and the typed data provider pattern (FD-01) are orthogonal and composable:

PlantUML diagram

  • FD-01 handles how data enters the component tree: typed provider hooks (e.g., useImageUpload, useCheckReachability) are injected via props or factory functions. Design system components never import @tanstack/react-query.
  • Edit Lifecycle handles what happens after data arrives: draft management, validation, phase transitions. It is agnostic to the data source.

They compose at the boundary: the data provider supplies initialValue and the persistence callback; the lifecycle manages everything between receiving data and confirming changes.

The following are deferred to ux-prototype#77:

  • useComposedDraft<T> — parent-level hook that registers children, composes their validators, and routes contextual errors automatically.
  • createCellEditorFactory<T> — factory that wires useDraft to AG Grid’s cell edit lifecycle (stopEditing(false) maps to confirm(), stopEditing(true) maps to cancel()).
  • EditablePanel<T> — wrapper component that provides the edit lifecycle context to a tree of child components.
  • Validation function convention — each editable component exports a pure validateXxx() function alongside the component, enabling parents to compose validation without importing the component itself.

Copyright: (c) Arda Systems 2025-2026, All rights reserved