/** App shell prop types — @see docs/COMPONENTS.md#app */
import type { Locale } from "date-fns";
import type { DayPickerProps } from "react-day-picker";
import type { AppLocale, AppRequestHeaders, AppTimeFormat, AppTimezone, AppTimezoneDefault, AppDateFormat } from "../../app/types.js";
import type { AppPreset } from "../../app/preset.js";
import type { AppBrand, AppDensity, AppFontSize, AppTheme } from "../../app/theme-axes.js";
import type { AppPreferenceAxis } from "../../app/storage.js";
import type { AppSettingPickerAppearanceProp, AppSettingCycleAppearanceProp, ChildrenProp, ClassNameProp, DisabledProp, IdProp, NameProp, OnValueChangeProp, ValueProp } from "../vocabulary/index.js";
/**
* @see ThemeScope
*
* A marker, not a configuration carrier: the theme is read from the DOM at this element, so there
* is no `primary`/`tenant`/`theme` prop to get wrong. Everything a `
` accepts is forwarded,
* which is how `data-tenant`, `className="dark"` and `style={tenantTheme(hex).vars}` are applied.
*/
export type ThemeScopeProp = {
children: ChildrenProp;
className?: ClassNameProp;
id?: IdProp;
};
/** @see AppProvider */
export type AppProviderProp = {
children: ChildrenProp;
/**
* Initial locale when nothing is in storage. Default: `` when it names a registered
* locale, then the preset's `defaultLocale`, then `en` (v32; was `vi`).
*/
defaultLocale?: AppLocale;
/**
* Product defaults the host opts into (`godxPreset` from `@godxjp/ui/themes/godx`). Fills only
* what the props leave unset; its `name` is written to ``. Omit for neutral.
*/
preset?: AppPreset;
/** Fallback when a translation key is missing. Default: `en`. */
fallbackLocale?: AppLocale;
/** Initial timezone: IANA id, `browser`, or `system`. Default: `browser`. */
defaultTimezone?: AppTimezoneDefault;
/** Backend/system timezone when `defaultTimezone` is `system`. */
systemTimezone?: AppTimezone;
/** Initial clock format. `"locale"` derives from `defaultLocale`. */
defaultTimeFormat?: AppTimeFormat | "locale";
/** Initial date display format. `"locale"` derives from `defaultLocale`. */
defaultDateFormat?: AppDateFormat | "locale";
/**
* IANA ids offered by the timezone-picker recipe (`useAppContext().timezoneOptions`). Omit for
* the full IANA list; set to restrict (e.g.
*/
timezoneOptions?: readonly AppTimezone[];
/**
* The languages the app stores USER CONTENT in (a product name in `ja`/`en`/`vi`), in order —
* source language first. Not the UI locale and not the registered UI catalogs: a Japanese UI
* can edit content in ja · en · vi, and content may be stored in a language the UI has no
* catalog for. Every `TranslatableInput` / `TranslatableTextarea` without its own `locales`
* takes its tabs from here and selects the first one. Omit to keep the per-field default
* (`getRegisteredLocales()`, first tab = the UI locale). App configuration, never persisted.
*/
contentLocales?: readonly string[];
/** localStorage key. Default: `godxjp.app`. */
storageKey?: string;
/**
* Which viewer preferences survive a reload. `true` (default) every axis, `false` none, or a
* LIST of axes — `["theme", "density", "fontSize"]`.
*
* The list exists because the axes do not share an owner. `theme` / `brand` / `density` /
* `fontSize` / `scaling` are the VIEWER's and belong in this browser. `locale` / `timezone` /
* `timeFormat` / `dateFormat` are frequently the SERVER's, resolved per request from a cookie,
* an account row or a header — and a stored copy then WINS over the value the server just sent,
* because storage is read after the props. Faced with one all-or-nothing flag, that consumer
* sets `persist={false}` and loses the viewer's theme along with it; naming the axes keeps both.
*/
persist?: boolean | readonly AppPreferenceAxis[];
/**
* Initial theme choice. `"light"` / `"dark"` are written straight to ``;
* `"system"` defers to `prefers-color-scheme` and is re-resolved whenever the OS changes.
* Default: `"light"`.
*/
theme?: AppTheme;
/**
* Initial brand palette preset — written to ``. OPT-IN: omit
* (or `null`) to keep the brand `--primary` your own `theme.css` defines.
*/
brand?: AppBrand | null;
/** Initial density — written to ``. Default: `"default"`. */
density?: AppDensity;
/** Initial base type size — written to ``. Default: `"default"`. */
fontSize?: AppFontSize;
/**
* Continuous global size multiplier — sets inline `--scaling` on ``. Every size token
* (spacing, control/table/checkbox/switch heights, radius) rescales in proportion (Radix-style).
*/
scaling?: number | null;
/**
* Emit a native `name` on every control a `FormField` wraps, taken from the field's key (`field`
* → `name` → `id`). `data-field` is inert metadata and is always emitted; `name` is NOT — it
* changes what a native `