You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
86 lines
3.2 KiB
86 lines
3.2 KiB
import type { Currency } from '$libs/currency';
|
|
import type { Locale } from '$libs/locale';
|
|
import type { Timezone } from '$libs/timezone';
|
|
|
|
import { currencyDimension } from './dimensions/currency.ts';
|
|
import { densityDimension } from './dimensions/density.ts';
|
|
import { directionDimension } from './dimensions/direction.ts';
|
|
import { languageDimension } from './dimensions/language.ts';
|
|
import { localeDimension } from './dimensions/locale.ts';
|
|
import { motionDimension } from './dimensions/motion.ts';
|
|
import { themeDimension } from './dimensions/theme.ts';
|
|
import { timezoneDimension } from './dimensions/timezone.ts';
|
|
import { unitSystemDimension } from './dimensions/unit-system.ts';
|
|
|
|
/**
|
|
* Catalog input for `standardPrefsDimensions`. Apps declare which
|
|
* languages, locales and currencies they support; the preset wires the
|
|
* canonical built-ins around them.
|
|
*/
|
|
export interface StandardPrefsCatalog {
|
|
readonly languages: readonly Locale[];
|
|
readonly locales: readonly Locale[];
|
|
readonly currencies: readonly Currency[];
|
|
/** Optional IANA zone allowlist; omit for "any zone Intl can canonicalize". */
|
|
readonly timezones?: readonly Timezone[];
|
|
/**
|
|
* Optional per-dimension defaults. When omitted each dimension picks
|
|
* its own — usually the first entry in its catalog.
|
|
*/
|
|
readonly defaults?: {
|
|
readonly language?: Locale;
|
|
readonly locale?: Locale;
|
|
readonly currency?: Currency;
|
|
readonly timezone?: Timezone;
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Compose the canonical built-in dimensions around the application's
|
|
* catalogs. Returns the schema fragment so apps can spread it into
|
|
* their full schema:
|
|
*
|
|
* ```ts
|
|
* const schema = {
|
|
* ...standardPrefsDimensions({ languages, locales, currencies }),
|
|
* // App-specific dimensions
|
|
* sidebarCollapsed: booleanDimension({ default: false }),
|
|
* notificationLevel: enumDimension(['all','mentions','none'] as const, { default: 'mentions' })
|
|
* };
|
|
*
|
|
* createActiveApp({ prefs: { schema } });
|
|
* ```
|
|
*
|
|
* Apps that don't want a particular built-in (say, a single-currency
|
|
* app skipping `currency`) drop the entry after spreading or compose a
|
|
* subset by hand instead of using this preset.
|
|
*/
|
|
export function standardPrefsDimensions(catalog: StandardPrefsCatalog) {
|
|
const defaults = catalog.defaults ?? {};
|
|
return {
|
|
language: languageDimension({ catalog: catalog.languages, default: defaults.language }),
|
|
locale: localeDimension({ catalog: catalog.locales, default: defaults.locale }),
|
|
currency: currencyDimension({ catalog: catalog.currencies, default: defaults.currency }),
|
|
timezone: timezoneDimension({ catalog: catalog.timezones, default: defaults.timezone }),
|
|
unitSystem: unitSystemDimension(),
|
|
theme: themeDimension(),
|
|
density: densityDimension(),
|
|
motion: motionDimension(),
|
|
direction: directionDimension()
|
|
} as const;
|
|
}
|
|
|
|
/**
|
|
* Neutral baseline used by `createActiveApp` when the caller omits
|
|
* `options.prefs`. Keeps the core surface populated even for apps that
|
|
* don't think about preferences. Apps that DO care override
|
|
* `options.prefs.schema`.
|
|
*/
|
|
export const NEUTRAL_PREFS_SCHEMA = standardPrefsDimensions({
|
|
languages: ['en'],
|
|
locales: ['en-US'],
|
|
currencies: ['USD']
|
|
});
|
|
|
|
export type StandardPrefsSchema = ReturnType<typeof standardPrefsDimensions>;
|