Skip to content

Adapter Architecture

This document describes the architecture of Formosaic adapter packages: how they integrate with core, what contracts they must fulfill, and the classification system.

Package Boundary

@formosaic/core (main export)

The main export provides the form engine, rules engine, providers, types, and all public APIs.

@formosaic/core/adapter-utils (subpath export)

Shared utilities for field rendering:

typescript
import {
  GetFieldDataTestId,
  FieldClassName,
  getFieldState,
  formatDateTime,
  convertBooleanToYesOrNoText,
  isNull,
} from "@formosaic/core/adapter-utils";

@formosaic/core/testing (subpath export)

Contract test infrastructure:

typescript
import {
  runAdapterContractTests,
  TIER_1_FIELDS,
  ALL_FIELD_TYPES,
} from "@formosaic/core/testing";

How cloneElement Integration Works

  1. RenderField looks up the field's type string in the injected field registry
  2. Gets the pre-created React.JSX.Element
  3. Calls React.cloneElement(element, fieldProps) to pass IFieldProps as props
  4. The field component renders using the received props

Registry Factory Pattern

Each adapter exports a factory function:

typescript
export function createXxxFieldRegistry(): Dictionary<React.JSX.Element> {
  return {
    [ComponentTypes.Textbox]: React.createElement(Textbox),
    [ComponentTypes.Number]: React.createElement(NumberField),
    // ...
  };
}

Naming convention: createXxxFieldRegistry() where Xxx is the adapter name.

Adapter Classification

ClassDefinition
NativeAll Tier 1 fields use the UI library's own components
Primitives-firstUses UI primitive library components without styling
ReferencePure semantic HTML canonical reference
HybridMix of native components and semantic HTML fallbacks
CompatibilityAll fields use semantic HTML, named for ecosystem compatibility

Classification Table

AdapterClassNative FieldsProduction Ready
fluentNative13/13Yes
muiNative13/13Yes
headlessReference13/13 (semantic HTML)Yes
antdNative13/13Yes
mantineNative13/13Yes
chakraHybrid7/13Yes
base-webHybrid3/13Conditional
atlaskitCompatibility0/13Conditional
herouiCompatibility0/13Conditional
radixPrimitives-first7/13Yes
react-ariaPrimitives-first10/13Yes

Provider Wrapper Requirements

AdapterWrapper RequiredProvider
fluentNo--
muiNo--
headlessNo--
antdNo--
chakraYes<ChakraProvider value={defaultSystem}>
mantineYes<MantineProvider> + matchMedia/ResizeObserver mocks
atlaskitNo--
base-webNo--
herouiNo--
radixNo--
react-ariaNo--

Contract Test Requirements

Every adapter should include contract tests:

typescript
import { runAdapterContractTests } from "@formosaic/core/testing";
import { createXxxFieldRegistry } from "../registry";

runAdapterContractTests(createXxxFieldRegistry, {
  suiteName: "xxx",
});

The contract tests verify:

  1. Registry coverage -- every expected type key has a valid React element
  2. Minimal rendering -- each field renders without errors
  3. Read-only rendering -- each field renders in read-only mode

Released under the MIT License.