@godxjp/ui 2.1.0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/BRAND.md +39 -29
  2. package/CHANGELOG.md +554 -10
  3. package/README.md +143 -168
  4. package/config/eslint.js +54 -0
  5. package/config/prettier.cjs +20 -0
  6. package/config/tsconfig.base.json +22 -0
  7. package/config/vitest.base.ts +26 -0
  8. package/dist/MiniMonth-YAmPGEpC.d.ts +143 -0
  9. package/dist/Table.types-BbsxoIYE.d.ts +352 -0
  10. package/dist/color-DO0qqUAb.d.ts +38 -0
  11. package/dist/components/composites.d.ts +963 -0
  12. package/dist/components/composites.js +7340 -0
  13. package/dist/components/composites.js.map +1 -0
  14. package/dist/components/primitives.d.ts +2633 -163
  15. package/dist/components/primitives.js +7264 -165
  16. package/dist/components/primitives.js.map +1 -1
  17. package/dist/components/shell.d.ts +82 -12
  18. package/dist/components/shell.js +168 -162
  19. package/dist/components/shell.js.map +1 -1
  20. package/dist/hooks.d.ts +83 -8
  21. package/dist/hooks.js +497 -83
  22. package/dist/hooks.js.map +1 -1
  23. package/dist/i18n.d.ts +55 -3
  24. package/dist/i18n.js +456 -5
  25. package/dist/i18n.js.map +1 -1
  26. package/dist/index.d.ts +24 -5
  27. package/dist/index.js +12522 -267
  28. package/dist/index.js.map +1 -1
  29. package/dist/padding-DY0JV5Ja.d.ts +16 -0
  30. package/dist/preferences.d.ts +132 -0
  31. package/dist/preferences.js +262 -0
  32. package/dist/preferences.js.map +1 -0
  33. package/dist/props.d.ts +86 -0
  34. package/dist/props.js +16 -0
  35. package/dist/props.js.map +1 -0
  36. package/dist/size-CQwNvOWd.d.ts +19 -0
  37. package/dist/{data.d.ts → types-LTj-2bl-.d.ts} +7 -12
  38. package/dist/useTableViews-D5NIAJ7h.d.ts +154 -0
  39. package/package.json +92 -34
  40. package/src/tokens/tailwind.css +158 -0
  41. package/dist/components/screens.d.ts +0 -51
  42. package/dist/components/screens.js +0 -806
  43. package/dist/components/screens.js.map +0 -1
  44. package/dist/data.js +0 -93
  45. package/dist/data.js.map +0 -1
  46. package/src/tokens/tokens.css +0 -765
package/dist/hooks.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/i18n/index.ts","../src/data/products.ts","../src/hooks/useTweaks.ts"],"names":[],"mappings":"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","file":"hooks.js","sourcesContent":["// GoDX Forge i18n bootstrap.\n//\n// Locale resolution order:\n// 1. localStorage[\"forge.locale\"] (user override via Tweaks panel)\n// 2. navigator.language prefix (ja-JP → ja, en-US → en, vi-VN → vi)\n// 3. JA fallback (design's primary locale)\n//\n// Supported locales follow the design prototype (chats + ui-kit.jsx): ja / en / vi.\nimport i18next from \"i18next\";\nimport LanguageDetector from \"i18next-browser-languagedetector\";\nimport { initReactI18next } from \"react-i18next\";\n\nimport ja from \"./locales/ja\";\nimport en from \"./locales/en\";\nimport vi from \"./locales/vi\";\n\nexport const SUPPORTED_LOCALES = [\"ja\", \"en\", \"vi\"] as const;\nexport type ForgeLocale = (typeof SUPPORTED_LOCALES)[number];\n\nexport const FORGE_LOCALE_STORAGE_KEY = \"forge.locale\";\n\nexport function initI18n(): typeof i18next {\n void i18next\n .use(LanguageDetector)\n .use(initReactI18next)\n .init({\n resources: {\n ja: { translation: ja },\n en: { translation: en },\n vi: { translation: vi },\n },\n fallbackLng: \"ja\",\n supportedLngs: SUPPORTED_LOCALES,\n load: \"languageOnly\",\n interpolation: { escapeValue: false },\n detection: {\n order: [\"localStorage\", \"navigator\"],\n lookupLocalStorage: FORGE_LOCALE_STORAGE_KEY,\n caches: [\"localStorage\"],\n },\n });\n return i18next;\n}\n\nexport default i18next;\n","// Product / project registry — mock data layer.\n//\n// Mirrors the design prototype's `PRODUCTS` array (shell.jsx). Today\n// this is a static fixture so the UI shell renders end-to-end; a\n// follow-up phase will swap it for `/api/v1/orgs/...` calls against\n// forge-service + identity-service.\n//\n// Vocabulary:\n// Product = Org (GitHub-shaped tenant). Owns projects, members,\n// domains, design tokens (per the OKLCH tenant override\n// in tokens-ext.css).\n// Project = Repo. Has a stack (e.g. \"Vue 3 · Vite\"), kind\n// (service / web / desktop / mobile / library / infra /\n// workstation), branch, lastCommit, openIssues, prs.\n//\n// Tenants must match a `[data-tenant=\"<id>\"]` block in tokens-ext.css.\nexport type ProjectKind =\n | \"service\"\n | \"web\"\n | \"desktop\"\n | \"workstation\"\n | \"mobile\"\n | \"library\"\n | \"infra\";\n\nexport type ProjectStatus = \"active\" | \"review\" | \"planning\" | \"archived\";\n\nexport type ForgeProject = {\n id: string;\n name: string;\n stack: string;\n kind: ProjectKind;\n devs: number;\n status: ProjectStatus;\n branch: string;\n lastCommit: string;\n openIssues: number;\n prs: number;\n sandbox: boolean;\n};\n\nexport type ForgeProduct = {\n id: string;\n name: string;\n tenant: \"godx\" | \"kintai\" | \"tempo\" | \"betoya\" | \"restaurant\";\n role: string;\n desc: string;\n /** Brand color in OKLCH — used as the sidebar logo mark + accent. */\n color: string;\n owner: string;\n devs: number;\n projects: ForgeProject[];\n};\n\nexport const PRODUCTS: ForgeProduct[] = [\n {\n id: \"restaurant\",\n name: \"godx-restaurant\",\n tenant: \"restaurant\",\n role: \"レストラン管理\",\n desc: \"店舗向け統合管理プラットフォーム\",\n color: \"oklch(58% 0.18 25)\",\n owner: \"Satoshi F\",\n devs: 6,\n projects: [\n { id: \"api\", name: \"restaurant-api\", stack: \"NestJS · PostgreSQL\", kind: \"service\", devs: 3, status: \"active\", branch: \"main\", lastCommit: \"12分前\", openIssues: 8, prs: 2, sandbox: true },\n { id: \"admin\", name: \"restaurant-admin\", stack: \"Next.js 14 · React\", kind: \"web\", devs: 2, status: \"active\", branch: \"main\", lastCommit: \"1時間前\", openIssues: 5, prs: 1, sandbox: true },\n { id: \"pos\", name: \"restaurant-pos\", stack: \"Tauri · Vue 3\", kind: \"desktop\", devs: 1, status: \"active\", branch: \"feature/print\", lastCommit: \"30分前\", openIssues: 3, prs: 1, sandbox: true },\n { id: \"kds\", name: \"restaurant-kds\", stack: \"React · Electron\", kind: \"workstation\", devs: 1, status: \"review\", branch: \"main\", lastCommit: \"昨日\", openIssues: 2, prs: 1, sandbox: true },\n { id: \"kintai\", name: \"restaurant-kintai\", stack: \"Vue 3 · Laravel\", kind: \"service\", devs: 2, status: \"active\", branch: \"main\", lastCommit: \"5分前\", openIssues: 4, prs: 0, sandbox: true },\n { id: \"mobile\", name: \"restaurant-mobile\", stack: \"React Native\", kind: \"mobile\", devs: 1, status: \"planning\", branch: \"develop\", lastCommit: \"3日前\", openIssues: 1, prs: 0, sandbox: false },\n ],\n },\n {\n id: \"godx\",\n name: \"godx-admin\",\n tenant: \"godx\",\n role: \"Platform admin\",\n desc: \"GoDX Forge developer workspace\",\n color: \"oklch(60% 0.137 163)\",\n owner: \"Satoshi F\",\n devs: 4,\n projects: [\n { id: \"frontend\", name: \"godx-admin-frontend\", stack: \"React · Vite\", kind: \"web\", devs: 2, status: \"active\", branch: \"master\", lastCommit: \"2時間前\", openIssues: 6, prs: 2, sandbox: true },\n { id: \"api\", name: \"godx-admin-api\", stack: \"Go · Gin\", kind: \"service\", devs: 1, status: \"active\", branch: \"master\", lastCommit: \"4時間前\", openIssues: 3, prs: 1, sandbox: true },\n { id: \"ui\", name: \"@godxjp/ui\", stack: \"TypeScript · React\", kind: \"library\", devs: 2, status: \"active\", branch: \"master\", lastCommit: \"1時間前\", openIssues: 2, prs: 0, sandbox: false },\n ],\n },\n {\n id: \"kintai\",\n name: \"dxs-kintai\",\n tenant: \"kintai\",\n role: \"HR / Attendance\",\n desc: \"勤怠管理プラットフォーム\",\n color: \"oklch(56% 0.15 240)\",\n owner: \"Naoki N\",\n devs: 3,\n projects: [\n { id: \"frontend\", name: \"kintai-web\", stack: \"Vue 3 · Vite\", kind: \"web\", devs: 2, status: \"active\", branch: \"main\", lastCommit: \"20分前\", openIssues: 7, prs: 1, sandbox: true },\n { id: \"backend\", name: \"kintai-api\", stack: \"Laravel 11\", kind: \"service\", devs: 1, status: \"active\", branch: \"main\", lastCommit: \"1日前\", openIssues: 4, prs: 0, sandbox: true },\n ],\n },\n {\n id: \"tempo\",\n name: \"dxs-tempo\",\n tenant: \"tempo\",\n role: \"Shop / Inventory\",\n desc: \"店舗・在庫バックエンド\",\n color: \"oklch(48% 0.16 285)\",\n owner: \"Naoki N\",\n devs: 2,\n projects: [\n { id: \"api\", name: \"tempo-api\", stack: \"Go · Echo\", kind: \"service\", devs: 2, status: \"active\", branch: \"main\", lastCommit: \"5時間前\", openIssues: 9, prs: 1, sandbox: true },\n { id: \"ops\", name: \"tempo-ops\", stack: \"Terraform\", kind: \"infra\", devs: 1, status: \"planning\", branch: \"main\", lastCommit: \"1週間前\", openIssues: 1, prs: 0, sandbox: false },\n ],\n },\n {\n id: \"betoya\",\n name: \"betoya\",\n tenant: \"betoya\",\n role: \"Vietnamese restaurant\",\n desc: \"ベト屋 Tenant\",\n color: \"oklch(58% 0.159 150)\",\n owner: \"Anh K\",\n devs: 1,\n projects: [\n { id: \"site\", name: \"betoya-site\", stack: \"Astro\", kind: \"web\", devs: 1, status: \"active\", branch: \"main\", lastCommit: \"昨日\", openIssues: 2, prs: 0, sandbox: false },\n ],\n },\n];\n\nexport const PROJECT_KIND: Record<ProjectKind, { color: string; label: string }> = {\n service: { color: \"oklch(60% 0.137 163)\", label: \"API\" },\n web: { color: \"oklch(56% 0.15 240)\", label: \"Web\" },\n desktop: { color: \"oklch(48% 0.16 285)\", label: \"Desktop\" },\n workstation: { color: \"oklch(50% 0.16 30)\", label: \"Workstation\" },\n mobile: { color: \"oklch(58% 0.18 25)\", label: \"Mobile\" },\n library: { color: \"oklch(50% 0.05 250)\", label: \"Library\" },\n infra: { color: \"oklch(45% 0.05 260)\", label: \"Infra\" },\n};\n\nexport function findProductByTenant(tenant: string): ForgeProduct | undefined {\n return PRODUCTS.find((p) => p.tenant === tenant);\n}\n","// useTweaks — shared client state for the design system's Tweaks panel.\n//\n// Mirrors the design prototype `useTweaks` hook (tweaks-panel.jsx). Each\n// tweak is persisted to localStorage so reloads keep the user's chosen\n// density / theme / tenant / sidebar-collapsed setting. Locale is owned\n// by i18next (see src/i18n/index.ts) but exposed through this hook so\n// the Tweaks UI has a single dispatcher.\nimport { useCallback, useEffect, useState } from \"react\";\nimport i18n, { FORGE_LOCALE_STORAGE_KEY, type ForgeLocale } from \"../i18n\";\nimport { PRODUCTS, type ForgeProduct } from \"../data/products\";\n\nexport type Density = \"compact\" | \"default\" | \"comfortable\";\nexport type Theme = \"light\" | \"dark\";\n\nexport type Tweaks = {\n density: Density;\n theme: Theme;\n tenant: ForgeProduct[\"tenant\"];\n locale: ForgeLocale;\n sidebarCollapsed: boolean;\n};\n\nconst STORAGE_KEY = \"forge.tweaks\";\n\nconst DEFAULTS: Tweaks = {\n density: \"default\",\n theme: \"light\",\n tenant: \"godx\",\n locale: \"ja\",\n sidebarCollapsed: false,\n};\n\nfunction loadInitial(): Tweaks {\n if (typeof window === \"undefined\") return DEFAULTS;\n try {\n const raw = window.localStorage.getItem(STORAGE_KEY);\n const stored = raw ? (JSON.parse(raw) as Partial<Tweaks>) : {};\n const detected = (i18n.language?.slice(0, 2) || \"ja\") as ForgeLocale;\n return {\n ...DEFAULTS,\n ...stored,\n locale: (stored.locale ?? detected) as ForgeLocale,\n };\n } catch {\n return DEFAULTS;\n }\n}\n\nexport function useTweaks() {\n const [tweaks, setTweaks] = useState<Tweaks>(loadInitial);\n\n // Persist every change to localStorage.\n useEffect(() => {\n try {\n window.localStorage.setItem(STORAGE_KEY, JSON.stringify(tweaks));\n } catch {\n /* Storage may be disabled (private mode). Silently degrade. */\n }\n }, [tweaks]);\n\n // Reflect tweaks onto <html> so the design tokens (CSS custom\n // properties scoped to [data-tenant=…], [data-theme=…], [data-density=…])\n // pick up the change without rerunning React.\n useEffect(() => {\n const html = document.documentElement;\n html.dataset.theme = tweaks.theme;\n html.dataset.density = tweaks.density;\n html.dataset.tenant = tweaks.tenant;\n html.lang = tweaks.locale;\n }, [tweaks.theme, tweaks.density, tweaks.tenant, tweaks.locale]);\n\n // Forward locale changes to i18next so the UI re-renders strings.\n useEffect(() => {\n if (i18n.language?.slice(0, 2) !== tweaks.locale) {\n void i18n.changeLanguage(tweaks.locale);\n try {\n window.localStorage.setItem(FORGE_LOCALE_STORAGE_KEY, tweaks.locale);\n } catch {\n /* ignore */\n }\n }\n }, [tweaks.locale]);\n\n const setTweak = useCallback(<K extends keyof Tweaks>(key: K, value: Tweaks[K]) => {\n setTweaks((prev) => ({ ...prev, [key]: value }));\n }, []);\n\n return { tweaks, setTweak, setTweaks } as const;\n}\n\nexport const PRODUCT_OPTIONS = PRODUCTS.map((p) => ({ value: p.tenant, label: p.name }));\n"]}
1
+ {"version":3,"sources":["../src/preferences/holder.ts","../src/i18n/format.ts","../src/i18n/relative.ts","../src/i18n/index.ts","../src/hooks/useTweaks.ts","../src/hooks/useBreakpoint.ts","../src/hooks/useFormatters.ts","../src/hooks/useTablePagination.ts","../src/hooks/useTableSelection.ts","../src/hooks/useTableState.ts","../src/hooks/useTableViews.ts"],"names":["useState","useEffect","useCallback"],"mappings":"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","file":"hooks.js","sourcesContent":["// Module-level GodxConfig holder.\n//\n// Why a module-level holder, not just React context: axios instances\n// are created at module-load time (before React mounts), and axios\n// interceptors need to read config at REQUEST time — which is after\n// the React tree is up. A mutable holder solves both: the React\n// provider writes into it on mount + on every state change; the\n// interceptor reads via `getGodxConfig()` per request.\n//\n// The holder is the single source of truth at runtime. The React\n// state mirrors it for re-renders; outside of React, anyone (axios,\n// fetch wrapper, error reporter, telemetry, etc.) reads through the\n// `getGodxConfig()` getter.\n\nexport interface GodxConfig {\n /** BCP 47 language tag, e.g. \"ja\", \"en-US\". */\n locale: string;\n /** IANA time zone name, e.g. \"Asia/Tokyo\". */\n timezone: string;\n /**\n * Currency default for `formatCurrency()` calls that omit a code.\n * ISO 4217 — e.g. \"JPY\", \"USD\", \"VND\", \"PHP\". Optional; helpers\n * require an explicit currency when this is undefined.\n */\n currency?: string;\n}\n\nconst DEFAULT: GodxConfig = {\n locale: \"ja\",\n timezone: \"Asia/Tokyo\",\n};\n\nlet CURRENT: GodxConfig = { ...DEFAULT };\nconst subscribers = new Set<(c: GodxConfig) => void>();\n\nexport function getGodxConfig(): GodxConfig {\n return CURRENT;\n}\n\nexport function setGodxConfig(next: Partial<GodxConfig>): void {\n const merged: GodxConfig = { ...CURRENT, ...next };\n if (\n merged.locale === CURRENT.locale &&\n merged.timezone === CURRENT.timezone &&\n merged.currency === CURRENT.currency\n ) {\n return;\n }\n CURRENT = merged;\n for (const fn of subscribers) {\n try {\n fn(CURRENT);\n } catch {\n /* subscriber threw — swallow so other subscribers run */\n }\n }\n}\n\nexport function resetGodxConfig(defaults: GodxConfig = DEFAULT): void {\n setGodxConfig(defaults);\n}\n\nexport function subscribeGodxConfig(\n fn: (c: GodxConfig) => void,\n): () => void {\n subscribers.add(fn);\n return () => {\n subscribers.delete(fn);\n };\n}\n","// Locale + timezone-aware formatters.\n//\n// Per ADR 0005 the framework standardises on native `Intl` APIs for\n// formatting and `@internationalized/date` for value types. These\n// helpers accept the value shapes the framework can encounter in the\n// wild (native `Date`, ISO string, or any `@internationalized/date`\n// value) and resolve the locale + timezone from the\n// preferences holder.\n//\n// Non-React surface — callable from anywhere (axios interceptors,\n// React renders, event handlers, tests). The matching React hook is\n// `useFormatters()` in `src/hooks/useFormatters.ts`; it returns the\n// same surface bound to the live provider context.\n\nimport {\n type CalendarDate,\n type CalendarDateTime,\n type Time,\n type ZonedDateTime,\n} from \"@internationalized/date\";\nimport { getGodxConfig } from \"../preferences/holder\";\n\n/** A value any framework primitive accepts as a date / time input. */\nexport type DateLike =\n | Date\n | string\n | number\n | CalendarDate\n | CalendarDateTime\n | ZonedDateTime;\n\n/** A value any framework primitive accepts as a time-only input. */\nexport type TimeLike = Date | string | number | Time | CalendarDateTime | ZonedDateTime;\n\nexport interface FormatOptions {\n /** BCP 47 locale override. Defaults to the preferences holder. */\n locale?: string;\n /** IANA timezone override. Defaults to the preferences holder. */\n timezone?: string;\n}\n\nexport interface FormatDateOptions extends FormatOptions, Intl.DateTimeFormatOptions {}\nexport interface FormatNumberOptions extends FormatOptions, Intl.NumberFormatOptions {}\nexport interface FormatCurrencyOptions extends FormatOptions, Intl.NumberFormatOptions {\n currency: string;\n}\n\nfunction resolveLocale(opts?: FormatOptions): string {\n return opts?.locale ?? getGodxConfig().locale;\n}\n\nfunction resolveTimezone(opts?: FormatOptions): string {\n return opts?.timezone ?? getGodxConfig().timezone;\n}\n\n/** Convert any DateLike value into a native `Date` for `Intl` use. */\nfunction toDate(value: DateLike): Date {\n if (value instanceof Date) return value;\n if (typeof value === \"number\") return new Date(value);\n if (typeof value === \"string\") return new Date(value);\n if (typeof value === \"object\" && value !== null && \"toDate\" in value) {\n const v = value as CalendarDate | CalendarDateTime | ZonedDateTime;\n return v.toDate(getGodxConfig().timezone);\n }\n throw new TypeError(`format helpers: unsupported value ${String(value)}`);\n}\n\n/** Drop format-specific opts before passing to Intl. */\nfunction extractIntlOpts<T extends FormatOptions>(opts: T | undefined): Omit<T, keyof FormatOptions> {\n if (!opts) return {} as Omit<T, keyof FormatOptions>;\n const { locale: _l, timezone: _t, ...rest } = opts;\n return rest as Omit<T, keyof FormatOptions>;\n}\n\n/** Format a date by locale + timezone. Defaults: medium date style. */\nexport function formatDate(value: DateLike, opts?: FormatDateOptions): string {\n const locale = resolveLocale(opts);\n const timezone = resolveTimezone(opts);\n const intlOpts: Intl.DateTimeFormatOptions = {\n dateStyle: \"medium\",\n ...extractIntlOpts(opts),\n timeZone: timezone,\n };\n return new Intl.DateTimeFormat(locale, intlOpts).format(toDate(value));\n}\n\n/** Format a time by locale + timezone. Defaults: short time. */\nexport function formatTime(value: DateLike, opts?: FormatDateOptions): string {\n const locale = resolveLocale(opts);\n const timezone = resolveTimezone(opts);\n const intlOpts: Intl.DateTimeFormatOptions = {\n timeStyle: \"short\",\n ...extractIntlOpts(opts),\n timeZone: timezone,\n };\n return new Intl.DateTimeFormat(locale, intlOpts).format(toDate(value));\n}\n\n/** Format both date + time. Defaults: medium date, short time. */\nexport function formatDateTime(value: DateLike, opts?: FormatDateOptions): string {\n const locale = resolveLocale(opts);\n const timezone = resolveTimezone(opts);\n const intlOpts: Intl.DateTimeFormatOptions = {\n dateStyle: \"medium\",\n timeStyle: \"short\",\n ...extractIntlOpts(opts),\n timeZone: timezone,\n };\n return new Intl.DateTimeFormat(locale, intlOpts).format(toDate(value));\n}\n\n/** Format a number by locale. */\nexport function formatNumber(value: number, opts?: FormatNumberOptions): string {\n const locale = resolveLocale(opts);\n return new Intl.NumberFormat(locale, extractIntlOpts(opts)).format(value);\n}\n\n/** Format a currency amount. ISO 4217 currency code required. */\nexport function formatCurrency(value: number, opts: FormatCurrencyOptions): string {\n const locale = resolveLocale(opts);\n const intlOpts: Intl.NumberFormatOptions = {\n style: \"currency\",\n ...extractIntlOpts(opts),\n };\n return new Intl.NumberFormat(locale, intlOpts).format(value);\n}\n","// Locale-aware relative-time formatter.\n//\n// Wraps `Intl.RelativeTimeFormat` (browser-native, no library cost) with\n// the diff-bucket logic — second / minute / hour / day / week / month /\n// year — so consumers can pass a single date/time value and get\n// \"2時間前\" / \"2 hours ago\" / \"2 giờ trước\" / \"2 oras na nakalipas\" by\n// reading the active locale from the preferences holder.\n\nimport { type DateLike } from \"./format\";\nimport { getGodxConfig } from \"../preferences/holder\";\n\nexport interface RelativeOptions {\n /** BCP 47 locale override. Defaults to the preferences holder. */\n locale?: string;\n /** Reference moment. Defaults to \"now\". Useful for tests. */\n now?: Date | number;\n /** `Intl.RelativeTimeFormat` numeric style. Default `\"auto\"`. */\n numeric?: \"always\" | \"auto\";\n /** `Intl.RelativeTimeFormat` style. Default `\"long\"`. */\n style?: \"long\" | \"short\" | \"narrow\";\n}\n\nconst SECOND = 1000;\nconst MINUTE = 60 * SECOND;\nconst HOUR = 60 * MINUTE;\nconst DAY = 24 * HOUR;\nconst WEEK = 7 * DAY;\nconst MONTH = 30 * DAY;\nconst YEAR = 365 * DAY;\n\nfunction toMs(value: DateLike): number {\n if (value instanceof Date) return value.getTime();\n if (typeof value === \"number\") return value;\n if (typeof value === \"string\") return new Date(value).getTime();\n if (typeof value === \"object\" && value !== null && \"toDate\" in value) {\n return value.toDate(getGodxConfig().timezone).getTime();\n }\n throw new TypeError(`formatRelative: unsupported value ${String(value)}`);\n}\n\n/**\n * Format the distance between `value` and `opts.now` (default: current\n * time) as a locale-aware string.\n *\n * Granularity tops out at \"year\". Anything longer than a year reports\n * \"in N years\" / \"N years ago\".\n */\nexport function formatRelative(value: DateLike, opts: RelativeOptions = {}): string {\n const locale = opts.locale ?? getGodxConfig().locale;\n const nowMs = opts.now instanceof Date ? opts.now.getTime() : (opts.now ?? Date.now());\n const valueMs = toMs(value);\n const diffMs = valueMs - nowMs;\n const abs = Math.abs(diffMs);\n\n let unit: Intl.RelativeTimeFormatUnit;\n let amount: number;\n\n if (abs < MINUTE) {\n unit = \"second\";\n amount = Math.round(diffMs / SECOND);\n } else if (abs < HOUR) {\n unit = \"minute\";\n amount = Math.round(diffMs / MINUTE);\n } else if (abs < DAY) {\n unit = \"hour\";\n amount = Math.round(diffMs / HOUR);\n } else if (abs < WEEK) {\n unit = \"day\";\n amount = Math.round(diffMs / DAY);\n } else if (abs < MONTH) {\n unit = \"week\";\n amount = Math.round(diffMs / WEEK);\n } else if (abs < YEAR) {\n unit = \"month\";\n amount = Math.round(diffMs / MONTH);\n } else {\n unit = \"year\";\n amount = Math.round(diffMs / YEAR);\n }\n\n return new Intl.RelativeTimeFormat(locale, {\n numeric: opts.numeric ?? \"auto\",\n style: opts.style ?? \"long\",\n }).format(amount, unit);\n}\n","// @godxjp/ui — i18n bootstrap.\n//\n// Locale resolution order:\n// 1. localStorage[\"godx.locale\"] (user override via Tweaks panel)\n// 2. navigator.language prefix (ja-JP → ja, en-US → en, vi-VN → vi)\n// 3. JA fallback (design's primary locale)\n//\n// Supported locales: ja / en / vi / fil (required by the umbrella\n// frontend-architecture spec §6).\n// Services may add extra locales via `i18n.addResourceBundle` — never\n// replace the base set.\nimport i18next from \"i18next\";\nimport LanguageDetector from \"i18next-browser-languagedetector\";\nimport { initReactI18next } from \"react-i18next\";\n\nimport ja from \"./locales/ja\";\nimport en from \"./locales/en\";\nimport vi from \"./locales/vi\";\nimport fil from \"./locales/fil\";\n\nexport const SUPPORTED_LOCALES = [\"ja\", \"en\", \"vi\", \"fil\"] as const;\n/** @deprecated Use GodxLocale instead. */\nexport type ForgeLocale = (typeof SUPPORTED_LOCALES)[number];\nexport type GodxLocale = (typeof SUPPORTED_LOCALES)[number];\n\nexport const GODX_LOCALE_STORAGE_KEY = \"godx.locale\";\n/** @deprecated Use GODX_LOCALE_STORAGE_KEY instead. */\nexport const FORGE_LOCALE_STORAGE_KEY = GODX_LOCALE_STORAGE_KEY;\n\nexport function initI18n(): typeof i18next {\n void i18next\n .use(LanguageDetector)\n .use(initReactI18next)\n .init({\n resources: {\n ja: { translation: ja },\n en: { translation: en },\n vi: { translation: vi },\n fil: { translation: fil },\n },\n fallbackLng: \"ja\",\n supportedLngs: SUPPORTED_LOCALES,\n load: \"languageOnly\",\n interpolation: { escapeValue: false },\n detection: {\n order: [\"localStorage\", \"navigator\"],\n lookupLocalStorage: GODX_LOCALE_STORAGE_KEY,\n caches: [\"localStorage\"],\n },\n });\n return i18next;\n}\n\nexport default i18next;\n\nexport {\n formatDate,\n formatTime,\n formatDateTime,\n formatNumber,\n formatCurrency,\n type DateLike,\n type TimeLike,\n type FormatOptions,\n type FormatDateOptions,\n type FormatNumberOptions,\n type FormatCurrencyOptions,\n} from \"./format\";\n\nexport { formatRelative, type RelativeOptions } from \"./relative\";\n","// useTweaks — shared client state for the design system's Tweaks panel.\n//\n// Mirrors the design prototype `useTweaks` hook (tweaks-panel.jsx). Each\n// tweak is persisted to localStorage so reloads keep the user's chosen\n// density / theme / tenant / sidebar-collapsed setting. Locale is owned\n// by i18next (see src/i18n/index.ts) but exposed through this hook so\n// the Tweaks UI has a single dispatcher.\nimport { useCallback, useEffect, useState } from \"react\";\nimport i18n, { GODX_LOCALE_STORAGE_KEY, type GodxLocale } from \"../i18n\";\nimport type { ForgeProduct } from \"../components/shell/types\";\n\nexport type Density = \"compact\" | \"default\" | \"comfortable\";\nexport type Theme = \"light\" | \"dark\";\n\nexport type Tweaks = {\n density: Density;\n theme: Theme;\n tenant: string;\n locale: GodxLocale;\n sidebarCollapsed: boolean;\n};\n\nconst STORAGE_KEY = \"godx.tweaks\";\n\nconst DEFAULTS: Tweaks = {\n density: \"default\",\n theme: \"light\",\n tenant: \"godx\",\n locale: \"ja\",\n sidebarCollapsed: false,\n};\n\nfunction loadInitial(): Tweaks {\n if (typeof window === \"undefined\") return DEFAULTS;\n try {\n const raw = window.localStorage.getItem(STORAGE_KEY);\n const stored = raw ? (JSON.parse(raw) as Partial<Tweaks>) : {};\n const detected = (i18n.language?.slice(0, 2) || \"ja\") as GodxLocale;\n return {\n ...DEFAULTS,\n ...stored,\n locale: (stored.locale ?? detected) as GodxLocale,\n };\n } catch {\n return DEFAULTS;\n }\n}\n\nexport function useTweaks() {\n const [tweaks, setTweaks] = useState<Tweaks>(loadInitial);\n\n // Persist every change to localStorage.\n useEffect(() => {\n try {\n window.localStorage.setItem(STORAGE_KEY, JSON.stringify(tweaks));\n } catch {\n /* Storage may be disabled (private mode). Silently degrade. */\n }\n }, [tweaks]);\n\n // Reflect tweaks onto <html> so the design tokens (CSS custom\n // properties scoped to [data-tenant=…], [data-theme=…], [data-density=…])\n // pick up the change without rerunning React.\n useEffect(() => {\n const html = document.documentElement;\n html.dataset.theme = tweaks.theme;\n html.dataset.density = tweaks.density;\n html.dataset.tenant = tweaks.tenant;\n html.lang = tweaks.locale;\n }, [tweaks.theme, tweaks.density, tweaks.tenant, tweaks.locale]);\n\n // Forward locale changes to i18next so the UI re-renders strings.\n // Guarded by `isInitialized` so consumers that mount this hook\n // before calling `initI18n()` no-op instead of crashing inside\n // i18next's resolver (`toResolveHierarchy is undefined`).\n useEffect(() => {\n if (!i18n.isInitialized) return;\n if (i18n.language?.slice(0, 2) !== tweaks.locale) {\n void i18n.changeLanguage(tweaks.locale);\n try {\n window.localStorage.setItem(GODX_LOCALE_STORAGE_KEY, tweaks.locale);\n } catch {\n /* ignore */\n }\n }\n }, [tweaks.locale]);\n\n const setTweak = useCallback(<K extends keyof Tweaks>(key: K, value: Tweaks[K]) => {\n setTweaks((prev) => ({ ...prev, [key]: value }));\n }, []);\n\n return { tweaks, setTweak, setTweaks } as const;\n}\n\n/** Derive tenant-select options from a consumer-supplied product\n * catalogue. Shell consumers pass their own products — useTweaks\n * doesn't ship with mock data per cardinal rule 28. */\nexport function productOptions(products: ForgeProduct[]): Array<{ value: string; label: string }> {\n return products.map((p) => ({ value: p.tenant, label: p.name }));\n}\n","import { useEffect, useState } from \"react\";\nimport type { Breakpoint } from \"../components/layout/Row\";\n\n/**\n * useBreakpoint — reads the framework's responsive breakpoint\n * tokens (`--breakpoint-{xs,sm,md,lg,xl,xxl}`) from the CSS\n * token system and returns the WIDEST currently-matching\n * breakpoint name.\n *\n * Per cardinal rule 22 the breakpoint values are token-pinned —\n * no hardcoded literals here; the hook reads `:root` via\n * `getComputedStyle`. Falls back to Tailwind v4 defaults if the\n * tokens aren't set yet (e.g. SSR / hydration / Storybook iframe\n * before theme.css loads).\n *\n * Per cardinal rule 23 §B the breakpoint name vocabulary is locked\n * across the framework — the `Breakpoint` type lives in\n * `components/layout/Row.ts` and is imported here so\n * consumers see exactly one definition.\n *\n * @example\n * const bp = useBreakpoint()\n * if (bp === \"xs\" || bp === \"sm\") return <MobileShell />\n * return <DesktopShell />\n *\n * @example\n * // Render only on >= md\n * const bp = useBreakpoint()\n * return matchBreakpoint(bp, \"md\") ? <Aside /> : null\n */\nexport type { Breakpoint };\n\nconst BP_ORDER: Breakpoint[] = [\"xxl\", \"xl\", \"lg\", \"md\", \"sm\", \"xs\"];\nconst BP_ORDER_ASC: Breakpoint[] = [\"xs\", \"sm\", \"md\", \"lg\", \"xl\", \"xxl\"];\n\nconst FALLBACK_WIDTH: Record<Breakpoint, string> = {\n xs: \"0px\",\n sm: \"640px\",\n md: \"768px\",\n lg: \"1024px\",\n xl: \"1280px\",\n xxl: \"1536px\",\n};\n\nfunction widthOf(bp: Breakpoint): string {\n if (typeof window === \"undefined\") return FALLBACK_WIDTH[bp];\n const v = getComputedStyle(document.documentElement)\n .getPropertyValue(`--breakpoint-${bp}`)\n .trim();\n return v || FALLBACK_WIDTH[bp];\n}\n\nfunction currentBreakpoint(): Breakpoint {\n if (typeof window === \"undefined\") return \"xs\";\n for (const bp of BP_ORDER) {\n if (window.matchMedia(`(min-width: ${widthOf(bp)})`).matches) {\n return bp;\n }\n }\n return \"xs\";\n}\n\nexport function useBreakpoint(): Breakpoint {\n const [bp, setBp] = useState<Breakpoint>(() => currentBreakpoint());\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n const mqls = BP_ORDER.map((b) =>\n window.matchMedia(`(min-width: ${widthOf(b)})`),\n );\n const update = () => setBp(currentBreakpoint());\n mqls.forEach((mql) => mql.addEventListener(\"change\", update));\n update();\n return () => {\n mqls.forEach((mql) => mql.removeEventListener(\"change\", update));\n };\n }, []);\n\n return bp;\n}\n\n/**\n * matchBreakpoint — true if `current` is at-or-above the target\n * breakpoint in the mobile-first order.\n *\n * matchBreakpoint(\"lg\", \"md\") → true (lg ≥ md)\n * matchBreakpoint(\"sm\", \"lg\") → false (sm < lg)\n */\nexport function matchBreakpoint(current: Breakpoint, target: Breakpoint): boolean {\n return BP_ORDER_ASC.indexOf(current) >= BP_ORDER_ASC.indexOf(target);\n}\n","// React hook — locale + timezone-bound formatter surface.\n//\n// Reads from `<GodxConfigProvider>` so components re-render when the\n// active locale or timezone changes. Returns a memoised object whose\n// methods always resolve to the current context values.\n//\n// Mirrors the surface of `src/i18n/format.ts` + `src/i18n/relative.ts`\n// — the non-React calls accept explicit `{ locale, timezone }` opts;\n// the hook fills them in from context.\n\nimport { useMemo, useSyncExternalStore } from \"react\";\nimport { getGodxConfig, subscribeGodxConfig } from \"../preferences/holder\";\nimport {\n formatCurrency as fnFormatCurrency,\n formatDate as fnFormatDate,\n formatDateTime as fnFormatDateTime,\n formatNumber as fnFormatNumber,\n formatTime as fnFormatTime,\n type DateLike,\n type FormatCurrencyOptions,\n type FormatDateOptions,\n type FormatNumberOptions,\n} from \"../i18n/format\";\nimport {\n formatRelative as fnFormatRelative,\n type RelativeOptions,\n} from \"../i18n/relative\";\n\nexport interface Formatters {\n /** Active locale (BCP 47). */\n locale: string;\n /** Active IANA timezone. */\n timezone: string;\n formatDate: (value: DateLike, opts?: Omit<FormatDateOptions, \"locale\" | \"timezone\">) => string;\n formatTime: (value: DateLike, opts?: Omit<FormatDateOptions, \"locale\" | \"timezone\">) => string;\n formatDateTime: (value: DateLike, opts?: Omit<FormatDateOptions, \"locale\" | \"timezone\">) => string;\n formatRelative: (value: DateLike, opts?: Omit<RelativeOptions, \"locale\">) => string;\n formatNumber: (value: number, opts?: Omit<FormatNumberOptions, \"locale\">) => string;\n formatCurrency: (value: number, opts: Omit<FormatCurrencyOptions, \"locale\">) => string;\n}\n\nexport function useFormatters(): Formatters {\n // Subscribes to the module-level holder so this hook also works when\n // no `<GodxConfigProvider>` is mounted (e.g. isolated Storybook\n // renders). The holder's initial value matches the provider's\n // initial value — locale/timezone fall through `Intl` defaults.\n const { locale, timezone } = useSyncExternalStore(\n subscribeGodxConfig,\n getGodxConfig,\n getGodxConfig,\n );\n\n return useMemo<Formatters>(\n () => ({\n locale,\n timezone,\n formatDate: (value, opts) => fnFormatDate(value, { ...opts, locale, timezone }),\n formatTime: (value, opts) => fnFormatTime(value, { ...opts, locale, timezone }),\n formatDateTime: (value, opts) =>\n fnFormatDateTime(value, { ...opts, locale, timezone }),\n formatRelative: (value, opts) => fnFormatRelative(value, { ...opts, locale }),\n formatNumber: (value, opts) => fnFormatNumber(value, { ...opts, locale }),\n formatCurrency: (value, opts) =>\n fnFormatCurrency(value, { ...opts, locale }),\n }),\n [locale, timezone],\n );\n}\n","import { useCallback, useState } from \"react\";\n\nexport interface UseTablePaginationOptions {\n /** Initial page (1-based). Default 1. */\n defaultPage?: number;\n /** Initial page size. Default 20. */\n defaultPageSize?: number;\n /** Controlled page — when set, hook becomes view-only for page. */\n page?: number;\n /** Controlled page size — when set, hook becomes view-only for size. */\n pageSize?: number;\n /** Fires when either page or pageSize changes. */\n onChange?: (page: number, pageSize: number) => void;\n}\n\nexport interface UseTablePaginationResult {\n page: number;\n pageSize: number;\n setPage: (page: number) => void;\n setPageSize: (pageSize: number) => void;\n /** Unified handler — matches `<Pagination onChange>` and `<Table pagination.onChange>` shapes. */\n onChange: (page: number, pageSize: number) => void;\n /** Reset page to 1 (keep size). Call after filter/sort/search changes. */\n resetPage: () => void;\n /** Reset both back to defaults. */\n reset: () => void;\n}\n\n/**\n * useTablePagination — `page` + `pageSize` slice.\n *\n * Ergonomic accessor for the canonical pagination state any\n * `<DataTable>` (or bare `<Table pagination=…>`) needs. Mirrors the\n * MRT / TanStack pattern: controlled OR uncontrolled, single `onChange`\n * surface that matches `<Pagination>`.\n *\n * @example\n * const pagination = useTablePagination({ defaultPageSize: 20 });\n * const rows = useMemo(\n * () => allRows.slice((pagination.page - 1) * pagination.pageSize, ...),\n * [allRows, pagination.page, pagination.pageSize],\n * );\n * <Table pagination={{ ...pagination, total: allRows.length }} />\n */\nexport function useTablePagination(\n options: UseTablePaginationOptions = {},\n): UseTablePaginationResult {\n const {\n defaultPage = 1,\n defaultPageSize = 20,\n page: controlledPage,\n pageSize: controlledPageSize,\n onChange,\n } = options;\n\n const [internalPage, setInternalPage] = useState(defaultPage);\n const [internalPageSize, setInternalPageSize] = useState(defaultPageSize);\n\n const page = controlledPage ?? internalPage;\n const pageSize = controlledPageSize ?? internalPageSize;\n\n const setPage = useCallback(\n (nextPage: number) => {\n if (controlledPage === undefined) setInternalPage(nextPage);\n onChange?.(nextPage, pageSize);\n },\n [controlledPage, onChange, pageSize],\n );\n\n const setPageSize = useCallback(\n (nextPageSize: number) => {\n if (controlledPageSize === undefined) setInternalPageSize(nextPageSize);\n // Page-size change conventionally resets to page 1.\n if (controlledPage === undefined) setInternalPage(1);\n onChange?.(1, nextPageSize);\n },\n [controlledPage, controlledPageSize, onChange],\n );\n\n const handleChange = useCallback(\n (nextPage: number, nextPageSize: number) => {\n if (controlledPage === undefined) setInternalPage(nextPage);\n if (controlledPageSize === undefined) setInternalPageSize(nextPageSize);\n onChange?.(nextPage, nextPageSize);\n },\n [controlledPage, controlledPageSize, onChange],\n );\n\n const resetPage = useCallback(() => {\n if (controlledPage === undefined) setInternalPage(1);\n onChange?.(1, pageSize);\n }, [controlledPage, onChange, pageSize]);\n\n const reset = useCallback(() => {\n if (controlledPage === undefined) setInternalPage(defaultPage);\n if (controlledPageSize === undefined) setInternalPageSize(defaultPageSize);\n onChange?.(defaultPage, defaultPageSize);\n }, [\n controlledPage,\n controlledPageSize,\n defaultPage,\n defaultPageSize,\n onChange,\n ]);\n\n return {\n page,\n pageSize,\n setPage,\n setPageSize,\n onChange: handleChange,\n resetPage,\n reset,\n };\n}\n","import { useCallback, useState } from \"react\";\n\nexport type TableSelectionMode = \"single\" | \"multiple\";\n\nexport interface UseTableSelectionOptions {\n /** \"single\" replaces previous selection on toggle/select. Default \"multiple\". */\n mode?: TableSelectionMode;\n /** Initial selected row keys (uncontrolled). */\n defaultSelected?: string[];\n /** Controlled selected row keys — when set, hook becomes view-only. */\n selected?: string[];\n /** Fires when selection changes. */\n onChange?: (selectedRowKeys: string[]) => void;\n}\n\nexport interface UseTableSelectionResult {\n selectedRowKeys: string[];\n setSelectedRowKeys: (keys: string[]) => void;\n /** Toggle a single row's selection. */\n toggle: (key: string) => void;\n /** Add a row to the selection (no-op in \"single\" — replaces). */\n select: (key: string) => void;\n /** Remove a row from the selection. */\n deselect: (key: string) => void;\n /** Clear the selection. */\n clear: () => void;\n /** True if the row is currently selected. */\n isSelected: (key: string) => boolean;\n /** Number of selected rows. */\n count: number;\n}\n\n/**\n * useTableSelection — controlled-or-uncontrolled row selection.\n *\n * Mirrors `<Table batchActions={{ selectedRowKeys, onSelectedRowKeysChange }}>`\n * shape. `mode=\"single\"` replaces on toggle; `mode=\"multiple\"` (default)\n * adds/removes individual keys.\n *\n * @example\n * const selection = useTableSelection({ mode: \"multiple\" });\n * <Table\n * batchActions={{\n * selectedRowKeys: selection.selectedRowKeys,\n * onSelectedRowKeysChange: selection.setSelectedRowKeys,\n * actions: <Button onClick={() => approve(selection.selectedRowKeys)}>承認</Button>,\n * }}\n * />\n */\nexport function useTableSelection(\n options: UseTableSelectionOptions = {},\n): UseTableSelectionResult {\n const {\n mode = \"multiple\",\n defaultSelected = [],\n selected: controlledSelected,\n onChange,\n } = options;\n\n const [internal, setInternal] = useState<string[]>(defaultSelected);\n const selectedRowKeys = controlledSelected ?? internal;\n\n const setSelectedRowKeys = useCallback(\n (next: string[]) => {\n if (controlledSelected === undefined) setInternal(next);\n onChange?.(next);\n },\n [controlledSelected, onChange],\n );\n\n const select = useCallback(\n (key: string) => {\n const next =\n mode === \"single\"\n ? [key]\n : selectedRowKeys.includes(key)\n ? selectedRowKeys\n : [...selectedRowKeys, key];\n if (next === selectedRowKeys) return;\n setSelectedRowKeys(next);\n },\n [mode, selectedRowKeys, setSelectedRowKeys],\n );\n\n const deselect = useCallback(\n (key: string) => {\n if (!selectedRowKeys.includes(key)) return;\n setSelectedRowKeys(selectedRowKeys.filter((k) => k !== key));\n },\n [selectedRowKeys, setSelectedRowKeys],\n );\n\n const toggle = useCallback(\n (key: string) => {\n if (selectedRowKeys.includes(key)) {\n setSelectedRowKeys(selectedRowKeys.filter((k) => k !== key));\n } else {\n setSelectedRowKeys(mode === \"single\" ? [key] : [...selectedRowKeys, key]);\n }\n },\n [mode, selectedRowKeys, setSelectedRowKeys],\n );\n\n const clear = useCallback(() => {\n if (selectedRowKeys.length === 0) return;\n setSelectedRowKeys([]);\n }, [selectedRowKeys.length, setSelectedRowKeys]);\n\n const isSelected = useCallback(\n (key: string) => selectedRowKeys.includes(key),\n [selectedRowKeys],\n );\n\n return {\n selectedRowKeys,\n setSelectedRowKeys,\n toggle,\n select,\n deselect,\n clear,\n isSelected,\n count: selectedRowKeys.length,\n };\n}\n","import { useCallback, useEffect, useState } from \"react\";\n\nexport interface UseTableStateOptions<T> {\n /** localStorage key — required to enable persistence. Hook acts as plain useState if omitted. */\n storageKey?: string;\n /** Initial value (used when storage is empty / invalid / disabled). */\n defaultValue: T;\n /**\n * Bump to invalidate previously persisted data. Stored records with a\n * different version are discarded on read.\n */\n version?: number;\n /**\n * Optional migration from older versions. Receives `{ version, value }`\n * and returns a value of the current schema, or `undefined` to discard.\n */\n migrate?: (stored: { version: number; value: unknown }) => T | undefined;\n /** Override the storage backend — useful in tests / SSR. Defaults to `window.localStorage`. */\n storage?: Storage | null;\n}\n\ninterface PersistedEnvelope<T> {\n version: number;\n value: T;\n}\n\nfunction readPersisted<T>(\n storage: Storage | null | undefined,\n storageKey: string,\n currentVersion: number,\n migrate?: UseTableStateOptions<T>[\"migrate\"],\n): T | undefined {\n if (!storage) return undefined;\n try {\n const raw = storage.getItem(storageKey);\n if (raw === null) return undefined;\n const parsed = JSON.parse(raw) as unknown;\n if (typeof parsed !== \"object\" || parsed === null) return undefined;\n const envelope = parsed as Partial<PersistedEnvelope<T>>;\n if (typeof envelope.version !== \"number\" || !(\"value\" in envelope))\n return undefined;\n if (envelope.version === currentVersion) return envelope.value as T;\n if (migrate)\n return migrate({\n version: envelope.version,\n value: envelope.value as unknown,\n });\n return undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction writePersisted<T>(\n storage: Storage | null | undefined,\n storageKey: string,\n version: number,\n value: T,\n) {\n if (!storage) return;\n try {\n storage.setItem(\n storageKey,\n JSON.stringify({ version, value } satisfies PersistedEnvelope<T>),\n );\n } catch {\n // Storage can be unavailable in private mode or sandboxed iframes.\n }\n}\n\nfunction resolveStorage(\n override: Storage | null | undefined,\n): Storage | null {\n if (override !== undefined) return override;\n if (typeof window === \"undefined\") return null;\n try {\n return window.localStorage;\n } catch {\n return null;\n }\n}\n\n/**\n * useTableState — versioned, persistent useState.\n *\n * Drop-in replacement for `useState<T>` that mirrors writes to\n * localStorage (or a custom Storage adapter) under `storageKey`.\n * Bump `version` to invalidate older records, or provide `migrate`\n * to transform them.\n *\n * Industry pattern: TanStack / MRT / MantineRT all recommend\n * \"consumer code with `onStateChange` callbacks\" for persistence —\n * this hook is the canonical small wrapper.\n *\n * @example\n * const [filters, setFilters] = useTableState({\n * storageKey: \"orders.filters.v1\",\n * defaultValue: [] as TableFilter[],\n * version: 1,\n * });\n */\nexport function useTableState<T>(\n options: UseTableStateOptions<T>,\n): [T, (next: T | ((prev: T) => T)) => void] {\n const {\n storageKey,\n defaultValue,\n version = 1,\n migrate,\n storage: storageOverride,\n } = options;\n\n const storage = resolveStorage(storageOverride);\n const [value, setValue] = useState<T>(() => {\n if (storageKey === undefined) return defaultValue;\n const persisted = readPersisted<T>(storage, storageKey, version, migrate);\n return persisted !== undefined ? persisted : defaultValue;\n });\n\n useEffect(() => {\n if (storageKey === undefined) return;\n writePersisted(storage, storageKey, version, value);\n }, [storage, storageKey, value, version]);\n\n const setNext = useCallback(\n (next: T | ((prev: T) => T)) => {\n setValue((prev) =>\n typeof next === \"function\" ? (next as (prev: T) => T)(prev) : next,\n );\n },\n [],\n );\n\n return [value, setNext];\n}\n","import { useCallback, useState } from \"react\";\nimport type {\n TableViewItem,\n TableViewSnapshot,\n} from \"../components/data-display/Table\";\nimport { useTableState } from \"./useTableState\";\n\nexport interface UseTableViewsOptions {\n /** Built-in (preset) views — never persisted, always present in the merged list. */\n items: TableViewItem[];\n /** Active view key on first render. Default: `items[0]?.key`. */\n defaultActive?: string;\n /** Controlled active view key. */\n activeKey?: string;\n /** Fires when the active view changes (via `apply` or `setActiveKey`). */\n onActiveKeyChange?: (key: string) => void;\n /** Fires when a user-saved view list mutates. */\n onSavedViewsChange?: (views: TableViewItem[]) => void;\n /**\n * Optional persistence — when set, user-saved views are stored under\n * this localStorage key (versioned via `useTableState`).\n */\n storageKey?: string;\n /** Max number of user-saved views kept. Default 20. */\n maxSavedViews?: number;\n}\n\nexport interface UseTableViewsResult {\n /** Merged list (built-in + saved). */\n items: TableViewItem[];\n /** Saved-by-user subset only. */\n savedViews: TableViewItem[];\n activeKey: string | undefined;\n setActiveKey: (key: string) => void;\n /** Apply a view — sets active key and returns the snapshot for state hydration. */\n applyView: (view: TableViewItem) => TableViewSnapshot;\n /** Persist a new user view from the current snapshot. Returns the saved view. */\n saveView: (label: string, snapshot: TableViewSnapshot) => TableViewItem;\n /** Remove a saved view by key. No-op for built-in views. */\n deleteView: (key: string) => void;\n /** Mark active view as \"custom\" (e.g. after manual filter/sort edits). */\n markCustom: () => void;\n}\n\nconst CUSTOM_KEY = \"custom\";\n\nfunction isPersistableLabel(label: TableViewItem[\"label\"]): label is string {\n return typeof label === \"string\";\n}\n\nfunction generateKey(): string {\n if (typeof crypto !== \"undefined\" && \"randomUUID\" in crypto) {\n return `view-${crypto.randomUUID()}`;\n }\n return `view-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n}\n\n/**\n * useTableViews — saved-view state for tabbed Table headers.\n *\n * Owns the active-view key + a list of user-saved views. Built-in\n * (preset) views pass through unchanged; user-saved views are\n * persisted to localStorage when `storageKey` is provided.\n *\n * @example\n * const views = useTableViews({\n * items: BUILT_IN_VIEWS,\n * storageKey: \"orders.views.v1\",\n * });\n * <Table\n * views={{\n * items: views.items,\n * activeKey: views.activeKey,\n * onActiveKeyChange: views.setActiveKey,\n * onViewApply: (v) => {\n * const snapshot = views.applyView(v);\n * setFilters(snapshot.filters ?? []);\n * setSort(snapshot.sort ?? null);\n * },\n * onDeleteView: (v) => views.deleteView(v.key),\n * }}\n * />\n */\nexport function useTableViews(\n options: UseTableViewsOptions,\n): UseTableViewsResult {\n const {\n items: builtInItems,\n defaultActive,\n activeKey: controlledActiveKey,\n onActiveKeyChange,\n onSavedViewsChange,\n storageKey,\n maxSavedViews = 20,\n } = options;\n\n const [internalActiveKey, setInternalActiveKey] = useState<string | undefined>(\n defaultActive ?? builtInItems[0]?.key,\n );\n const activeKey = controlledActiveKey ?? internalActiveKey;\n\n const [savedViews, setSavedViewsState] = useTableState<TableViewItem[]>({\n storageKey,\n defaultValue: [],\n version: 1,\n });\n\n const updateSavedViews = useCallback(\n (next: TableViewItem[] | ((prev: TableViewItem[]) => TableViewItem[])) => {\n setSavedViewsState((prev) => {\n const resolved = typeof next === \"function\" ? next(prev) : next;\n const trimmed = resolved.slice(-maxSavedViews);\n onSavedViewsChange?.(trimmed);\n return trimmed;\n });\n },\n [maxSavedViews, onSavedViewsChange, setSavedViewsState],\n );\n\n const setActiveKey = useCallback(\n (key: string) => {\n if (controlledActiveKey === undefined) setInternalActiveKey(key);\n onActiveKeyChange?.(key);\n },\n [controlledActiveKey, onActiveKeyChange],\n );\n\n const applyView = useCallback(\n (view: TableViewItem): TableViewSnapshot => {\n setActiveKey(view.key);\n return {\n filters: view.filters,\n sort: view.sort,\n columnVisibility: view.columnVisibility,\n };\n },\n [setActiveKey],\n );\n\n const saveView = useCallback(\n (label: string, snapshot: TableViewSnapshot): TableViewItem => {\n const next: TableViewItem = {\n key: generateKey(),\n label,\n ...snapshot,\n deletable: true,\n };\n updateSavedViews((prev) => [...prev, next]);\n setActiveKey(next.key);\n return next;\n },\n [setActiveKey, updateSavedViews],\n );\n\n const deleteView = useCallback(\n (key: string) => {\n const target = savedViews.find((view) => view.key === key);\n if (!target || !isPersistableLabel(target.label)) return;\n updateSavedViews((prev) => prev.filter((view) => view.key !== key));\n if (activeKey === key) {\n const firstBuiltIn = builtInItems[0]?.key;\n if (firstBuiltIn !== undefined) setActiveKey(firstBuiltIn);\n }\n },\n [activeKey, builtInItems, savedViews, setActiveKey, updateSavedViews],\n );\n\n const markCustom = useCallback(() => {\n if (activeKey === CUSTOM_KEY) return;\n setActiveKey(CUSTOM_KEY);\n }, [activeKey, setActiveKey]);\n\n return {\n items: [...builtInItems, ...savedViews],\n savedViews,\n activeKey,\n setActiveKey,\n applyView,\n saveView,\n deleteView,\n markCustom,\n };\n}\n"]}
package/dist/i18n.d.ts CHANGED
@@ -1,9 +1,61 @@
1
1
  import i18next from 'i18next';
2
2
  export { default } from 'i18next';
3
+ import { CalendarDate, CalendarDateTime, ZonedDateTime, Time } from '@internationalized/date';
3
4
 
4
- declare const SUPPORTED_LOCALES: readonly ["ja", "en", "vi"];
5
+ /** A value any framework primitive accepts as a date / time input. */
6
+ type DateLike = Date | string | number | CalendarDate | CalendarDateTime | ZonedDateTime;
7
+ /** A value any framework primitive accepts as a time-only input. */
8
+ type TimeLike = Date | string | number | Time | CalendarDateTime | ZonedDateTime;
9
+ interface FormatOptions {
10
+ /** BCP 47 locale override. Defaults to the preferences holder. */
11
+ locale?: string;
12
+ /** IANA timezone override. Defaults to the preferences holder. */
13
+ timezone?: string;
14
+ }
15
+ interface FormatDateOptions extends FormatOptions, Intl.DateTimeFormatOptions {
16
+ }
17
+ interface FormatNumberOptions extends FormatOptions, Intl.NumberFormatOptions {
18
+ }
19
+ interface FormatCurrencyOptions extends FormatOptions, Intl.NumberFormatOptions {
20
+ currency: string;
21
+ }
22
+ /** Format a date by locale + timezone. Defaults: medium date style. */
23
+ declare function formatDate(value: DateLike, opts?: FormatDateOptions): string;
24
+ /** Format a time by locale + timezone. Defaults: short time. */
25
+ declare function formatTime(value: DateLike, opts?: FormatDateOptions): string;
26
+ /** Format both date + time. Defaults: medium date, short time. */
27
+ declare function formatDateTime(value: DateLike, opts?: FormatDateOptions): string;
28
+ /** Format a number by locale. */
29
+ declare function formatNumber(value: number, opts?: FormatNumberOptions): string;
30
+ /** Format a currency amount. ISO 4217 currency code required. */
31
+ declare function formatCurrency(value: number, opts: FormatCurrencyOptions): string;
32
+
33
+ interface RelativeOptions {
34
+ /** BCP 47 locale override. Defaults to the preferences holder. */
35
+ locale?: string;
36
+ /** Reference moment. Defaults to "now". Useful for tests. */
37
+ now?: Date | number;
38
+ /** `Intl.RelativeTimeFormat` numeric style. Default `"auto"`. */
39
+ numeric?: "always" | "auto";
40
+ /** `Intl.RelativeTimeFormat` style. Default `"long"`. */
41
+ style?: "long" | "short" | "narrow";
42
+ }
43
+ /**
44
+ * Format the distance between `value` and `opts.now` (default: current
45
+ * time) as a locale-aware string.
46
+ *
47
+ * Granularity tops out at "year". Anything longer than a year reports
48
+ * "in N years" / "N years ago".
49
+ */
50
+ declare function formatRelative(value: DateLike, opts?: RelativeOptions): string;
51
+
52
+ declare const SUPPORTED_LOCALES: readonly ["ja", "en", "vi", "fil"];
53
+ /** @deprecated Use GodxLocale instead. */
5
54
  type ForgeLocale = (typeof SUPPORTED_LOCALES)[number];
6
- declare const FORGE_LOCALE_STORAGE_KEY = "forge.locale";
55
+ type GodxLocale = (typeof SUPPORTED_LOCALES)[number];
56
+ declare const GODX_LOCALE_STORAGE_KEY = "godx.locale";
57
+ /** @deprecated Use GODX_LOCALE_STORAGE_KEY instead. */
58
+ declare const FORGE_LOCALE_STORAGE_KEY = "godx.locale";
7
59
  declare function initI18n(): typeof i18next;
8
60
 
9
- export { FORGE_LOCALE_STORAGE_KEY, type ForgeLocale, SUPPORTED_LOCALES, initI18n };
61
+ export { type DateLike, FORGE_LOCALE_STORAGE_KEY, type ForgeLocale, type FormatCurrencyOptions, type FormatDateOptions, type FormatNumberOptions, type FormatOptions, GODX_LOCALE_STORAGE_KEY, type GodxLocale, type RelativeOptions, SUPPORTED_LOCALES, type TimeLike, formatCurrency, formatDate, formatDateTime, formatNumber, formatRelative, formatTime, initI18n };