@labb/react-dx-containers
v25.18.1
Published
Headless Pega containers for React. Translate Pega PContainer state into a standardized design-system contract, so each app only supplies its visual components.
Maintainers
Readme
@labb/react-dx-containers
Headless Pega containers for React.
Each container translates a Pega PContainer into a standardized
design-system contract and renders the visual component an application
supplies. All Pega knowledge (field metadata, value coercion, formatting) lives
here once; an app only provides its presentational components.
How it works
There are two seams:
| Seam | Answers | Owner |
| --- | --- | --- |
| Container mapping (@labb/react-adapter) | Pega component name → container behavior | consumer (imperative, last-write-wins) |
| Design-system slot table (DxDesignSystemProvider) | contract → visual component | consumer (typed React context) |
The value you pass to DxDesignSystemProvider is the DxDesignSystem
interface, so TypeScript forces you to implement every slot — a missing
component is a compile error.
Usage
Register the standard containers, overriding selectively where you need custom behavior:
// pega/ContainerMapping.ts
import { DxReactAdapter } from '@labb/react-adapter';
import { registerDefaultContainers } from '@labb/react-dx-containers';
import * as React from 'react';
registerDefaultContainers(DxReactAdapter);
// optional: selective override
DxReactAdapter.registerMapping(
'TextInput',
React.lazy(() => import('./containers/MyTextInput'))
);Provide your design system once at the root:
import { DxDesignSystemProvider } from '@labb/react-dx-containers';
import { MyTextField } from './design-system/MyTextField';
<DxDesignSystemProvider value={{ TextField: MyTextField }}>
<App />
</DxDesignSystemProvider>;Implement a slot against its contract:
import { DxTextFieldProps } from '@labb/react-dx-containers';
export function MyTextField(props: DxTextFieldProps) {
if (props.readOnly) {
return (
<>
<dt>{props.label}</dt>
<dd>{props.displayValue || '--'}</dd>
</>
);
}
return (
<label htmlFor={props.id}>
{props.label}
<input
id={props.id}
type={props.type}
inputMode={props.inputMode}
step={props.step}
required={props.required}
value={props.value ?? ''}
onChange={(e) => props.onChange(e.target.value)}
onBlur={(e) => props.onBlur(e.target.value)}
/>
{props.error}
</label>
);
}