@incld/react
v0.2.1
Published
Shared React provider, appearance, and async primitives for incld components
Readme
@incld/react
Shared React provider, async behavior, accessible primitives, theming, labels, and error helpers for every incld feature package.
Install and configure
npm install @incld/client @incld/reactimport {IncldProvider} from '@incld/react';
import '@incld/react/styles.css';
export function Providers({children}: {children: React.ReactNode}) {
return (
<IncldProvider
baseUrl="/api/incld"
refreshInterval={5_000}
appearance={{
colorScheme: 'system',
accentColor: 'emerald',
radius: 'large',
density: 'comfortable',
variables: {fontFamily: 'Inter, sans-serif'},
}}
labels={{loading: 'Please wait', retry: 'Try again'}}
onError={error => reportError(error.code, error.requestId)}
>
{children}
</IncldProvider>
);
}The provider uses IncldBrowser, never a project secret. Mount a framework proxy under /api/incld/v1/*; the browser client appends /v1 to the provider base URL.
IncldProvider props
| Prop | Type | Default / behavior |
| --- | --- | --- |
| children | ReactNode | Required |
| client | IncldBrowser | Optional preconstructed client |
| baseUrl | string | /api/incld; ignored when client is supplied |
| appearance | IncldAppearance | System scheme, indigo, medium radius, comfortable density |
| labels | Record<string, string> | {}; shared localization overrides |
| refreshInterval | number \| false | 5000; mounted query hooks refresh while the document is visible. Positive values below 1000 are clamped; false disables automatic refresh. |
| onError | (error: IncldError) => void | Called by feature mutation hooks |
| className | string | Added to .incld-root |
| style | CSSProperties | Merged after mapped theme variables |
The default five-second refresh makes mounted lists, details, histories, progress, and gates converge on server state without application wiring. Refreshes pause while the document is hidden and run immediately when it becomes visible again. Only hooks mounted in the current application view make requests. Use refreshInterval={false} for manual-only behavior or call useIncld().refresh() after an application event.
appearance accepts colorScheme: 'light' | 'dark' | 'system', accentColor: 'indigo' | 'blue' | 'emerald' | 'amber' | 'rose', radius: 'small' | 'medium' | 'large', and density: 'compact' | 'comfortable'.
Theme variable keys are accent, accentHover, accentContrast, accentInk, accentSoft, background, surface, surfaceHover, border, text, muted, danger, dangerSoft, dangerBorder, success, successSoft, successBorder, warning, warningSoft, warningBorder, radius, spacing, shadow, fontFamily, fontSize, lineHeight, and focusRing. They map to --incld-* properties on the provider root.
Hooks
useIncld()returnsclient, resolvedappearance,labels,version, resolvedrefreshInterval,refresh(), andreportError(error). It throws outside a provider.useIncldLabel(key, fallback)returns a provider label or the fallback.useAsyncResource(loader, dependencies)is an abort-aware loader returning{data, error, status, refresh}. Status isidle | loading | success | error.
The provider interval and successful feature mutations call provider refresh(), causing mounted query hooks to refetch. In-flight loaders are aborted when a newer refresh begins.
Async component contract
List/detail components use:
interface AsyncViewProps {
loading?: ReactNode;
empty?: ReactNode;
error?: (error: IncldError, retry: () => void) => ReactNode;
}Omitted renderers use the accessible defaults below.
Primitives
| Export | Props / behavior |
| --- | --- |
| IncldButton | Native button props plus busy?; disables and sets aria-busy |
| IncldDialog | open, onOpenChange, title, children, description?, className?, backdropClassName?, closeLabel?; focus trap, Escape/backdrop close, focus restoration |
| IncldSpinner | label?, className?; role=status |
| IncldEmptyState | title, description?, className? |
| IncldErrorState | error, retry, className?; role=alert |
| IncldFieldError | error?, fields: string | string[], id?, className? |
| errorMessagesFor | (error, ...fields) returns deduplicated field messages |
Import each feature package's stylesheet once in addition to the shared stylesheet. Do not nest providers unless you intentionally need a separate browser client and refresh boundary.
