75 lines
2.0 KiB
Plaintext
75 lines
2.0 KiB
Plaintext
|
|
---
|
||
|
|
title: Define and provide preferences
|
||
|
|
description: Declare the application preference shape and mount the provider with an SSR-safe snapshot.
|
||
|
|
order: 10
|
||
|
|
toc:
|
||
|
|
- id: declare-preferences
|
||
|
|
title: Declare preferences
|
||
|
|
- id: define-defaults
|
||
|
|
title: Define defaults
|
||
|
|
- id: mount-the-provider
|
||
|
|
title: Mount the provider
|
||
|
|
---
|
||
|
|
|
||
|
|
## Declare preferences {#declare-preferences}
|
||
|
|
|
||
|
|
Use module augmentation in an application-owned TypeScript module:
|
||
|
|
|
||
|
|
```ts
|
||
|
|
import "@workspace/preferences"
|
||
|
|
|
||
|
|
declare module "@workspace/preferences" {
|
||
|
|
interface PreferencesCustom {
|
||
|
|
"navigation-density": "comfortable" | "compact"
|
||
|
|
"theme-mode": "light" | "dark" | "system"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
The declaration updates `Preferences`, `PreferenceKey`, `PreferenceValue`, `PreferenceUpdate`, and both preference hooks.
|
||
|
|
|
||
|
|
## Define defaults {#define-defaults}
|
||
|
|
|
||
|
|
Definitions keep parsing, serialization, defaults, and runtime validation together:
|
||
|
|
|
||
|
|
```ts
|
||
|
|
const definitions = {
|
||
|
|
"navigation-density": {
|
||
|
|
cookie: "navigation-density",
|
||
|
|
defaultValue: "comfortable",
|
||
|
|
is: (value) => value === "comfortable" || value === "compact",
|
||
|
|
parse: (value) => (value === "compact" ? "compact" : "comfortable"),
|
||
|
|
serialize: (value) => value,
|
||
|
|
},
|
||
|
|
"theme-mode": {
|
||
|
|
cookie: "theme-mode",
|
||
|
|
defaultValue: "system",
|
||
|
|
is: (value) => value === "light" || value === "dark" || value === "system",
|
||
|
|
parse: (value) =>
|
||
|
|
value === "light" || value === "dark" ? value : "system",
|
||
|
|
serialize: (value) => value,
|
||
|
|
},
|
||
|
|
} satisfies PreferenceDefinitions<Preferences>
|
||
|
|
|
||
|
|
const defaultPreferences = createDefaultPreferences(definitions)
|
||
|
|
```
|
||
|
|
|
||
|
|
## Mount the provider {#mount-the-provider}
|
||
|
|
|
||
|
|
Pass the complete server-derived snapshot to the provider:
|
||
|
|
|
||
|
|
```tsx
|
||
|
|
<PreferencesProvider
|
||
|
|
initialPreferences={preferences}
|
||
|
|
onPreferenceChange={(update) => savePreference(update)}
|
||
|
|
>
|
||
|
|
<App />
|
||
|
|
</PreferencesProvider>
|
||
|
|
```
|
||
|
|
|
||
|
|
Read one preference with an API matching `useState`:
|
||
|
|
|
||
|
|
```tsx
|
||
|
|
const [themeMode, setThemeMode] = usePreference("theme-mode")
|
||
|
|
```
|