first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,96 @@
# DetectorChainContext
## Purpose
`DetectorChainContext` is the React context that carries the configured
locale-detector chain (plus any SSR-authoritative `initialLocale`) to
descendants of `<DetectorChainProvider>`. It exists as a separate
context from `TranslationContext` because the foundation
`<TranslationProvider>` config schema does not yet expose a
`detectors` field — splitting the surfaces lets the detector chain
consumer (`useLocaleDetection`) read both contexts independently
without forcing the foundation to know about detectors.
The default value is `null` so `useLocaleDetection` can throw a clear
"used without `<DetectorChainProvider>`" error rather than silently
no-op.
## Features
- `null` default value (lets the hook detect missing Provider)
- `displayName: "SuaveplanDetectorChainContext"` for React DevTools
## Usage: Basic Example
```tsx
import { DetectorChainContext } from "@suaveplan/react-i18n/hooks/use-locale-detection/detector-chain-context";
import { useContext } from "react";
function CustomChainConsumer() {
const config = useContext(DetectorChainContext);
if (!config) throw new Error("missing DetectorChainProvider");
return <span>{config.detectors.length} detectors registered</span>;
}
```
## Usage: Advanced Example
```tsx
import { DetectorChainContext } from "@suaveplan/react-i18n/hooks/use-locale-detection/detector-chain-context";
import { defaultDetectorChain } from "@suaveplan/react-i18n/detector/default-chain/default-chain";
// Bypass `<DetectorChainProvider>` for advanced cases (typically tests
// that need to inject a synthetic chain config without the provider's
// memoisation semantics).
function StaticChainScope(props: { children: ReactNode }) {
return (
<DetectorChainContext.Provider
value={{
detectors: defaultDetectorChain({ fallback: "en-GB" }),
}}
>
{props.children}
</DetectorChainContext.Provider>
);
}
```
## API Reference
### `DetectorChainContext: Context<DetectorChainConfig | null>`
Standard React context; default value `null`. The associated config
shape is `DetectorChainConfig` from
`./use-locale-detection.types.ts`:
```ts
interface DetectorChainConfig {
readonly detectors: ReadonlyArray<LocaleDetector>;
readonly buildContext?: () => DetectorContext;
readonly initialLocale?: string;
readonly initialSource?: string;
}
```
## Implementation Notes
- The context value is intentionally a plain config object (not a
store) so React DevTools can introspect the registered detectors
by name without needing the chain runner's internals. The
configured detector list is therefore surface-visible via the
React DevTools Components panel which makes diagnosing chain
ordering issues during development a quick one-step inspection.
- A `null` default plus an explicit hook-level error message is
preferred over a constructed default (e.g. an empty chain) because
the empty default would silently surface as "no detection ran"
when the real failure is "Provider not mounted". Returning the
empty array would also make tests pass that should fail (a
consumer forgetting the Provider would still see an unresolved
chain), so the `null` discriminator preserves a fail-loud
contract during development.
- The `displayName` set on the context surfaces in React DevTools
as `"SuaveplanDetectorChainContext"` rather than the autogenerated
`Context.Provider`/`Context.Consumer` placeholder. This makes
multi-context trees easier to navigate and aligns with the
display-name convention used by the foundation
`TranslationContext`.