import { AppProvider, useAppContext } from "@godxjp/ui/app"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@godxjp/ui/data-display"; import { Label } from "@godxjp/ui/data-entry"; import { Text } from "@godxjp/ui/general"; import { Flex, PageContainer } from "@godxjp/ui/layout"; import { AppSettingPicker } from "@godxjp/ui/navigation"; /** * AppProvider · root locale/timezone/date-time context. * Mount ONCE at app root; every AppSettingPicker + formatDate reads from it automatically. * AppSettingPicker rendered here has NO value/onValueChange · it reads/writes AppProvider * context for the setting named by `kind`. Composed only from real @godxjp/ui components. */ export default function Demo() { return ( 概要 AppProvider はアプリのルートに一度だけマウントする。defaultLocale / defaultTimezone / defaultDateFormat / defaultTimeFormat を渡すと、ツリー内のすべての AppSettingPicker と formatDate がそのコンテキストを共有する。persist=false はストーリーやテストで localStorage を使わない場合に指定。 このデモ全体が AppProvider でラップされており、以下の各 AppSettingPicker は value / onValueChange なしでコンテキストを読み書きする。 kind=locale · 言語選択 AppProvider の locale を自動で読み書きする。選択すると他の AppSettingPicker のラベル言語も切り替わる。 kind=timezone · タイムゾーン選択 AppProvider の timezoneOptions を省略するとフル IANA リスト(約 600 件)を表示。timezoneOptions を渡すと絞り込める。 kind=dateFormat · 日付フォーマット選択 iso(yyyy-MM-dd)/ dmy(dd/MM/yyyy)/ mdy(MM/dd/yyyy)の 3 種から選択。dateFormat コンテキストを読み書きし、以後の formatDate 呼び出しに即時反映される。 kind=timeFormat · 時刻フォーマット選択 24h / 12h を選択。timeFormat コンテキストを読み書きする。ja デフォルトは 24h。formatDate の time / datetime 出力に反映される。 設定パネル · 4 つの設定をまとめて配置 ユーザー設定ページの典型パターン。AppProvider の中に kind 違いの AppSettingPicker を並べると、それぞれがコンテキストを共有して連動する。 テーマ軸 · theme / brand / density / fontSize 見た目の状態も AppProvider が一元管理する。各 picker は HTML の data 属性と コンテキストを同時に更新し、個別コンポーネントへの CSS 上書きを不要にする。 {(["theme", "brand", "density", "fontSize"] as const).map((kind) => ( ))} ); } function ProviderState() { const state = useAppContext(); return ( 現在の provider state picker の変更が全 consumer に共有されることを目視確認するための状態表示。 locale={state.locale} · timezone={state.timezone} · date={state.dateFormat} · time= {state.timeFormat} · theme={state.theme} · brand={state.brand ?? "custom"} · density= {state.density} · fontSize={state.fontSize} · scaling={state.scaling ?? "density default"} ); }