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

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>;

Powered by TurnKey Linux.