@apotech-os/ui-sdk 3.0.0 → 3.0.2
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.
- package/dist/index.cjs +8 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +8 -4
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cn.ts","../src/hooks.ts","../src/utils.ts","../src/components.tsx","../src/data-table.tsx","../src/period.ts","../src/date-range-compare.tsx","../src/chart-primitives.tsx","../src/chart-kit.tsx","../src/toast.tsx","../src/tooltip.tsx"],"names":["React","BaseSelect","BaseTabs","BaseSwitch","Textarea","BaseCheckbox","BasePopover","jsxs","jsx","_","compare","React3","range","React4","Fragment","RechartsBarChart","RechartsLineChart","RechartsAreaChart","RechartsFunnelChart","createContext","useContext","useState","useRef","useCallback","Tooltip"],"mappings":"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","file":"index.js","sourcesContent":["import { type ClassValue, clsx } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n","/**\n * Runtime hooks provided by the shell via @apotech-os/ui-sdk.\n *\n * These hooks are implemented by the shell and injected at runtime via the\n * import map. App pages call them without knowing the shell internals.\n *\n * The default implementations throw if called outside of the shell context\n * (which should never happen in production — the shell always provides them\n * via the import map before mounting an app page).\n */\n\nimport { useContext, createContext, useCallback, useEffect, useRef, useState } from 'react';\n// `import type` only: ui-sdk has no runtime dependency on app-kit, so this must\n// not appear in the built dist/index.js (verified — see error-codes.ts).\nimport type { AppErrorCode, AppRunRecord, AppRunStatus } from '@apotech-os/app-kit';\n\n// ---------------------------------------------------------------------------\n// AppContext\n// ---------------------------------------------------------------------------\n\nexport interface AppContextValue {\n /** The slug of the installed app owning this page. */\n appSlug: string;\n /** The page path within the app (e.g. 'attribution'). */\n pagePath: string;\n /** The active space id, when applicable. */\n spaceId?: string;\n /**\n * The current user's grant role on this app context, when the shell knows it.\n * Settings pages use it to render read-only fields below ADMIN instead of\n * letting the user discover the 403 at save time.\n */\n role?: 'VIEWER' | 'EDITOR' | 'ADMIN';\n}\n\nconst AppContextInternalCtx = createContext<AppContextValue | null>(null);\n\nexport const AppContextProvider = AppContextInternalCtx.Provider;\n\n/** Returns context info for the current app page (appSlug, pagePath, spaceId). */\nexport function useAppContext(): AppContextValue {\n const ctx = useContext(AppContextInternalCtx);\n if (!ctx) throw new Error('useAppContext must be used inside an app page mounted by the shell');\n return ctx;\n}\n\n// ---------------------------------------------------------------------------\n// AppApi\n// ---------------------------------------------------------------------------\n\nexport interface AppApiClient {\n /**\n * Perform a GET request to a platform-data endpoint.\n * The session cookie is forwarded automatically (same-origin, withCredentials).\n */\n get<T>(path: string, params?: Record<string, string>): Promise<T>;\n /**\n * Perform a POST request to a platform-data endpoint.\n */\n post<T>(path: string, body?: unknown): Promise<T>;\n /**\n * Perform a PUT request to a platform-data endpoint (e.g. write app settings).\n */\n put<T>(path: string, body?: unknown): Promise<T>;\n /**\n * Perform a PATCH request to a platform-data endpoint (e.g. update a record).\n */\n patch<T>(path: string, body?: unknown): Promise<T>;\n /**\n * Perform a DELETE request to a platform-data endpoint (e.g. delete a record).\n */\n delete<T>(path: string): Promise<T>;\n /**\n * Run one of this app's `uiInvoke` functions and get its return value back.\n *\n * This is the ONLY way a page can reach an integration: the action endpoint\n * requires an app token and refuses a browser session. The platform mints the\n * token server-side and runs the handler in-process.\n *\n * The function must be declared `trigger: { type: 'uiInvoke' }` in the\n * manifest, and the caller must hold its `minRole` (default EDITOR).\n *\n * Pass `idempotencyKey` for anything that must not run twice on a double\n * click — a concurrent duplicate is rejected with 409 INVOCATION_IN_FLIGHT.\n *\n * Throws AppInvokeError. `code === 'FUNCTION_REJECTED'` carries an app-authored\n * message that is safe to show the user; every other failure is generic on\n * purpose (raw provider errors can leak tokens or PII).\n */\n invoke<TResult, TInput = Record<string, unknown>>(\n functionName: string,\n input?: TInput,\n opts?: { idempotencyKey?: string; signal?: AbortSignal },\n ): Promise<TResult>;\n}\n\n/** Thrown by AppApiClient.invoke. */\nexport class AppInvokeError extends Error {\n constructor(\n readonly status: number,\n message: string,\n // `AppErrorCode | (string & {})` gives autocomplete on the known codes\n // while keeping any other string assignable — a server that returns an\n // unlisted `code` (or none) must not fail to compile against this type.\n readonly code?: AppErrorCode | (string & {}),\n readonly invocationId?: string,\n ) {\n super(message);\n this.name = 'AppInvokeError';\n }\n}\n\nconst AppApiCtx = createContext<AppApiClient | null>(null);\n\nexport const AppApiProvider = AppApiCtx.Provider;\n\n/**\n * Returns an API client scoped to the current user session.\n * Requests go to /api/data/* with the session cookie (RBAC applies server-side).\n */\nexport function useAppApi(): AppApiClient {\n const client = useContext(AppApiCtx);\n if (!client) throw new Error('useAppApi must be used inside an app page mounted by the shell');\n return client;\n}\n\n// ---------------------------------------------------------------------------\n// AppSettings\n// ---------------------------------------------------------------------------\n\n/**\n * Reads and writes this app's settings (GET/PUT /data/apps/:appSlug/settings).\n *\n * The app slug comes from the surrounding AppContext, so a settings page only\n * has to describe its form. Values are the ones the server merged with the\n * `settings.fields` defaults declared in the manifest.\n *\n * Reading requires VIEWER, writing requires ADMIN. `save` never throws: it\n * reports through `saveError`, which carries the raw failure (422\n * SETTINGS_VALIDATION_FAILED with its per-key errors, or 403) so the page can\n * map it back onto its fields. A failed save leaves `settings` untouched.\n */\nexport function useAppSettings<T = Record<string, unknown>>(): {\n settings: T | undefined;\n isLoading: boolean;\n error: unknown;\n save: (patch: Partial<T>) => Promise<void>;\n isSaving: boolean;\n saveError: unknown;\n} {\n const { appSlug } = useAppContext();\n const api = useAppApi();\n const path = `/data/apps/${appSlug}/settings`;\n\n const [settings, setSettings] = useState<T | undefined>(undefined);\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<unknown>(undefined);\n const [isSaving, setIsSaving] = useState(false);\n const [saveError, setSaveError] = useState<unknown>(undefined);\n\n // The shell rebuilds the client on every render, so it cannot be an effect\n // dependency without refetching in a loop.\n const clientRef = useRef(api);\n clientRef.current = api;\n // Bumped by every request and by unmount: a superseded or late response is\n // dropped instead of overwriting fresher state.\n const requestIdRef = useRef(0);\n const isMountedRef = useRef(true);\n\n /**\n * `silent` skips the isLoading flip for the refetch that follows a save: a page\n * written as `if (isLoading) return <Spinner/>` would otherwise unmount its own\n * form mid-save, losing focus and any uncommitted input. isSaving already covers\n * that window.\n */\n const load = useCallback(\n async ({ silent }: { silent?: boolean } = {}) => {\n const requestId = ++requestIdRef.current;\n if (!silent) setIsLoading(true);\n try {\n const loaded = await clientRef.current.get<T>(path);\n if (requestId !== requestIdRef.current) return;\n setSettings(loaded);\n setError(undefined);\n } catch (err) {\n if (requestId !== requestIdRef.current) return;\n setError(err);\n } finally {\n // Clearing is NOT conditional on `silent`: a save that races the very first\n // GET supersedes it, so the initial load can no longer clear the flag it\n // set — only the request that actually settles last can.\n if (requestId === requestIdRef.current) setIsLoading(false);\n }\n },\n [path],\n );\n\n useEffect(() => {\n isMountedRef.current = true;\n void load();\n return () => {\n isMountedRef.current = false;\n requestIdRef.current += 1;\n };\n }, [load]);\n\n const save = useCallback(\n async (patch: Partial<T>) => {\n setIsSaving(true);\n setSaveError(undefined);\n try {\n await clientRef.current.put<unknown>(path, patch);\n await load({ silent: true });\n } catch (err) {\n if (isMountedRef.current) setSaveError(err);\n } finally {\n if (isMountedRef.current) setIsSaving(false);\n }\n },\n [path, load],\n );\n\n return { settings, isLoading, error, save, isSaving, saveError };\n}\n\n// ---------------------------------------------------------------------------\n// AppRun (P2-11)\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_RUN_POLL_INTERVAL_MS = 1_000;\nconst MAX_RUN_POLL_INTERVAL_MS = 5_000;\nconst RUN_POLL_BACKOFF = 1.5;\n/** Fixed cadence for useAppRuns' `follow` mode — it exposes no interval knobs. */\nconst RUNS_FOLLOW_POLL_INTERVAL_MS = 3_000;\n\n/** A stable key for the (progress, message) pair — the backoff resets whenever it changes. */\nfunction runProgressSignature(run: AppRunRecord): string {\n return `${run.progress ?? ''}|${run.message ?? ''}`;\n}\n\n/**\n * The outcome of one `fetchOnce()` call. Four cases, not two: a superseded or\n * late response (`'superseded'` — a newer tick, or a caller-facing `refresh()`,\n * bumped `requestIdRef` first) must NOT be conflated with a real failure\n * (`'error'`) — the poll loop reacts to them differently. Collapsing both into\n * one falsy value was the root cause of `tick()` silently dying whenever a\n * `refresh()` call raced an in-flight poll request: `tick()` only reschedules\n * itself on an outcome it recognizes, so a `'superseded'` response must still\n * lead to a reschedule, exactly like a transient `'error'` does.\n */\ntype FetchOutcome =\n | { kind: 'success'; run: AppRunRecord }\n | { kind: 'error'; err: unknown }\n | { kind: 'superseded' }\n | { kind: 'no-path' };\n\n/**\n * A 404 (the run was purged) or a 403 (the caller lost access) will never\n * resolve on retry — polling forever on either leaves a permanent spinner.\n * Any other failure (a network blip, a 5xx) is transient and keeps retrying\n * at the current pace, unchanged.\n *\n * The shell's `AppApiClient.get` has no typed error (unlike `invoke`'s\n * `AppInvokeError`) — it leaks whatever the underlying transport throws, so\n * this reads both an axios-style `err.response.status` and a bare `err.status`.\n */\nfunction isTerminalRunError(err: unknown): boolean {\n const status = extractHttpStatus(err);\n return status === 403 || status === 404;\n}\n\nfunction extractHttpStatus(err: unknown): number | undefined {\n if (typeof err !== 'object' || err === null) return undefined;\n const direct = (err as { status?: unknown }).status;\n if (typeof direct === 'number') return direct;\n const response = (err as { response?: unknown }).response;\n if (typeof response !== 'object' || response === null) return undefined;\n const nested = (response as { status?: unknown }).status;\n return typeof nested === 'number' ? nested : undefined;\n}\n\n/**\n * Follows a single run until it reaches a terminal status.\n *\n * Polling uses a recursive `setTimeout` (never `setInterval`, which piles up\n * requests when the API slows down), starting at `intervalMs` (default 1 s)\n * and multiplying by 1.5 each tick up to `maxIntervalMs` (default 5 s). The\n * backoff resets to `intervalMs` whenever `progress` or `message` changes —\n * an actively-progressing run is polled fast, a stalled one is polled slowly.\n *\n * `runId === null` puts the hook to sleep: no request is ever sent. This lets\n * a page call the hook unconditionally with a run id that may not exist yet\n * (e.g. before the triggering `uiInvoke` has returned).\n */\nexport function useAppRun(\n runId: string | null,\n opts: { intervalMs?: number; maxIntervalMs?: number } = {},\n): {\n run: AppRunRecord | undefined;\n isPolling: boolean;\n error: unknown;\n refresh: () => Promise<void>;\n} {\n const { appSlug } = useAppContext();\n const api = useAppApi();\n const intervalMs = opts.intervalMs ?? DEFAULT_RUN_POLL_INTERVAL_MS;\n const maxIntervalMs = opts.maxIntervalMs ?? MAX_RUN_POLL_INTERVAL_MS;\n\n const [run, setRun] = useState<AppRunRecord | undefined>(undefined);\n const [isPolling, setIsPolling] = useState(false);\n const [error, setError] = useState<unknown>(undefined);\n\n // The shell rebuilds the client on every render (app-page-view.tsx builds it\n // outside a useMemo), so it cannot be an effect dependency without restarting\n // the poll loop on every render.\n const clientRef = useRef(api);\n clientRef.current = api;\n const requestIdRef = useRef(0);\n const isMountedRef = useRef(true);\n\n const path = runId !== null ? `/data/apps/${appSlug}/runs/${encodeURIComponent(runId)}` : null;\n\n const fetchOnce = useCallback(async (): Promise<FetchOutcome> => {\n if (path === null) return { kind: 'no-path' };\n const requestId = ++requestIdRef.current;\n try {\n const loaded = await clientRef.current.get<AppRunRecord>(path);\n if (requestId !== requestIdRef.current || !isMountedRef.current) return { kind: 'superseded' };\n setRun(loaded);\n setError(undefined);\n return { kind: 'success', run: loaded };\n } catch (err) {\n if (requestId !== requestIdRef.current || !isMountedRef.current) return { kind: 'superseded' };\n setError(err);\n return { kind: 'error', err };\n }\n }, [path]);\n\n useEffect(() => {\n isMountedRef.current = true;\n // Invalidate any request from a previous runId/path so its late response\n // cannot overwrite the state of the run we are now following.\n requestIdRef.current += 1;\n setRun(undefined);\n setError(undefined);\n\n if (path === null) {\n setIsPolling(false);\n return () => {\n isMountedRef.current = false;\n };\n }\n\n let timeoutHandle: ReturnType<typeof setTimeout> | undefined;\n let interval = intervalMs;\n let lastSignature: string | undefined;\n let cancelled = false;\n\n const tick = async (): Promise<void> => {\n const outcome = await fetchOnce();\n if (cancelled || !isMountedRef.current) return;\n\n if (outcome.kind === 'no-path') {\n setIsPolling(false);\n return;\n }\n\n if (outcome.kind === 'superseded') {\n // A caller-facing refresh() (or a newer tick, though ticks never\n // overlap) raced this request and won. The response itself is\n // discarded, but the poll loop is still alive and must keep going —\n // rescheduling at the current pace is what stops it from stalling.\n timeoutHandle = setTimeout(() => void tick(), interval);\n return;\n }\n\n if (outcome.kind === 'error') {\n if (isTerminalRunError(outcome.err)) {\n // Purged (404) or forbidden (403): this will never recover on its\n // own. Stop polling instead of spinning forever — the failure is\n // already surfaced via `error`.\n setIsPolling(false);\n return;\n }\n // Any other failure does not accelerate the loop — retry at the current pace.\n timeoutHandle = setTimeout(() => void tick(), interval);\n return;\n }\n\n const loaded = outcome.run;\n const signature = runProgressSignature(loaded);\n interval =\n signature === lastSignature\n ? Math.min(interval * RUN_POLL_BACKOFF, maxIntervalMs)\n : intervalMs;\n lastSignature = signature;\n\n if (loaded.status !== 'running') {\n setIsPolling(false);\n return;\n }\n timeoutHandle = setTimeout(() => void tick(), interval);\n };\n\n setIsPolling(true);\n void tick();\n\n return () => {\n cancelled = true;\n isMountedRef.current = false;\n if (timeoutHandle) clearTimeout(timeoutHandle);\n };\n }, [path, fetchOnce, intervalMs, maxIntervalMs]);\n\n const refresh = useCallback(async () => {\n await fetchOnce();\n }, [fetchOnce]);\n\n return { run, isPolling, error, refresh };\n}\n\n// ---------------------------------------------------------------------------\n// AppRuns (P2-11)\n// ---------------------------------------------------------------------------\n\n/**\n * The outcome of one `fetchOnce()` call, mirroring `FetchOutcome` above for\n * the same reason: a superseded/late response and a genuine fetch error must\n * stay distinguishable from a real \"no runs are running\" success, or the\n * follow loop below cannot tell \"we don't know\" from \"stop following\" and\n * one dropped request kills it permanently.\n */\ntype ListFetchOutcome =\n | { kind: 'success'; items: AppRunRecord[] }\n | { kind: 'error'; err: unknown }\n | { kind: 'superseded' };\n\n/**\n * Lists the latest runs of a `kind` — used to re-attach the UI after a page\n * reload, where the runId returned by `invoke()` is lost, and to follow a run\n * by its business `key` rather than by its id.\n */\nexport function useAppRuns(opts: {\n kind?: string;\n key?: string;\n status?: AppRunStatus[];\n limit?: number;\n /** Keeps refreshing while a non-terminal run is present. Default: true. */\n follow?: boolean;\n}): { runs: AppRunRecord[]; isLoading: boolean; error: unknown; refresh: () => Promise<void> } {\n const { appSlug } = useAppContext();\n const api = useAppApi();\n const follow = opts.follow ?? true;\n\n const [runs, setRuns] = useState<AppRunRecord[]>([]);\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<unknown>(undefined);\n\n const clientRef = useRef(api);\n clientRef.current = api;\n const requestIdRef = useRef(0);\n const isMountedRef = useRef(true);\n\n const params: Record<string, string> = {};\n if (opts.kind) params['kind'] = opts.kind;\n if (opts.key) params['key'] = opts.key;\n if (opts.status?.length) params['status'] = opts.status.join(',');\n if (opts.limit) params['limit'] = String(opts.limit);\n // Stable string key so the effect below does not restart on every render\n // just because `opts` is a fresh object literal from the caller.\n const paramsKey = JSON.stringify(params);\n const path = `/data/apps/${appSlug}/runs`;\n\n const fetchOnce = useCallback(\n async ({ silent }: { silent?: boolean } = {}): Promise<ListFetchOutcome> => {\n const requestId = ++requestIdRef.current;\n if (!silent) setIsLoading(true);\n try {\n const page = await clientRef.current.get<{ items: AppRunRecord[] }>(\n path,\n JSON.parse(paramsKey) as Record<string, string>,\n );\n if (requestId !== requestIdRef.current || !isMountedRef.current) return { kind: 'superseded' };\n setRuns(page.items);\n setError(undefined);\n return { kind: 'success', items: page.items };\n } catch (err) {\n if (requestId !== requestIdRef.current || !isMountedRef.current) return { kind: 'superseded' };\n setError(err);\n return { kind: 'error', err };\n } finally {\n if (requestId === requestIdRef.current) setIsLoading(false);\n }\n },\n [path, paramsKey],\n );\n\n useEffect(() => {\n isMountedRef.current = true;\n let timeoutHandle: ReturnType<typeof setTimeout> | undefined;\n let cancelled = false;\n\n const tick = async (silent: boolean): Promise<void> => {\n const outcome = await fetchOnce({ silent });\n if (cancelled || !isMountedRef.current || !follow) return;\n // A superseded response or a transient fetch error cannot tell us\n // whether a running item still exists — retry at the same cadence\n // rather than treating \"we don't know\" as \"nothing is running\" and\n // stalling the follow loop for good. Only a clean success with no\n // running item is a real reason to stop.\n if (outcome.kind !== 'success' || outcome.items.some((r) => r.status === 'running')) {\n timeoutHandle = setTimeout(() => void tick(true), RUNS_FOLLOW_POLL_INTERVAL_MS);\n }\n };\n\n void tick(false);\n\n return () => {\n cancelled = true;\n isMountedRef.current = false;\n if (timeoutHandle) clearTimeout(timeoutHandle);\n };\n }, [fetchOnce, follow]);\n\n const refresh = useCallback(async () => {\n await fetchOnce({ silent: true });\n }, [fetchOnce]);\n\n return { runs, isLoading, error, refresh };\n}\n","/**\n * Browser helpers for app pages.\n *\n * App bundles get react, react-dom and this SDK from the shell's import map and\n * bundle everything else themselves — so without these here, every app would\n * reimplement clipboard handling and CSV escaping, and get the edge cases wrong\n * in its own way.\n */\n\n/**\n * Copy text to the clipboard.\n *\n * Returns `false` instead of throwing when the clipboard is unavailable (non\n * secure context, permission refused) so the caller can render inline feedback.\n * No `document.execCommand('copy')` fallback: it is deprecated, and the shell\n * only ever runs on https or localhost, both secure contexts.\n */\nexport async function copyToClipboard(text: string): Promise<boolean> {\n if (!navigator?.clipboard || !window.isSecureContext) return false;\n try {\n await navigator.clipboard.writeText(text);\n return true;\n } catch {\n return false;\n }\n}\n\n/** Trigger a browser download of a Blob via a throwaway object URL + `<a>` click. */\nexport function downloadBlob(blob: Blob, filename: string): void {\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = filename;\n document.body.appendChild(a);\n a.click();\n a.remove();\n URL.revokeObjectURL(url);\n}\n\n/** Escape one CSV field per RFC 4180: quote it, and double any embedded quote,\n * whenever it contains a comma, a quote, or a line break. */\nfunction escapeCsvField(value: string): string {\n return /[\",\\r\\n]/.test(value) ? `\"${value.replace(/\"/g, '\"\"')}\"` : value;\n}\n\n/** Serialize rows (header included) into an RFC 4180 CSV string. */\nexport function toCsv(rows: string[][]): string {\n return rows.map((row) => row.map(escapeCsvField).join(',')).join('\\r\\n');\n}\n\n/** UTF-8 byte order mark. */\nconst BOM = '\\uFEFF';\n\n/**\n * Serialize + download in one call.\n *\n * The BOM is the whole reason this helper exists: without it Excel on Windows\n * reads the file as latin-1 and mangles every accented character.\n */\nexport function downloadCsv(rows: string[][], filename: string): void {\n const blob = new Blob([`${BOM}${toCsv(rows)}`], { type: 'text/csv;charset=utf-8' });\n downloadBlob(blob, filename);\n}\n","/**\n * Design system components exported by @apotech-os/ui-sdk.\n *\n * These are minimal self-contained copies of the shell's component library.\n * They use the same Tailwind utility classes as the shell — Tailwind classes\n * are plain strings and work without any build step when the shell's stylesheet\n * is loaded (which it is, since these pages run inside the shell).\n *\n * Strategy note:\n * - Not imported from apps/web (would create a circular dep pkg → app).\n * - Copied/adapted here to keep the SDK self-contained and publishable.\n * - The exhaustive component inventory is tracked in #75.\n */\n\nimport { Dialog } from '@base-ui/react/dialog';\nimport { Menu } from '@base-ui/react/menu';\nimport { Checkbox as BaseCheckbox } from '@base-ui/react/checkbox';\nimport { Popover as BasePopover } from '@base-ui/react/popover';\nimport { Select as BaseSelect } from '@base-ui/react/select';\nimport { Switch as BaseSwitch } from '@base-ui/react/switch';\nimport { Tabs as BaseTabs } from '@base-ui/react/tabs';\nimport { type VariantProps, cva } from 'class-variance-authority';\nimport * as React from 'react';\nimport { cn } from './cn';\nimport { copyToClipboard } from './utils';\n\n/**\n * Give Base UI the caller's own element to render as, rather than wrapping it.\n *\n * `trigger` is `ReactNode` in our public API, so it may be a `<button>` — wrapping\n * that in Base UI's default button is invalid HTML and the source of the nested-\n * button defect. Passing the element through `render` merges the trigger props\n * into it instead. A non-element (a bare string) still needs a host, and a span\n * with the button semantics Base UI adds is the least surprising one.\n *\n * `nativeButton` tells Base UI which it got, and it is not cosmetic: on the\n * native branch Base UI adds `type=\"button\"`, without which a trigger inside a\n * <form> submits it. Only a literal <button> and our own `Button` can be known to\n * be one — anything else is reported honestly as not-a-button, and Base UI says so\n * loudly in the console if it was wrong.\n */\nfunction triggerProps(trigger: React.ReactNode): {\n render: React.ReactElement;\n nativeButton: boolean;\n} {\n if (React.isValidElement(trigger)) {\n return { render: trigger, nativeButton: trigger.type === 'button' || trigger.type === Button };\n }\n return { render: <span>{trigger}</span>, nativeButton: false };\n}\n\n// ---------------------------------------------------------------------------\n// Button\n// ---------------------------------------------------------------------------\n\nexport const buttonVariants = cva(\n 'inline-flex cursor-pointer items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50',\n {\n variants: {\n variant: {\n default: 'bg-primary text-primary-foreground hover:bg-primary/90',\n secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',\n outline: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',\n ghost: 'hover:bg-accent hover:text-accent-foreground',\n destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',\n },\n size: {\n default: 'h-9 px-4 py-2',\n sm: 'h-8 rounded-md px-3 text-xs',\n lg: 'h-10 rounded-md px-6',\n icon: 'h-9 w-9',\n },\n },\n defaultVariants: { variant: 'default', size: 'default' },\n },\n);\n\nexport interface ButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {}\n\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant, size, ...props }, ref) => (\n <button ref={ref} className={cn(buttonVariants({ variant, size, className }))} {...props} />\n ),\n);\nButton.displayName = 'Button';\n\n// ---------------------------------------------------------------------------\n// Badge\n// ---------------------------------------------------------------------------\n\nexport const badgeVariants = cva(\n 'inline-flex items-center gap-1.5 rounded-full border px-2 py-0.5 text-xs font-medium whitespace-nowrap',\n {\n variants: {\n variant: {\n neutral: 'border-border bg-muted text-muted-foreground',\n brand: 'border-primary/20 bg-primary/10 text-primary',\n success: 'border-status-success/25 bg-status-success/10 text-status-success',\n warning: 'border-status-pending/30 bg-status-pending/10 text-status-pending',\n danger: 'border-status-blocked/25 bg-status-blocked/10 text-status-blocked',\n info: 'border-status-info/25 bg-status-info/10 text-status-info',\n outline: 'border-border bg-transparent text-muted-foreground',\n },\n },\n defaultVariants: { variant: 'neutral' },\n },\n);\n\nexport interface BadgeProps\n extends React.HTMLAttributes<HTMLSpanElement>, VariantProps<typeof badgeVariants> {\n dot?: boolean;\n}\n\nexport function Badge({ className, variant, dot, children, ...props }: BadgeProps) {\n return (\n <span className={cn(badgeVariants({ variant }), className)} {...props}>\n {dot && <span className=\"size-1.5 rounded-full bg-current\" />}\n {children}\n </span>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Card\n// ---------------------------------------------------------------------------\n\nexport function Card({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n return (\n <div\n className={cn('rounded-xl border bg-card text-card-foreground shadow-sm', className)}\n {...props}\n />\n );\n}\n\nexport function CardHeader({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n return <div className={cn('flex flex-col space-y-1.5 p-6', className)} {...props} />;\n}\n\nexport function CardTitle({ className, ...props }: React.HTMLAttributes<HTMLHeadingElement>) {\n return (\n <h3 className={cn('text-lg font-semibold leading-none tracking-tight', className)} {...props} />\n );\n}\n\nexport function CardDescription({\n className,\n ...props\n}: React.HTMLAttributes<HTMLParagraphElement>) {\n return <p className={cn('text-sm text-muted-foreground', className)} {...props} />;\n}\n\nexport function CardContent({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n return <div className={cn('p-6 pt-0', className)} {...props} />;\n}\n\nexport function CardFooter({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n return <div className={cn('flex items-center p-6 pt-0', className)} {...props} />;\n}\n\n// ---------------------------------------------------------------------------\n// Input\n// ---------------------------------------------------------------------------\n\nexport const Input = React.forwardRef<\n HTMLInputElement,\n React.InputHTMLAttributes<HTMLInputElement>\n>(({ className, type, ...props }, ref) => (\n <input\n type={type}\n className={cn(\n 'flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50',\n className,\n )}\n ref={ref}\n {...props}\n />\n));\nInput.displayName = 'Input';\n\n// ---------------------------------------------------------------------------\n// Table\n// ---------------------------------------------------------------------------\n\nexport function Table({ className, ...props }: React.HTMLAttributes<HTMLTableElement>) {\n return <table className={cn('w-full text-sm', className)} {...props} />;\n}\n\nexport function TableHeader({\n className,\n ...props\n}: React.HTMLAttributes<HTMLTableSectionElement>) {\n return (\n <thead\n // The hover tint is a data-row affordance; on the header band it reads as\n // \"this is clickable\", which it is not.\n className={cn('[&_tr]:border-b [&_tr]:hover:bg-transparent', className)}\n {...props}\n />\n );\n}\n\nexport function TableBody({ className, ...props }: React.HTMLAttributes<HTMLTableSectionElement>) {\n return <tbody className={cn('[&_tr:last-child]:border-0', className)} {...props} />;\n}\n\nexport function TableRow({ className, ...props }: React.HTMLAttributes<HTMLTableRowElement>) {\n return (\n <tr\n className={cn(\n 'border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted',\n className,\n )}\n {...props}\n />\n );\n}\n\nexport function TableHead({ className, ...props }: React.ThHTMLAttributes<HTMLTableCellElement>) {\n return (\n <th\n className={cn(\n 'h-10 px-4 text-left align-middle text-xs font-medium uppercase tracking-wide text-muted-foreground',\n className,\n )}\n {...props}\n />\n );\n}\n\nexport function TableCell({ className, ...props }: React.TdHTMLAttributes<HTMLTableCellElement>) {\n return <td className={cn('p-4 align-middle', className)} {...props} />;\n}\n\n// ---------------------------------------------------------------------------\n// Select\n// ---------------------------------------------------------------------------\n\nexport interface SelectOption {\n value: string;\n label: React.ReactNode;\n disabled?: boolean;\n}\n\nexport interface SelectProps {\n /** Controlled value. Pair with `onValueChange`. */\n value?: string;\n defaultValue?: string;\n onValueChange?: (value: string) => void;\n items: SelectOption[];\n /** Shown when nothing is chosen. */\n placeholder?: React.ReactNode;\n disabled?: boolean;\n /** Submitted with a surrounding form, through a hidden native input. */\n name?: string;\n className?: string;\n 'aria-label'?: string;\n}\n\n/**\n * Listbox select.\n *\n * Contract 2: this used to be a native `<select>` taking `<option>` children.\n * The popup is ours now — themed, positioned and keyboard-driven like every\n * other floating surface — which a native select cannot be. `items` replaces the\n * children, and the ref is gone: there is no `HTMLSelectElement` behind it.\n */\nexport function Select({\n value,\n defaultValue,\n onValueChange,\n items,\n placeholder = 'Choisir…',\n disabled,\n name,\n className,\n ...props\n}: SelectProps) {\n return (\n <BaseSelect.Root\n // Base UI needs the list to render the chosen item's label rather than its\n // raw value in the trigger.\n items={items}\n value={value}\n defaultValue={defaultValue}\n onValueChange={(next) => onValueChange?.(String(next))}\n disabled={disabled}\n name={name}\n >\n <BaseSelect.Trigger\n className={cn(\n 'flex h-9 w-full cursor-pointer items-center justify-between gap-2 rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50',\n className,\n )}\n {...props}\n >\n <BaseSelect.Value placeholder={placeholder} />\n <BaseSelect.Icon aria-hidden className=\"text-xs text-muted-foreground\">\n ▾\n </BaseSelect.Icon>\n </BaseSelect.Trigger>\n <BaseSelect.Portal>\n <BaseSelect.Positioner className=\"z-50\" sideOffset={4}>\n <BaseSelect.Popup className=\"max-h-72 min-w-(--anchor-width) overflow-auto rounded-md border bg-card p-1 shadow-lg\">\n {items.map((item) => (\n <BaseSelect.Item\n key={item.value}\n value={item.value}\n disabled={item.disabled}\n className=\"cursor-pointer rounded px-2 py-1.5 text-sm outline-none data-[highlighted]:bg-accent data-[disabled]:pointer-events-none data-[disabled]:opacity-50\"\n >\n <BaseSelect.ItemText>{item.label}</BaseSelect.ItemText>\n </BaseSelect.Item>\n ))}\n </BaseSelect.Popup>\n </BaseSelect.Positioner>\n </BaseSelect.Portal>\n </BaseSelect.Root>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Tabs\n// ---------------------------------------------------------------------------\n\nexport interface TabsProps {\n defaultValue?: string;\n value?: string;\n onValueChange?: (v: string) => void;\n className?: string;\n children: React.ReactNode;\n}\n\nexport function Tabs({ defaultValue, value, onValueChange, className, children }: TabsProps) {\n return (\n <BaseTabs.Root\n className={className}\n defaultValue={defaultValue}\n value={value}\n onValueChange={(next) => onValueChange?.(String(next))}\n >\n {children}\n </BaseTabs.Root>\n );\n}\n\nexport function TabsList({\n className,\n children,\n}: {\n className?: string;\n children: React.ReactNode;\n}) {\n return (\n <BaseTabs.List\n className={cn('inline-flex items-center gap-1 rounded-lg bg-muted p-1', className)}\n >\n {children}\n </BaseTabs.List>\n );\n}\n\nexport function TabsTrigger({\n value,\n className,\n children,\n}: {\n value: string;\n className?: string;\n children: React.ReactNode;\n}) {\n return (\n <BaseTabs.Tab\n value={value}\n className={cn(\n 'rounded-md px-3 py-1.5 text-sm font-medium transition-colors',\n 'text-muted-foreground hover:text-foreground',\n 'data-[active]:bg-card data-[active]:text-foreground data-[active]:shadow-sm',\n className,\n )}\n >\n {children}\n </BaseTabs.Tab>\n );\n}\n\nexport function TabsContent({\n value,\n className,\n children,\n}: {\n value: string;\n className?: string;\n children: React.ReactNode;\n}) {\n return (\n <BaseTabs.Panel value={value} className={className}>\n {children}\n </BaseTabs.Panel>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Modal\n// ---------------------------------------------------------------------------\n\nexport interface ModalProps {\n open: boolean;\n onClose: () => void;\n title?: React.ReactNode;\n children: React.ReactNode;\n className?: string;\n}\n\n/** Centred blocking dialog. Base UI owns the focus trap, focus restore and Escape. */\nexport function Modal({ open, onClose, title, children, className }: ModalProps) {\n return (\n <Dialog.Root open={open} onOpenChange={(next) => !next && onClose()}>\n <Dialog.Portal>\n {/* Base UI renders the backdrop `aria-hidden`, so this label is for the\n pointer affordance only — Escape is the accessible way out. */}\n <Dialog.Backdrop aria-label=\"Close\" className=\"fixed inset-0 z-50 bg-overlay\" />\n <Dialog.Popup\n className={cn(\n 'fixed left-1/2 top-1/2 z-50 w-[calc(100%-2rem)] max-w-md -translate-x-1/2 -translate-y-1/2 rounded-xl border bg-card p-5 shadow-lg',\n className,\n )}\n >\n {title && <Dialog.Title className=\"mb-3 text-base font-semibold\">{title}</Dialog.Title>}\n {children}\n </Dialog.Popup>\n </Dialog.Portal>\n </Dialog.Root>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Spinner\n// ---------------------------------------------------------------------------\n\nexport interface SpinnerProps {\n className?: string;\n size?: 'sm' | 'md' | 'lg';\n}\n\nconst spinnerSizes = { sm: 'size-4', md: 'size-6', lg: 'size-8' };\n\nexport function Spinner({ className, size = 'md' }: SpinnerProps) {\n return (\n <svg\n className={cn('animate-spin text-muted-foreground', spinnerSizes[size], className)}\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n aria-label=\"Loading\"\n role=\"status\"\n >\n <circle className=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" strokeWidth=\"4\" />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z\"\n />\n </svg>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Link\n// ---------------------------------------------------------------------------\n\nexport interface LinkProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {\n variant?: 'default' | 'muted';\n}\n\nexport const Link = React.forwardRef<HTMLAnchorElement, LinkProps>(\n ({ className, variant = 'default', ...props }, ref) => (\n <a\n ref={ref}\n className={cn(\n 'underline-offset-4 hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',\n variant === 'default' ? 'text-primary' : 'text-muted-foreground',\n className,\n )}\n {...props}\n />\n ),\n);\nLink.displayName = 'Link';\n\n// ---------------------------------------------------------------------------\n// Switch\n// ---------------------------------------------------------------------------\n\n/**\n * Do not pass `aria-label` when the switch sits inside a `<label>`: the label\n * already names it, and the two naming sources cancel out into no name at all.\n */\nexport interface SwitchProps {\n checked?: boolean;\n onCheckedChange?: (checked: boolean) => void;\n disabled?: boolean;\n className?: string;\n 'aria-label'?: string;\n}\n\nexport function Switch({\n checked = false,\n onCheckedChange,\n disabled,\n className,\n ...props\n}: SwitchProps) {\n return (\n <BaseSwitch.Root\n checked={checked}\n onCheckedChange={(next) => onCheckedChange?.(next)}\n disabled={disabled}\n className={cn(\n // `data-[disabled]`, not `disabled:` — the root is a span, so `:disabled`\n // never matches it and the dimming would silently stop happening.\n 'relative inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full bg-input transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring data-[checked]:bg-primary data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50',\n className,\n )}\n {...props}\n >\n <BaseSwitch.Thumb className=\"inline-block size-4 translate-x-0.5 rounded-full bg-white shadow transition-transform data-[checked]:translate-x-4\" />\n </BaseSwitch.Root>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Icons\n//\n// Inline SVGs rather than a lucide-react dependency: the SDK is loaded through\n// the shell's import map as a single vendor chunk, so a dependency here inflates\n// every app page. Same precedent as Spinner above.\n// ---------------------------------------------------------------------------\n\nfunction IconX({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M18 6 6 18M6 6l12 12\" />\n </svg>\n );\n}\n\nfunction IconCopy({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\" />\n <path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\" />\n </svg>\n );\n}\n\nfunction IconCheck({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M20 6 9 17l-5-5\" />\n </svg>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Textarea\n// ---------------------------------------------------------------------------\n\nexport type TextareaProps = React.TextareaHTMLAttributes<HTMLTextAreaElement>;\n\nexport const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(function Textarea(\n { className, ...props },\n ref,\n) {\n return (\n <textarea\n ref={ref}\n className={cn(\n 'flex min-h-20 w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50',\n className,\n )}\n {...props}\n />\n );\n});\n\n// ---------------------------------------------------------------------------\n// Checkbox\n// ---------------------------------------------------------------------------\n\nexport interface CheckboxProps {\n checked?: boolean;\n defaultChecked?: boolean;\n /** Receives the boolean directly. */\n onCheckedChange?: (checked: boolean) => void;\n disabled?: boolean;\n label?: React.ReactNode;\n /** Submitted with a surrounding form, through a hidden native input. */\n name?: string;\n className?: string;\n 'aria-label'?: string;\n}\n\n/**\n * Checkbox.\n *\n * Contract 2: this used to be a native `<input type=\"checkbox\">` forwarding an\n * `HTMLInputElement` ref and taking every input attribute. Base UI renders a\n * button with the role and a hidden input for form submission, so neither could\n * survive — `onChange` and the ref are gone, `onCheckedChange` is the way in.\n */\nexport function Checkbox({\n checked,\n defaultChecked,\n onCheckedChange,\n disabled,\n label,\n name,\n className,\n ...props\n}: CheckboxProps) {\n const labelId = React.useId();\n const control = React.useRef<HTMLButtonElement>(null);\n const box = (\n <BaseCheckbox.Root\n ref={control}\n aria-labelledby={label ? labelId : undefined}\n checked={checked}\n defaultChecked={defaultChecked}\n onCheckedChange={(next) => onCheckedChange?.(next)}\n disabled={disabled}\n name={name}\n className={cn(\n 'flex size-4 shrink-0 cursor-pointer items-center justify-center rounded border border-input text-primary-foreground transition-colors data-[checked]:border-primary data-[checked]:bg-primary data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50',\n className,\n )}\n {...props}\n >\n <BaseCheckbox.Indicator className=\"text-[10px] leading-none\">✓</BaseCheckbox.Indicator>\n </BaseCheckbox.Root>\n );\n if (!label) return box;\n return (\n // Not a wrapping <label>: Base UI would associate it AND keep its own label,\n // so the text and the control would both answer to the same name and\n // `getByLabelText` would go ambiguous. Pointing `aria-labelledby` at the text\n // names the control once; the click handler keeps the label clickable.\n <span className=\"inline-flex items-center gap-2 text-sm\">\n {box}\n <span\n id={labelId}\n className=\"cursor-pointer\"\n // Forwarded to the control rather than re-derived: the checkbox owns its\n // state when uncontrolled, so computing `!checked` here would report a\n // change that never happened — and `checked` is `undefined` besides.\n onClick={() => control.current?.click()}\n >\n {label}\n </span>\n </span>\n );\n}\n\n// ---------------------------------------------------------------------------\n// SidePanel\n// ---------------------------------------------------------------------------\n\nexport interface SidePanelProps {\n open: boolean;\n onClose: () => void;\n title?: React.ReactNode;\n description?: React.ReactNode;\n children: React.ReactNode;\n className?: string;\n}\n\n/**\n * Blocking slide-over — reach for it when a task has more fields than a `Modal`\n * can show without an inner scrollbar. Full height, so the body scrolls once and\n * a footer can stay pinned; `Modal` centres a box and does no height management.\n *\n * Children are laid out in a flex column filling the panel: put the scrollable\n * region in a `min-h-0 flex-1 overflow-y-auto` child and the footer after it.\n *\n * Focus is trapped inside while open and restored to the opener on close — Base\n * UI's dialog does both, which is what the hand-rolled version never did.\n */\nexport function SidePanel({\n open,\n onClose,\n title,\n description,\n children,\n className,\n}: SidePanelProps) {\n return (\n <Dialog.Root open={open} onOpenChange={(next) => !next && onClose()}>\n <Dialog.Portal>\n <Dialog.Backdrop aria-label=\"Fermer\" className=\"fixed inset-0 z-50 bg-overlay\" />\n <Dialog.Popup\n className={cn(\n 'fixed inset-y-0 right-0 z-50 flex w-full max-w-lg flex-col border-l bg-card shadow-xl',\n className,\n )}\n >\n <header className=\"flex shrink-0 items-start gap-3 border-b px-5 py-4\">\n <div className=\"min-w-0 flex-1\">\n {title && <Dialog.Title className=\"text-base font-semibold\">{title}</Dialog.Title>}\n {description && (\n <Dialog.Description className=\"mt-0.5 text-xs text-muted-foreground\">\n {description}\n </Dialog.Description>\n )}\n </div>\n <Dialog.Close\n aria-label=\"Fermer\"\n className=\"-mr-1 shrink-0 rounded-md p-1 text-muted-foreground hover:bg-accent hover:text-foreground\"\n >\n <IconX className=\"size-4\" />\n </Dialog.Close>\n </header>\n <div className=\"flex min-h-0 flex-1 flex-col px-5 py-4\">{children}</div>\n </Dialog.Popup>\n </Dialog.Portal>\n </Dialog.Root>\n );\n}\n\n// ---------------------------------------------------------------------------\n// CopyButton\n// ---------------------------------------------------------------------------\n\nexport interface CopyButtonProps {\n value: string;\n label?: string;\n copiedLabel?: string;\n variant?: ButtonProps['variant'];\n size?: ButtonProps['size'];\n className?: string;\n}\n\n/** How long the confirmation stays up before reverting. */\nconst COPY_FEEDBACK_MS = 2000;\n\n/**\n * Copy-to-clipboard button with inline feedback. On failure it says so rather\n * than silently doing nothing — keep the copyable text selectable so manual\n * copy stays the fallback.\n */\nexport function CopyButton({\n value,\n label = 'Copier',\n copiedLabel = 'Copié',\n variant = 'outline',\n size = 'sm',\n className,\n}: CopyButtonProps) {\n const [state, setState] = React.useState<'idle' | 'copied' | 'error'>('idle');\n const timeout = React.useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n\n // Held in a ref and cleared on unmount: the panel can close mid-feedback.\n React.useEffect(() => () => clearTimeout(timeout.current), []);\n\n async function copy() {\n const ok = await copyToClipboard(value);\n setState(ok ? 'copied' : 'error');\n clearTimeout(timeout.current);\n timeout.current = setTimeout(() => setState('idle'), COPY_FEEDBACK_MS);\n }\n\n return (\n <Button\n type=\"button\"\n variant={variant}\n size={size}\n className={className}\n onClick={() => void copy()}\n >\n {state === 'copied' ? <IconCheck className=\"size-3.5\" /> : <IconCopy className=\"size-3.5\" />}\n <span aria-live=\"polite\" className={state === 'error' ? 'text-destructive' : undefined}>\n {state === 'copied' ? copiedLabel : state === 'error' ? 'Copie impossible' : label}\n </span>\n </Button>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Popover\n// ---------------------------------------------------------------------------\n\nexport interface PopoverProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n trigger: React.ReactNode;\n children: React.ReactNode;\n align?: 'start' | 'end';\n className?: string;\n}\n\n/** Anchored panel. Controlled — the caller owns `open`. Closes on outside click\n * and Escape, which is what a filter pill needs and a Modal is too heavy for. */\nexport function Popover({\n open,\n onOpenChange,\n trigger,\n children,\n align = 'start',\n className,\n}: PopoverProps) {\n return (\n // The callback is re-wrapped so Base UI's event-details argument stops at the\n // SDK boundary: the engine is an implementation detail, not part of the API.\n <BasePopover.Root open={open} onOpenChange={(next) => onOpenChange(next)}>\n {/* The `inline-block` host is layout parity, not positioning: the old\n Popover wrapped its trigger in one, so dropping it would stretch a\n trigger that used to hug its text inside a flex or grid parent. */}\n <span className=\"inline-block\">\n <BasePopover.Trigger {...triggerProps(trigger)} />\n </span>\n <BasePopover.Portal>\n {/* The stacking context belongs on the positioner: it is the positioned\n element, so a z-index on the statically-positioned popup would do\n nothing. `z-50` matches the dialogs, and DOM order then puts a popover\n opened from inside a panel above it rather than under. */}\n <BasePopover.Positioner side=\"bottom\" align={align} sideOffset={4} className=\"z-50\">\n <BasePopover.Popup\n className={cn('min-w-48 rounded-md border bg-card p-2 shadow-lg', className)}\n >\n {children}\n </BasePopover.Popup>\n </BasePopover.Positioner>\n </BasePopover.Portal>\n </BasePopover.Root>\n );\n}\n\n// ---------------------------------------------------------------------------\n// DropdownMenu\n// ---------------------------------------------------------------------------\n\nexport interface DropdownMenuItem {\n label: React.ReactNode;\n onSelect: () => void;\n disabled?: boolean;\n destructive?: boolean;\n}\n\nexport interface DropdownMenuProps {\n trigger: React.ReactNode;\n items: DropdownMenuItem[];\n align?: 'start' | 'end';\n className?: string;\n}\n\n/** Uncontrolled menu. Selecting an item closes it; arrow keys move between them. */\nexport function DropdownMenu({ trigger, items, align = 'end', className }: DropdownMenuProps) {\n return (\n <Menu.Root>\n <span className=\"inline-block\">\n <Menu.Trigger {...triggerProps(trigger)} />\n </span>\n <Menu.Portal>\n <Menu.Positioner side=\"bottom\" align={align} sideOffset={4} className=\"z-50\">\n <Menu.Popup\n className={cn(\n 'flex min-w-48 flex-col rounded-md border bg-card p-1 shadow-lg',\n className,\n )}\n >\n {items.map((item, i) => (\n <Menu.Item\n key={i}\n disabled={item.disabled}\n onClick={item.onSelect}\n className={cn(\n 'cursor-pointer rounded px-2 py-1.5 text-left text-sm outline-none data-[highlighted]:bg-accent data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n item.destructive && 'text-destructive',\n )}\n >\n {item.label}\n </Menu.Item>\n ))}\n </Menu.Popup>\n </Menu.Positioner>\n </Menu.Portal>\n </Menu.Root>\n );\n}\n","/**\n * `<DataTable>` — the one table the platform has.\n *\n * TanStack Table drives it and `@tanstack/react-virtual` keeps long lists cheap,\n * but neither type crosses this file: the engines are replaceable dependencies of\n * the SDK, not part of its contract. Everything below is plain data.\n *\n * State (search, sort, faceted filters, hidden columns, selection) is\n * controlled-or-uncontrolled in the usual React sense, so a host that wants it in\n * the URL wires nuqs on the outside and the SDK never learns about routing.\n *\n * `manual` is the switch that matters. Off, the table sorts and filters the rows\n * it was given — right for a page that already holds everything. On, it renders\n * `rows` untouched and only reports what the user asked for, which is the only\n * correct behaviour when the server paginates by cursor: filtering a page\n * client-side would silently drop rows that live on the next one.\n */\nimport {\n flexRender,\n getCoreRowModel,\n getFilteredRowModel,\n getSortedRowModel,\n useReactTable,\n type ColumnDef,\n type SortingState,\n} from '@tanstack/react-table';\nimport { useVirtualizer } from '@tanstack/react-virtual';\nimport * as React from 'react';\nimport { cn } from './cn';\nimport {\n Button,\n Checkbox,\n Input,\n Popover,\n Select,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from './components';\n\nexport interface DataTableColumn<Row> {\n /** Stable identifier — also the key used for sorting and hiding. */\n key: string;\n header: React.ReactNode;\n /** Defaults to `String(row[key])`. */\n cell?: (row: Row) => React.ReactNode;\n /** Raw value used for client-side sorting and faceting. */\n value?: (row: Row) => unknown;\n sortable?: boolean;\n align?: 'left' | 'right';\n /** Starting width in pixels; the user can drag from there. */\n width?: number;\n}\n\n/**\n * The operators a filter can use — the same ten names the app manifest declares\n * and the records endpoint implements.\n *\n * The names match; the edges do not, so do not assume a filter composed here and\n * a `views[]` filter agree on every row. Two known differences: `neq` keeps rows\n * whose value is absent here and drops them server-side, and the server compares\n * `gt`/`lt`/`gte`/`lte` on the raw JSON text where this compares numbers and\n * dates as such. And the endpoint's operator map takes one value per operator\n * with no `in`, so a server-side facet should offer single-value operators —\n * multi-select is a client-side affordance.\n */\nexport type DataTableFilterOperator =\n | 'eq'\n | 'neq'\n | 'contains'\n | 'ncontains'\n | 'gt'\n | 'lt'\n | 'gte'\n | 'lte'\n | 'empty'\n | 'nempty';\n\nexport interface DataTableFacet {\n key: string;\n label: string;\n /** Values to choose from. Without them the facet takes a typed value instead. */\n options?: Array<{ value: string; label?: string }>;\n /** Offered operators, first one default. Equality alone if omitted. */\n operators?: DataTableFilterOperator[];\n}\n\nexport interface DataTableFilter {\n operator: DataTableFilterOperator;\n /** Empty for `empty`/`nempty`; one entry for a comparison; several for a set. */\n values: string[];\n}\n\nexport interface DataTableSort {\n key: string;\n direction: 'asc' | 'desc';\n}\n\nexport interface DataTableState {\n search: string;\n sort: DataTableSort | null;\n /** Faceted filters, by facet key. An absent key means \"no constraint\". */\n filters: Record<string, DataTableFilter>;\n hidden: string[];\n selected: string[];\n}\n\nexport interface DataTablePagination {\n hasNext: boolean;\n hasPrevious: boolean;\n onNext: () => void;\n onPrevious: () => void;\n}\n\nexport interface DataTableProps<Row> {\n columns: Array<DataTableColumn<Row>>;\n rows: Row[];\n rowId: (row: Row) => string;\n /** Controlled state. Anything left out falls back to `defaultState`. */\n state?: Partial<DataTableState>;\n defaultState?: Partial<DataTableState>;\n onStateChange?: (state: DataTableState) => void;\n facets?: DataTableFacet[];\n searchPlaceholder?: string;\n selectable?: boolean;\n onRowClick?: (row: Row) => void;\n pagination?: DataTablePagination;\n /** Server does the sorting, filtering and searching; render `rows` as given. */\n manual?: boolean;\n loading?: boolean;\n error?: React.ReactNode;\n empty?: React.ReactNode;\n /** Beyond this many rows the body is virtualised. */\n virtualizeFrom?: number;\n className?: string;\n}\n\nconst EMPTY_STATE: DataTableState = {\n search: '',\n sort: null,\n filters: {},\n hidden: [],\n selected: [],\n};\n\n/** Narrower than this and a column has no room for its own label. */\nconst MIN_COLUMN_WIDTH_PX = 64;\n\n/** Virtualising a short list costs more than it saves. */\nconst DEFAULT_VIRTUALIZE_FROM = 100;\nconst ROW_HEIGHT_PX = 53;\nconst VIRTUAL_VIEWPORT_PX = 640;\n\nfunction useDataTableState(\n controlled: Partial<DataTableState> | undefined,\n initial: Partial<DataTableState> | undefined,\n onStateChange: ((state: DataTableState) => void) | undefined,\n): [DataTableState, (patch: Partial<DataTableState>) => void] {\n const [internal, setInternal] = React.useState<DataTableState>({ ...EMPTY_STATE, ...initial });\n const state = React.useMemo<DataTableState>(\n () => ({ ...EMPTY_STATE, ...initial, ...internal, ...controlled }),\n [controlled, initial, internal],\n );\n\n const patch = (next: Partial<DataTableState>) => {\n const merged = { ...state, ...next };\n setInternal(merged);\n onStateChange?.(merged);\n };\n\n return [state, patch];\n}\n\nexport function DataTable<Row>({\n columns,\n rows,\n rowId,\n state: controlled,\n defaultState,\n onStateChange,\n facets = [],\n searchPlaceholder = 'Rechercher…',\n selectable = false,\n onRowClick,\n pagination,\n manual = false,\n loading = false,\n error,\n empty = 'Aucun résultat.',\n virtualizeFrom = DEFAULT_VIRTUALIZE_FROM,\n className,\n}: DataTableProps<Row>) {\n const [state, patch] = useDataTableState(controlled, defaultState, onStateChange);\n // Column widths are a per-session comfort, not part of the reported state:\n // nobody wants their colleague's column widths in a shared link.\n const [widths, setWidths] = React.useState<Record<string, number>>({});\n const hidden = React.useMemo(() => new Set(state.hidden), [state.hidden]);\n const selected = React.useMemo(() => new Set(state.selected), [state.selected]);\n\n const visibleColumns = React.useMemo(\n () => columns.filter((column) => !hidden.has(column.key)),\n [columns, hidden],\n );\n\n const columnDefs = React.useMemo<Array<ColumnDef<Row>>>(\n () =>\n visibleColumns.map((column) => ({\n id: column.key,\n accessorFn: (row: Row) =>\n column.value ? column.value(row) : (row as Record<string, unknown>)[column.key],\n enableSorting: column.sortable ?? false,\n size: column.width,\n cell: ({ row }) =>\n column.cell\n ? column.cell(row.original)\n : String((row.original as Record<string, unknown>)[column.key] ?? ''),\n })),\n [visibleColumns],\n );\n\n const sorting = React.useMemo<SortingState>(\n () => (state.sort ? [{ id: state.sort.key, desc: state.sort.direction === 'desc' }] : []),\n [state.sort],\n );\n\n const table = useReactTable<Row>({\n data: rows,\n columns: columnDefs,\n state: { sorting, globalFilter: manual ? '' : state.search },\n getRowId: (row) => rowId(row),\n getCoreRowModel: getCoreRowModel(),\n ...(manual\n ? { manualSorting: true, manualFiltering: true }\n : { getSortedRowModel: getSortedRowModel(), getFilteredRowModel: getFilteredRowModel() }),\n });\n\n // Faceted selections narrow the rows the same way in both modes when the host\n // is not doing it: a facet the server does not know about must still work.\n const facetedRows = React.useMemo(() => {\n const active = Object.entries(state.filters).filter(([, filter]) => isApplied(filter));\n if (manual || active.length === 0) return table.getRowModel().rows;\n return table.getRowModel().rows.filter((row) =>\n active.every(([key, filter]) => {\n const column = columns.find((c) => c.key === key);\n const raw = column?.value\n ? column.value(row.original)\n : (row.original as Record<string, unknown>)[key];\n return matches(raw, filter);\n }),\n );\n }, [columns, manual, state.filters, table.getRowModel().rows]);\n\n const bodyRef = React.useRef<HTMLDivElement>(null);\n const longEnoughToVirtualise = facetedRows.length > virtualizeFrom;\n const virtualizer = useVirtualizer({\n count: facetedRows.length,\n getScrollElement: () => bodyRef.current,\n estimateSize: () => ROW_HEIGHT_PX,\n overscan: 8,\n enabled: longEnoughToVirtualise,\n });\n const virtualItems = virtualizer.getVirtualItems();\n // An unmeasured scroll container yields no items. Rendering the whole list is\n // slow; rendering nothing is a blank table, so the slow one wins.\n const virtualise = longEnoughToVirtualise && virtualItems.length > 0;\n\n const toggleSort = (key: string) => {\n const next: DataTableSort | null =\n state.sort?.key !== key\n ? { key, direction: 'asc' }\n : state.sort.direction === 'asc'\n ? { key, direction: 'desc' }\n : null;\n patch({ sort: next });\n };\n\n const toggleSelected = (id: string) => {\n const next = new Set(selected);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n patch({ selected: [...next] });\n };\n\n const allVisibleSelected =\n facetedRows.length > 0 && facetedRows.every((row) => selected.has(row.id));\n\n const toggleAll = () => {\n patch({ selected: allVisibleSelected ? [] : facetedRows.map((row) => row.id) });\n };\n\n const setFilter = (facetKey: string, filter: DataTableFilter | null) => {\n const next = { ...state.filters };\n if (filter) next[facetKey] = filter;\n else delete next[facetKey];\n patch({ filters: next });\n };\n\n const renderedRows = virtualise\n ? virtualItems.map((item) => facetedRows[item.index]!)\n : facetedRows;\n // Spacer rows stand in for what is not rendered, above and below, so the\n // scrollbar reports the height of the whole list rather than of the window.\n const spaceAbove = virtualise ? (virtualItems[0]?.start ?? 0) : 0;\n const spaceBelow = virtualise\n ? virtualizer.getTotalSize() - (virtualItems[virtualItems.length - 1]?.end ?? 0)\n : 0;\n\n const columnCount = visibleColumns.length + (selectable ? 1 : 0);\n\n return (\n <div className={cn('flex flex-col gap-3', className)}>\n <div className=\"flex flex-wrap items-center gap-2\">\n <Input\n value={state.search}\n onChange={(event) => patch({ search: event.target.value })}\n placeholder={searchPlaceholder}\n aria-label={searchPlaceholder}\n className=\"h-9 max-w-xs\"\n />\n\n {facets.map((facet) => (\n <FacetFilter\n key={facet.key}\n facet={facet}\n filter={state.filters[facet.key]}\n onChange={(filter) => setFilter(facet.key, filter)}\n />\n ))}\n\n <ColumnPicker\n columns={columns}\n hidden={hidden}\n onToggle={(key) =>\n patch({\n hidden: hidden.has(key)\n ? state.hidden.filter((k) => k !== key)\n : [...state.hidden, key],\n })\n }\n />\n\n {selectable && selected.size > 0 && (\n <span className=\"text-xs text-muted-foreground\" role=\"status\">\n {selected.size} sélectionné{selected.size > 1 ? 's' : ''}\n </span>\n )}\n </div>\n\n <div\n ref={bodyRef}\n className={cn('overflow-auto rounded-xl border bg-card', virtualise && 'max-h-160')}\n style={virtualise ? { maxHeight: VIRTUAL_VIEWPORT_PX } : undefined}\n >\n <Table>\n <TableHeader className={virtualise ? 'sticky top-0 z-10 bg-card' : undefined}>\n <TableRow>\n {selectable && (\n <TableHead className=\"w-10\">\n <Checkbox\n checked={allVisibleSelected}\n onCheckedChange={toggleAll}\n aria-label=\"Tout sélectionner\"\n />\n </TableHead>\n )}\n {visibleColumns.map((column) => {\n const label = typeof column.header === 'string' ? column.header : column.key;\n return (\n <TableHead\n key={column.key}\n style={{ width: widths[column.key] ?? column.width }}\n className={cn('relative', column.align === 'right' && 'text-right')}\n // Only a column that can be sorted may claim a direction: the\n // state can name a key this table refuses to order by, and\n // announcing a sort that is not happening is worse than silence.\n aria-sort={\n !column.sortable\n ? undefined\n : state.sort?.key === column.key\n ? state.sort.direction === 'asc'\n ? 'ascending'\n : 'descending'\n : 'none'\n }\n >\n {column.sortable ? (\n <button\n type=\"button\"\n onClick={() => toggleSort(column.key)}\n className=\"inline-flex cursor-pointer items-center gap-1 hover:text-foreground\"\n >\n {column.header}\n <SortGlyph\n direction={state.sort?.key === column.key ? state.sort.direction : null}\n />\n </button>\n ) : (\n column.header\n )}\n <ResizeHandle\n label={label}\n onResize={(delta, from) =>\n setWidths((current) => ({\n ...current,\n [column.key]: Math.max(MIN_COLUMN_WIDTH_PX, from + delta),\n }))\n }\n />\n </TableHead>\n );\n })}\n </TableRow>\n </TableHeader>\n\n <TableBody>\n {error ? (\n <StatusRow colSpan={columnCount} tone=\"error\">\n {error}\n </StatusRow>\n ) : loading ? (\n <SkeletonRows columns={columnCount} />\n ) : facetedRows.length === 0 ? (\n <StatusRow colSpan={columnCount}>{empty}</StatusRow>\n ) : (\n <>\n {spaceAbove > 0 && <tr aria-hidden style={{ height: spaceAbove }} />}\n {renderedRows.map((row) => (\n <TableRow\n key={row.id}\n data-state={selected.has(row.id) ? 'selected' : undefined}\n className={\n onRowClick\n ? 'cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset'\n : 'hover:bg-transparent'\n }\n // A clickable row is a control: without these it can only be\n // reached with a mouse. The row keeps its implicit `row`\n // role (a `role=\"button\"` <tr> would break the table's own\n // structure for a screen reader); `tabIndex` + Enter/Space\n // are what make it operable.\n tabIndex={onRowClick ? 0 : undefined}\n onClick={onRowClick ? () => onRowClick(row.original) : undefined}\n onKeyDown={\n onRowClick\n ? (event) => {\n // Only the row's own keystrokes: Space on the\n // selection checkbox must tick the box, not open\n // the row behind it.\n if (event.target !== event.currentTarget) return;\n if (event.key !== 'Enter' && event.key !== ' ') return;\n event.preventDefault();\n onRowClick(row.original);\n }\n : undefined\n }\n >\n {selectable && (\n <TableCell onClick={(event) => event.stopPropagation()}>\n <Checkbox\n checked={selected.has(row.id)}\n onCheckedChange={() => toggleSelected(row.id)}\n aria-label={`Sélectionner ${row.id}`}\n />\n </TableCell>\n )}\n {row.getVisibleCells().map((cell) => {\n const column = visibleColumns.find((c) => c.key === cell.column.id);\n return (\n <TableCell\n key={cell.id}\n className={column?.align === 'right' ? 'text-right' : undefined}\n >\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </TableCell>\n );\n })}\n </TableRow>\n ))}\n {spaceBelow > 0 && <tr aria-hidden style={{ height: spaceBelow }} />}\n </>\n )}\n </TableBody>\n </Table>\n </div>\n\n {pagination && (\n <div className=\"flex items-center justify-end gap-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={!pagination.hasPrevious}\n onClick={pagination.onPrevious}\n >\n Précédent\n </Button>\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={!pagination.hasNext}\n onClick={pagination.onNext}\n >\n Suivant\n </Button>\n </div>\n )}\n </div>\n );\n}\n\n/**\n * Drag the boundary to widen a column.\n *\n * Deliberately out of the accessibility tree. A labelled widget inside a `<th>`\n * joins that header's accessible name — the column would announce as \"Nom\n * Redimensionner Nom\", and `getByLabelText('Nom')` would become ambiguous across\n * the page. Column width is cosmetic and duplicates no function, so hiding the\n * grip costs a keyboard user nothing; hiding a column, which does change what\n * they can read, stays fully keyboard-operable in the picker.\n */\nfunction ResizeHandle({\n label,\n onResize,\n}: {\n label: string;\n onResize: (delta: number, from: number) => void;\n}) {\n const start = (event: React.PointerEvent<HTMLElement>) => {\n const header = event.currentTarget.parentElement;\n if (!header) return;\n const from = header.getBoundingClientRect().width;\n const originX = event.clientX;\n const move = (moveEvent: PointerEvent) => onResize(moveEvent.clientX - originX, from);\n const stop = () => {\n window.removeEventListener('pointermove', move);\n window.removeEventListener('pointerup', stop);\n };\n window.addEventListener('pointermove', move);\n window.addEventListener('pointerup', stop);\n event.preventDefault();\n };\n\n return (\n <span\n aria-hidden\n data-resize-handle={label}\n onPointerDown={start}\n className=\"absolute inset-y-0 right-0 w-1 cursor-col-resize select-none hover:bg-border\"\n />\n );\n}\n\nfunction SortGlyph({ direction }: { direction: 'asc' | 'desc' | null }) {\n return (\n <span aria-hidden className=\"text-[10px] leading-none\">\n {direction === 'asc' ? '▲' : direction === 'desc' ? '▼' : '↕'}\n </span>\n );\n}\n\nfunction StatusRow({\n colSpan,\n tone,\n children,\n}: {\n colSpan: number;\n tone?: 'error';\n children: React.ReactNode;\n}) {\n return (\n <TableRow className=\"hover:bg-transparent\">\n <TableCell\n colSpan={colSpan}\n className={cn(\n 'text-sm',\n tone === 'error' ? 'text-status-blocked' : 'text-muted-foreground',\n )}\n >\n {children}\n </TableCell>\n </TableRow>\n );\n}\n\n/** Grey bars rather than a spinner: the table keeps its shape while it loads. */\nfunction SkeletonRows({ columns }: { columns: number }) {\n return (\n <>\n {Array.from({ length: 5 }, (_, row) => (\n <TableRow key={row} className=\"hover:bg-transparent\">\n {Array.from({ length: columns }, (_, cell) => (\n <TableCell key={cell}>\n <span className=\"block h-3 w-full animate-pulse rounded bg-muted\" />\n </TableCell>\n ))}\n </TableRow>\n ))}\n </>\n );\n}\n\n/** Operators that need no value at all, and those that take exactly one. */\nconst VALUELESS: ReadonlySet<DataTableFilterOperator> = new Set(['empty', 'nempty']);\nconst SINGLE_VALUE: ReadonlySet<DataTableFilterOperator> = new Set([\n 'contains',\n 'ncontains',\n 'gt',\n 'lt',\n 'gte',\n 'lte',\n]);\n\nconst OPERATOR_LABELS: Record<DataTableFilterOperator, string> = {\n eq: 'est',\n neq: \"n'est pas\",\n contains: 'contient',\n ncontains: 'ne contient pas',\n gt: 'supérieur à',\n lt: 'inférieur à',\n gte: 'supérieur ou égal à',\n lte: 'inférieur ou égal à',\n empty: 'est vide',\n nempty: \"n'est pas vide\",\n};\n\n/** A filter with no value to compare against does nothing — except the two that need none. */\nfunction isApplied(filter: DataTableFilter | undefined): filter is DataTableFilter {\n if (!filter) return false;\n return VALUELESS.has(filter.operator) || filter.values.length > 0;\n}\n\n/**\n * Orders two values, or reports that they cannot be ordered.\n *\n * The mode is decided by the bound, not per row: deciding per row makes one\n * filter compare some rows as numbers and others as text, which is how \"montant\n * ≥ 20\" silently keeps a row reading \"n/a\". An empty value orders against\n * nothing — `Number('')` is 0, and a blank cell is not \"zero\".\n */\nfunction compare(value: string, bound: string): number | null {\n if (value === '' || bound === '') return null;\n\n const boundNumber = Number(bound);\n if (!Number.isNaN(boundNumber)) {\n const valueNumber = Number(value);\n return Number.isNaN(valueNumber) ? null : valueNumber - boundNumber;\n }\n\n const boundDate = Date.parse(bound);\n if (!Number.isNaN(boundDate)) {\n const valueDate = Date.parse(value);\n return Number.isNaN(valueDate) ? null : valueDate - boundDate;\n }\n\n return value < bound ? -1 : value > bound ? 1 : 0;\n}\n\nfunction matches(raw: unknown, filter: DataTableFilter): boolean {\n const value = raw == null ? '' : String(raw);\n const [bound = ''] = filter.values;\n const ordering = compare(value, bound);\n\n switch (filter.operator) {\n case 'eq':\n return filter.values.includes(value);\n case 'neq':\n return !filter.values.includes(value);\n case 'contains':\n return value.toLowerCase().includes(bound.toLowerCase());\n case 'ncontains':\n return !value.toLowerCase().includes(bound.toLowerCase());\n case 'gt':\n return ordering !== null && ordering > 0;\n case 'lt':\n return ordering !== null && ordering < 0;\n case 'gte':\n return ordering !== null && ordering >= 0;\n case 'lte':\n return ordering !== null && ordering <= 0;\n case 'empty':\n return value === '';\n case 'nempty':\n return value !== '';\n }\n}\n\n/**\n * One facet: an operator, then whatever that operator needs.\n *\n * The operator picker only appears when there is a choice to make — a facet that\n * offers equality alone stays the plain checkbox list it was.\n */\nfunction FacetFilter({\n facet,\n filter,\n onChange,\n}: {\n facet: DataTableFacet;\n filter: DataTableFilter | undefined;\n onChange: (filter: DataTableFilter | null) => void;\n}) {\n const [open, setOpen] = React.useState(false);\n const operators = facet.operators ?? ['eq'];\n const operator = filter?.operator ?? operators[0] ?? 'eq';\n const values = filter?.values ?? [];\n\n const summary = !isApplied(filter)\n ? facet.label\n : VALUELESS.has(operator)\n ? `${facet.label} · ${OPERATOR_LABELS[operator]}`\n : `${facet.label} · ${values.length}`;\n\n const setOperator = (next: DataTableFilterOperator) => {\n // Values only survive between operators that take the same kind of value. A\n // typed bound carried into `est` becomes a selection that matches nothing and\n // that no checkbox shows as ticked — an active filter the user cannot untick.\n const sameKind = SINGLE_VALUE.has(next) === SINGLE_VALUE.has(operator);\n onChange({\n operator: next,\n values:\n VALUELESS.has(next) || !sameKind\n ? []\n : SINGLE_VALUE.has(next)\n ? values.slice(0, 1)\n : values,\n });\n };\n\n return (\n <Popover\n open={open}\n onOpenChange={setOpen}\n trigger={\n // Named for what it does: a chip reading just \"Nom\" tells a screen-reader\n // user nothing, and collides with the sortable column header of that name.\n <Button variant=\"outline\" size=\"sm\" aria-label={`Filtrer par ${summary}`}>\n {summary}\n </Button>\n }\n >\n <div className=\"flex w-56 flex-col gap-2\">\n {operators.length > 1 && (\n <Select\n value={operator}\n aria-label={`Opérateur — ${facet.label}`}\n onValueChange={(next) => setOperator(next as DataTableFilterOperator)}\n items={operators.map((candidate) => ({\n value: candidate,\n label: OPERATOR_LABELS[candidate],\n }))}\n />\n )}\n\n {VALUELESS.has(operator) ? null : SINGLE_VALUE.has(operator) || !facet.options ? (\n <Input\n value={values[0] ?? ''}\n aria-label={`Valeur — ${facet.label}`}\n onChange={(event) =>\n onChange({ operator, values: event.target.value ? [event.target.value] : [] })\n }\n />\n ) : (\n facet.options.map((option) => (\n <Checkbox\n key={option.value}\n checked={values.includes(option.value)}\n onCheckedChange={() =>\n onChange({\n operator,\n values: values.includes(option.value)\n ? values.filter((v) => v !== option.value)\n : [...values, option.value],\n })\n }\n label={option.label ?? option.value}\n />\n ))\n )}\n\n {isApplied(filter) && (\n <Button variant=\"ghost\" size=\"sm\" onClick={() => onChange(null)}>\n Effacer\n </Button>\n )}\n </div>\n </Popover>\n );\n}\n\nfunction ColumnPicker<Row>({\n columns,\n hidden,\n onToggle,\n}: {\n columns: Array<DataTableColumn<Row>>;\n hidden: Set<string>;\n onToggle: (key: string) => void;\n}) {\n const [open, setOpen] = React.useState(false);\n return (\n <Popover\n open={open}\n onOpenChange={setOpen}\n align=\"end\"\n trigger={\n <Button variant=\"outline\" size=\"sm\">\n Colonnes\n </Button>\n }\n >\n <div className=\"flex flex-col gap-1\">\n {columns.map((column) => (\n <Checkbox\n key={column.key}\n checked={!hidden.has(column.key)}\n onCheckedChange={() => onToggle(column.key)}\n label={typeof column.header === 'string' ? column.header : column.key}\n />\n ))}\n </div>\n </Popover>\n );\n}\n","/**\n * The period a dashboard is looking at, and the window it compares against.\n *\n * Days are local-calendar `YYYY-MM-DD` — the same shape `DateRange` already\n * speaks, and the one a date input and DayPicker both understand. Turning a day\n * into an instant is the caller's business: only it knows whether its filter\n * wants an inclusive end-of-day or an exclusive next-midnight.\n *\n * Every resolution takes the reference day as an argument. Reading the clock is\n * left to the edge (a handler, an effect) so the maths stays a pure function of\n * its inputs, and a test does not have to freeze time to be deterministic.\n */\nimport {\n differenceInCalendarDays,\n endOfMonth,\n format,\n parse,\n startOfMonth,\n startOfQuarter,\n startOfYear,\n subDays,\n subMonths,\n subYears,\n} from 'date-fns';\n\nexport type PeriodPresetKey =\n | 'today'\n | 'yesterday'\n | 'last7'\n | 'last30'\n | 'last90'\n | 'thisMonth'\n | 'lastMonth'\n | 'thisQuarter'\n | 'last12Months'\n | 'thisYear'\n | 'all'\n | 'custom';\n\nexport interface PeriodRange {\n /**\n * Absent means unbounded — only the `all` preset produces it. The spec's\n * `PeriodValue` sketch types `from` as required, which cannot express the\n * \"all time\" entry its own preset rail asks for; a filter with no lower bound\n * is a different query, so the type says so rather than encoding it as a\n * sentinel date the caller would have to recognise.\n */\n from?: string;\n to: string;\n}\n\nexport type PeriodCompareMode = 'none' | 'previous_period' | 'previous_year' | 'custom';\n\nexport interface PeriodValue {\n preset: PeriodPresetKey;\n range: PeriodRange;\n compare: PeriodCompareMode;\n /** The window `compare` resolves to. Absent when comparing to nothing. */\n compareRange?: PeriodRange;\n}\n\nexport interface PeriodPreset {\n key: PeriodPresetKey;\n label: string;\n}\n\n/** The rail, in the order it is offered. `custom` is reached by picking days. */\nexport const PERIOD_PRESETS: readonly PeriodPreset[] = [\n { key: 'today', label: \"Aujourd'hui\" },\n { key: 'yesterday', label: 'Hier' },\n { key: 'last7', label: '7 derniers jours' },\n { key: 'last30', label: '30 derniers jours' },\n { key: 'last90', label: '90 derniers jours' },\n { key: 'thisMonth', label: 'Mois en cours' },\n { key: 'lastMonth', label: 'Mois dernier' },\n { key: 'thisQuarter', label: 'Trimestre en cours' },\n { key: 'last12Months', label: '12 derniers mois' },\n { key: 'thisYear', label: 'Année en cours' },\n { key: 'all', label: \"Tout l'historique\" },\n];\n\nexport const COMPARE_LABELS: Record<PeriodCompareMode, string> = {\n none: 'Ne pas comparer',\n previous_period: 'Période précédente',\n previous_year: 'Année précédente',\n custom: 'Période personnalisée',\n};\n\n/**\n * The comparison as the trigger says it, next to a range that already takes the\n * width. `COMPARE_LABELS` is what the panel offers; this is what a button can\n * afford to show.\n */\nexport const COMPARE_SHORT_LABELS: Record<PeriodCompareMode, string> = {\n none: '',\n previous_period: 'période préc.',\n previous_year: 'N-1',\n custom: 'période choisie',\n};\n\nconst DAY_FORMAT = 'yyyy-MM-dd';\n\n/** A Date as a local `YYYY-MM-DD`. */\nexport const toDay = (date: Date): string => format(date, DAY_FORMAT);\n\n/** A local `YYYY-MM-DD` back to a Date at local midnight. */\nexport const fromDay = (day: string): Date => parse(day, DAY_FORMAT, new Date());\n\n/**\n * The day bounds of a preset, relative to `today`.\n *\n * No preset ever reaches into the future: \"this month\" is the month so far, not\n * the whole month. Two things depend on it. Nobody has data for tomorrow, so a\n * period that included it would put an empty tail on every axis; and the picker\n * refuses to let a future day be clicked, so a preset landing there would offer\n * a range the calendar itself would not let anyone build.\n *\n * These are business rules, not implementation: two screens that both say \"30\n * derniers jours\" have to mean the same thirty days. The rolling windows include\n * today — seven days is J−6 to J, not J−7.\n */\nfunction presetRange(preset: PeriodPresetKey, today: Date): PeriodRange {\n const day = toDay(today);\n switch (preset) {\n case 'today':\n return { from: day, to: day };\n case 'yesterday': {\n const yesterday = toDay(subDays(today, 1));\n return { from: yesterday, to: yesterday };\n }\n case 'last7':\n return { from: toDay(subDays(today, 6)), to: day };\n case 'last30':\n return { from: toDay(subDays(today, 29)), to: day };\n case 'last90':\n return { from: toDay(subDays(today, 89)), to: day };\n case 'thisMonth':\n return { from: toDay(startOfMonth(today)), to: day };\n case 'lastMonth': {\n // The one calendar preset that is whole, because it is entirely behind us.\n const previous = subMonths(today, 1);\n return { from: toDay(startOfMonth(previous)), to: toDay(endOfMonth(previous)) };\n }\n case 'thisQuarter':\n return { from: toDay(startOfQuarter(today)), to: day };\n case 'last12Months':\n // The same day of the month, twelve months back. `subMonths` clamps a 31st\n // onto a short month rather than spilling into the next one.\n return { from: toDay(subMonths(today, 12)), to: day };\n case 'thisYear':\n return { from: toDay(startOfYear(today)), to: day };\n case 'all':\n return { to: day };\n case 'custom':\n return { from: day, to: day };\n }\n}\n\n/**\n * The window a comparison mode resolves to, or undefined when there is nothing\n * to compare against — `none`, an unbounded period, or `custom`, whose range the\n * user picks and which therefore cannot be derived.\n */\nexport function comparisonRange(\n // Unread since the calendar presets stopped being a special case, and kept\n // because dropping it from a published signature breaks every caller for no\n // gain — a future mode that needs the preset would want it back.\n preset: PeriodPresetKey,\n range: PeriodRange,\n compare: PeriodCompareMode,\n): PeriodRange | undefined {\n if (compare === 'none' || compare === 'custom' || range.from === undefined) return undefined;\n\n const from = fromDay(range.from);\n const to = fromDay(range.to);\n\n if (compare === 'previous_year') {\n // The year shifts, not 365 days: June 2026 compares to June 2025 whatever\n // the months in between are worth. A day count would slide the comparison a\n // day or two a year and destroy the season-to-season comparability that is\n // the whole point of the mode. A 29 February lands on the 28th.\n return { from: toDay(subYears(from, 1)), to: toDay(subYears(to, 1)) };\n }\n\n // One formula, every preset: the same number of days, ending the day before\n // this period starts. A calendar preset gets no special case — \"mois en cours\"\n // is the month so far, so the fifteen days before it are the honest\n // comparison, not the thirty-one of a whole previous month.\n const length = differenceInCalendarDays(to, from) + 1;\n return { from: toDay(subDays(from, length)), to: toDay(subDays(to, length)) };\n}\n\n/** A period with its comparison window resolved — the only way to build one. */\nexport function makePeriod(\n preset: PeriodPresetKey,\n range: PeriodRange,\n compare: PeriodCompareMode,\n customCompareRange?: PeriodRange,\n): PeriodValue {\n const resolved =\n compare === 'custom' ? customCompareRange : comparisonRange(preset, range, compare);\n // An unbounded period has no window to shift, so the mode it advertises has to\n // fall back to the truth rather than claim a comparison that produced nothing.\n const effective: PeriodCompareMode = resolved === undefined ? 'none' : compare;\n return {\n preset,\n range,\n compare: effective,\n ...(resolved ? { compareRange: resolved } : {}),\n };\n}\n\n/** The period a preset resolves to, relative to `today`. */\nexport function periodFromPreset(\n preset: PeriodPresetKey,\n today: Date,\n compare: PeriodCompareMode = 'none',\n): PeriodValue {\n return makePeriod(preset, presetRange(preset, today), compare);\n}\n\nconst MONTHS_ABBR = [\n 'janv.',\n 'févr.',\n 'mars',\n 'avr.',\n 'mai',\n 'juin',\n 'juil.',\n 'août',\n 'sept.',\n 'oct.',\n 'nov.',\n 'déc.',\n];\n\nconst formatDay = (day: string): string => {\n const date = fromDay(day);\n return `${date.getDate()} ${MONTHS_ABBR[date.getMonth()]} ${date.getFullYear()}`;\n};\n\n/** A range as a person reads it, collapsing the parts both ends share. */\nexport function formatRange(range: PeriodRange): string {\n if (range.from === undefined) return `Jusqu'au ${formatDay(range.to)}`;\n if (range.from === range.to) return formatDay(range.from);\n\n const from = fromDay(range.from);\n const to = fromDay(range.to);\n if (from.getFullYear() === to.getFullYear() && from.getMonth() === to.getMonth()) {\n return `${from.getDate()} – ${to.getDate()} ${MONTHS_ABBR[to.getMonth()]} ${to.getFullYear()}`;\n }\n return `${formatDay(range.from)} – ${formatDay(range.to)}`;\n}\n\n/**\n * What the trigger shows: the preset's name, or the days a custom range spans.\n *\n * A range can arrive incomplete — the picker it replaced accepted `{from: '',\n * to: ''}` as \"nothing chosen yet\" — and formatting one would print an Invalid\n * Date rather than say there is nothing to show.\n */\nexport function formatPeriod(value: PeriodValue): string {\n const preset = PERIOD_PRESETS.find((entry) => entry.key === value.preset);\n if (preset) return preset.label;\n return isCompleteRange(value.range) ? formatRange(value.range) : 'Période';\n}\n\nconst DAY_PATTERN = /^\\d{4}-\\d{2}-\\d{2}$/;\n\n/** Whether a string is a day this module can do arithmetic on. */\nexport const isDay = (value: string | undefined): value is string =>\n value !== undefined && DAY_PATTERN.test(value);\n\n/** Whether a range has the ends it needs. Only `all` is allowed to lack a start. */\nexport function isCompleteRange(range: PeriodRange): boolean {\n return isDay(range.to) && (range.from === undefined || isDay(range.from));\n}\n\n/**\n * Whether the calendar needs two months to show a range whole.\n *\n * Any range whose ends fall in different months, not just a long one: a five-day\n * range across the turn of a month is still a range with an end the user cannot\n * see, which is the thing a second month is there to fix.\n */\nexport function spansTwoMonths(range: PeriodRange): boolean {\n if (!isDay(range.from) || !isDay(range.to)) return false;\n const from = fromDay(range.from);\n const to = fromDay(range.to);\n return from.getFullYear() !== to.getFullYear() || from.getMonth() !== to.getMonth();\n}\n\n/** Puts a pair of days in order, so an inverted range never leaves the picker. */\nexport function orderedRange(from: string, to: string): PeriodRange {\n return from <= to ? { from, to } : { from: to, to: from };\n}\n","/**\n * The period control: a preset rail, a calendar, and the window to compare with.\n *\n * Controlled, and applied on an explicit press — except that a rail without a\n * comparison to settle afterwards applies straight away, because that is a click\n * and not a form. Every dashboard built on this refetches when the period\n * changes, so emitting a half-picked range — the state the calendar is in\n * between the two clicks that make a range — would fire a query for a period\n * nobody asked for.\n *\n * One grid, two ranges. Two pills above the calendar say which of them a click\n * is about to change, so the comparison is picked where it is read rather than\n * typed into a pair of date fields beside it.\n *\n * Routing is not this component's business: `PeriodValue` is plain data, so a\n * host that wants a shared link to carry the comparison stores it with whatever\n * router it already has (see the shell's `useTableUrlState` for the precedent).\n */\nimport { fr } from 'date-fns/locale/fr';\nimport * as React from 'react';\nimport { DayPicker, labelDayButton } from 'react-day-picker';\nimport { Button, Popover } from './components';\nimport { cn } from './cn';\nimport {\n COMPARE_LABELS,\n COMPARE_SHORT_LABELS,\n PERIOD_PRESETS,\n comparisonRange,\n formatPeriod,\n formatRange,\n fromDay,\n isDay,\n makePeriod,\n orderedRange,\n periodFromPreset,\n spansTwoMonths,\n toDay,\n type PeriodCompareMode,\n type PeriodPreset,\n type PeriodPresetKey,\n type PeriodRange,\n type PeriodValue,\n} from './period';\n\nexport interface DateRangeCompareProps {\n value: PeriodValue;\n onChange: (value: PeriodValue) => void;\n /** Offer the comparison section. */\n comparable?: boolean;\n /** Override the rail — a subset, or presets in another order. */\n presets?: readonly PeriodPreset[];\n /**\n * How many months the grid shows. `'auto'` widens to two whenever the range\n * straddles them. One by default: two doubles the panel's width, which a\n * dashboard header rarely has, and a range wider than the grid stays correctly\n * highlighted on the part that is visible.\n */\n months?: 1 | 2 | 'auto';\n align?: 'start' | 'end';\n disabled?: boolean;\n className?: string;\n}\n\nconst COMPARE_MODES: readonly PeriodCompareMode[] = [\n 'none',\n 'previous_period',\n 'previous_year',\n 'custom',\n];\n\n/** Where a click in the grid goes. */\ntype PeriodTarget = 'period' | 'compare';\n\n/**\n * DayPicker ships a stylesheet, which this deliberately does not import: the SDK\n * is styled by the shell's Tailwind build, and a second source of styles would\n * escape both the theme and the CSS invariant that proves the shell ships every\n * class the SDK renders. Only the keys that need to look like the design system\n * are named; the rest keep DayPicker's own inert class names.\n *\n * `selected` and `range_*` are among the ones left inert on purpose — see\n * `DAY_MODIFIER_CLASS_NAMES`, which paints both ranges by hand.\n */\nconst DAY_PICKER_CLASS_NAMES = {\n // DayPicker renders its Nav as a sibling of the months, before them, so the\n // arrows are positioned against this box rather than against a caption.\n months: 'relative flex gap-4',\n month: 'space-y-2',\n month_caption: 'flex h-8 items-center justify-center',\n caption_label: 'text-sm font-medium capitalize',\n nav: 'flex items-center justify-between absolute inset-x-0 h-8 px-1 pointer-events-none',\n button_previous:\n 'pointer-events-auto inline-flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground disabled:opacity-40',\n button_next:\n 'pointer-events-auto inline-flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground disabled:opacity-40',\n chevron: 'h-4 w-4 fill-current',\n month_grid: 'w-full border-collapse',\n weekdays: 'flex',\n weekday: 'w-9 text-xs font-normal text-muted-foreground',\n week: 'flex w-full',\n day: 'h-9 w-9 p-0 text-center text-sm',\n day_button:\n 'h-9 w-9 rounded-md transition-colors hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',\n today: 'font-semibold text-primary',\n outside: 'text-muted-foreground/50',\n disabled: 'opacity-40',\n // A cell DayPicker decided not to fill still occupies the grid, and still\n // matches the range modifiers below — without this it would show a stretch of\n // painted band with no number in it. `invisible`, not `hidden`: the six-week\n // grid keeps its height either way.\n hidden: 'invisible',\n};\n\n/**\n * Both ranges, painted by hand.\n *\n * DayPicker's own `range_*` classes follow its single selection, which follows\n * the target — so they cannot describe a grid showing two ranges at once, and\n * would repaint the comparison in the period's colours the moment the target\n * moved. Dropping them from `classNames` makes the grid's appearance independent\n * of where clicks are going.\n *\n * \"When the two ranges cross, the period wins the cell\" is not an ordering\n * question: DayPicker joins modifier class names in an order that means nothing\n * to Tailwind — which resolves conflicts by stylesheet order — and that is not\n * even stable, since the keys are built from whichever modifier the first\n * matching day of the grid happened to hit. The two sets are made disjoint\n * instead: the comparison is only ever drawn where the period is not.\n *\n * The other half is that a band paints the cell and a bound paints the button\n * inside it. Different elements, so the band's tint and the bound's fill never\n * race.\n *\n * The two are told apart by shape before colour — the period fills its bounds,\n * the comparison rings them — because the shell's dark theme sets `--chart-2` to\n * the same Jour as `--primary`, and a pair of ranges distinguished by hue alone\n * would collapse into one there. The tints are two steps apart for the same\n * reason: same hue, different weight, still two bands.\n */\nconst DAY_MODIFIER_CLASS_NAMES = {\n period_middle: 'bg-primary/15',\n period_start:\n 'rounded-l-md [&_button]:bg-primary [&_button]:text-primary-foreground [&_button]:hover:bg-primary',\n period_end:\n 'rounded-r-md [&_button]:bg-primary [&_button]:text-primary-foreground [&_button]:hover:bg-primary',\n compare_middle: 'bg-chart-2/30',\n compare_start:\n 'rounded-l-md bg-chart-2/30 [&_button]:ring-2 [&_button]:ring-inset [&_button]:ring-chart-2 [&_button]:font-semibold [&_button]:text-chart-2',\n compare_end:\n 'rounded-r-md bg-chart-2/30 [&_button]:ring-2 [&_button]:ring-inset [&_button]:ring-chart-2 [&_button]:font-semibold [&_button]:text-chart-2',\n};\n\n/** What the calendar is showing while the popover is open. */\ninterface Draft {\n preset: PeriodPresetKey;\n from?: string;\n to?: string;\n compare: PeriodCompareMode;\n compareFrom?: string;\n compareTo?: string;\n}\n\nfunction draftOf(value: PeriodValue): Draft {\n return {\n preset: value.preset,\n // Anything that is not a day is \"not chosen yet\". The picker this replaced\n // accepted `{ from: '', to: '' }` for exactly that, and its callers still do.\n from: isDay(value.range.from) ? value.range.from : undefined,\n to: isDay(value.range.to) ? value.range.to : undefined,\n compare: value.compare,\n compareFrom: value.compareRange?.from,\n compareTo: value.compareRange?.to,\n };\n}\n\n/**\n * The range the draft describes, once it has both ends. The `all` preset is the\n * one case with no start, which is why a missing `from` alone cannot mean\n * \"still picking\".\n */\nfunction rangeOf(draft: Draft): PeriodRange | null {\n if (!isDay(draft.to)) return null;\n if (draft.preset === 'all') return { to: draft.to };\n if (!isDay(draft.from)) return null;\n return { from: draft.from, to: draft.to };\n}\n\n/**\n * The comparison window the user picked by hand, in order. A pair of clicks can\n * land either way round, so it is sorted here rather than trusted.\n */\nfunction customCompareOf(draft: Draft): PeriodRange | undefined {\n if (!isDay(draft.compareFrom) || !isDay(draft.compareTo)) return undefined;\n return orderedRange(draft.compareFrom, draft.compareTo);\n}\n\n/** The window the footer previews — derived for the modes that derive one. */\nfunction previewCompare(draft: Draft): PeriodRange | undefined {\n const range = rangeOf(draft);\n if (!range) return undefined;\n if (draft.compare === 'custom') return customCompareOf(draft);\n return comparisonRange(draft.preset, range, draft.compare);\n}\n\n/**\n * The comparison the draft can actually express. An unbounded period has no\n * length to shift, so the section falls back to \"none\" without overwriting the\n * mode the user picked — going through \"tout l'historique\" on the way to another\n * preset must not silently drop their choice.\n */\nfunction activeCompare(draft: Draft): PeriodCompareMode {\n return draft.preset === 'all' ? 'none' : draft.compare;\n}\n\n/** A pair of days as a band the grid can paint. One clicked day is a one-day band. */\ninterface Band {\n from: Date;\n to: Date;\n}\n\n/**\n * A band from a half-picked pair. The first of two clicks has to leave a mark,\n * or the calendar looks broken between them.\n */\nfunction bandOf(from: string | undefined, to: string | undefined): Band | undefined {\n if (!isDay(from)) return undefined;\n const start = fromDay(from);\n return { from: start, to: isDay(to) ? fromDay(to) : start };\n}\n\n// `fromDay` always lands on local midnight, so plain comparison is exact here.\nconst inBand = (band: Band | undefined, date: Date): boolean =>\n band !== undefined && date >= band.from && date <= band.to;\n\nconst isBound = (date: Date, bound: Date | undefined): boolean =>\n bound !== undefined && date.getTime() === bound.getTime();\n\n/** The comparison as the grid shows it: the pair being picked, or the derived one. */\nfunction compareBandOf(draft: Draft): Band | undefined {\n const active = activeCompare(draft);\n if (active === 'none') return undefined;\n if (active === 'custom') return bandOf(draft.compareFrom, draft.compareTo);\n const derived = previewCompare(draft);\n return derived?.from ? { from: fromDay(derived.from), to: fromDay(derived.to) } : undefined;\n}\n\n/**\n * The month the grid should be showing for a range.\n *\n * Two months are a window onto the whole range, so they anchor on its start and\n * the end falls into the second grid. One month cannot show both ends, and the\n * end is the one that matters: someone reopening on \"mois en cours\" is asking\n * about the days they already have, not about the first of the month.\n *\n * The end is clamped to today because a caller may hand in a range that reaches\n * into the future, and anchoring there would open the panel on a grid where\n * every day is disabled. No preset does this — this guards the callers.\n */\nfunction anchorMonth(range: PeriodRange, visible: 1 | 2, today: Date): Date | undefined {\n const from = isDay(range.from) ? fromDay(range.from) : undefined;\n const to = isDay(range.to) ? fromDay(range.to) : undefined;\n if (visible === 2) return from ?? to;\n if (!to) return from;\n if (to <= today) return to;\n return from && from <= today ? today : (from ?? today);\n}\n\n/** DayPicker wants the open end as `undefined`, or it closes a one-day range. */\nfunction selectionOf(from: string | undefined, to: string | undefined) {\n if (!isDay(from)) return undefined;\n return { from: fromDay(from), to: isDay(to) ? fromDay(to) : undefined };\n}\n\nexport function DateRangeCompare({\n value,\n onChange,\n comparable = true,\n presets = PERIOD_PRESETS,\n months = 1,\n align = 'start',\n disabled,\n className,\n}: DateRangeCompareProps) {\n const [open, setOpen] = React.useState(false);\n const [draft, setDraft] = React.useState<Draft>(() => draftOf(value));\n // The calendar is driven, not merely initialised: DayPicker reads `defaultMonth`\n // once and then stays mounted, so a preset that lands in another month would\n // leave the grid where it was, showing none of the days it just selected.\n const [month, setMonth] = React.useState<Date | undefined>(undefined);\n // Only consulted in `'auto'`. Recomputed when the rail changes the range, never\n // while days are being clicked — a grid that grew a second month under the\n // cursor mid-selection would move every day the user was aiming at.\n const [autoMonths, setAutoMonths] = React.useState<1 | 2>(1);\n const [target, setTarget] = React.useState<PeriodTarget>('period');\n // Re-read when the panel opens, then held still: a fresh Date every render\n // re-matches every modifier for nothing, and a panel left open across midnight\n // would change its rules mid-gesture.\n const [today, setToday] = React.useState(() => new Date());\n\n const visibleMonths: 1 | 2 = months === 'auto' ? autoMonths : months;\n\n // The count is derived locally rather than read back from state, which is a\n // render behind while `showRange` is still running.\n const showRange = (range: PeriodRange, at: Date = today) => {\n const next: 1 | 2 = months === 'auto' ? (spansTwoMonths(range) ? 2 : 1) : months;\n setAutoMonths(next);\n setMonth(anchorMonth(range, next, at));\n };\n\n const openPanel = () => {\n const now = new Date();\n setToday(now);\n setDraft(draftOf(value));\n setTarget('period');\n showRange(value.range, now);\n setOpen(true);\n };\n\n const range = rangeOf(draft);\n const compareRange = previewCompare(draft);\n // Only a comparison picked by hand has anything for the grid to change, and a\n // stale 'compare' target would send a click into a window nothing displays.\n // Derived rather than an effect: no render ever shows the inconsistent pair.\n const compareEditable = comparable && activeCompare(draft) === 'custom';\n const activeTarget: PeriodTarget = compareEditable ? target : 'period';\n\n const periodBand = bandOf(draft.from, draft.to);\n const compareBand = compareBandOf(draft);\n\n /** Emits a draft as a period and closes. False when it has nothing to emit. */\n const emit = (candidate: Draft): boolean => {\n const complete = rangeOf(candidate);\n if (!complete) return false;\n onChange(\n makePeriod(candidate.preset, complete, activeCompare(candidate), customCompareOf(candidate)),\n );\n setOpen(false);\n return true;\n };\n\n const apply = () => emit(draft);\n\n const pickPreset = (preset: PeriodPresetKey, commit: boolean) => {\n const resolved = periodFromPreset(preset, today, activeCompare(draft));\n const next: Draft = {\n ...draftOf(resolved),\n // The rail changes the period, not the comparison: the mode the user chose\n // survives, and `activeCompare` decides whether it can apply here.\n compare: draft.compare,\n compareFrom: draft.compareFrom,\n compareTo: draft.compareTo,\n };\n setDraft(next);\n setTarget('period');\n showRange(resolved.range);\n // With no comparison to settle afterwards, a preset is a decision rather\n // than a draft — one click, not a form. As soon as a comparison is on offer\n // everything stays a draft, because settling it takes a second gesture and\n // applying in between would reload the screen on a state nobody asked for.\n if (!comparable && commit) emit(next);\n };\n\n const pickDays = (selected: { from?: Date; to?: Date } | undefined) => {\n const from = selected?.from ? toDay(selected.from) : undefined;\n const to = selected?.to ? toDay(selected.to) : undefined;\n if (activeTarget === 'compare') {\n // Picking days in the grid is what the custom mode is: writing the pair\n // without saying so would leave a draft whose mode contradicts its range.\n setDraft({ ...draft, compare: 'custom', compareFrom: from, compareTo: to });\n return;\n }\n // A click in the grid cancels the preset — the period becomes custom.\n setDraft({ ...draft, preset: 'custom', from, to });\n };\n\n const chooseCompare = (mode: PeriodCompareMode) => {\n const next: Draft = { ...draft, compare: mode };\n setDraft(next);\n // Asking for a custom window is asking to draw one, so the grid follows.\n setTarget(mode === 'custom' ? 'compare' : 'period');\n const shown = mode === 'custom' ? customCompareOf(next) : range;\n if (shown) showRange(shown);\n };\n\n const focusTarget = (next: PeriodTarget) => {\n setTarget(next);\n const shown = next === 'compare' ? customCompareOf(draft) : range;\n if (shown) showRange(shown);\n };\n\n const footer =\n activeTarget === 'compare'\n ? compareRange\n ? formatRange(compareRange)\n : 'Période de comparaison à choisir'\n : range\n ? `${formatRange(range)}${compareRange ? ` vs ${formatRange(compareRange)}` : ''}`\n : 'Date de fin à choisir';\n\n return (\n <Popover\n open={open}\n onOpenChange={(next) => (next ? openPanel() : setOpen(false))}\n align={align}\n className={cn('w-auto p-0', className)}\n trigger={\n <Button variant=\"outline\" disabled={disabled}>\n <IconCalendar className=\"size-4 text-muted-foreground\" />\n <span>{formatPeriod(value)}</span>\n {/* `makePeriod` reports `none` when a window fails to resolve, so this\n badge cannot claim a comparison that produced nothing. */}\n {value.compare !== 'none' && value.compareRange !== undefined && (\n <span className=\"rounded-md bg-chart-2/15 px-1.5 py-0.5 text-xs font-medium text-chart-2\">\n vs {COMPARE_SHORT_LABELS[value.compare]}\n </span>\n )}\n <IconChevronDown className=\"size-4 text-muted-foreground\" />\n </Button>\n }\n >\n {/* The rail sets the height when it is taller than the calendar, so eleven\n presets are all reachable without scrolling — hiding half of them\n behind a scrollbar to keep the panel calendar-sized costs more than the\n slack under the grid. The cap is what stops a caller with thirty\n presets from growing a panel past the viewport; past it the list\n scrolls and the \"Comparer\" block stays put at the bottom. */}\n <div className=\"flex max-h-[80vh] items-stretch\">\n {(presets.length > 0 || comparable) && (\n <div className=\"flex w-48 shrink-0 flex-col border-r\">\n {presets.length > 0 && (\n <PresetRail\n presets={presets}\n selected={draft.preset}\n onSelect={pickPreset}\n // `min-h-0` is what lets a flex child shrink below its content,\n // which is what makes `overflow-y-auto` do anything at all here.\n className=\"min-h-0 flex-1 overflow-y-auto p-2\"\n />\n )}\n {comparable && (\n <CompareSection\n draft={draft}\n compareRange={compareRange}\n onModeChange={chooseCompare}\n />\n )}\n </div>\n )}\n\n <div className=\"flex flex-col\">\n {comparable && (\n <TargetPills\n target={activeTarget}\n onSelect={focusTarget}\n compareEditable={compareEditable}\n />\n )}\n\n <div className=\"relative p-3\">\n <DayPicker\n mode=\"range\"\n // The rest of the SDK ships French labels; an English month caption\n // in the middle of them would be the only word a user has to\n // translate. `weekStartsOn` is restated so the grid does not change\n // shape if the locale ever does.\n locale={fr}\n weekStartsOn={1}\n numberOfMonths={visibleMonths}\n month={month}\n onMonthChange={setMonth}\n today={today}\n // Nobody has data for tomorrow. This blocks the click and nothing\n // else — a range reaching past today is still painted whole. Never\n // pair it with `excludeDisabled`, which resets any range holding a\n // disabled day.\n disabled={{ after: today }}\n // Always six weeks: without it the panel changes height between a\n // five-week month and a six-week one, and the footer's buttons jump\n // out from under the cursor.\n fixedWeeks\n // One grid gains from them: a range that starts in the previous\n // month still shows its opening edge. Two grids would render the\n // overlapping days twice, once as each month's neighbour, and the\n // second month already shows what the outside days were standing in\n // for.\n showOutsideDays={visibleMonths === 1}\n selected={\n activeTarget === 'compare'\n ? selectionOf(draft.compareFrom, draft.compareTo)\n : selectionOf(draft.from, draft.to)\n }\n onSelect={pickDays}\n modifiers={{\n period_middle: periodBand ? [{ from: periodBand.from, to: periodBand.to }] : [],\n period_start: periodBand ? [periodBand.from] : [],\n period_end: periodBand ? [periodBand.to] : [],\n // The period wins any cell both ranges claim.\n compare_middle: (date) => inBand(compareBand, date) && !inBand(periodBand, date),\n compare_start: (date) =>\n isBound(date, compareBand?.from) && !inBand(periodBand, date),\n compare_end: (date) => isBound(date, compareBand?.to) && !inBand(periodBand, date),\n }}\n modifiersClassNames={DAY_MODIFIER_CLASS_NAMES}\n classNames={DAY_PICKER_CLASS_NAMES}\n aria-label={\n activeTarget === 'compare'\n ? 'Calendrier — sélection de la comparaison'\n : 'Calendrier — sélection de la période'\n }\n labels={{\n // Suffixed rather than replaced: which range a click lands in is\n // the one thing a screen reader cannot get from the grid, and the\n // default label still carries the date and its state.\n labelDayButton: (date, modifiers, options, dateLib) =>\n `${labelDayButton(date, modifiers, options, dateLib)} — ${\n activeTarget === 'compare' ? 'comparaison' : 'période'\n }`,\n }}\n />\n </div>\n\n <div className=\"mt-auto flex items-center justify-between gap-4 border-t px-3 py-2\">\n {/* The only place that says what is being composed, so switching\n target re-announces the range that switch is about. */}\n <p role=\"status\" aria-live=\"polite\" className=\"text-xs text-muted-foreground\">\n {footer}\n </p>\n <div className=\"flex gap-2\">\n <Button variant=\"ghost\" size=\"sm\" onClick={() => setOpen(false)}>\n Annuler\n </Button>\n <Button size=\"sm\" onClick={apply} disabled={!range}>\n Appliquer\n </Button>\n </div>\n </div>\n </div>\n </div>\n </Popover>\n );\n}\n\n/** A day range with both ends — what the pre-contract-2 picker spoke. */\nexport interface DateRange {\n from: string;\n to: string;\n}\n\nexport interface DateRangePickerProps {\n value: DateRange;\n onChange: (range: DateRange) => void;\n className?: string;\n disabled?: boolean;\n}\n\n/**\n * The plain range picker, now a view of `DateRangeCompare` with the preset rail\n * and the comparison section it does not need.\n *\n * It stays because removing an export breaks the contract, and its signature is\n * unchanged: a caller that only ever wanted two days keeps passing two days.\n * `months` is pinned to the old behaviour for the same reason — one month is the\n * answer to a panel crowding a dashboard header, a problem a picker with no rail\n * does not have.\n */\nexport function DateRangePicker({ value, onChange, className, disabled }: DateRangePickerProps) {\n return (\n <DateRangeCompare\n value={{ preset: 'custom', range: value, compare: 'none' }}\n onChange={(next) => {\n if (next.range.from !== undefined) onChange({ from: next.range.from, to: next.range.to });\n }}\n comparable={false}\n presets={[]}\n months=\"auto\"\n disabled={disabled}\n className={className}\n />\n );\n}\n\n/**\n * Exactly one preset is chosen at a time, which is a radio group — not a listbox,\n * whose interaction model (arrow keys moving a virtual cursor) this does not\n * implement, and not a row of independent buttons either.\n *\n * One stop in the tab order for the whole rail, arrows to move within it: a\n * keyboard user tabbing past eleven presets to reach the calendar is the cost of\n * getting this wrong.\n */\nfunction PresetRail({\n presets,\n selected,\n onSelect,\n className,\n}: {\n presets: readonly PeriodPreset[];\n selected: PeriodPresetKey;\n /**\n * `commit` says the choice was made rather than merely moved through: an arrow\n * key walks the group, and must not be the gesture that closes the panel.\n */\n onSelect: (preset: PeriodPresetKey, commit: boolean) => void;\n className?: string;\n}) {\n const refs = React.useRef<Array<HTMLButtonElement | null>>([]);\n // Nothing is selected while the range is custom, so the first entry holds the\n // tab stop — the group still has to be reachable.\n const activeIndex = Math.max(\n 0,\n presets.findIndex((preset) => preset.key === selected),\n );\n\n const moveTo = (index: number) => {\n const next = (index + presets.length) % presets.length;\n refs.current[next]?.focus();\n onSelect(presets[next]!.key, false);\n };\n\n const onKeyDown = (event: React.KeyboardEvent, index: number) => {\n const step = { ArrowDown: 1, ArrowRight: 1, ArrowUp: -1, ArrowLeft: -1 }[event.key];\n if (step !== undefined) {\n event.preventDefault();\n moveTo(index + step);\n return;\n }\n if (event.key === 'Home' || event.key === 'End') {\n event.preventDefault();\n moveTo(event.key === 'Home' ? 0 : presets.length - 1);\n }\n };\n\n return (\n <div\n role=\"radiogroup\"\n aria-label=\"Période prédéfinie\"\n className={cn('flex flex-col gap-0.5', className)}\n >\n {presets.map((preset, index) => (\n <button\n key={preset.key}\n ref={(node) => {\n refs.current[index] = node;\n }}\n type=\"button\"\n role=\"radio\"\n aria-checked={preset.key === selected}\n tabIndex={index === activeIndex ? 0 : -1}\n onKeyDown={(event) => onKeyDown(event, index)}\n onClick={() => onSelect(preset.key, true)}\n className={cn(\n 'shrink-0 rounded px-3 py-1.5 text-left text-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',\n preset.key === selected\n ? 'bg-muted font-medium text-foreground'\n : 'text-muted-foreground hover:bg-muted hover:text-foreground',\n )}\n >\n {preset.label}\n </button>\n ))}\n </div>\n );\n}\n\nconst TARGETS = [\n { key: 'period' as const, label: 'Période', swatch: 'bg-primary' },\n { key: 'compare' as const, label: 'Comparaison', swatch: 'ring-2 ring-inset ring-chart-2' },\n];\n\n/**\n * Which of the two ranges the grid is editing.\n *\n * A radio group rather than two toggles: the targets are exclusive, and two\n * `aria-pressed` buttons would suggest both can be held down at once. It also\n * keeps `getByRole('radio', { name: 'Période' })` unambiguous next to a trigger\n * whose fallback label is the same word.\n *\n * Rendered whenever a comparison is on offer, never only while one is being\n * drawn: a row that appears and disappears makes the panel change height, which\n * is the thing `fixedWeeks` is there to prevent.\n */\nfunction TargetPills({\n target,\n onSelect,\n compareEditable,\n}: {\n target: PeriodTarget;\n onSelect: (target: PeriodTarget) => void;\n compareEditable: boolean;\n}) {\n return (\n <div\n role=\"radiogroup\"\n aria-label=\"Cible de la sélection\"\n className=\"flex items-center gap-1 border-b px-3 py-2\"\n >\n {TARGETS.map((entry) => {\n // Only a custom window is drawn by hand. Letting this pill switch the\n // mode itself would quietly turn a derived comparison into a manual one.\n const enabled = entry.key === 'period' || compareEditable;\n return (\n <button\n key={entry.key}\n type=\"button\"\n role=\"radio\"\n aria-checked={target === entry.key}\n disabled={!enabled}\n tabIndex={target === entry.key ? 0 : -1}\n onKeyDown={(event) => {\n if (!['ArrowDown', 'ArrowRight', 'ArrowUp', 'ArrowLeft'].includes(event.key)) return;\n event.preventDefault();\n if (compareEditable) onSelect(target === 'period' ? 'compare' : 'period');\n }}\n onClick={() => onSelect(entry.key)}\n className={cn(\n 'inline-flex items-center gap-1.5 rounded-full border px-2.5 py-1 text-xs transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-40',\n target === entry.key\n ? 'border-border bg-muted font-medium text-foreground'\n : 'border-border text-muted-foreground hover:bg-muted hover:text-foreground',\n )}\n >\n <span aria-hidden className={cn('size-2.5 rounded-sm', entry.swatch)} />\n {entry.label}\n </button>\n );\n })}\n </div>\n );\n}\n\nfunction CompareSection({\n draft,\n compareRange,\n onModeChange,\n}: {\n draft: Draft;\n compareRange: PeriodRange | undefined;\n onModeChange: (mode: PeriodCompareMode) => void;\n}) {\n // An unbounded period has no length to shift, so offering to shift it would\n // advertise a comparison that resolves to nothing.\n const derivable = draft.preset !== 'all';\n // What the entries report is what would actually apply, which is not always\n // what the draft remembers: the stored mode is kept so that passing through\n // \"tout l'historique\" on the way to another preset does not erase it.\n const active = activeCompare(draft);\n\n return (\n <div className=\"flex flex-col gap-0.5 border-t p-2\">\n <p className=\"px-3 pb-1 text-xs font-medium text-muted-foreground\">Comparer à</p>\n {/* `aria-pressed` rather than a third radio group in one panel: the modes\n are exclusive, but a group here would make every query in this popover\n spell out which of the three it means. */}\n {COMPARE_MODES.map((mode) => (\n <button\n key={mode}\n type=\"button\"\n aria-pressed={active === mode}\n disabled={mode !== 'none' && !derivable}\n onClick={() => onModeChange(mode)}\n className={cn(\n 'shrink-0 rounded px-3 py-1.5 text-left text-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-40',\n active === mode\n ? 'bg-muted font-medium text-foreground'\n : 'text-muted-foreground hover:bg-muted hover:text-foreground',\n )}\n >\n {COMPARE_LABELS[mode]}\n </button>\n ))}\n\n {compareRange && active !== 'custom' && (\n <p className=\"px-3 pt-1 text-xs text-muted-foreground\">{formatRange(compareRange)}</p>\n )}\n </div>\n );\n}\n\n/**\n * Inline, for the same reason as the icons in `components.tsx`: the SDK is one\n * vendor chunk behind the shell's import map, and a `lucide-react` dependency\n * would land on every app page for two glyphs.\n */\nfunction IconCalendar({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M8 2v4M16 2v4M3 10h18\" />\n <rect width=\"18\" height=\"18\" x=\"3\" y=\"4\" rx=\"2\" />\n </svg>\n );\n}\n\nfunction IconChevronDown({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n );\n}\n","/**\n * The pieces every chart in the kit is built from — the shadcn/chart blocks,\n * adapted to this SDK.\n *\n * Two deliberate departures from the upstream blocks:\n *\n * Upstream lets a series carry any CSS colour and injects a per-chart `<style>`\n * to declare it. Here a series names a `--chart-*` token instead, so there is\n * nothing to inject: the theme already defines those variables for both colour\n * schemes, and a chart cannot end up holding a colour the theme does not know.\n *\n * Nothing in this file is exported from the package. Recharts is an\n * implementation detail, and these compose only with Recharts elements, so\n * exporting them would put the engine in the public API through the back door.\n */\nimport * as React from 'react';\nimport { Legend, ResponsiveContainer, Tooltip } from 'recharts';\nimport { cn } from './cn';\n\n/** The five series colours the theme guarantees, in both light and dark. */\nexport const CHART_COLORS = [\n 'var(--chart-1)',\n 'var(--chart-2)',\n 'var(--chart-3)',\n 'var(--chart-4)',\n 'var(--chart-5)',\n] as const;\n\n/** Palette slot 2, the one a comparison is always drawn in. */\nexport const COMPARE_COLOR = CHART_COLORS[1];\n\n/** The colour of the nth series, cycling once the palette runs out. */\nexport const colorAt = (index: number): string =>\n CHART_COLORS[index % CHART_COLORS.length] as string;\n\nexport interface ChartSeries {\n /** The key this series reads from each row. */\n key: string;\n label: string;\n /** Palette slot. Defaults to the series' position. */\n colorIndex?: number;\n}\n\nexport type ValueFormatter = (value: number) => string;\n\n/** The default: a plain integer, grouped for readability. */\nexport const formatNumber: ValueFormatter = (value) =>\n new Intl.NumberFormat('fr-FR').format(Math.round(value));\n\ninterface ChartContextValue {\n formatValue: ValueFormatter;\n}\n\nconst ChartContext = React.createContext<ChartContextValue>({ formatValue: formatNumber });\n\nexport interface ChartContainerProps {\n children: React.ReactElement;\n /** Fixed pixel height. Charts need one — a percentage of nothing is nothing. */\n height?: number;\n formatValue?: ValueFormatter;\n /** Read by a screen reader in place of the graphic. */\n label?: string;\n className?: string;\n}\n\n/**\n * Sizes the chart and styles the parts Recharts renders as bare SVG, which no\n * class of ours would otherwise reach.\n */\nexport function ChartContainer({\n children,\n height = 320,\n formatValue = formatNumber,\n label,\n className,\n}: ChartContainerProps) {\n const context = React.useMemo(() => ({ formatValue }), [formatValue]);\n return (\n <ChartContext.Provider value={context}>\n <div\n role=\"img\"\n aria-label={label}\n style={{ height }}\n className={cn(\n 'w-full text-xs',\n '[&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground',\n '[&_.recharts-cartesian-grid_line]:stroke-border',\n '[&_.recharts-curve.recharts-tooltip-cursor]:stroke-border',\n '[&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted/40',\n '[&_.recharts-sector]:outline-none',\n '[&_.recharts-surface]:outline-none',\n className,\n )}\n >\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n {children}\n </ResponsiveContainer>\n </div>\n </ChartContext.Provider>\n );\n}\n\ninterface TooltipPayloadEntry {\n name?: string | number;\n value?: number | string;\n color?: string;\n dataKey?: string | number;\n}\n\n/**\n * The legend's entries are not shaped like the tooltip's: Recharts puts the\n * series name in `value` here and in `name` there, and a legend entry carries no\n * measurement at all.\n */\ninterface LegendPayloadEntry {\n value?: string | number;\n color?: string;\n dataKey?: string | number;\n}\n\nfunction ChartTooltipContent({\n active,\n payload,\n label,\n}: {\n active?: boolean;\n payload?: TooltipPayloadEntry[];\n label?: React.ReactNode;\n}) {\n const { formatValue } = React.useContext(ChartContext);\n if (!active || !payload?.length) return null;\n\n return (\n <div className=\"rounded-md border bg-card px-2.5 py-1.5 text-xs shadow-md\">\n {label !== undefined && <p className=\"mb-1 font-medium text-foreground\">{label}</p>}\n <ul className=\"flex flex-col gap-0.5\">\n {payload.map((entry, index) => (\n <li key={`${entry.dataKey}-${index}`} className=\"flex items-center gap-2\">\n <span\n aria-hidden\n className=\"h-2 w-2 shrink-0 rounded-[2px]\"\n style={{ backgroundColor: entry.color }}\n />\n <span className=\"text-muted-foreground\">{entry.name}</span>\n <span className=\"ml-auto font-medium tabular-nums text-foreground\">\n {typeof entry.value === 'number' ? formatValue(entry.value) : entry.value}\n </span>\n </li>\n ))}\n </ul>\n </div>\n );\n}\n\n/** The tooltip every chart in the kit uses. */\nexport const ChartTooltip = (\n <Tooltip\n cursor={{ strokeWidth: 1 }}\n content={<ChartTooltipContent />}\n // Recharts' default wrapper carries a white background and a grey border of\n // its own, which would sit behind the themed panel above in dark mode.\n wrapperStyle={{ outline: 'none' }}\n />\n);\n\nfunction ChartLegendContent({ payload }: { payload?: LegendPayloadEntry[] }) {\n if (!payload?.length) return null;\n return (\n <ul className=\"flex flex-wrap items-center justify-center gap-x-4 gap-y-1 pt-3\">\n {payload.map((entry, index) => (\n <li key={`${entry.dataKey}-${index}`} className=\"flex items-center gap-1.5\">\n <span\n aria-hidden\n className=\"h-2 w-2 shrink-0 rounded-[2px]\"\n style={{ backgroundColor: entry.color }}\n />\n <span className=\"text-muted-foreground\">{entry.value}</span>\n </li>\n ))}\n </ul>\n );\n}\n\n/** The legend every chart in the kit uses. Omitted when there is one series. */\nexport const ChartLegend = <Legend content={<ChartLegendContent />} />;\n\n/**\n * How a comparison series is drawn, everywhere, without exception: dashed, faded\n * and always in the second palette slot. Fixing it here is the point — a\n * comparison that looked different from one dashboard to the next would stop\n * reading as \"the same thing, earlier\".\n */\nexport const COMPARE_LINE_PROPS = {\n stroke: COMPARE_COLOR,\n strokeDasharray: '4 4',\n strokeOpacity: 0.4,\n strokeWidth: 2,\n dot: false,\n activeDot: false,\n // Not a preference: Recharts animates `strokeDasharray` from `0px 0px`, so an\n // animated comparison line is drawn solid and only becomes dashed once the\n // animation ends. Off, it is dashed from the first frame — and a reference\n // line that draws itself in is pulling the eye towards the thing meant to\n // recede behind the real series anyway.\n isAnimationActive: false,\n} as const;\n","/**\n * ChartKit — the charts an app is allowed to draw.\n *\n * Each one is a finished block with a narrow, typed surface: rows, the field on\n * the category axis, and the series to plot. Recharts is never re-exported and\n * none of its elements appear in a prop type, so the engine stays replaceable\n * and an app cannot assemble a chart that steps outside the design system.\n *\n * Colours come only from the `--chart-*` tokens, which the theme defines for\n * both colour schemes. That is the whole reason charts belong in the SDK: a\n * hand-drawn SVG with a hex literal is invisible in dark mode, and every app\n * that drew its own got that wrong.\n */\nimport * as React from 'react';\nimport {\n Area,\n AreaChart as RechartsAreaChart,\n Bar,\n BarChart as RechartsBarChart,\n CartesianGrid,\n Funnel,\n FunnelChart as RechartsFunnelChart,\n LabelList,\n Line,\n LineChart as RechartsLineChart,\n Cell,\n XAxis,\n YAxis,\n} from 'recharts';\nimport { Card, CardContent } from './components';\nimport { cn } from './cn';\nimport {\n COMPARE_LINE_PROPS,\n ChartContainer,\n ChartLegend,\n ChartTooltip,\n colorAt,\n formatNumber,\n type ChartSeries,\n type ValueFormatter,\n} from './chart-primitives';\n\nexport type { ChartSeries, ValueFormatter } from './chart-primitives';\n\n/** A row is whatever an app has; the chart only reads the keys it was given. */\nexport type ChartRow = Record<string, string | number | null | undefined>;\n\nexport interface CartesianChartProps {\n data: ChartRow[];\n /** The field on the category axis. */\n x: string;\n series: ChartSeries[];\n /** The same measure over an earlier period, drawn dashed and faded. */\n compareSeries?: ChartSeries;\n formatValue?: ValueFormatter;\n height?: number;\n /** Read out in place of the graphic. Defaults to the series names. */\n label?: string;\n hideLegend?: boolean;\n className?: string;\n}\n\nconst AXIS_PROPS = {\n tickLine: false,\n axisLine: false,\n tickMargin: 8,\n} as const;\n\n/**\n * Every mark in the kit is drawn without an entrance animation.\n *\n * These charts redraw whenever the period, the filters or the comparison change\n * — which is most interactions on a dashboard — and Recharts replays the growth\n * animation on each of them. Numbers that crawl back up from zero every time a\n * filter moves are harder to read, not more alive. It also removes the window\n * during which a comparison line is drawn solid, since Recharts animates\n * `strokeDasharray` from nothing.\n */\nconst MARK_PROPS = { isAnimationActive: false } as const;\n\n/** Both axes and the grid, identical across the cartesian charts. */\nfunction CartesianFrame({ x, formatValue }: { x: string; formatValue: ValueFormatter }) {\n return (\n <>\n <CartesianGrid vertical={false} strokeDasharray=\"3 3\" />\n <XAxis dataKey={x} {...AXIS_PROPS} />\n <YAxis {...AXIS_PROPS} width={56} tickFormatter={formatValue} />\n </>\n );\n}\n\nfunction accessibleLabel(series: ChartSeries[], label?: string): string {\n return label ?? series.map((entry) => entry.label).join(', ');\n}\n\n/** Whether the legend earns its space: one unnamed series does not. */\nfunction showsLegend(props: CartesianChartProps): boolean {\n if (props.hideLegend) return false;\n return props.series.length > 1 || props.compareSeries !== undefined;\n}\n\nexport function BarChart(props: CartesianChartProps) {\n const { data, x, series, compareSeries, formatValue = formatNumber } = props;\n return (\n <ChartContainer\n height={props.height}\n formatValue={formatValue}\n label={accessibleLabel(series, props.label)}\n className={props.className}\n >\n <RechartsBarChart data={data}>\n <CartesianFrame x={x} formatValue={formatValue} />\n {ChartTooltip}\n {showsLegend(props) && ChartLegend}\n {series.map((entry, index) => (\n <Bar\n key={entry.key}\n dataKey={entry.key}\n name={entry.label}\n fill={colorAt(entry.colorIndex ?? index)}\n radius={[4, 4, 0, 0]}\n {...MARK_PROPS}\n />\n ))}\n {compareSeries && (\n <Bar\n dataKey={compareSeries.key}\n name={compareSeries.label}\n fill={COMPARE_LINE_PROPS.stroke}\n fillOpacity={COMPARE_LINE_PROPS.strokeOpacity}\n radius={[4, 4, 0, 0]}\n {...MARK_PROPS}\n />\n )}\n </RechartsBarChart>\n </ChartContainer>\n );\n}\n\nexport function StackedBarChart(props: CartesianChartProps) {\n const { data, x, series, formatValue = formatNumber } = props;\n return (\n <ChartContainer\n height={props.height}\n formatValue={formatValue}\n label={accessibleLabel(series, props.label)}\n className={props.className}\n >\n <RechartsBarChart data={data}>\n <CartesianFrame x={x} formatValue={formatValue} />\n {ChartTooltip}\n {showsLegend(props) && ChartLegend}\n {series.map((entry, index) => (\n <Bar\n key={entry.key}\n dataKey={entry.key}\n name={entry.label}\n stackId=\"stack\"\n fill={colorAt(entry.colorIndex ?? index)}\n // Only the topmost segment is rounded, and which one that is depends\n // on the data, so none of them are.\n radius={0}\n {...MARK_PROPS}\n />\n ))}\n </RechartsBarChart>\n </ChartContainer>\n );\n}\n\nexport function LineChart(props: CartesianChartProps) {\n const { data, x, series, compareSeries, formatValue = formatNumber } = props;\n return (\n <ChartContainer\n height={props.height}\n formatValue={formatValue}\n label={accessibleLabel(series, props.label)}\n className={props.className}\n >\n <RechartsLineChart data={data}>\n <CartesianFrame x={x} formatValue={formatValue} />\n {ChartTooltip}\n {showsLegend(props) && ChartLegend}\n {series.map((entry, index) => (\n <Line\n key={entry.key}\n type=\"monotone\"\n dataKey={entry.key}\n name={entry.label}\n stroke={colorAt(entry.colorIndex ?? index)}\n strokeWidth={2}\n dot={false}\n {...MARK_PROPS}\n />\n ))}\n {compareSeries && (\n <Line\n type=\"monotone\"\n dataKey={compareSeries.key}\n name={compareSeries.label}\n {...COMPARE_LINE_PROPS}\n />\n )}\n </RechartsLineChart>\n </ChartContainer>\n );\n}\n\nexport function AreaChart(props: CartesianChartProps) {\n const { data, x, series, compareSeries, formatValue = formatNumber } = props;\n return (\n <ChartContainer\n height={props.height}\n formatValue={formatValue}\n label={accessibleLabel(series, props.label)}\n className={props.className}\n >\n <RechartsAreaChart data={data}>\n <CartesianFrame x={x} formatValue={formatValue} />\n {ChartTooltip}\n {showsLegend(props) && ChartLegend}\n {series.map((entry, index) => {\n const color = colorAt(entry.colorIndex ?? index);\n return (\n <Area\n key={entry.key}\n type=\"monotone\"\n dataKey={entry.key}\n name={entry.label}\n stroke={color}\n strokeWidth={2}\n fill={color}\n fillOpacity={0.15}\n {...MARK_PROPS}\n />\n );\n })}\n {compareSeries && (\n <Area\n type=\"monotone\"\n dataKey={compareSeries.key}\n name={compareSeries.label}\n fill=\"none\"\n {...COMPARE_LINE_PROPS}\n />\n )}\n </RechartsAreaChart>\n </ChartContainer>\n );\n}\n\nexport interface FunnelStep {\n label: string;\n value: number;\n}\n\nexport interface FunnelChartProps {\n data: FunnelStep[];\n formatValue?: ValueFormatter;\n height?: number;\n label?: string;\n className?: string;\n}\n\n/**\n * The one chart with no shadcn block, so it is assembled from Recharts' own\n * funnel elements. Steps keep their palette slot in the order they are given —\n * a funnel is read top to bottom, and a colour that moved between renders would\n * read as a different step.\n */\nexport function FunnelChart({\n data,\n formatValue = formatNumber,\n height,\n label,\n className,\n}: FunnelChartProps) {\n return (\n <ChartContainer\n height={height}\n formatValue={formatValue}\n label={label ?? data.map((step) => step.label).join(', ')}\n className={className}\n >\n <RechartsFunnelChart>\n {ChartTooltip}\n <Funnel dataKey=\"value\" nameKey=\"label\" data={data} {...MARK_PROPS}>\n {data.map((step, index) => (\n <Cell key={step.label} fill={colorAt(index)} />\n ))}\n <LabelList\n dataKey=\"label\"\n position=\"right\"\n className=\"fill-foreground\"\n stroke=\"none\"\n fontSize={12}\n />\n </Funnel>\n </RechartsFunnelChart>\n </ChartContainer>\n );\n}\n\nexport interface KpiCardProps {\n label: string;\n value: number;\n /** The same measure over the compared period. Drives the delta. */\n compareValue?: number;\n formatValue?: ValueFormatter;\n /** For measures that are better when lower — cost, churn, delay. */\n lowerIsBetter?: boolean;\n /** A bare trend line under the figure. */\n sparkline?: number[];\n className?: string;\n}\n\n/** The signed change, or null when there is no baseline to divide by. */\nexport function relativeDelta(value: number, compareValue: number | undefined): number | null {\n if (compareValue === undefined || compareValue === 0) return null;\n return (value - compareValue) / Math.abs(compareValue);\n}\n\nconst DELTA_FORMAT = new Intl.NumberFormat('fr-FR', {\n style: 'percent',\n maximumFractionDigits: 1,\n signDisplay: 'exceptZero',\n});\n\nexport function KpiCard({\n label,\n value,\n compareValue,\n formatValue = formatNumber,\n lowerIsBetter = false,\n sparkline,\n className,\n}: KpiCardProps) {\n const delta = relativeDelta(value, compareValue);\n const improved = delta === null ? null : delta > 0 !== lowerIsBetter;\n\n return (\n <Card className={className}>\n <CardContent className=\"space-y-1 p-4\">\n <p className=\"text-sm text-muted-foreground\">{label}</p>\n <p className=\"text-2xl font-semibold tabular-nums text-foreground\">{formatValue(value)}</p>\n {delta !== null && (\n <p\n className={cn(\n 'text-xs font-medium tabular-nums',\n // Direction is in the sign as well as the colour: a red figure and\n // a green one differ by more than hue for nobody who cannot see it.\n improved ? 'text-status-success' : 'text-status-blocked',\n )}\n >\n {DELTA_FORMAT.format(delta)}\n {compareValue !== undefined && (\n <span className=\"ml-1 font-normal text-muted-foreground\">\n vs {formatValue(compareValue)}\n </span>\n )}\n </p>\n )}\n {sparkline && sparkline.length > 1 && (\n <ChartContainer height={40} label={`Tendance — ${label}`} className=\"pt-1\">\n <RechartsLineChart data={sparkline.map((point, index) => ({ index, point }))}>\n <Line\n type=\"monotone\"\n dataKey=\"point\"\n stroke={colorAt(0)}\n strokeWidth={1.5}\n dot={false}\n {...MARK_PROPS}\n />\n </RechartsLineChart>\n </ChartContainer>\n )}\n </CardContent>\n </Card>\n );\n}\n","/**\n * Toast stack, lifted from the shell so an app page can announce an outcome the\n * same way the platform does.\n *\n * The shell copy painted with `green-*` / `red-*` from Tailwind's palette, which\n * ignores the instance theme entirely. Here it uses `--status-success` and\n * `--status-blocked`, so a rebranded instance and dark mode both carry through —\n * the same rule the SDK asks apps to follow.\n */\nimport { createContext, useCallback, useContext, useRef, useState, type ReactNode } from 'react';\nimport { cn } from './cn';\n\nexport interface ToastInput {\n title: string;\n description?: string;\n /** `info` exists because Pilotage's own stack had it — a neutral outcome is not a success. */\n variant?: 'success' | 'error' | 'info';\n}\n\ninterface ToastItem extends ToastInput {\n id: number;\n}\n\nconst ToastContext = createContext<((toast: ToastInput) => void) | null>(null);\n\n/** Returns a `toast({ title, description?, variant? })` function. */\nexport function useToast(): (toast: ToastInput) => void {\n const toast = useContext(ToastContext);\n if (!toast) throw new Error('useToast must be used within ToastProvider');\n return toast;\n}\n\n/** How long a toast stays up before it dismisses itself. */\nconst TOAST_TTL_MS = 4000;\n\n/**\n * The status hue is a border accent, not a wash: a toast floats over whatever is\n * on screen — including a modal's dark scrim — and a translucent tint composites\n * with it into mud. `bg-card` keeps it opaque, `--foreground` keeps the message\n * above 4.5:1, and the hue still reads at a glance down the left edge.\n */\nconst TONE: Record<NonNullable<ToastInput['variant']>, string> = {\n success: 'border-l-status-success',\n error: 'border-l-status-blocked',\n info: 'border-l-status-info',\n};\n\n/** Fixed bottom-right stack, auto-dismissing. */\nexport function ToastProvider({ children }: { children: ReactNode }) {\n const [toasts, setToasts] = useState<ToastItem[]>([]);\n const nextId = useRef(0);\n\n const toast = useCallback((input: ToastInput) => {\n const id = nextId.current++;\n setToasts((prev) => [...prev, { id, ...input }]);\n setTimeout(() => setToasts((prev) => prev.filter((t) => t.id !== id)), TOAST_TTL_MS);\n }, []);\n\n return (\n <ToastContext.Provider value={toast}>\n {children}\n <div className=\"pointer-events-none fixed bottom-4 right-4 z-[60] flex w-80 flex-col gap-2\">\n {toasts.map((t) => (\n <div\n key={t.id}\n role=\"status\"\n className={cn(\n 'pointer-events-auto rounded-lg border border-l-4 bg-card px-4 py-3 text-foreground shadow-md',\n TONE[t.variant ?? 'success'],\n )}\n >\n <p className=\"text-sm font-medium\">{t.title}</p>\n {t.description && (\n <p className=\"mt-0.5 break-all text-xs text-muted-foreground\">{t.description}</p>\n )}\n </div>\n ))}\n </div>\n </ToastContext.Provider>\n );\n}\n","/**\n * Hover tooltip, lifted from the shell.\n *\n * Deliberately CSS-only (`group-hover`) rather than another Base UI surface: it\n * carries no focus, no dismissal and no state, so a portal and a positioner would\n * be weight for nothing. If a tooltip ever needs to be keyboard-reachable or to\n * survive a scroll container, that is the moment to move it onto Base UI's.\n */\nimport * as React from 'react';\nimport { cn } from './cn';\n\nconst SIDES = {\n top: 'bottom-full left-1/2 -translate-x-1/2 mb-1.5',\n right: 'left-full top-1/2 -translate-y-1/2 ml-1.5',\n bottom: 'top-full left-1/2 -translate-x-1/2 mt-1.5',\n left: 'right-full top-1/2 -translate-y-1/2 mr-1.5',\n} as const;\n\nexport interface TooltipProps {\n label: React.ReactNode;\n children: React.ReactNode;\n side?: keyof typeof SIDES;\n className?: string;\n}\n\nexport function Tooltip({ label, children, side = 'top', className }: TooltipProps) {\n return (\n <span className=\"group/tt relative inline-flex\">\n {children}\n <span\n role=\"tooltip\"\n className={cn(\n 'pointer-events-none absolute z-50 whitespace-nowrap rounded-md bg-foreground px-2 py-1 text-xs font-medium text-background opacity-0 shadow-md transition-opacity group-hover/tt:opacity-100',\n SIDES[side],\n className,\n )}\n >\n {label}\n </span>\n </span>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/cn.ts","../src/hooks.ts","../src/utils.ts","../src/components.tsx","../src/data-table.tsx","../src/period.ts","../src/date-range-compare.tsx","../src/chart-primitives.tsx","../src/chart-kit.tsx","../src/toast.tsx","../src/tooltip.tsx"],"names":["React","BaseSelect","BaseTabs","BaseSwitch","Textarea","BaseCheckbox","BasePopover","jsxs","jsx","_","compare","React3","range","React4","Fragment","RechartsBarChart","RechartsLineChart","RechartsAreaChart","RechartsFunnelChart","createContext","useContext","useState","useRef","useCallback","Tooltip"],"mappings":"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","file":"index.js","sourcesContent":["import { type ClassValue, clsx } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n","/**\n * Runtime hooks provided by the shell via @apotech-os/ui-sdk.\n *\n * These hooks are implemented by the shell and injected at runtime via the\n * import map. App pages call them without knowing the shell internals.\n *\n * The default implementations throw if called outside of the shell context\n * (which should never happen in production — the shell always provides them\n * via the import map before mounting an app page).\n */\n\nimport { useContext, createContext, useCallback, useEffect, useRef, useState } from 'react';\n// `import type` only: ui-sdk has no runtime dependency on app-kit, so this must\n// not appear in the built dist/index.js (verified — see error-codes.ts).\nimport type { AppErrorCode, AppRunRecord, AppRunStatus } from '@apotech-os/app-kit';\n\n// ---------------------------------------------------------------------------\n// AppContext\n// ---------------------------------------------------------------------------\n\nexport interface AppContextValue {\n /** The slug of the installed app owning this page. */\n appSlug: string;\n /** The page path within the app (e.g. 'attribution'). */\n pagePath: string;\n /** The active space id, when applicable. */\n spaceId?: string;\n /**\n * The current user's grant role on this app context, when the shell knows it.\n * Settings pages use it to render read-only fields below ADMIN instead of\n * letting the user discover the 403 at save time.\n */\n role?: 'VIEWER' | 'EDITOR' | 'ADMIN';\n /**\n * The current user's role on the PLATFORM context, when the shell knows it.\n * A different axis from `role`: some platform primitives a page may reach\n * (prompt promotion, quality writes) have a company-wide blast radius and\n * are gated server-side on platform EDITOR+, not on any one app's grant.\n * Undefined means \"the shell did not say\" — treat that as no authority and\n * hide the control, never as permission.\n */\n platformRole?: 'VIEWER' | 'EDITOR' | 'ADMIN';\n}\n\nconst AppContextInternalCtx = createContext<AppContextValue | null>(null);\n\nexport const AppContextProvider = AppContextInternalCtx.Provider;\n\n/** Returns context info for the current app page (appSlug, pagePath, spaceId). */\nexport function useAppContext(): AppContextValue {\n const ctx = useContext(AppContextInternalCtx);\n if (!ctx) throw new Error('useAppContext must be used inside an app page mounted by the shell');\n return ctx;\n}\n\n// ---------------------------------------------------------------------------\n// AppApi\n// ---------------------------------------------------------------------------\n\nexport interface AppApiClient {\n /**\n * Perform a GET request to a platform-data endpoint.\n * The session cookie is forwarded automatically (same-origin, withCredentials).\n */\n get<T>(path: string, params?: Record<string, string>): Promise<T>;\n /**\n * Perform a POST request to a platform-data endpoint.\n */\n post<T>(path: string, body?: unknown): Promise<T>;\n /**\n * Perform a PUT request to a platform-data endpoint (e.g. write app settings).\n */\n put<T>(path: string, body?: unknown): Promise<T>;\n /**\n * Perform a PATCH request to a platform-data endpoint (e.g. update a record).\n */\n patch<T>(path: string, body?: unknown): Promise<T>;\n /**\n * Perform a DELETE request to a platform-data endpoint (e.g. delete a record).\n */\n delete<T>(path: string): Promise<T>;\n /**\n * Run one of this app's `uiInvoke` functions and get its return value back.\n *\n * This is the ONLY way a page can reach an integration: the action endpoint\n * requires an app token and refuses a browser session. The platform mints the\n * token server-side and runs the handler in-process.\n *\n * The function must be declared `trigger: { type: 'uiInvoke' }` in the\n * manifest, and the caller must hold its `minRole` (default EDITOR).\n *\n * Pass `idempotencyKey` for anything that must not run twice on a double\n * click — a concurrent duplicate is rejected with 409 INVOCATION_IN_FLIGHT.\n *\n * Throws AppInvokeError. `code === 'FUNCTION_REJECTED'` carries an app-authored\n * message that is safe to show the user; every other failure is generic on\n * purpose (raw provider errors can leak tokens or PII).\n */\n invoke<TResult, TInput = Record<string, unknown>>(\n functionName: string,\n input?: TInput,\n opts?: { idempotencyKey?: string; signal?: AbortSignal },\n ): Promise<TResult>;\n}\n\n/** Thrown by AppApiClient.invoke. */\nexport class AppInvokeError extends Error {\n constructor(\n readonly status: number,\n message: string,\n // `AppErrorCode | (string & {})` gives autocomplete on the known codes\n // while keeping any other string assignable — a server that returns an\n // unlisted `code` (or none) must not fail to compile against this type.\n readonly code?: AppErrorCode | (string & {}),\n readonly invocationId?: string,\n ) {\n super(message);\n this.name = 'AppInvokeError';\n }\n}\n\nconst AppApiCtx = createContext<AppApiClient | null>(null);\n\nexport const AppApiProvider = AppApiCtx.Provider;\n\n/**\n * Returns an API client scoped to the current user session.\n * Requests go to /api/data/* with the session cookie (RBAC applies server-side).\n */\nexport function useAppApi(): AppApiClient {\n const client = useContext(AppApiCtx);\n if (!client) throw new Error('useAppApi must be used inside an app page mounted by the shell');\n return client;\n}\n\n// ---------------------------------------------------------------------------\n// AppSettings\n// ---------------------------------------------------------------------------\n\n/**\n * Reads and writes this app's settings (GET/PUT /data/apps/:appSlug/settings).\n *\n * The app slug comes from the surrounding AppContext, so a settings page only\n * has to describe its form. Values are the ones the server merged with the\n * `settings.fields` defaults declared in the manifest.\n *\n * Reading requires VIEWER, writing requires ADMIN. `save` never throws: it\n * reports through `saveError`, which carries the raw failure (422\n * SETTINGS_VALIDATION_FAILED with its per-key errors, or 403) so the page can\n * map it back onto its fields. A failed save leaves `settings` untouched.\n */\nexport function useAppSettings<T = Record<string, unknown>>(): {\n settings: T | undefined;\n isLoading: boolean;\n error: unknown;\n save: (patch: Partial<T>) => Promise<void>;\n isSaving: boolean;\n saveError: unknown;\n} {\n const { appSlug } = useAppContext();\n const api = useAppApi();\n const path = `/data/apps/${appSlug}/settings`;\n\n const [settings, setSettings] = useState<T | undefined>(undefined);\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<unknown>(undefined);\n const [isSaving, setIsSaving] = useState(false);\n const [saveError, setSaveError] = useState<unknown>(undefined);\n\n // The shell rebuilds the client on every render, so it cannot be an effect\n // dependency without refetching in a loop.\n const clientRef = useRef(api);\n clientRef.current = api;\n // Bumped by every request and by unmount: a superseded or late response is\n // dropped instead of overwriting fresher state.\n const requestIdRef = useRef(0);\n const isMountedRef = useRef(true);\n\n /**\n * `silent` skips the isLoading flip for the refetch that follows a save: a page\n * written as `if (isLoading) return <Spinner/>` would otherwise unmount its own\n * form mid-save, losing focus and any uncommitted input. isSaving already covers\n * that window.\n */\n const load = useCallback(\n async ({ silent }: { silent?: boolean } = {}) => {\n const requestId = ++requestIdRef.current;\n if (!silent) setIsLoading(true);\n try {\n const loaded = await clientRef.current.get<T>(path);\n if (requestId !== requestIdRef.current) return;\n setSettings(loaded);\n setError(undefined);\n } catch (err) {\n if (requestId !== requestIdRef.current) return;\n setError(err);\n } finally {\n // Clearing is NOT conditional on `silent`: a save that races the very first\n // GET supersedes it, so the initial load can no longer clear the flag it\n // set — only the request that actually settles last can.\n if (requestId === requestIdRef.current) setIsLoading(false);\n }\n },\n [path],\n );\n\n useEffect(() => {\n isMountedRef.current = true;\n void load();\n return () => {\n isMountedRef.current = false;\n requestIdRef.current += 1;\n };\n }, [load]);\n\n const save = useCallback(\n async (patch: Partial<T>) => {\n setIsSaving(true);\n setSaveError(undefined);\n try {\n await clientRef.current.put<unknown>(path, patch);\n await load({ silent: true });\n } catch (err) {\n if (isMountedRef.current) setSaveError(err);\n } finally {\n if (isMountedRef.current) setIsSaving(false);\n }\n },\n [path, load],\n );\n\n return { settings, isLoading, error, save, isSaving, saveError };\n}\n\n// ---------------------------------------------------------------------------\n// AppRun (P2-11)\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_RUN_POLL_INTERVAL_MS = 1_000;\nconst MAX_RUN_POLL_INTERVAL_MS = 5_000;\nconst RUN_POLL_BACKOFF = 1.5;\n/** Fixed cadence for useAppRuns' `follow` mode — it exposes no interval knobs. */\nconst RUNS_FOLLOW_POLL_INTERVAL_MS = 3_000;\n\n/** A stable key for the (progress, message) pair — the backoff resets whenever it changes. */\nfunction runProgressSignature(run: AppRunRecord): string {\n return `${run.progress ?? ''}|${run.message ?? ''}`;\n}\n\n/**\n * The outcome of one `fetchOnce()` call. Four cases, not two: a superseded or\n * late response (`'superseded'` — a newer tick, or a caller-facing `refresh()`,\n * bumped `requestIdRef` first) must NOT be conflated with a real failure\n * (`'error'`) — the poll loop reacts to them differently. Collapsing both into\n * one falsy value was the root cause of `tick()` silently dying whenever a\n * `refresh()` call raced an in-flight poll request: `tick()` only reschedules\n * itself on an outcome it recognizes, so a `'superseded'` response must still\n * lead to a reschedule, exactly like a transient `'error'` does.\n */\ntype FetchOutcome =\n | { kind: 'success'; run: AppRunRecord }\n | { kind: 'error'; err: unknown }\n | { kind: 'superseded' }\n | { kind: 'no-path' };\n\n/**\n * A 404 (the run was purged) or a 403 (the caller lost access) will never\n * resolve on retry — polling forever on either leaves a permanent spinner.\n * Any other failure (a network blip, a 5xx) is transient and keeps retrying\n * at the current pace, unchanged.\n *\n * The shell's `AppApiClient.get` has no typed error (unlike `invoke`'s\n * `AppInvokeError`) — it leaks whatever the underlying transport throws, so\n * this reads both an axios-style `err.response.status` and a bare `err.status`.\n */\nfunction isTerminalRunError(err: unknown): boolean {\n const status = extractHttpStatus(err);\n return status === 403 || status === 404;\n}\n\nfunction extractHttpStatus(err: unknown): number | undefined {\n if (typeof err !== 'object' || err === null) return undefined;\n const direct = (err as { status?: unknown }).status;\n if (typeof direct === 'number') return direct;\n const response = (err as { response?: unknown }).response;\n if (typeof response !== 'object' || response === null) return undefined;\n const nested = (response as { status?: unknown }).status;\n return typeof nested === 'number' ? nested : undefined;\n}\n\n/**\n * Follows a single run until it reaches a terminal status.\n *\n * Polling uses a recursive `setTimeout` (never `setInterval`, which piles up\n * requests when the API slows down), starting at `intervalMs` (default 1 s)\n * and multiplying by 1.5 each tick up to `maxIntervalMs` (default 5 s). The\n * backoff resets to `intervalMs` whenever `progress` or `message` changes —\n * an actively-progressing run is polled fast, a stalled one is polled slowly.\n *\n * `runId === null` puts the hook to sleep: no request is ever sent. This lets\n * a page call the hook unconditionally with a run id that may not exist yet\n * (e.g. before the triggering `uiInvoke` has returned).\n */\nexport function useAppRun(\n runId: string | null,\n opts: { intervalMs?: number; maxIntervalMs?: number } = {},\n): {\n run: AppRunRecord | undefined;\n isPolling: boolean;\n error: unknown;\n refresh: () => Promise<void>;\n} {\n const { appSlug } = useAppContext();\n const api = useAppApi();\n const intervalMs = opts.intervalMs ?? DEFAULT_RUN_POLL_INTERVAL_MS;\n const maxIntervalMs = opts.maxIntervalMs ?? MAX_RUN_POLL_INTERVAL_MS;\n\n const [run, setRun] = useState<AppRunRecord | undefined>(undefined);\n const [isPolling, setIsPolling] = useState(false);\n const [error, setError] = useState<unknown>(undefined);\n\n // The shell rebuilds the client on every render (app-page-view.tsx builds it\n // outside a useMemo), so it cannot be an effect dependency without restarting\n // the poll loop on every render.\n const clientRef = useRef(api);\n clientRef.current = api;\n const requestIdRef = useRef(0);\n const isMountedRef = useRef(true);\n\n const path = runId !== null ? `/data/apps/${appSlug}/runs/${encodeURIComponent(runId)}` : null;\n\n const fetchOnce = useCallback(async (): Promise<FetchOutcome> => {\n if (path === null) return { kind: 'no-path' };\n const requestId = ++requestIdRef.current;\n try {\n const loaded = await clientRef.current.get<AppRunRecord>(path);\n if (requestId !== requestIdRef.current || !isMountedRef.current)\n return { kind: 'superseded' };\n setRun(loaded);\n setError(undefined);\n return { kind: 'success', run: loaded };\n } catch (err) {\n if (requestId !== requestIdRef.current || !isMountedRef.current)\n return { kind: 'superseded' };\n setError(err);\n return { kind: 'error', err };\n }\n }, [path]);\n\n useEffect(() => {\n isMountedRef.current = true;\n // Invalidate any request from a previous runId/path so its late response\n // cannot overwrite the state of the run we are now following.\n requestIdRef.current += 1;\n setRun(undefined);\n setError(undefined);\n\n if (path === null) {\n setIsPolling(false);\n return () => {\n isMountedRef.current = false;\n };\n }\n\n let timeoutHandle: ReturnType<typeof setTimeout> | undefined;\n let interval = intervalMs;\n let lastSignature: string | undefined;\n let cancelled = false;\n\n const tick = async (): Promise<void> => {\n const outcome = await fetchOnce();\n if (cancelled || !isMountedRef.current) return;\n\n if (outcome.kind === 'no-path') {\n setIsPolling(false);\n return;\n }\n\n if (outcome.kind === 'superseded') {\n // A caller-facing refresh() (or a newer tick, though ticks never\n // overlap) raced this request and won. The response itself is\n // discarded, but the poll loop is still alive and must keep going —\n // rescheduling at the current pace is what stops it from stalling.\n timeoutHandle = setTimeout(() => void tick(), interval);\n return;\n }\n\n if (outcome.kind === 'error') {\n if (isTerminalRunError(outcome.err)) {\n // Purged (404) or forbidden (403): this will never recover on its\n // own. Stop polling instead of spinning forever — the failure is\n // already surfaced via `error`.\n setIsPolling(false);\n return;\n }\n // Any other failure does not accelerate the loop — retry at the current pace.\n timeoutHandle = setTimeout(() => void tick(), interval);\n return;\n }\n\n const loaded = outcome.run;\n const signature = runProgressSignature(loaded);\n interval =\n signature === lastSignature\n ? Math.min(interval * RUN_POLL_BACKOFF, maxIntervalMs)\n : intervalMs;\n lastSignature = signature;\n\n if (loaded.status !== 'running') {\n setIsPolling(false);\n return;\n }\n timeoutHandle = setTimeout(() => void tick(), interval);\n };\n\n setIsPolling(true);\n void tick();\n\n return () => {\n cancelled = true;\n isMountedRef.current = false;\n if (timeoutHandle) clearTimeout(timeoutHandle);\n };\n }, [path, fetchOnce, intervalMs, maxIntervalMs]);\n\n const refresh = useCallback(async () => {\n await fetchOnce();\n }, [fetchOnce]);\n\n return { run, isPolling, error, refresh };\n}\n\n// ---------------------------------------------------------------------------\n// AppRuns (P2-11)\n// ---------------------------------------------------------------------------\n\n/**\n * The outcome of one `fetchOnce()` call, mirroring `FetchOutcome` above for\n * the same reason: a superseded/late response and a genuine fetch error must\n * stay distinguishable from a real \"no runs are running\" success, or the\n * follow loop below cannot tell \"we don't know\" from \"stop following\" and\n * one dropped request kills it permanently.\n */\ntype ListFetchOutcome =\n | { kind: 'success'; items: AppRunRecord[] }\n | { kind: 'error'; err: unknown }\n | { kind: 'superseded' };\n\n/**\n * Lists the latest runs of a `kind` — used to re-attach the UI after a page\n * reload, where the runId returned by `invoke()` is lost, and to follow a run\n * by its business `key` rather than by its id.\n */\nexport function useAppRuns(opts: {\n kind?: string;\n key?: string;\n status?: AppRunStatus[];\n limit?: number;\n /** Keeps refreshing while a non-terminal run is present. Default: true. */\n follow?: boolean;\n}): { runs: AppRunRecord[]; isLoading: boolean; error: unknown; refresh: () => Promise<void> } {\n const { appSlug } = useAppContext();\n const api = useAppApi();\n const follow = opts.follow ?? true;\n\n const [runs, setRuns] = useState<AppRunRecord[]>([]);\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<unknown>(undefined);\n\n const clientRef = useRef(api);\n clientRef.current = api;\n const requestIdRef = useRef(0);\n const isMountedRef = useRef(true);\n\n const params: Record<string, string> = {};\n if (opts.kind) params['kind'] = opts.kind;\n if (opts.key) params['key'] = opts.key;\n if (opts.status?.length) params['status'] = opts.status.join(',');\n if (opts.limit) params['limit'] = String(opts.limit);\n // Stable string key so the effect below does not restart on every render\n // just because `opts` is a fresh object literal from the caller.\n const paramsKey = JSON.stringify(params);\n const path = `/data/apps/${appSlug}/runs`;\n\n const fetchOnce = useCallback(\n async ({ silent }: { silent?: boolean } = {}): Promise<ListFetchOutcome> => {\n const requestId = ++requestIdRef.current;\n if (!silent) setIsLoading(true);\n try {\n const page = await clientRef.current.get<{ items: AppRunRecord[] }>(\n path,\n JSON.parse(paramsKey) as Record<string, string>,\n );\n if (requestId !== requestIdRef.current || !isMountedRef.current)\n return { kind: 'superseded' };\n setRuns(page.items);\n setError(undefined);\n return { kind: 'success', items: page.items };\n } catch (err) {\n if (requestId !== requestIdRef.current || !isMountedRef.current)\n return { kind: 'superseded' };\n setError(err);\n return { kind: 'error', err };\n } finally {\n if (requestId === requestIdRef.current) setIsLoading(false);\n }\n },\n [path, paramsKey],\n );\n\n useEffect(() => {\n isMountedRef.current = true;\n let timeoutHandle: ReturnType<typeof setTimeout> | undefined;\n let cancelled = false;\n\n const tick = async (silent: boolean): Promise<void> => {\n const outcome = await fetchOnce({ silent });\n if (cancelled || !isMountedRef.current || !follow) return;\n // A superseded response or a transient fetch error cannot tell us\n // whether a running item still exists — retry at the same cadence\n // rather than treating \"we don't know\" as \"nothing is running\" and\n // stalling the follow loop for good. Only a clean success with no\n // running item is a real reason to stop.\n if (outcome.kind !== 'success' || outcome.items.some((r) => r.status === 'running')) {\n timeoutHandle = setTimeout(() => void tick(true), RUNS_FOLLOW_POLL_INTERVAL_MS);\n }\n };\n\n void tick(false);\n\n return () => {\n cancelled = true;\n isMountedRef.current = false;\n if (timeoutHandle) clearTimeout(timeoutHandle);\n };\n }, [fetchOnce, follow]);\n\n const refresh = useCallback(async () => {\n await fetchOnce({ silent: true });\n }, [fetchOnce]);\n\n return { runs, isLoading, error, refresh };\n}\n","/**\n * Browser helpers for app pages.\n *\n * App bundles get react, react-dom and this SDK from the shell's import map and\n * bundle everything else themselves — so without these here, every app would\n * reimplement clipboard handling and CSV escaping, and get the edge cases wrong\n * in its own way.\n */\n\n/**\n * Copy text to the clipboard.\n *\n * Returns `false` instead of throwing when the clipboard is unavailable (non\n * secure context, permission refused) so the caller can render inline feedback.\n * No `document.execCommand('copy')` fallback: it is deprecated, and the shell\n * only ever runs on https or localhost, both secure contexts.\n */\nexport async function copyToClipboard(text: string): Promise<boolean> {\n if (!navigator?.clipboard || !window.isSecureContext) return false;\n try {\n await navigator.clipboard.writeText(text);\n return true;\n } catch {\n return false;\n }\n}\n\n/** Trigger a browser download of a Blob via a throwaway object URL + `<a>` click. */\nexport function downloadBlob(blob: Blob, filename: string): void {\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = filename;\n document.body.appendChild(a);\n a.click();\n a.remove();\n URL.revokeObjectURL(url);\n}\n\n/** Escape one CSV field per RFC 4180: quote it, and double any embedded quote,\n * whenever it contains a comma, a quote, or a line break. */\nfunction escapeCsvField(value: string): string {\n return /[\",\\r\\n]/.test(value) ? `\"${value.replace(/\"/g, '\"\"')}\"` : value;\n}\n\n/** Serialize rows (header included) into an RFC 4180 CSV string. */\nexport function toCsv(rows: string[][]): string {\n return rows.map((row) => row.map(escapeCsvField).join(',')).join('\\r\\n');\n}\n\n/** UTF-8 byte order mark. */\nconst BOM = '\\uFEFF';\n\n/**\n * Serialize + download in one call.\n *\n * The BOM is the whole reason this helper exists: without it Excel on Windows\n * reads the file as latin-1 and mangles every accented character.\n */\nexport function downloadCsv(rows: string[][], filename: string): void {\n const blob = new Blob([`${BOM}${toCsv(rows)}`], { type: 'text/csv;charset=utf-8' });\n downloadBlob(blob, filename);\n}\n","/**\n * Design system components exported by @apotech-os/ui-sdk.\n *\n * These are minimal self-contained copies of the shell's component library.\n * They use the same Tailwind utility classes as the shell — Tailwind classes\n * are plain strings and work without any build step when the shell's stylesheet\n * is loaded (which it is, since these pages run inside the shell).\n *\n * Strategy note:\n * - Not imported from apps/web (would create a circular dep pkg → app).\n * - Copied/adapted here to keep the SDK self-contained and publishable.\n * - The exhaustive component inventory is tracked in #75.\n */\n\nimport { Dialog } from '@base-ui/react/dialog';\nimport { Menu } from '@base-ui/react/menu';\nimport { Checkbox as BaseCheckbox } from '@base-ui/react/checkbox';\nimport { Popover as BasePopover } from '@base-ui/react/popover';\nimport { Select as BaseSelect } from '@base-ui/react/select';\nimport { Switch as BaseSwitch } from '@base-ui/react/switch';\nimport { Tabs as BaseTabs } from '@base-ui/react/tabs';\nimport { type VariantProps, cva } from 'class-variance-authority';\nimport * as React from 'react';\nimport { cn } from './cn';\nimport { copyToClipboard } from './utils';\n\n/**\n * Give Base UI the caller's own element to render as, rather than wrapping it.\n *\n * `trigger` is `ReactNode` in our public API, so it may be a `<button>` — wrapping\n * that in Base UI's default button is invalid HTML and the source of the nested-\n * button defect. Passing the element through `render` merges the trigger props\n * into it instead. A non-element (a bare string) still needs a host, and a span\n * with the button semantics Base UI adds is the least surprising one.\n *\n * `nativeButton` tells Base UI which it got, and it is not cosmetic: on the\n * native branch Base UI adds `type=\"button\"`, without which a trigger inside a\n * <form> submits it. Only a literal <button> and our own `Button` can be known to\n * be one — anything else is reported honestly as not-a-button, and Base UI says so\n * loudly in the console if it was wrong.\n */\nfunction triggerProps(trigger: React.ReactNode): {\n render: React.ReactElement;\n nativeButton: boolean;\n} {\n if (React.isValidElement(trigger)) {\n return { render: trigger, nativeButton: trigger.type === 'button' || trigger.type === Button };\n }\n return { render: <span>{trigger}</span>, nativeButton: false };\n}\n\n// ---------------------------------------------------------------------------\n// Button\n// ---------------------------------------------------------------------------\n\nexport const buttonVariants = cva(\n 'inline-flex cursor-pointer items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50',\n {\n variants: {\n variant: {\n default: 'bg-primary text-primary-foreground hover:bg-primary/90',\n secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',\n outline: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',\n ghost: 'hover:bg-accent hover:text-accent-foreground',\n destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',\n },\n size: {\n default: 'h-9 px-4 py-2',\n sm: 'h-8 rounded-md px-3 text-xs',\n lg: 'h-10 rounded-md px-6',\n icon: 'h-9 w-9',\n },\n },\n defaultVariants: { variant: 'default', size: 'default' },\n },\n);\n\nexport interface ButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {}\n\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant, size, ...props }, ref) => (\n <button ref={ref} className={cn(buttonVariants({ variant, size, className }))} {...props} />\n ),\n);\nButton.displayName = 'Button';\n\n// ---------------------------------------------------------------------------\n// Badge\n// ---------------------------------------------------------------------------\n\nexport const badgeVariants = cva(\n 'inline-flex items-center gap-1.5 rounded-full border px-2 py-0.5 text-xs font-medium whitespace-nowrap',\n {\n variants: {\n variant: {\n neutral: 'border-border bg-muted text-muted-foreground',\n brand: 'border-primary/20 bg-primary/10 text-primary',\n success: 'border-status-success/25 bg-status-success/10 text-status-success',\n warning: 'border-status-pending/30 bg-status-pending/10 text-status-pending',\n danger: 'border-status-blocked/25 bg-status-blocked/10 text-status-blocked',\n info: 'border-status-info/25 bg-status-info/10 text-status-info',\n outline: 'border-border bg-transparent text-muted-foreground',\n },\n },\n defaultVariants: { variant: 'neutral' },\n },\n);\n\nexport interface BadgeProps\n extends React.HTMLAttributes<HTMLSpanElement>, VariantProps<typeof badgeVariants> {\n dot?: boolean;\n}\n\nexport function Badge({ className, variant, dot, children, ...props }: BadgeProps) {\n return (\n <span className={cn(badgeVariants({ variant }), className)} {...props}>\n {dot && <span className=\"size-1.5 rounded-full bg-current\" />}\n {children}\n </span>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Card\n// ---------------------------------------------------------------------------\n\nexport function Card({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n return (\n <div\n className={cn('rounded-xl border bg-card text-card-foreground shadow-sm', className)}\n {...props}\n />\n );\n}\n\nexport function CardHeader({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n return <div className={cn('flex flex-col space-y-1.5 p-6', className)} {...props} />;\n}\n\nexport function CardTitle({ className, ...props }: React.HTMLAttributes<HTMLHeadingElement>) {\n return (\n <h3 className={cn('text-lg font-semibold leading-none tracking-tight', className)} {...props} />\n );\n}\n\nexport function CardDescription({\n className,\n ...props\n}: React.HTMLAttributes<HTMLParagraphElement>) {\n return <p className={cn('text-sm text-muted-foreground', className)} {...props} />;\n}\n\nexport function CardContent({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n return <div className={cn('p-6 pt-0', className)} {...props} />;\n}\n\nexport function CardFooter({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n return <div className={cn('flex items-center p-6 pt-0', className)} {...props} />;\n}\n\n// ---------------------------------------------------------------------------\n// Input\n// ---------------------------------------------------------------------------\n\nexport const Input = React.forwardRef<\n HTMLInputElement,\n React.InputHTMLAttributes<HTMLInputElement>\n>(({ className, type, ...props }, ref) => (\n <input\n type={type}\n className={cn(\n 'flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50',\n className,\n )}\n ref={ref}\n {...props}\n />\n));\nInput.displayName = 'Input';\n\n// ---------------------------------------------------------------------------\n// Table\n// ---------------------------------------------------------------------------\n\nexport function Table({ className, ...props }: React.HTMLAttributes<HTMLTableElement>) {\n return <table className={cn('w-full text-sm', className)} {...props} />;\n}\n\nexport function TableHeader({\n className,\n ...props\n}: React.HTMLAttributes<HTMLTableSectionElement>) {\n return (\n <thead\n // The hover tint is a data-row affordance; on the header band it reads as\n // \"this is clickable\", which it is not.\n className={cn('[&_tr]:border-b [&_tr]:hover:bg-transparent', className)}\n {...props}\n />\n );\n}\n\nexport function TableBody({ className, ...props }: React.HTMLAttributes<HTMLTableSectionElement>) {\n return <tbody className={cn('[&_tr:last-child]:border-0', className)} {...props} />;\n}\n\nexport function TableRow({ className, ...props }: React.HTMLAttributes<HTMLTableRowElement>) {\n return (\n <tr\n className={cn(\n 'border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted',\n className,\n )}\n {...props}\n />\n );\n}\n\nexport function TableHead({ className, ...props }: React.ThHTMLAttributes<HTMLTableCellElement>) {\n return (\n <th\n className={cn(\n 'h-10 px-4 text-left align-middle text-xs font-medium uppercase tracking-wide text-muted-foreground',\n className,\n )}\n {...props}\n />\n );\n}\n\nexport function TableCell({ className, ...props }: React.TdHTMLAttributes<HTMLTableCellElement>) {\n return <td className={cn('p-4 align-middle', className)} {...props} />;\n}\n\n// ---------------------------------------------------------------------------\n// Select\n// ---------------------------------------------------------------------------\n\nexport interface SelectOption {\n value: string;\n label: React.ReactNode;\n disabled?: boolean;\n}\n\nexport interface SelectProps {\n /** Controlled value. Pair with `onValueChange`. */\n value?: string;\n defaultValue?: string;\n onValueChange?: (value: string) => void;\n items: SelectOption[];\n /** Shown when nothing is chosen. */\n placeholder?: React.ReactNode;\n disabled?: boolean;\n /** Submitted with a surrounding form, through a hidden native input. */\n name?: string;\n className?: string;\n 'aria-label'?: string;\n}\n\n/**\n * Listbox select.\n *\n * Contract 2: this used to be a native `<select>` taking `<option>` children.\n * The popup is ours now — themed, positioned and keyboard-driven like every\n * other floating surface — which a native select cannot be. `items` replaces the\n * children, and the ref is gone: there is no `HTMLSelectElement` behind it.\n */\nexport function Select({\n value,\n defaultValue,\n onValueChange,\n items,\n placeholder = 'Choisir…',\n disabled,\n name,\n className,\n ...props\n}: SelectProps) {\n return (\n <BaseSelect.Root\n // Base UI needs the list to render the chosen item's label rather than its\n // raw value in the trigger.\n items={items}\n value={value}\n defaultValue={defaultValue}\n onValueChange={(next) => onValueChange?.(String(next))}\n disabled={disabled}\n name={name}\n >\n <BaseSelect.Trigger\n className={cn(\n 'flex h-9 w-full cursor-pointer items-center justify-between gap-2 rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50',\n className,\n )}\n {...props}\n >\n <BaseSelect.Value placeholder={placeholder} />\n <BaseSelect.Icon aria-hidden className=\"text-xs text-muted-foreground\">\n ▾\n </BaseSelect.Icon>\n </BaseSelect.Trigger>\n <BaseSelect.Portal>\n <BaseSelect.Positioner className=\"z-50\" sideOffset={4}>\n <BaseSelect.Popup className=\"max-h-72 min-w-(--anchor-width) overflow-auto rounded-md border bg-card p-1 shadow-lg\">\n {items.map((item) => (\n <BaseSelect.Item\n key={item.value}\n value={item.value}\n disabled={item.disabled}\n className=\"cursor-pointer rounded px-2 py-1.5 text-sm outline-none data-[highlighted]:bg-accent data-[disabled]:pointer-events-none data-[disabled]:opacity-50\"\n >\n <BaseSelect.ItemText>{item.label}</BaseSelect.ItemText>\n </BaseSelect.Item>\n ))}\n </BaseSelect.Popup>\n </BaseSelect.Positioner>\n </BaseSelect.Portal>\n </BaseSelect.Root>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Tabs\n// ---------------------------------------------------------------------------\n\nexport interface TabsProps {\n defaultValue?: string;\n value?: string;\n onValueChange?: (v: string) => void;\n className?: string;\n children: React.ReactNode;\n}\n\nexport function Tabs({ defaultValue, value, onValueChange, className, children }: TabsProps) {\n return (\n <BaseTabs.Root\n className={className}\n defaultValue={defaultValue}\n value={value}\n onValueChange={(next) => onValueChange?.(String(next))}\n >\n {children}\n </BaseTabs.Root>\n );\n}\n\nexport function TabsList({\n className,\n children,\n}: {\n className?: string;\n children: React.ReactNode;\n}) {\n return (\n <BaseTabs.List\n className={cn('inline-flex items-center gap-1 rounded-lg bg-muted p-1', className)}\n >\n {children}\n </BaseTabs.List>\n );\n}\n\nexport function TabsTrigger({\n value,\n className,\n children,\n}: {\n value: string;\n className?: string;\n children: React.ReactNode;\n}) {\n return (\n <BaseTabs.Tab\n value={value}\n className={cn(\n 'rounded-md px-3 py-1.5 text-sm font-medium transition-colors',\n 'text-muted-foreground hover:text-foreground',\n 'data-[active]:bg-card data-[active]:text-foreground data-[active]:shadow-sm',\n className,\n )}\n >\n {children}\n </BaseTabs.Tab>\n );\n}\n\nexport function TabsContent({\n value,\n className,\n children,\n}: {\n value: string;\n className?: string;\n children: React.ReactNode;\n}) {\n return (\n <BaseTabs.Panel value={value} className={className}>\n {children}\n </BaseTabs.Panel>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Modal\n// ---------------------------------------------------------------------------\n\nexport interface ModalProps {\n open: boolean;\n onClose: () => void;\n title?: React.ReactNode;\n children: React.ReactNode;\n className?: string;\n}\n\n/** Centred blocking dialog. Base UI owns the focus trap, focus restore and Escape. */\nexport function Modal({ open, onClose, title, children, className }: ModalProps) {\n return (\n <Dialog.Root open={open} onOpenChange={(next) => !next && onClose()}>\n <Dialog.Portal>\n {/* Base UI renders the backdrop `aria-hidden`, so this label is for the\n pointer affordance only — Escape is the accessible way out. */}\n <Dialog.Backdrop aria-label=\"Close\" className=\"fixed inset-0 z-50 bg-overlay\" />\n <Dialog.Popup\n className={cn(\n 'fixed left-1/2 top-1/2 z-50 w-[calc(100%-2rem)] max-w-md -translate-x-1/2 -translate-y-1/2 rounded-xl border bg-card p-5 shadow-lg',\n className,\n )}\n >\n {title && <Dialog.Title className=\"mb-3 text-base font-semibold\">{title}</Dialog.Title>}\n {children}\n </Dialog.Popup>\n </Dialog.Portal>\n </Dialog.Root>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Spinner\n// ---------------------------------------------------------------------------\n\nexport interface SpinnerProps {\n className?: string;\n size?: 'sm' | 'md' | 'lg';\n}\n\nconst spinnerSizes = { sm: 'size-4', md: 'size-6', lg: 'size-8' };\n\nexport function Spinner({ className, size = 'md' }: SpinnerProps) {\n return (\n <svg\n className={cn('animate-spin text-muted-foreground', spinnerSizes[size], className)}\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n aria-label=\"Loading\"\n role=\"status\"\n >\n <circle className=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" strokeWidth=\"4\" />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z\"\n />\n </svg>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Link\n// ---------------------------------------------------------------------------\n\nexport interface LinkProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {\n variant?: 'default' | 'muted';\n}\n\nexport const Link = React.forwardRef<HTMLAnchorElement, LinkProps>(\n ({ className, variant = 'default', ...props }, ref) => (\n <a\n ref={ref}\n className={cn(\n 'underline-offset-4 hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',\n variant === 'default' ? 'text-primary' : 'text-muted-foreground',\n className,\n )}\n {...props}\n />\n ),\n);\nLink.displayName = 'Link';\n\n// ---------------------------------------------------------------------------\n// Switch\n// ---------------------------------------------------------------------------\n\n/**\n * Do not pass `aria-label` when the switch sits inside a `<label>`: the label\n * already names it, and the two naming sources cancel out into no name at all.\n */\nexport interface SwitchProps {\n checked?: boolean;\n onCheckedChange?: (checked: boolean) => void;\n disabled?: boolean;\n className?: string;\n 'aria-label'?: string;\n}\n\nexport function Switch({\n checked = false,\n onCheckedChange,\n disabled,\n className,\n ...props\n}: SwitchProps) {\n return (\n <BaseSwitch.Root\n checked={checked}\n onCheckedChange={(next) => onCheckedChange?.(next)}\n disabled={disabled}\n className={cn(\n // `data-[disabled]`, not `disabled:` — the root is a span, so `:disabled`\n // never matches it and the dimming would silently stop happening.\n 'relative inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full bg-input transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring data-[checked]:bg-primary data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50',\n className,\n )}\n {...props}\n >\n <BaseSwitch.Thumb className=\"inline-block size-4 translate-x-0.5 rounded-full bg-white shadow transition-transform data-[checked]:translate-x-4\" />\n </BaseSwitch.Root>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Icons\n//\n// Inline SVGs rather than a lucide-react dependency: the SDK is loaded through\n// the shell's import map as a single vendor chunk, so a dependency here inflates\n// every app page. Same precedent as Spinner above.\n// ---------------------------------------------------------------------------\n\nfunction IconX({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M18 6 6 18M6 6l12 12\" />\n </svg>\n );\n}\n\nfunction IconCopy({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\" />\n <path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\" />\n </svg>\n );\n}\n\nfunction IconCheck({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M20 6 9 17l-5-5\" />\n </svg>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Textarea\n// ---------------------------------------------------------------------------\n\nexport type TextareaProps = React.TextareaHTMLAttributes<HTMLTextAreaElement>;\n\nexport const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(function Textarea(\n { className, ...props },\n ref,\n) {\n return (\n <textarea\n ref={ref}\n className={cn(\n 'flex min-h-20 w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50',\n className,\n )}\n {...props}\n />\n );\n});\n\n// ---------------------------------------------------------------------------\n// Checkbox\n// ---------------------------------------------------------------------------\n\nexport interface CheckboxProps {\n checked?: boolean;\n defaultChecked?: boolean;\n /** Receives the boolean directly. */\n onCheckedChange?: (checked: boolean) => void;\n disabled?: boolean;\n label?: React.ReactNode;\n /** Submitted with a surrounding form, through a hidden native input. */\n name?: string;\n className?: string;\n 'aria-label'?: string;\n}\n\n/**\n * Checkbox.\n *\n * Contract 2: this used to be a native `<input type=\"checkbox\">` forwarding an\n * `HTMLInputElement` ref and taking every input attribute. Base UI renders a\n * button with the role and a hidden input for form submission, so neither could\n * survive — `onChange` and the ref are gone, `onCheckedChange` is the way in.\n */\nexport function Checkbox({\n checked,\n defaultChecked,\n onCheckedChange,\n disabled,\n label,\n name,\n className,\n ...props\n}: CheckboxProps) {\n const labelId = React.useId();\n const control = React.useRef<HTMLButtonElement>(null);\n const box = (\n <BaseCheckbox.Root\n ref={control}\n aria-labelledby={label ? labelId : undefined}\n checked={checked}\n defaultChecked={defaultChecked}\n onCheckedChange={(next) => onCheckedChange?.(next)}\n disabled={disabled}\n name={name}\n className={cn(\n 'flex size-4 shrink-0 cursor-pointer items-center justify-center rounded border border-input text-primary-foreground transition-colors data-[checked]:border-primary data-[checked]:bg-primary data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50',\n className,\n )}\n {...props}\n >\n <BaseCheckbox.Indicator className=\"text-[10px] leading-none\">✓</BaseCheckbox.Indicator>\n </BaseCheckbox.Root>\n );\n if (!label) return box;\n return (\n // Not a wrapping <label>: Base UI would associate it AND keep its own label,\n // so the text and the control would both answer to the same name and\n // `getByLabelText` would go ambiguous. Pointing `aria-labelledby` at the text\n // names the control once; the click handler keeps the label clickable.\n <span className=\"inline-flex items-center gap-2 text-sm\">\n {box}\n <span\n id={labelId}\n className=\"cursor-pointer\"\n // Forwarded to the control rather than re-derived: the checkbox owns its\n // state when uncontrolled, so computing `!checked` here would report a\n // change that never happened — and `checked` is `undefined` besides.\n onClick={() => control.current?.click()}\n >\n {label}\n </span>\n </span>\n );\n}\n\n// ---------------------------------------------------------------------------\n// SidePanel\n// ---------------------------------------------------------------------------\n\nexport interface SidePanelProps {\n open: boolean;\n onClose: () => void;\n title?: React.ReactNode;\n description?: React.ReactNode;\n children: React.ReactNode;\n className?: string;\n}\n\n/**\n * Blocking slide-over — reach for it when a task has more fields than a `Modal`\n * can show without an inner scrollbar. Full height, so the body scrolls once and\n * a footer can stay pinned; `Modal` centres a box and does no height management.\n *\n * Children are laid out in a flex column filling the panel: put the scrollable\n * region in a `min-h-0 flex-1 overflow-y-auto` child and the footer after it.\n *\n * Focus is trapped inside while open and restored to the opener on close — Base\n * UI's dialog does both, which is what the hand-rolled version never did.\n */\nexport function SidePanel({\n open,\n onClose,\n title,\n description,\n children,\n className,\n}: SidePanelProps) {\n return (\n <Dialog.Root open={open} onOpenChange={(next) => !next && onClose()}>\n <Dialog.Portal>\n <Dialog.Backdrop aria-label=\"Fermer\" className=\"fixed inset-0 z-50 bg-overlay\" />\n <Dialog.Popup\n className={cn(\n 'fixed inset-y-0 right-0 z-50 flex w-full max-w-lg flex-col border-l bg-card shadow-xl',\n className,\n )}\n >\n <header className=\"flex shrink-0 items-start gap-3 border-b px-5 py-4\">\n <div className=\"min-w-0 flex-1\">\n {title && <Dialog.Title className=\"text-base font-semibold\">{title}</Dialog.Title>}\n {description && (\n <Dialog.Description className=\"mt-0.5 text-xs text-muted-foreground\">\n {description}\n </Dialog.Description>\n )}\n </div>\n <Dialog.Close\n aria-label=\"Fermer\"\n className=\"-mr-1 shrink-0 rounded-md p-1 text-muted-foreground hover:bg-accent hover:text-foreground\"\n >\n <IconX className=\"size-4\" />\n </Dialog.Close>\n </header>\n <div className=\"flex min-h-0 flex-1 flex-col px-5 py-4\">{children}</div>\n </Dialog.Popup>\n </Dialog.Portal>\n </Dialog.Root>\n );\n}\n\n// ---------------------------------------------------------------------------\n// CopyButton\n// ---------------------------------------------------------------------------\n\nexport interface CopyButtonProps {\n value: string;\n label?: string;\n copiedLabel?: string;\n variant?: ButtonProps['variant'];\n size?: ButtonProps['size'];\n className?: string;\n}\n\n/** How long the confirmation stays up before reverting. */\nconst COPY_FEEDBACK_MS = 2000;\n\n/**\n * Copy-to-clipboard button with inline feedback. On failure it says so rather\n * than silently doing nothing — keep the copyable text selectable so manual\n * copy stays the fallback.\n */\nexport function CopyButton({\n value,\n label = 'Copier',\n copiedLabel = 'Copié',\n variant = 'outline',\n size = 'sm',\n className,\n}: CopyButtonProps) {\n const [state, setState] = React.useState<'idle' | 'copied' | 'error'>('idle');\n const timeout = React.useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n\n // Held in a ref and cleared on unmount: the panel can close mid-feedback.\n React.useEffect(() => () => clearTimeout(timeout.current), []);\n\n async function copy() {\n const ok = await copyToClipboard(value);\n setState(ok ? 'copied' : 'error');\n clearTimeout(timeout.current);\n timeout.current = setTimeout(() => setState('idle'), COPY_FEEDBACK_MS);\n }\n\n return (\n <Button\n type=\"button\"\n variant={variant}\n size={size}\n className={className}\n onClick={() => void copy()}\n >\n {state === 'copied' ? <IconCheck className=\"size-3.5\" /> : <IconCopy className=\"size-3.5\" />}\n <span aria-live=\"polite\" className={state === 'error' ? 'text-destructive' : undefined}>\n {state === 'copied' ? copiedLabel : state === 'error' ? 'Copie impossible' : label}\n </span>\n </Button>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Popover\n// ---------------------------------------------------------------------------\n\nexport interface PopoverProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n trigger: React.ReactNode;\n children: React.ReactNode;\n align?: 'start' | 'end';\n className?: string;\n}\n\n/** Anchored panel. Controlled — the caller owns `open`. Closes on outside click\n * and Escape, which is what a filter pill needs and a Modal is too heavy for. */\nexport function Popover({\n open,\n onOpenChange,\n trigger,\n children,\n align = 'start',\n className,\n}: PopoverProps) {\n return (\n // The callback is re-wrapped so Base UI's event-details argument stops at the\n // SDK boundary: the engine is an implementation detail, not part of the API.\n <BasePopover.Root open={open} onOpenChange={(next) => onOpenChange(next)}>\n {/* The `inline-block` host is layout parity, not positioning: the old\n Popover wrapped its trigger in one, so dropping it would stretch a\n trigger that used to hug its text inside a flex or grid parent. */}\n <span className=\"inline-block\">\n <BasePopover.Trigger {...triggerProps(trigger)} />\n </span>\n <BasePopover.Portal>\n {/* The stacking context belongs on the positioner: it is the positioned\n element, so a z-index on the statically-positioned popup would do\n nothing. `z-50` matches the dialogs, and DOM order then puts a popover\n opened from inside a panel above it rather than under. */}\n <BasePopover.Positioner side=\"bottom\" align={align} sideOffset={4} className=\"z-50\">\n <BasePopover.Popup\n className={cn('min-w-48 rounded-md border bg-card p-2 shadow-lg', className)}\n >\n {children}\n </BasePopover.Popup>\n </BasePopover.Positioner>\n </BasePopover.Portal>\n </BasePopover.Root>\n );\n}\n\n// ---------------------------------------------------------------------------\n// DropdownMenu\n// ---------------------------------------------------------------------------\n\nexport interface DropdownMenuItem {\n label: React.ReactNode;\n onSelect: () => void;\n disabled?: boolean;\n destructive?: boolean;\n}\n\nexport interface DropdownMenuProps {\n trigger: React.ReactNode;\n items: DropdownMenuItem[];\n align?: 'start' | 'end';\n className?: string;\n}\n\n/** Uncontrolled menu. Selecting an item closes it; arrow keys move between them. */\nexport function DropdownMenu({ trigger, items, align = 'end', className }: DropdownMenuProps) {\n return (\n <Menu.Root>\n <span className=\"inline-block\">\n <Menu.Trigger {...triggerProps(trigger)} />\n </span>\n <Menu.Portal>\n <Menu.Positioner side=\"bottom\" align={align} sideOffset={4} className=\"z-50\">\n <Menu.Popup\n className={cn(\n 'flex min-w-48 flex-col rounded-md border bg-card p-1 shadow-lg',\n className,\n )}\n >\n {items.map((item, i) => (\n <Menu.Item\n key={i}\n disabled={item.disabled}\n onClick={item.onSelect}\n className={cn(\n 'cursor-pointer rounded px-2 py-1.5 text-left text-sm outline-none data-[highlighted]:bg-accent data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n item.destructive && 'text-destructive',\n )}\n >\n {item.label}\n </Menu.Item>\n ))}\n </Menu.Popup>\n </Menu.Positioner>\n </Menu.Portal>\n </Menu.Root>\n );\n}\n","/**\n * `<DataTable>` — the one table the platform has.\n *\n * TanStack Table drives it and `@tanstack/react-virtual` keeps long lists cheap,\n * but neither type crosses this file: the engines are replaceable dependencies of\n * the SDK, not part of its contract. Everything below is plain data.\n *\n * State (search, sort, faceted filters, hidden columns, selection) is\n * controlled-or-uncontrolled in the usual React sense, so a host that wants it in\n * the URL wires nuqs on the outside and the SDK never learns about routing.\n *\n * `manual` is the switch that matters. Off, the table sorts and filters the rows\n * it was given — right for a page that already holds everything. On, it renders\n * `rows` untouched and only reports what the user asked for, which is the only\n * correct behaviour when the server paginates by cursor: filtering a page\n * client-side would silently drop rows that live on the next one.\n */\nimport {\n flexRender,\n getCoreRowModel,\n getFilteredRowModel,\n getSortedRowModel,\n useReactTable,\n type ColumnDef,\n type SortingState,\n} from '@tanstack/react-table';\nimport { useVirtualizer } from '@tanstack/react-virtual';\nimport * as React from 'react';\nimport { cn } from './cn';\nimport {\n Button,\n Checkbox,\n Input,\n Popover,\n Select,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from './components';\n\nexport interface DataTableColumn<Row> {\n /** Stable identifier — also the key used for sorting and hiding. */\n key: string;\n header: React.ReactNode;\n /** Defaults to `String(row[key])`. */\n cell?: (row: Row) => React.ReactNode;\n /** Raw value used for client-side sorting and faceting. */\n value?: (row: Row) => unknown;\n sortable?: boolean;\n align?: 'left' | 'right';\n /** Starting width in pixels; the user can drag from there. */\n width?: number;\n}\n\n/**\n * The operators a filter can use — the same ten names the app manifest declares\n * and the records endpoint implements.\n *\n * The names match; the edges do not, so do not assume a filter composed here and\n * a `views[]` filter agree on every row. Two known differences: `neq` keeps rows\n * whose value is absent here and drops them server-side, and the server compares\n * `gt`/`lt`/`gte`/`lte` on the raw JSON text where this compares numbers and\n * dates as such. And the endpoint's operator map takes one value per operator\n * with no `in`, so a server-side facet should offer single-value operators —\n * multi-select is a client-side affordance.\n */\nexport type DataTableFilterOperator =\n | 'eq'\n | 'neq'\n | 'contains'\n | 'ncontains'\n | 'gt'\n | 'lt'\n | 'gte'\n | 'lte'\n | 'empty'\n | 'nempty';\n\nexport interface DataTableFacet {\n key: string;\n label: string;\n /** Values to choose from. Without them the facet takes a typed value instead. */\n options?: Array<{ value: string; label?: string }>;\n /** Offered operators, first one default. Equality alone if omitted. */\n operators?: DataTableFilterOperator[];\n}\n\nexport interface DataTableFilter {\n operator: DataTableFilterOperator;\n /** Empty for `empty`/`nempty`; one entry for a comparison; several for a set. */\n values: string[];\n}\n\nexport interface DataTableSort {\n key: string;\n direction: 'asc' | 'desc';\n}\n\nexport interface DataTableState {\n search: string;\n sort: DataTableSort | null;\n /** Faceted filters, by facet key. An absent key means \"no constraint\". */\n filters: Record<string, DataTableFilter>;\n hidden: string[];\n selected: string[];\n}\n\nexport interface DataTablePagination {\n hasNext: boolean;\n hasPrevious: boolean;\n onNext: () => void;\n onPrevious: () => void;\n}\n\nexport interface DataTableProps<Row> {\n columns: Array<DataTableColumn<Row>>;\n rows: Row[];\n rowId: (row: Row) => string;\n /** Controlled state. Anything left out falls back to `defaultState`. */\n state?: Partial<DataTableState>;\n defaultState?: Partial<DataTableState>;\n onStateChange?: (state: DataTableState) => void;\n facets?: DataTableFacet[];\n searchPlaceholder?: string;\n selectable?: boolean;\n onRowClick?: (row: Row) => void;\n pagination?: DataTablePagination;\n /** Server does the sorting, filtering and searching; render `rows` as given. */\n manual?: boolean;\n loading?: boolean;\n error?: React.ReactNode;\n empty?: React.ReactNode;\n /** Beyond this many rows the body is virtualised. */\n virtualizeFrom?: number;\n className?: string;\n}\n\nconst EMPTY_STATE: DataTableState = {\n search: '',\n sort: null,\n filters: {},\n hidden: [],\n selected: [],\n};\n\n/** Narrower than this and a column has no room for its own label. */\nconst MIN_COLUMN_WIDTH_PX = 64;\n\n/** Virtualising a short list costs more than it saves. */\nconst DEFAULT_VIRTUALIZE_FROM = 100;\nconst ROW_HEIGHT_PX = 53;\nconst VIRTUAL_VIEWPORT_PX = 640;\n\nfunction useDataTableState(\n controlled: Partial<DataTableState> | undefined,\n initial: Partial<DataTableState> | undefined,\n onStateChange: ((state: DataTableState) => void) | undefined,\n): [DataTableState, (patch: Partial<DataTableState>) => void] {\n const [internal, setInternal] = React.useState<DataTableState>({ ...EMPTY_STATE, ...initial });\n const state = React.useMemo<DataTableState>(\n () => ({ ...EMPTY_STATE, ...initial, ...internal, ...controlled }),\n [controlled, initial, internal],\n );\n\n const patch = (next: Partial<DataTableState>) => {\n const merged = { ...state, ...next };\n setInternal(merged);\n onStateChange?.(merged);\n };\n\n return [state, patch];\n}\n\nexport function DataTable<Row>({\n columns,\n rows,\n rowId,\n state: controlled,\n defaultState,\n onStateChange,\n facets = [],\n searchPlaceholder = 'Rechercher…',\n selectable = false,\n onRowClick,\n pagination,\n manual = false,\n loading = false,\n error,\n empty = 'Aucun résultat.',\n virtualizeFrom = DEFAULT_VIRTUALIZE_FROM,\n className,\n}: DataTableProps<Row>) {\n const [state, patch] = useDataTableState(controlled, defaultState, onStateChange);\n // Column widths are a per-session comfort, not part of the reported state:\n // nobody wants their colleague's column widths in a shared link.\n const [widths, setWidths] = React.useState<Record<string, number>>({});\n const hidden = React.useMemo(() => new Set(state.hidden), [state.hidden]);\n const selected = React.useMemo(() => new Set(state.selected), [state.selected]);\n\n const visibleColumns = React.useMemo(\n () => columns.filter((column) => !hidden.has(column.key)),\n [columns, hidden],\n );\n\n const columnDefs = React.useMemo<Array<ColumnDef<Row>>>(\n () =>\n visibleColumns.map((column) => ({\n id: column.key,\n accessorFn: (row: Row) =>\n column.value ? column.value(row) : (row as Record<string, unknown>)[column.key],\n enableSorting: column.sortable ?? false,\n size: column.width,\n cell: ({ row }) =>\n column.cell\n ? column.cell(row.original)\n : String((row.original as Record<string, unknown>)[column.key] ?? ''),\n })),\n [visibleColumns],\n );\n\n const sorting = React.useMemo<SortingState>(\n () => (state.sort ? [{ id: state.sort.key, desc: state.sort.direction === 'desc' }] : []),\n [state.sort],\n );\n\n const table = useReactTable<Row>({\n data: rows,\n columns: columnDefs,\n state: { sorting, globalFilter: manual ? '' : state.search },\n getRowId: (row) => rowId(row),\n getCoreRowModel: getCoreRowModel(),\n ...(manual\n ? { manualSorting: true, manualFiltering: true }\n : { getSortedRowModel: getSortedRowModel(), getFilteredRowModel: getFilteredRowModel() }),\n });\n\n // Faceted selections narrow the rows the same way in both modes when the host\n // is not doing it: a facet the server does not know about must still work.\n const facetedRows = React.useMemo(() => {\n const active = Object.entries(state.filters).filter(([, filter]) => isApplied(filter));\n if (manual || active.length === 0) return table.getRowModel().rows;\n return table.getRowModel().rows.filter((row) =>\n active.every(([key, filter]) => {\n const column = columns.find((c) => c.key === key);\n const raw = column?.value\n ? column.value(row.original)\n : (row.original as Record<string, unknown>)[key];\n return matches(raw, filter);\n }),\n );\n }, [columns, manual, state.filters, table.getRowModel().rows]);\n\n const bodyRef = React.useRef<HTMLDivElement>(null);\n const longEnoughToVirtualise = facetedRows.length > virtualizeFrom;\n const virtualizer = useVirtualizer({\n count: facetedRows.length,\n getScrollElement: () => bodyRef.current,\n estimateSize: () => ROW_HEIGHT_PX,\n overscan: 8,\n enabled: longEnoughToVirtualise,\n });\n const virtualItems = virtualizer.getVirtualItems();\n // An unmeasured scroll container yields no items. Rendering the whole list is\n // slow; rendering nothing is a blank table, so the slow one wins.\n const virtualise = longEnoughToVirtualise && virtualItems.length > 0;\n\n const toggleSort = (key: string) => {\n const next: DataTableSort | null =\n state.sort?.key !== key\n ? { key, direction: 'asc' }\n : state.sort.direction === 'asc'\n ? { key, direction: 'desc' }\n : null;\n patch({ sort: next });\n };\n\n const toggleSelected = (id: string) => {\n const next = new Set(selected);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n patch({ selected: [...next] });\n };\n\n const allVisibleSelected =\n facetedRows.length > 0 && facetedRows.every((row) => selected.has(row.id));\n\n const toggleAll = () => {\n patch({ selected: allVisibleSelected ? [] : facetedRows.map((row) => row.id) });\n };\n\n const setFilter = (facetKey: string, filter: DataTableFilter | null) => {\n const next = { ...state.filters };\n if (filter) next[facetKey] = filter;\n else delete next[facetKey];\n patch({ filters: next });\n };\n\n const renderedRows = virtualise\n ? virtualItems.map((item) => facetedRows[item.index]!)\n : facetedRows;\n // Spacer rows stand in for what is not rendered, above and below, so the\n // scrollbar reports the height of the whole list rather than of the window.\n const spaceAbove = virtualise ? (virtualItems[0]?.start ?? 0) : 0;\n const spaceBelow = virtualise\n ? virtualizer.getTotalSize() - (virtualItems[virtualItems.length - 1]?.end ?? 0)\n : 0;\n\n const columnCount = visibleColumns.length + (selectable ? 1 : 0);\n\n return (\n <div className={cn('flex flex-col gap-3', className)}>\n <div className=\"flex flex-wrap items-center gap-2\">\n <Input\n value={state.search}\n onChange={(event) => patch({ search: event.target.value })}\n placeholder={searchPlaceholder}\n aria-label={searchPlaceholder}\n className=\"h-9 max-w-xs\"\n />\n\n {facets.map((facet) => (\n <FacetFilter\n key={facet.key}\n facet={facet}\n filter={state.filters[facet.key]}\n onChange={(filter) => setFilter(facet.key, filter)}\n />\n ))}\n\n <ColumnPicker\n columns={columns}\n hidden={hidden}\n onToggle={(key) =>\n patch({\n hidden: hidden.has(key)\n ? state.hidden.filter((k) => k !== key)\n : [...state.hidden, key],\n })\n }\n />\n\n {selectable && selected.size > 0 && (\n <span className=\"text-xs text-muted-foreground\" role=\"status\">\n {selected.size} sélectionné{selected.size > 1 ? 's' : ''}\n </span>\n )}\n </div>\n\n <div\n ref={bodyRef}\n className={cn('overflow-auto rounded-xl border bg-card', virtualise && 'max-h-160')}\n style={virtualise ? { maxHeight: VIRTUAL_VIEWPORT_PX } : undefined}\n >\n <Table>\n <TableHeader className={virtualise ? 'sticky top-0 z-10 bg-card' : undefined}>\n <TableRow>\n {selectable && (\n <TableHead className=\"w-10\">\n <Checkbox\n checked={allVisibleSelected}\n onCheckedChange={toggleAll}\n aria-label=\"Tout sélectionner\"\n />\n </TableHead>\n )}\n {visibleColumns.map((column) => {\n const label = typeof column.header === 'string' ? column.header : column.key;\n return (\n <TableHead\n key={column.key}\n style={{ width: widths[column.key] ?? column.width }}\n className={cn('relative', column.align === 'right' && 'text-right')}\n // Only a column that can be sorted may claim a direction: the\n // state can name a key this table refuses to order by, and\n // announcing a sort that is not happening is worse than silence.\n aria-sort={\n !column.sortable\n ? undefined\n : state.sort?.key === column.key\n ? state.sort.direction === 'asc'\n ? 'ascending'\n : 'descending'\n : 'none'\n }\n >\n {column.sortable ? (\n <button\n type=\"button\"\n onClick={() => toggleSort(column.key)}\n className=\"inline-flex cursor-pointer items-center gap-1 hover:text-foreground\"\n >\n {column.header}\n <SortGlyph\n direction={state.sort?.key === column.key ? state.sort.direction : null}\n />\n </button>\n ) : (\n column.header\n )}\n <ResizeHandle\n label={label}\n onResize={(delta, from) =>\n setWidths((current) => ({\n ...current,\n [column.key]: Math.max(MIN_COLUMN_WIDTH_PX, from + delta),\n }))\n }\n />\n </TableHead>\n );\n })}\n </TableRow>\n </TableHeader>\n\n <TableBody>\n {error ? (\n <StatusRow colSpan={columnCount} tone=\"error\">\n {error}\n </StatusRow>\n ) : loading ? (\n <SkeletonRows columns={columnCount} />\n ) : facetedRows.length === 0 ? (\n <StatusRow colSpan={columnCount}>{empty}</StatusRow>\n ) : (\n <>\n {spaceAbove > 0 && <tr aria-hidden style={{ height: spaceAbove }} />}\n {renderedRows.map((row) => (\n <TableRow\n key={row.id}\n data-state={selected.has(row.id) ? 'selected' : undefined}\n className={\n onRowClick\n ? 'cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset'\n : 'hover:bg-transparent'\n }\n // A clickable row is a control: without these it can only be\n // reached with a mouse. The row keeps its implicit `row`\n // role (a `role=\"button\"` <tr> would break the table's own\n // structure for a screen reader); `tabIndex` + Enter/Space\n // are what make it operable.\n tabIndex={onRowClick ? 0 : undefined}\n onClick={onRowClick ? () => onRowClick(row.original) : undefined}\n onKeyDown={\n onRowClick\n ? (event) => {\n // Only the row's own keystrokes: Space on the\n // selection checkbox must tick the box, not open\n // the row behind it.\n if (event.target !== event.currentTarget) return;\n if (event.key !== 'Enter' && event.key !== ' ') return;\n event.preventDefault();\n onRowClick(row.original);\n }\n : undefined\n }\n >\n {selectable && (\n <TableCell onClick={(event) => event.stopPropagation()}>\n <Checkbox\n checked={selected.has(row.id)}\n onCheckedChange={() => toggleSelected(row.id)}\n aria-label={`Sélectionner ${row.id}`}\n />\n </TableCell>\n )}\n {row.getVisibleCells().map((cell) => {\n const column = visibleColumns.find((c) => c.key === cell.column.id);\n return (\n <TableCell\n key={cell.id}\n className={column?.align === 'right' ? 'text-right' : undefined}\n >\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </TableCell>\n );\n })}\n </TableRow>\n ))}\n {spaceBelow > 0 && <tr aria-hidden style={{ height: spaceBelow }} />}\n </>\n )}\n </TableBody>\n </Table>\n </div>\n\n {pagination && (\n <div className=\"flex items-center justify-end gap-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={!pagination.hasPrevious}\n onClick={pagination.onPrevious}\n >\n Précédent\n </Button>\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={!pagination.hasNext}\n onClick={pagination.onNext}\n >\n Suivant\n </Button>\n </div>\n )}\n </div>\n );\n}\n\n/**\n * Drag the boundary to widen a column.\n *\n * Deliberately out of the accessibility tree. A labelled widget inside a `<th>`\n * joins that header's accessible name — the column would announce as \"Nom\n * Redimensionner Nom\", and `getByLabelText('Nom')` would become ambiguous across\n * the page. Column width is cosmetic and duplicates no function, so hiding the\n * grip costs a keyboard user nothing; hiding a column, which does change what\n * they can read, stays fully keyboard-operable in the picker.\n */\nfunction ResizeHandle({\n label,\n onResize,\n}: {\n label: string;\n onResize: (delta: number, from: number) => void;\n}) {\n const start = (event: React.PointerEvent<HTMLElement>) => {\n const header = event.currentTarget.parentElement;\n if (!header) return;\n const from = header.getBoundingClientRect().width;\n const originX = event.clientX;\n const move = (moveEvent: PointerEvent) => onResize(moveEvent.clientX - originX, from);\n const stop = () => {\n window.removeEventListener('pointermove', move);\n window.removeEventListener('pointerup', stop);\n };\n window.addEventListener('pointermove', move);\n window.addEventListener('pointerup', stop);\n event.preventDefault();\n };\n\n return (\n <span\n aria-hidden\n data-resize-handle={label}\n onPointerDown={start}\n className=\"absolute inset-y-0 right-0 w-1 cursor-col-resize select-none hover:bg-border\"\n />\n );\n}\n\nfunction SortGlyph({ direction }: { direction: 'asc' | 'desc' | null }) {\n return (\n <span aria-hidden className=\"text-[10px] leading-none\">\n {direction === 'asc' ? '▲' : direction === 'desc' ? '▼' : '↕'}\n </span>\n );\n}\n\nfunction StatusRow({\n colSpan,\n tone,\n children,\n}: {\n colSpan: number;\n tone?: 'error';\n children: React.ReactNode;\n}) {\n return (\n <TableRow className=\"hover:bg-transparent\">\n <TableCell\n colSpan={colSpan}\n className={cn(\n 'text-sm',\n tone === 'error' ? 'text-status-blocked' : 'text-muted-foreground',\n )}\n >\n {children}\n </TableCell>\n </TableRow>\n );\n}\n\n/** Grey bars rather than a spinner: the table keeps its shape while it loads. */\nfunction SkeletonRows({ columns }: { columns: number }) {\n return (\n <>\n {Array.from({ length: 5 }, (_, row) => (\n <TableRow key={row} className=\"hover:bg-transparent\">\n {Array.from({ length: columns }, (_, cell) => (\n <TableCell key={cell}>\n <span className=\"block h-3 w-full animate-pulse rounded bg-muted\" />\n </TableCell>\n ))}\n </TableRow>\n ))}\n </>\n );\n}\n\n/** Operators that need no value at all, and those that take exactly one. */\nconst VALUELESS: ReadonlySet<DataTableFilterOperator> = new Set(['empty', 'nempty']);\nconst SINGLE_VALUE: ReadonlySet<DataTableFilterOperator> = new Set([\n 'contains',\n 'ncontains',\n 'gt',\n 'lt',\n 'gte',\n 'lte',\n]);\n\nconst OPERATOR_LABELS: Record<DataTableFilterOperator, string> = {\n eq: 'est',\n neq: \"n'est pas\",\n contains: 'contient',\n ncontains: 'ne contient pas',\n gt: 'supérieur à',\n lt: 'inférieur à',\n gte: 'supérieur ou égal à',\n lte: 'inférieur ou égal à',\n empty: 'est vide',\n nempty: \"n'est pas vide\",\n};\n\n/** A filter with no value to compare against does nothing — except the two that need none. */\nfunction isApplied(filter: DataTableFilter | undefined): filter is DataTableFilter {\n if (!filter) return false;\n return VALUELESS.has(filter.operator) || filter.values.length > 0;\n}\n\n/**\n * Orders two values, or reports that they cannot be ordered.\n *\n * The mode is decided by the bound, not per row: deciding per row makes one\n * filter compare some rows as numbers and others as text, which is how \"montant\n * ≥ 20\" silently keeps a row reading \"n/a\". An empty value orders against\n * nothing — `Number('')` is 0, and a blank cell is not \"zero\".\n */\nfunction compare(value: string, bound: string): number | null {\n if (value === '' || bound === '') return null;\n\n const boundNumber = Number(bound);\n if (!Number.isNaN(boundNumber)) {\n const valueNumber = Number(value);\n return Number.isNaN(valueNumber) ? null : valueNumber - boundNumber;\n }\n\n const boundDate = Date.parse(bound);\n if (!Number.isNaN(boundDate)) {\n const valueDate = Date.parse(value);\n return Number.isNaN(valueDate) ? null : valueDate - boundDate;\n }\n\n return value < bound ? -1 : value > bound ? 1 : 0;\n}\n\nfunction matches(raw: unknown, filter: DataTableFilter): boolean {\n const value = raw == null ? '' : String(raw);\n const [bound = ''] = filter.values;\n const ordering = compare(value, bound);\n\n switch (filter.operator) {\n case 'eq':\n return filter.values.includes(value);\n case 'neq':\n return !filter.values.includes(value);\n case 'contains':\n return value.toLowerCase().includes(bound.toLowerCase());\n case 'ncontains':\n return !value.toLowerCase().includes(bound.toLowerCase());\n case 'gt':\n return ordering !== null && ordering > 0;\n case 'lt':\n return ordering !== null && ordering < 0;\n case 'gte':\n return ordering !== null && ordering >= 0;\n case 'lte':\n return ordering !== null && ordering <= 0;\n case 'empty':\n return value === '';\n case 'nempty':\n return value !== '';\n }\n}\n\n/**\n * One facet: an operator, then whatever that operator needs.\n *\n * The operator picker only appears when there is a choice to make — a facet that\n * offers equality alone stays the plain checkbox list it was.\n */\nfunction FacetFilter({\n facet,\n filter,\n onChange,\n}: {\n facet: DataTableFacet;\n filter: DataTableFilter | undefined;\n onChange: (filter: DataTableFilter | null) => void;\n}) {\n const [open, setOpen] = React.useState(false);\n const operators = facet.operators ?? ['eq'];\n const operator = filter?.operator ?? operators[0] ?? 'eq';\n const values = filter?.values ?? [];\n\n const summary = !isApplied(filter)\n ? facet.label\n : VALUELESS.has(operator)\n ? `${facet.label} · ${OPERATOR_LABELS[operator]}`\n : `${facet.label} · ${values.length}`;\n\n const setOperator = (next: DataTableFilterOperator) => {\n // Values only survive between operators that take the same kind of value. A\n // typed bound carried into `est` becomes a selection that matches nothing and\n // that no checkbox shows as ticked — an active filter the user cannot untick.\n const sameKind = SINGLE_VALUE.has(next) === SINGLE_VALUE.has(operator);\n onChange({\n operator: next,\n values:\n VALUELESS.has(next) || !sameKind\n ? []\n : SINGLE_VALUE.has(next)\n ? values.slice(0, 1)\n : values,\n });\n };\n\n return (\n <Popover\n open={open}\n onOpenChange={setOpen}\n trigger={\n // Named for what it does: a chip reading just \"Nom\" tells a screen-reader\n // user nothing, and collides with the sortable column header of that name.\n <Button variant=\"outline\" size=\"sm\" aria-label={`Filtrer par ${summary}`}>\n {summary}\n </Button>\n }\n >\n <div className=\"flex w-56 flex-col gap-2\">\n {operators.length > 1 && (\n <Select\n value={operator}\n aria-label={`Opérateur — ${facet.label}`}\n onValueChange={(next) => setOperator(next as DataTableFilterOperator)}\n items={operators.map((candidate) => ({\n value: candidate,\n label: OPERATOR_LABELS[candidate],\n }))}\n />\n )}\n\n {VALUELESS.has(operator) ? null : SINGLE_VALUE.has(operator) || !facet.options ? (\n <Input\n value={values[0] ?? ''}\n aria-label={`Valeur — ${facet.label}`}\n onChange={(event) =>\n onChange({ operator, values: event.target.value ? [event.target.value] : [] })\n }\n />\n ) : (\n facet.options.map((option) => (\n <Checkbox\n key={option.value}\n checked={values.includes(option.value)}\n onCheckedChange={() =>\n onChange({\n operator,\n values: values.includes(option.value)\n ? values.filter((v) => v !== option.value)\n : [...values, option.value],\n })\n }\n label={option.label ?? option.value}\n />\n ))\n )}\n\n {isApplied(filter) && (\n <Button variant=\"ghost\" size=\"sm\" onClick={() => onChange(null)}>\n Effacer\n </Button>\n )}\n </div>\n </Popover>\n );\n}\n\nfunction ColumnPicker<Row>({\n columns,\n hidden,\n onToggle,\n}: {\n columns: Array<DataTableColumn<Row>>;\n hidden: Set<string>;\n onToggle: (key: string) => void;\n}) {\n const [open, setOpen] = React.useState(false);\n return (\n <Popover\n open={open}\n onOpenChange={setOpen}\n align=\"end\"\n trigger={\n <Button variant=\"outline\" size=\"sm\">\n Colonnes\n </Button>\n }\n >\n <div className=\"flex flex-col gap-1\">\n {columns.map((column) => (\n <Checkbox\n key={column.key}\n checked={!hidden.has(column.key)}\n onCheckedChange={() => onToggle(column.key)}\n label={typeof column.header === 'string' ? column.header : column.key}\n />\n ))}\n </div>\n </Popover>\n );\n}\n","/**\n * The period a dashboard is looking at, and the window it compares against.\n *\n * Days are local-calendar `YYYY-MM-DD` — the same shape `DateRange` already\n * speaks, and the one a date input and DayPicker both understand. Turning a day\n * into an instant is the caller's business: only it knows whether its filter\n * wants an inclusive end-of-day or an exclusive next-midnight.\n *\n * Every resolution takes the reference day as an argument. Reading the clock is\n * left to the edge (a handler, an effect) so the maths stays a pure function of\n * its inputs, and a test does not have to freeze time to be deterministic.\n */\nimport {\n differenceInCalendarDays,\n endOfMonth,\n format,\n parse,\n startOfMonth,\n startOfQuarter,\n startOfYear,\n subDays,\n subMonths,\n subYears,\n} from 'date-fns';\n\nexport type PeriodPresetKey =\n | 'today'\n | 'yesterday'\n | 'last7'\n | 'last30'\n | 'last90'\n | 'thisMonth'\n | 'lastMonth'\n | 'thisQuarter'\n | 'last12Months'\n | 'thisYear'\n | 'all'\n | 'custom';\n\nexport interface PeriodRange {\n /**\n * Absent means unbounded — only the `all` preset produces it. The spec's\n * `PeriodValue` sketch types `from` as required, which cannot express the\n * \"all time\" entry its own preset rail asks for; a filter with no lower bound\n * is a different query, so the type says so rather than encoding it as a\n * sentinel date the caller would have to recognise.\n */\n from?: string;\n to: string;\n}\n\nexport type PeriodCompareMode = 'none' | 'previous_period' | 'previous_year' | 'custom';\n\nexport interface PeriodValue {\n preset: PeriodPresetKey;\n range: PeriodRange;\n compare: PeriodCompareMode;\n /** The window `compare` resolves to. Absent when comparing to nothing. */\n compareRange?: PeriodRange;\n}\n\nexport interface PeriodPreset {\n key: PeriodPresetKey;\n label: string;\n}\n\n/** The rail, in the order it is offered. `custom` is reached by picking days. */\nexport const PERIOD_PRESETS: readonly PeriodPreset[] = [\n { key: 'today', label: \"Aujourd'hui\" },\n { key: 'yesterday', label: 'Hier' },\n { key: 'last7', label: '7 derniers jours' },\n { key: 'last30', label: '30 derniers jours' },\n { key: 'last90', label: '90 derniers jours' },\n { key: 'thisMonth', label: 'Mois en cours' },\n { key: 'lastMonth', label: 'Mois dernier' },\n { key: 'thisQuarter', label: 'Trimestre en cours' },\n { key: 'last12Months', label: '12 derniers mois' },\n { key: 'thisYear', label: 'Année en cours' },\n { key: 'all', label: \"Tout l'historique\" },\n];\n\nexport const COMPARE_LABELS: Record<PeriodCompareMode, string> = {\n none: 'Ne pas comparer',\n previous_period: 'Période précédente',\n previous_year: 'Année précédente',\n custom: 'Période personnalisée',\n};\n\n/**\n * The comparison as the trigger says it, next to a range that already takes the\n * width. `COMPARE_LABELS` is what the panel offers; this is what a button can\n * afford to show.\n */\nexport const COMPARE_SHORT_LABELS: Record<PeriodCompareMode, string> = {\n none: '',\n previous_period: 'période préc.',\n previous_year: 'N-1',\n custom: 'période choisie',\n};\n\nconst DAY_FORMAT = 'yyyy-MM-dd';\n\n/** A Date as a local `YYYY-MM-DD`. */\nexport const toDay = (date: Date): string => format(date, DAY_FORMAT);\n\n/** A local `YYYY-MM-DD` back to a Date at local midnight. */\nexport const fromDay = (day: string): Date => parse(day, DAY_FORMAT, new Date());\n\n/**\n * The day bounds of a preset, relative to `today`.\n *\n * No preset ever reaches into the future: \"this month\" is the month so far, not\n * the whole month. Two things depend on it. Nobody has data for tomorrow, so a\n * period that included it would put an empty tail on every axis; and the picker\n * refuses to let a future day be clicked, so a preset landing there would offer\n * a range the calendar itself would not let anyone build.\n *\n * These are business rules, not implementation: two screens that both say \"30\n * derniers jours\" have to mean the same thirty days. The rolling windows include\n * today — seven days is J−6 to J, not J−7.\n */\nfunction presetRange(preset: PeriodPresetKey, today: Date): PeriodRange {\n const day = toDay(today);\n switch (preset) {\n case 'today':\n return { from: day, to: day };\n case 'yesterday': {\n const yesterday = toDay(subDays(today, 1));\n return { from: yesterday, to: yesterday };\n }\n case 'last7':\n return { from: toDay(subDays(today, 6)), to: day };\n case 'last30':\n return { from: toDay(subDays(today, 29)), to: day };\n case 'last90':\n return { from: toDay(subDays(today, 89)), to: day };\n case 'thisMonth':\n return { from: toDay(startOfMonth(today)), to: day };\n case 'lastMonth': {\n // The one calendar preset that is whole, because it is entirely behind us.\n const previous = subMonths(today, 1);\n return { from: toDay(startOfMonth(previous)), to: toDay(endOfMonth(previous)) };\n }\n case 'thisQuarter':\n return { from: toDay(startOfQuarter(today)), to: day };\n case 'last12Months':\n // The same day of the month, twelve months back. `subMonths` clamps a 31st\n // onto a short month rather than spilling into the next one.\n return { from: toDay(subMonths(today, 12)), to: day };\n case 'thisYear':\n return { from: toDay(startOfYear(today)), to: day };\n case 'all':\n return { to: day };\n case 'custom':\n return { from: day, to: day };\n }\n}\n\n/**\n * The window a comparison mode resolves to, or undefined when there is nothing\n * to compare against — `none`, an unbounded period, or `custom`, whose range the\n * user picks and which therefore cannot be derived.\n */\nexport function comparisonRange(\n // Unread since the calendar presets stopped being a special case, and kept\n // because dropping it from a published signature breaks every caller for no\n // gain — a future mode that needs the preset would want it back.\n preset: PeriodPresetKey,\n range: PeriodRange,\n compare: PeriodCompareMode,\n): PeriodRange | undefined {\n if (compare === 'none' || compare === 'custom' || range.from === undefined) return undefined;\n\n const from = fromDay(range.from);\n const to = fromDay(range.to);\n\n if (compare === 'previous_year') {\n // The year shifts, not 365 days: June 2026 compares to June 2025 whatever\n // the months in between are worth. A day count would slide the comparison a\n // day or two a year and destroy the season-to-season comparability that is\n // the whole point of the mode. A 29 February lands on the 28th.\n return { from: toDay(subYears(from, 1)), to: toDay(subYears(to, 1)) };\n }\n\n // One formula, every preset: the same number of days, ending the day before\n // this period starts. A calendar preset gets no special case — \"mois en cours\"\n // is the month so far, so the fifteen days before it are the honest\n // comparison, not the thirty-one of a whole previous month.\n const length = differenceInCalendarDays(to, from) + 1;\n return { from: toDay(subDays(from, length)), to: toDay(subDays(to, length)) };\n}\n\n/** A period with its comparison window resolved — the only way to build one. */\nexport function makePeriod(\n preset: PeriodPresetKey,\n range: PeriodRange,\n compare: PeriodCompareMode,\n customCompareRange?: PeriodRange,\n): PeriodValue {\n const resolved =\n compare === 'custom' ? customCompareRange : comparisonRange(preset, range, compare);\n // An unbounded period has no window to shift, so the mode it advertises has to\n // fall back to the truth rather than claim a comparison that produced nothing.\n const effective: PeriodCompareMode = resolved === undefined ? 'none' : compare;\n return {\n preset,\n range,\n compare: effective,\n ...(resolved ? { compareRange: resolved } : {}),\n };\n}\n\n/** The period a preset resolves to, relative to `today`. */\nexport function periodFromPreset(\n preset: PeriodPresetKey,\n today: Date,\n compare: PeriodCompareMode = 'none',\n): PeriodValue {\n return makePeriod(preset, presetRange(preset, today), compare);\n}\n\nconst MONTHS_ABBR = [\n 'janv.',\n 'févr.',\n 'mars',\n 'avr.',\n 'mai',\n 'juin',\n 'juil.',\n 'août',\n 'sept.',\n 'oct.',\n 'nov.',\n 'déc.',\n];\n\nconst formatDay = (day: string): string => {\n const date = fromDay(day);\n return `${date.getDate()} ${MONTHS_ABBR[date.getMonth()]} ${date.getFullYear()}`;\n};\n\n/** A range as a person reads it, collapsing the parts both ends share. */\nexport function formatRange(range: PeriodRange): string {\n if (range.from === undefined) return `Jusqu'au ${formatDay(range.to)}`;\n if (range.from === range.to) return formatDay(range.from);\n\n const from = fromDay(range.from);\n const to = fromDay(range.to);\n if (from.getFullYear() === to.getFullYear() && from.getMonth() === to.getMonth()) {\n return `${from.getDate()} – ${to.getDate()} ${MONTHS_ABBR[to.getMonth()]} ${to.getFullYear()}`;\n }\n return `${formatDay(range.from)} – ${formatDay(range.to)}`;\n}\n\n/**\n * What the trigger shows: the preset's name, or the days a custom range spans.\n *\n * A range can arrive incomplete — the picker it replaced accepted `{from: '',\n * to: ''}` as \"nothing chosen yet\" — and formatting one would print an Invalid\n * Date rather than say there is nothing to show.\n */\nexport function formatPeriod(value: PeriodValue): string {\n const preset = PERIOD_PRESETS.find((entry) => entry.key === value.preset);\n if (preset) return preset.label;\n return isCompleteRange(value.range) ? formatRange(value.range) : 'Période';\n}\n\nconst DAY_PATTERN = /^\\d{4}-\\d{2}-\\d{2}$/;\n\n/** Whether a string is a day this module can do arithmetic on. */\nexport const isDay = (value: string | undefined): value is string =>\n value !== undefined && DAY_PATTERN.test(value);\n\n/** Whether a range has the ends it needs. Only `all` is allowed to lack a start. */\nexport function isCompleteRange(range: PeriodRange): boolean {\n return isDay(range.to) && (range.from === undefined || isDay(range.from));\n}\n\n/**\n * Whether the calendar needs two months to show a range whole.\n *\n * Any range whose ends fall in different months, not just a long one: a five-day\n * range across the turn of a month is still a range with an end the user cannot\n * see, which is the thing a second month is there to fix.\n */\nexport function spansTwoMonths(range: PeriodRange): boolean {\n if (!isDay(range.from) || !isDay(range.to)) return false;\n const from = fromDay(range.from);\n const to = fromDay(range.to);\n return from.getFullYear() !== to.getFullYear() || from.getMonth() !== to.getMonth();\n}\n\n/** Puts a pair of days in order, so an inverted range never leaves the picker. */\nexport function orderedRange(from: string, to: string): PeriodRange {\n return from <= to ? { from, to } : { from: to, to: from };\n}\n","/**\n * The period control: a preset rail, a calendar, and the window to compare with.\n *\n * Controlled, and applied on an explicit press — except that a rail without a\n * comparison to settle afterwards applies straight away, because that is a click\n * and not a form. Every dashboard built on this refetches when the period\n * changes, so emitting a half-picked range — the state the calendar is in\n * between the two clicks that make a range — would fire a query for a period\n * nobody asked for.\n *\n * One grid, two ranges. Two pills above the calendar say which of them a click\n * is about to change, so the comparison is picked where it is read rather than\n * typed into a pair of date fields beside it.\n *\n * Routing is not this component's business: `PeriodValue` is plain data, so a\n * host that wants a shared link to carry the comparison stores it with whatever\n * router it already has (see the shell's `useTableUrlState` for the precedent).\n */\nimport { fr } from 'date-fns/locale/fr';\nimport * as React from 'react';\nimport { DayPicker, labelDayButton } from 'react-day-picker';\nimport { Button, Popover } from './components';\nimport { cn } from './cn';\nimport {\n COMPARE_LABELS,\n COMPARE_SHORT_LABELS,\n PERIOD_PRESETS,\n comparisonRange,\n formatPeriod,\n formatRange,\n fromDay,\n isDay,\n makePeriod,\n orderedRange,\n periodFromPreset,\n spansTwoMonths,\n toDay,\n type PeriodCompareMode,\n type PeriodPreset,\n type PeriodPresetKey,\n type PeriodRange,\n type PeriodValue,\n} from './period';\n\nexport interface DateRangeCompareProps {\n value: PeriodValue;\n onChange: (value: PeriodValue) => void;\n /** Offer the comparison section. */\n comparable?: boolean;\n /** Override the rail — a subset, or presets in another order. */\n presets?: readonly PeriodPreset[];\n /**\n * How many months the grid shows. `'auto'` widens to two whenever the range\n * straddles them. One by default: two doubles the panel's width, which a\n * dashboard header rarely has, and a range wider than the grid stays correctly\n * highlighted on the part that is visible.\n */\n months?: 1 | 2 | 'auto';\n align?: 'start' | 'end';\n disabled?: boolean;\n className?: string;\n}\n\nconst COMPARE_MODES: readonly PeriodCompareMode[] = [\n 'none',\n 'previous_period',\n 'previous_year',\n 'custom',\n];\n\n/** Where a click in the grid goes. */\ntype PeriodTarget = 'period' | 'compare';\n\n/**\n * DayPicker ships a stylesheet, which this deliberately does not import: the SDK\n * is styled by the shell's Tailwind build, and a second source of styles would\n * escape both the theme and the CSS invariant that proves the shell ships every\n * class the SDK renders. Only the keys that need to look like the design system\n * are named; the rest keep DayPicker's own inert class names.\n *\n * `selected` and `range_*` are among the ones left inert on purpose — see\n * `DAY_MODIFIER_CLASS_NAMES`, which paints both ranges by hand.\n */\nconst DAY_PICKER_CLASS_NAMES = {\n // DayPicker renders its Nav as a sibling of the months, before them, so the\n // arrows are positioned against this box rather than against a caption.\n months: 'relative flex gap-4',\n month: 'space-y-2',\n month_caption: 'flex h-8 items-center justify-center',\n caption_label: 'text-sm font-medium capitalize',\n nav: 'flex items-center justify-between absolute inset-x-0 h-8 px-1 pointer-events-none',\n button_previous:\n 'pointer-events-auto inline-flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground disabled:opacity-40',\n button_next:\n 'pointer-events-auto inline-flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground disabled:opacity-40',\n chevron: 'h-4 w-4 fill-current',\n month_grid: 'w-full border-collapse',\n weekdays: 'flex',\n weekday: 'w-9 text-xs font-normal text-muted-foreground',\n week: 'flex w-full',\n day: 'h-9 w-9 p-0 text-center text-sm',\n day_button:\n 'h-9 w-9 rounded-md transition-colors hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',\n today: 'font-semibold text-primary',\n outside: 'text-muted-foreground/50',\n disabled: 'opacity-40',\n // A cell DayPicker decided not to fill still occupies the grid, and still\n // matches the range modifiers below — without this it would show a stretch of\n // painted band with no number in it. `invisible`, not `hidden`: the six-week\n // grid keeps its height either way.\n hidden: 'invisible',\n};\n\n/**\n * Both ranges, painted by hand.\n *\n * DayPicker's own `range_*` classes follow its single selection, which follows\n * the target — so they cannot describe a grid showing two ranges at once, and\n * would repaint the comparison in the period's colours the moment the target\n * moved. Dropping them from `classNames` makes the grid's appearance independent\n * of where clicks are going.\n *\n * \"When the two ranges cross, the period wins the cell\" is not an ordering\n * question: DayPicker joins modifier class names in an order that means nothing\n * to Tailwind — which resolves conflicts by stylesheet order — and that is not\n * even stable, since the keys are built from whichever modifier the first\n * matching day of the grid happened to hit. The two sets are made disjoint\n * instead: the comparison is only ever drawn where the period is not.\n *\n * The other half is that a band paints the cell and a bound paints the button\n * inside it. Different elements, so the band's tint and the bound's fill never\n * race.\n *\n * The two are told apart by shape before colour — the period fills its bounds,\n * the comparison rings them — because the shell's dark theme sets `--chart-2` to\n * the same Jour as `--primary`, and a pair of ranges distinguished by hue alone\n * would collapse into one there. The tints are two steps apart for the same\n * reason: same hue, different weight, still two bands.\n */\nconst DAY_MODIFIER_CLASS_NAMES = {\n period_middle: 'bg-primary/15',\n period_start:\n 'rounded-l-md [&_button]:bg-primary [&_button]:text-primary-foreground [&_button]:hover:bg-primary',\n period_end:\n 'rounded-r-md [&_button]:bg-primary [&_button]:text-primary-foreground [&_button]:hover:bg-primary',\n compare_middle: 'bg-chart-2/30',\n compare_start:\n 'rounded-l-md bg-chart-2/30 [&_button]:ring-2 [&_button]:ring-inset [&_button]:ring-chart-2 [&_button]:font-semibold [&_button]:text-chart-2',\n compare_end:\n 'rounded-r-md bg-chart-2/30 [&_button]:ring-2 [&_button]:ring-inset [&_button]:ring-chart-2 [&_button]:font-semibold [&_button]:text-chart-2',\n};\n\n/** What the calendar is showing while the popover is open. */\ninterface Draft {\n preset: PeriodPresetKey;\n from?: string;\n to?: string;\n compare: PeriodCompareMode;\n compareFrom?: string;\n compareTo?: string;\n}\n\nfunction draftOf(value: PeriodValue): Draft {\n return {\n preset: value.preset,\n // Anything that is not a day is \"not chosen yet\". The picker this replaced\n // accepted `{ from: '', to: '' }` for exactly that, and its callers still do.\n from: isDay(value.range.from) ? value.range.from : undefined,\n to: isDay(value.range.to) ? value.range.to : undefined,\n compare: value.compare,\n compareFrom: value.compareRange?.from,\n compareTo: value.compareRange?.to,\n };\n}\n\n/**\n * The range the draft describes, once it has both ends. The `all` preset is the\n * one case with no start, which is why a missing `from` alone cannot mean\n * \"still picking\".\n */\nfunction rangeOf(draft: Draft): PeriodRange | null {\n if (!isDay(draft.to)) return null;\n if (draft.preset === 'all') return { to: draft.to };\n if (!isDay(draft.from)) return null;\n return { from: draft.from, to: draft.to };\n}\n\n/**\n * The comparison window the user picked by hand, in order. A pair of clicks can\n * land either way round, so it is sorted here rather than trusted.\n */\nfunction customCompareOf(draft: Draft): PeriodRange | undefined {\n if (!isDay(draft.compareFrom) || !isDay(draft.compareTo)) return undefined;\n return orderedRange(draft.compareFrom, draft.compareTo);\n}\n\n/** The window the footer previews — derived for the modes that derive one. */\nfunction previewCompare(draft: Draft): PeriodRange | undefined {\n const range = rangeOf(draft);\n if (!range) return undefined;\n if (draft.compare === 'custom') return customCompareOf(draft);\n return comparisonRange(draft.preset, range, draft.compare);\n}\n\n/**\n * The comparison the draft can actually express. An unbounded period has no\n * length to shift, so the section falls back to \"none\" without overwriting the\n * mode the user picked — going through \"tout l'historique\" on the way to another\n * preset must not silently drop their choice.\n */\nfunction activeCompare(draft: Draft): PeriodCompareMode {\n return draft.preset === 'all' ? 'none' : draft.compare;\n}\n\n/** A pair of days as a band the grid can paint. One clicked day is a one-day band. */\ninterface Band {\n from: Date;\n to: Date;\n}\n\n/**\n * A band from a half-picked pair. The first of two clicks has to leave a mark,\n * or the calendar looks broken between them.\n */\nfunction bandOf(from: string | undefined, to: string | undefined): Band | undefined {\n if (!isDay(from)) return undefined;\n const start = fromDay(from);\n return { from: start, to: isDay(to) ? fromDay(to) : start };\n}\n\n// `fromDay` always lands on local midnight, so plain comparison is exact here.\nconst inBand = (band: Band | undefined, date: Date): boolean =>\n band !== undefined && date >= band.from && date <= band.to;\n\nconst isBound = (date: Date, bound: Date | undefined): boolean =>\n bound !== undefined && date.getTime() === bound.getTime();\n\n/** The comparison as the grid shows it: the pair being picked, or the derived one. */\nfunction compareBandOf(draft: Draft): Band | undefined {\n const active = activeCompare(draft);\n if (active === 'none') return undefined;\n if (active === 'custom') return bandOf(draft.compareFrom, draft.compareTo);\n const derived = previewCompare(draft);\n return derived?.from ? { from: fromDay(derived.from), to: fromDay(derived.to) } : undefined;\n}\n\n/**\n * The month the grid should be showing for a range.\n *\n * Two months are a window onto the whole range, so they anchor on its start and\n * the end falls into the second grid. One month cannot show both ends, and the\n * end is the one that matters: someone reopening on \"mois en cours\" is asking\n * about the days they already have, not about the first of the month.\n *\n * The end is clamped to today because a caller may hand in a range that reaches\n * into the future, and anchoring there would open the panel on a grid where\n * every day is disabled. No preset does this — this guards the callers.\n */\nfunction anchorMonth(range: PeriodRange, visible: 1 | 2, today: Date): Date | undefined {\n const from = isDay(range.from) ? fromDay(range.from) : undefined;\n const to = isDay(range.to) ? fromDay(range.to) : undefined;\n if (visible === 2) return from ?? to;\n if (!to) return from;\n if (to <= today) return to;\n return from && from <= today ? today : (from ?? today);\n}\n\n/** DayPicker wants the open end as `undefined`, or it closes a one-day range. */\nfunction selectionOf(from: string | undefined, to: string | undefined) {\n if (!isDay(from)) return undefined;\n return { from: fromDay(from), to: isDay(to) ? fromDay(to) : undefined };\n}\n\nexport function DateRangeCompare({\n value,\n onChange,\n comparable = true,\n presets = PERIOD_PRESETS,\n months = 1,\n align = 'start',\n disabled,\n className,\n}: DateRangeCompareProps) {\n const [open, setOpen] = React.useState(false);\n const [draft, setDraft] = React.useState<Draft>(() => draftOf(value));\n // The calendar is driven, not merely initialised: DayPicker reads `defaultMonth`\n // once and then stays mounted, so a preset that lands in another month would\n // leave the grid where it was, showing none of the days it just selected.\n const [month, setMonth] = React.useState<Date | undefined>(undefined);\n // Only consulted in `'auto'`. Recomputed when the rail changes the range, never\n // while days are being clicked — a grid that grew a second month under the\n // cursor mid-selection would move every day the user was aiming at.\n const [autoMonths, setAutoMonths] = React.useState<1 | 2>(1);\n const [target, setTarget] = React.useState<PeriodTarget>('period');\n // Re-read when the panel opens, then held still: a fresh Date every render\n // re-matches every modifier for nothing, and a panel left open across midnight\n // would change its rules mid-gesture.\n const [today, setToday] = React.useState(() => new Date());\n\n const visibleMonths: 1 | 2 = months === 'auto' ? autoMonths : months;\n\n // The count is derived locally rather than read back from state, which is a\n // render behind while `showRange` is still running.\n const showRange = (range: PeriodRange, at: Date = today) => {\n const next: 1 | 2 = months === 'auto' ? (spansTwoMonths(range) ? 2 : 1) : months;\n setAutoMonths(next);\n setMonth(anchorMonth(range, next, at));\n };\n\n const openPanel = () => {\n const now = new Date();\n setToday(now);\n setDraft(draftOf(value));\n setTarget('period');\n showRange(value.range, now);\n setOpen(true);\n };\n\n const range = rangeOf(draft);\n const compareRange = previewCompare(draft);\n // Only a comparison picked by hand has anything for the grid to change, and a\n // stale 'compare' target would send a click into a window nothing displays.\n // Derived rather than an effect: no render ever shows the inconsistent pair.\n const compareEditable = comparable && activeCompare(draft) === 'custom';\n const activeTarget: PeriodTarget = compareEditable ? target : 'period';\n\n const periodBand = bandOf(draft.from, draft.to);\n const compareBand = compareBandOf(draft);\n\n /** Emits a draft as a period and closes. False when it has nothing to emit. */\n const emit = (candidate: Draft): boolean => {\n const complete = rangeOf(candidate);\n if (!complete) return false;\n onChange(\n makePeriod(candidate.preset, complete, activeCompare(candidate), customCompareOf(candidate)),\n );\n setOpen(false);\n return true;\n };\n\n const apply = () => emit(draft);\n\n const pickPreset = (preset: PeriodPresetKey, commit: boolean) => {\n const resolved = periodFromPreset(preset, today, activeCompare(draft));\n const next: Draft = {\n ...draftOf(resolved),\n // The rail changes the period, not the comparison: the mode the user chose\n // survives, and `activeCompare` decides whether it can apply here.\n compare: draft.compare,\n compareFrom: draft.compareFrom,\n compareTo: draft.compareTo,\n };\n setDraft(next);\n setTarget('period');\n showRange(resolved.range);\n // With no comparison to settle afterwards, a preset is a decision rather\n // than a draft — one click, not a form. As soon as a comparison is on offer\n // everything stays a draft, because settling it takes a second gesture and\n // applying in between would reload the screen on a state nobody asked for.\n if (!comparable && commit) emit(next);\n };\n\n const pickDays = (selected: { from?: Date; to?: Date } | undefined) => {\n const from = selected?.from ? toDay(selected.from) : undefined;\n const to = selected?.to ? toDay(selected.to) : undefined;\n if (activeTarget === 'compare') {\n // Picking days in the grid is what the custom mode is: writing the pair\n // without saying so would leave a draft whose mode contradicts its range.\n setDraft({ ...draft, compare: 'custom', compareFrom: from, compareTo: to });\n return;\n }\n // A click in the grid cancels the preset — the period becomes custom.\n setDraft({ ...draft, preset: 'custom', from, to });\n };\n\n const chooseCompare = (mode: PeriodCompareMode) => {\n const next: Draft = { ...draft, compare: mode };\n setDraft(next);\n // Asking for a custom window is asking to draw one, so the grid follows.\n setTarget(mode === 'custom' ? 'compare' : 'period');\n const shown = mode === 'custom' ? customCompareOf(next) : range;\n if (shown) showRange(shown);\n };\n\n const focusTarget = (next: PeriodTarget) => {\n setTarget(next);\n const shown = next === 'compare' ? customCompareOf(draft) : range;\n if (shown) showRange(shown);\n };\n\n const footer =\n activeTarget === 'compare'\n ? compareRange\n ? formatRange(compareRange)\n : 'Période de comparaison à choisir'\n : range\n ? `${formatRange(range)}${compareRange ? ` vs ${formatRange(compareRange)}` : ''}`\n : 'Date de fin à choisir';\n\n return (\n <Popover\n open={open}\n onOpenChange={(next) => (next ? openPanel() : setOpen(false))}\n align={align}\n className={cn('w-auto p-0', className)}\n trigger={\n <Button variant=\"outline\" disabled={disabled}>\n <IconCalendar className=\"size-4 text-muted-foreground\" />\n <span>{formatPeriod(value)}</span>\n {/* `makePeriod` reports `none` when a window fails to resolve, so this\n badge cannot claim a comparison that produced nothing. */}\n {value.compare !== 'none' && value.compareRange !== undefined && (\n <span className=\"rounded-md bg-chart-2/15 px-1.5 py-0.5 text-xs font-medium text-chart-2\">\n vs {COMPARE_SHORT_LABELS[value.compare]}\n </span>\n )}\n <IconChevronDown className=\"size-4 text-muted-foreground\" />\n </Button>\n }\n >\n {/* The rail sets the height when it is taller than the calendar, so eleven\n presets are all reachable without scrolling — hiding half of them\n behind a scrollbar to keep the panel calendar-sized costs more than the\n slack under the grid. The cap is what stops a caller with thirty\n presets from growing a panel past the viewport; past it the list\n scrolls and the \"Comparer\" block stays put at the bottom. */}\n <div className=\"flex max-h-[80vh] items-stretch\">\n {(presets.length > 0 || comparable) && (\n <div className=\"flex w-48 shrink-0 flex-col border-r\">\n {presets.length > 0 && (\n <PresetRail\n presets={presets}\n selected={draft.preset}\n onSelect={pickPreset}\n // `min-h-0` is what lets a flex child shrink below its content,\n // which is what makes `overflow-y-auto` do anything at all here.\n className=\"min-h-0 flex-1 overflow-y-auto p-2\"\n />\n )}\n {comparable && (\n <CompareSection\n draft={draft}\n compareRange={compareRange}\n onModeChange={chooseCompare}\n />\n )}\n </div>\n )}\n\n <div className=\"flex flex-col\">\n {comparable && (\n <TargetPills\n target={activeTarget}\n onSelect={focusTarget}\n compareEditable={compareEditable}\n />\n )}\n\n <div className=\"relative p-3\">\n <DayPicker\n mode=\"range\"\n // The rest of the SDK ships French labels; an English month caption\n // in the middle of them would be the only word a user has to\n // translate. `weekStartsOn` is restated so the grid does not change\n // shape if the locale ever does.\n locale={fr}\n weekStartsOn={1}\n numberOfMonths={visibleMonths}\n month={month}\n onMonthChange={setMonth}\n today={today}\n // Nobody has data for tomorrow. This blocks the click and nothing\n // else — a range reaching past today is still painted whole. Never\n // pair it with `excludeDisabled`, which resets any range holding a\n // disabled day.\n disabled={{ after: today }}\n // Always six weeks: without it the panel changes height between a\n // five-week month and a six-week one, and the footer's buttons jump\n // out from under the cursor.\n fixedWeeks\n // One grid gains from them: a range that starts in the previous\n // month still shows its opening edge. Two grids would render the\n // overlapping days twice, once as each month's neighbour, and the\n // second month already shows what the outside days were standing in\n // for.\n showOutsideDays={visibleMonths === 1}\n selected={\n activeTarget === 'compare'\n ? selectionOf(draft.compareFrom, draft.compareTo)\n : selectionOf(draft.from, draft.to)\n }\n onSelect={pickDays}\n modifiers={{\n period_middle: periodBand ? [{ from: periodBand.from, to: periodBand.to }] : [],\n period_start: periodBand ? [periodBand.from] : [],\n period_end: periodBand ? [periodBand.to] : [],\n // The period wins any cell both ranges claim.\n compare_middle: (date) => inBand(compareBand, date) && !inBand(periodBand, date),\n compare_start: (date) =>\n isBound(date, compareBand?.from) && !inBand(periodBand, date),\n compare_end: (date) => isBound(date, compareBand?.to) && !inBand(periodBand, date),\n }}\n modifiersClassNames={DAY_MODIFIER_CLASS_NAMES}\n classNames={DAY_PICKER_CLASS_NAMES}\n aria-label={\n activeTarget === 'compare'\n ? 'Calendrier — sélection de la comparaison'\n : 'Calendrier — sélection de la période'\n }\n labels={{\n // Suffixed rather than replaced: which range a click lands in is\n // the one thing a screen reader cannot get from the grid, and the\n // default label still carries the date and its state.\n labelDayButton: (date, modifiers, options, dateLib) =>\n `${labelDayButton(date, modifiers, options, dateLib)} — ${\n activeTarget === 'compare' ? 'comparaison' : 'période'\n }`,\n }}\n />\n </div>\n\n <div className=\"mt-auto flex items-center justify-between gap-4 border-t px-3 py-2\">\n {/* The only place that says what is being composed, so switching\n target re-announces the range that switch is about. */}\n <p role=\"status\" aria-live=\"polite\" className=\"text-xs text-muted-foreground\">\n {footer}\n </p>\n <div className=\"flex gap-2\">\n <Button variant=\"ghost\" size=\"sm\" onClick={() => setOpen(false)}>\n Annuler\n </Button>\n <Button size=\"sm\" onClick={apply} disabled={!range}>\n Appliquer\n </Button>\n </div>\n </div>\n </div>\n </div>\n </Popover>\n );\n}\n\n/** A day range with both ends — what the pre-contract-2 picker spoke. */\nexport interface DateRange {\n from: string;\n to: string;\n}\n\nexport interface DateRangePickerProps {\n value: DateRange;\n onChange: (range: DateRange) => void;\n className?: string;\n disabled?: boolean;\n}\n\n/**\n * The plain range picker, now a view of `DateRangeCompare` with the preset rail\n * and the comparison section it does not need.\n *\n * It stays because removing an export breaks the contract, and its signature is\n * unchanged: a caller that only ever wanted two days keeps passing two days.\n * `months` is pinned to the old behaviour for the same reason — one month is the\n * answer to a panel crowding a dashboard header, a problem a picker with no rail\n * does not have.\n */\nexport function DateRangePicker({ value, onChange, className, disabled }: DateRangePickerProps) {\n return (\n <DateRangeCompare\n value={{ preset: 'custom', range: value, compare: 'none' }}\n onChange={(next) => {\n if (next.range.from !== undefined) onChange({ from: next.range.from, to: next.range.to });\n }}\n comparable={false}\n presets={[]}\n months=\"auto\"\n disabled={disabled}\n className={className}\n />\n );\n}\n\n/**\n * Exactly one preset is chosen at a time, which is a radio group — not a listbox,\n * whose interaction model (arrow keys moving a virtual cursor) this does not\n * implement, and not a row of independent buttons either.\n *\n * One stop in the tab order for the whole rail, arrows to move within it: a\n * keyboard user tabbing past eleven presets to reach the calendar is the cost of\n * getting this wrong.\n */\nfunction PresetRail({\n presets,\n selected,\n onSelect,\n className,\n}: {\n presets: readonly PeriodPreset[];\n selected: PeriodPresetKey;\n /**\n * `commit` says the choice was made rather than merely moved through: an arrow\n * key walks the group, and must not be the gesture that closes the panel.\n */\n onSelect: (preset: PeriodPresetKey, commit: boolean) => void;\n className?: string;\n}) {\n const refs = React.useRef<Array<HTMLButtonElement | null>>([]);\n // Nothing is selected while the range is custom, so the first entry holds the\n // tab stop — the group still has to be reachable.\n const activeIndex = Math.max(\n 0,\n presets.findIndex((preset) => preset.key === selected),\n );\n\n const moveTo = (index: number) => {\n const next = (index + presets.length) % presets.length;\n refs.current[next]?.focus();\n onSelect(presets[next]!.key, false);\n };\n\n const onKeyDown = (event: React.KeyboardEvent, index: number) => {\n const step = { ArrowDown: 1, ArrowRight: 1, ArrowUp: -1, ArrowLeft: -1 }[event.key];\n if (step !== undefined) {\n event.preventDefault();\n moveTo(index + step);\n return;\n }\n if (event.key === 'Home' || event.key === 'End') {\n event.preventDefault();\n moveTo(event.key === 'Home' ? 0 : presets.length - 1);\n }\n };\n\n return (\n <div\n role=\"radiogroup\"\n aria-label=\"Période prédéfinie\"\n className={cn('flex flex-col gap-0.5', className)}\n >\n {presets.map((preset, index) => (\n <button\n key={preset.key}\n ref={(node) => {\n refs.current[index] = node;\n }}\n type=\"button\"\n role=\"radio\"\n aria-checked={preset.key === selected}\n tabIndex={index === activeIndex ? 0 : -1}\n onKeyDown={(event) => onKeyDown(event, index)}\n onClick={() => onSelect(preset.key, true)}\n className={cn(\n 'shrink-0 rounded px-3 py-1.5 text-left text-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',\n preset.key === selected\n ? 'bg-muted font-medium text-foreground'\n : 'text-muted-foreground hover:bg-muted hover:text-foreground',\n )}\n >\n {preset.label}\n </button>\n ))}\n </div>\n );\n}\n\nconst TARGETS = [\n { key: 'period' as const, label: 'Période', swatch: 'bg-primary' },\n { key: 'compare' as const, label: 'Comparaison', swatch: 'ring-2 ring-inset ring-chart-2' },\n];\n\n/**\n * Which of the two ranges the grid is editing.\n *\n * A radio group rather than two toggles: the targets are exclusive, and two\n * `aria-pressed` buttons would suggest both can be held down at once. It also\n * keeps `getByRole('radio', { name: 'Période' })` unambiguous next to a trigger\n * whose fallback label is the same word.\n *\n * Rendered whenever a comparison is on offer, never only while one is being\n * drawn: a row that appears and disappears makes the panel change height, which\n * is the thing `fixedWeeks` is there to prevent.\n */\nfunction TargetPills({\n target,\n onSelect,\n compareEditable,\n}: {\n target: PeriodTarget;\n onSelect: (target: PeriodTarget) => void;\n compareEditable: boolean;\n}) {\n return (\n <div\n role=\"radiogroup\"\n aria-label=\"Cible de la sélection\"\n className=\"flex items-center gap-1 border-b px-3 py-2\"\n >\n {TARGETS.map((entry) => {\n // Only a custom window is drawn by hand. Letting this pill switch the\n // mode itself would quietly turn a derived comparison into a manual one.\n const enabled = entry.key === 'period' || compareEditable;\n return (\n <button\n key={entry.key}\n type=\"button\"\n role=\"radio\"\n aria-checked={target === entry.key}\n disabled={!enabled}\n tabIndex={target === entry.key ? 0 : -1}\n onKeyDown={(event) => {\n if (!['ArrowDown', 'ArrowRight', 'ArrowUp', 'ArrowLeft'].includes(event.key)) return;\n event.preventDefault();\n if (compareEditable) onSelect(target === 'period' ? 'compare' : 'period');\n }}\n onClick={() => onSelect(entry.key)}\n className={cn(\n 'inline-flex items-center gap-1.5 rounded-full border px-2.5 py-1 text-xs transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-40',\n target === entry.key\n ? 'border-border bg-muted font-medium text-foreground'\n : 'border-border text-muted-foreground hover:bg-muted hover:text-foreground',\n )}\n >\n <span aria-hidden className={cn('size-2.5 rounded-sm', entry.swatch)} />\n {entry.label}\n </button>\n );\n })}\n </div>\n );\n}\n\nfunction CompareSection({\n draft,\n compareRange,\n onModeChange,\n}: {\n draft: Draft;\n compareRange: PeriodRange | undefined;\n onModeChange: (mode: PeriodCompareMode) => void;\n}) {\n // An unbounded period has no length to shift, so offering to shift it would\n // advertise a comparison that resolves to nothing.\n const derivable = draft.preset !== 'all';\n // What the entries report is what would actually apply, which is not always\n // what the draft remembers: the stored mode is kept so that passing through\n // \"tout l'historique\" on the way to another preset does not erase it.\n const active = activeCompare(draft);\n\n return (\n <div className=\"flex flex-col gap-0.5 border-t p-2\">\n <p className=\"px-3 pb-1 text-xs font-medium text-muted-foreground\">Comparer à</p>\n {/* `aria-pressed` rather than a third radio group in one panel: the modes\n are exclusive, but a group here would make every query in this popover\n spell out which of the three it means. */}\n {COMPARE_MODES.map((mode) => (\n <button\n key={mode}\n type=\"button\"\n aria-pressed={active === mode}\n disabled={mode !== 'none' && !derivable}\n onClick={() => onModeChange(mode)}\n className={cn(\n 'shrink-0 rounded px-3 py-1.5 text-left text-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-40',\n active === mode\n ? 'bg-muted font-medium text-foreground'\n : 'text-muted-foreground hover:bg-muted hover:text-foreground',\n )}\n >\n {COMPARE_LABELS[mode]}\n </button>\n ))}\n\n {compareRange && active !== 'custom' && (\n <p className=\"px-3 pt-1 text-xs text-muted-foreground\">{formatRange(compareRange)}</p>\n )}\n </div>\n );\n}\n\n/**\n * Inline, for the same reason as the icons in `components.tsx`: the SDK is one\n * vendor chunk behind the shell's import map, and a `lucide-react` dependency\n * would land on every app page for two glyphs.\n */\nfunction IconCalendar({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M8 2v4M16 2v4M3 10h18\" />\n <rect width=\"18\" height=\"18\" x=\"3\" y=\"4\" rx=\"2\" />\n </svg>\n );\n}\n\nfunction IconChevronDown({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n );\n}\n","/**\n * The pieces every chart in the kit is built from — the shadcn/chart blocks,\n * adapted to this SDK.\n *\n * Two deliberate departures from the upstream blocks:\n *\n * Upstream lets a series carry any CSS colour and injects a per-chart `<style>`\n * to declare it. Here a series names a `--chart-*` token instead, so there is\n * nothing to inject: the theme already defines those variables for both colour\n * schemes, and a chart cannot end up holding a colour the theme does not know.\n *\n * Nothing in this file is exported from the package. Recharts is an\n * implementation detail, and these compose only with Recharts elements, so\n * exporting them would put the engine in the public API through the back door.\n */\nimport * as React from 'react';\nimport { Legend, ResponsiveContainer, Tooltip } from 'recharts';\nimport { cn } from './cn';\n\n/** The five series colours the theme guarantees, in both light and dark. */\nexport const CHART_COLORS = [\n 'var(--chart-1)',\n 'var(--chart-2)',\n 'var(--chart-3)',\n 'var(--chart-4)',\n 'var(--chart-5)',\n] as const;\n\n/** Palette slot 2, the one a comparison is always drawn in. */\nexport const COMPARE_COLOR = CHART_COLORS[1];\n\n/** The colour of the nth series, cycling once the palette runs out. */\nexport const colorAt = (index: number): string =>\n CHART_COLORS[index % CHART_COLORS.length] as string;\n\nexport interface ChartSeries {\n /** The key this series reads from each row. */\n key: string;\n label: string;\n /** Palette slot. Defaults to the series' position. */\n colorIndex?: number;\n}\n\nexport type ValueFormatter = (value: number) => string;\n\n/** The default: a plain integer, grouped for readability. */\nexport const formatNumber: ValueFormatter = (value) =>\n new Intl.NumberFormat('fr-FR').format(Math.round(value));\n\ninterface ChartContextValue {\n formatValue: ValueFormatter;\n}\n\nconst ChartContext = React.createContext<ChartContextValue>({ formatValue: formatNumber });\n\nexport interface ChartContainerProps {\n children: React.ReactElement;\n /** Fixed pixel height. Charts need one — a percentage of nothing is nothing. */\n height?: number;\n formatValue?: ValueFormatter;\n /** Read by a screen reader in place of the graphic. */\n label?: string;\n className?: string;\n}\n\n/**\n * Sizes the chart and styles the parts Recharts renders as bare SVG, which no\n * class of ours would otherwise reach.\n */\nexport function ChartContainer({\n children,\n height = 320,\n formatValue = formatNumber,\n label,\n className,\n}: ChartContainerProps) {\n const context = React.useMemo(() => ({ formatValue }), [formatValue]);\n return (\n <ChartContext.Provider value={context}>\n <div\n role=\"img\"\n aria-label={label}\n style={{ height }}\n className={cn(\n 'w-full text-xs',\n '[&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground',\n '[&_.recharts-cartesian-grid_line]:stroke-border',\n '[&_.recharts-curve.recharts-tooltip-cursor]:stroke-border',\n '[&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted/40',\n '[&_.recharts-sector]:outline-none',\n '[&_.recharts-surface]:outline-none',\n className,\n )}\n >\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n {children}\n </ResponsiveContainer>\n </div>\n </ChartContext.Provider>\n );\n}\n\ninterface TooltipPayloadEntry {\n name?: string | number;\n value?: number | string;\n color?: string;\n dataKey?: string | number;\n}\n\n/**\n * The legend's entries are not shaped like the tooltip's: Recharts puts the\n * series name in `value` here and in `name` there, and a legend entry carries no\n * measurement at all.\n */\ninterface LegendPayloadEntry {\n value?: string | number;\n color?: string;\n dataKey?: string | number;\n}\n\nfunction ChartTooltipContent({\n active,\n payload,\n label,\n}: {\n active?: boolean;\n payload?: TooltipPayloadEntry[];\n label?: React.ReactNode;\n}) {\n const { formatValue } = React.useContext(ChartContext);\n if (!active || !payload?.length) return null;\n\n return (\n <div className=\"rounded-md border bg-card px-2.5 py-1.5 text-xs shadow-md\">\n {label !== undefined && <p className=\"mb-1 font-medium text-foreground\">{label}</p>}\n <ul className=\"flex flex-col gap-0.5\">\n {payload.map((entry, index) => (\n <li key={`${entry.dataKey}-${index}`} className=\"flex items-center gap-2\">\n <span\n aria-hidden\n className=\"h-2 w-2 shrink-0 rounded-[2px]\"\n style={{ backgroundColor: entry.color }}\n />\n <span className=\"text-muted-foreground\">{entry.name}</span>\n <span className=\"ml-auto font-medium tabular-nums text-foreground\">\n {typeof entry.value === 'number' ? formatValue(entry.value) : entry.value}\n </span>\n </li>\n ))}\n </ul>\n </div>\n );\n}\n\n/** The tooltip every chart in the kit uses. */\nexport const ChartTooltip = (\n <Tooltip\n cursor={{ strokeWidth: 1 }}\n content={<ChartTooltipContent />}\n // Recharts' default wrapper carries a white background and a grey border of\n // its own, which would sit behind the themed panel above in dark mode.\n wrapperStyle={{ outline: 'none' }}\n />\n);\n\nfunction ChartLegendContent({ payload }: { payload?: LegendPayloadEntry[] }) {\n if (!payload?.length) return null;\n return (\n <ul className=\"flex flex-wrap items-center justify-center gap-x-4 gap-y-1 pt-3\">\n {payload.map((entry, index) => (\n <li key={`${entry.dataKey}-${index}`} className=\"flex items-center gap-1.5\">\n <span\n aria-hidden\n className=\"h-2 w-2 shrink-0 rounded-[2px]\"\n style={{ backgroundColor: entry.color }}\n />\n <span className=\"text-muted-foreground\">{entry.value}</span>\n </li>\n ))}\n </ul>\n );\n}\n\n/** The legend every chart in the kit uses. Omitted when there is one series. */\nexport const ChartLegend = <Legend content={<ChartLegendContent />} />;\n\n/**\n * How a comparison series is drawn, everywhere, without exception: dashed, faded\n * and always in the second palette slot. Fixing it here is the point — a\n * comparison that looked different from one dashboard to the next would stop\n * reading as \"the same thing, earlier\".\n */\nexport const COMPARE_LINE_PROPS = {\n stroke: COMPARE_COLOR,\n strokeDasharray: '4 4',\n strokeOpacity: 0.4,\n strokeWidth: 2,\n dot: false,\n activeDot: false,\n // Not a preference: Recharts animates `strokeDasharray` from `0px 0px`, so an\n // animated comparison line is drawn solid and only becomes dashed once the\n // animation ends. Off, it is dashed from the first frame — and a reference\n // line that draws itself in is pulling the eye towards the thing meant to\n // recede behind the real series anyway.\n isAnimationActive: false,\n} as const;\n","/**\n * ChartKit — the charts an app is allowed to draw.\n *\n * Each one is a finished block with a narrow, typed surface: rows, the field on\n * the category axis, and the series to plot. Recharts is never re-exported and\n * none of its elements appear in a prop type, so the engine stays replaceable\n * and an app cannot assemble a chart that steps outside the design system.\n *\n * Colours come only from the `--chart-*` tokens, which the theme defines for\n * both colour schemes. That is the whole reason charts belong in the SDK: a\n * hand-drawn SVG with a hex literal is invisible in dark mode, and every app\n * that drew its own got that wrong.\n */\nimport * as React from 'react';\nimport {\n Area,\n AreaChart as RechartsAreaChart,\n Bar,\n BarChart as RechartsBarChart,\n CartesianGrid,\n Funnel,\n FunnelChart as RechartsFunnelChart,\n LabelList,\n Line,\n LineChart as RechartsLineChart,\n Cell,\n XAxis,\n YAxis,\n} from 'recharts';\nimport { Card, CardContent } from './components';\nimport { cn } from './cn';\nimport {\n COMPARE_LINE_PROPS,\n ChartContainer,\n ChartLegend,\n ChartTooltip,\n colorAt,\n formatNumber,\n type ChartSeries,\n type ValueFormatter,\n} from './chart-primitives';\n\nexport type { ChartSeries, ValueFormatter } from './chart-primitives';\n\n/** A row is whatever an app has; the chart only reads the keys it was given. */\nexport type ChartRow = Record<string, string | number | null | undefined>;\n\nexport interface CartesianChartProps {\n data: ChartRow[];\n /** The field on the category axis. */\n x: string;\n series: ChartSeries[];\n /** The same measure over an earlier period, drawn dashed and faded. */\n compareSeries?: ChartSeries;\n formatValue?: ValueFormatter;\n height?: number;\n /** Read out in place of the graphic. Defaults to the series names. */\n label?: string;\n hideLegend?: boolean;\n className?: string;\n}\n\nconst AXIS_PROPS = {\n tickLine: false,\n axisLine: false,\n tickMargin: 8,\n} as const;\n\n/**\n * Every mark in the kit is drawn without an entrance animation.\n *\n * These charts redraw whenever the period, the filters or the comparison change\n * — which is most interactions on a dashboard — and Recharts replays the growth\n * animation on each of them. Numbers that crawl back up from zero every time a\n * filter moves are harder to read, not more alive. It also removes the window\n * during which a comparison line is drawn solid, since Recharts animates\n * `strokeDasharray` from nothing.\n */\nconst MARK_PROPS = { isAnimationActive: false } as const;\n\n/** Both axes and the grid, identical across the cartesian charts. */\nfunction CartesianFrame({ x, formatValue }: { x: string; formatValue: ValueFormatter }) {\n return (\n <>\n <CartesianGrid vertical={false} strokeDasharray=\"3 3\" />\n <XAxis dataKey={x} {...AXIS_PROPS} />\n <YAxis {...AXIS_PROPS} width={56} tickFormatter={formatValue} />\n </>\n );\n}\n\nfunction accessibleLabel(series: ChartSeries[], label?: string): string {\n return label ?? series.map((entry) => entry.label).join(', ');\n}\n\n/** Whether the legend earns its space: one unnamed series does not. */\nfunction showsLegend(props: CartesianChartProps): boolean {\n if (props.hideLegend) return false;\n return props.series.length > 1 || props.compareSeries !== undefined;\n}\n\nexport function BarChart(props: CartesianChartProps) {\n const { data, x, series, compareSeries, formatValue = formatNumber } = props;\n return (\n <ChartContainer\n height={props.height}\n formatValue={formatValue}\n label={accessibleLabel(series, props.label)}\n className={props.className}\n >\n <RechartsBarChart data={data}>\n <CartesianFrame x={x} formatValue={formatValue} />\n {ChartTooltip}\n {showsLegend(props) && ChartLegend}\n {series.map((entry, index) => (\n <Bar\n key={entry.key}\n dataKey={entry.key}\n name={entry.label}\n fill={colorAt(entry.colorIndex ?? index)}\n radius={[4, 4, 0, 0]}\n {...MARK_PROPS}\n />\n ))}\n {compareSeries && (\n <Bar\n dataKey={compareSeries.key}\n name={compareSeries.label}\n fill={COMPARE_LINE_PROPS.stroke}\n fillOpacity={COMPARE_LINE_PROPS.strokeOpacity}\n radius={[4, 4, 0, 0]}\n {...MARK_PROPS}\n />\n )}\n </RechartsBarChart>\n </ChartContainer>\n );\n}\n\nexport function StackedBarChart(props: CartesianChartProps) {\n const { data, x, series, formatValue = formatNumber } = props;\n return (\n <ChartContainer\n height={props.height}\n formatValue={formatValue}\n label={accessibleLabel(series, props.label)}\n className={props.className}\n >\n <RechartsBarChart data={data}>\n <CartesianFrame x={x} formatValue={formatValue} />\n {ChartTooltip}\n {showsLegend(props) && ChartLegend}\n {series.map((entry, index) => (\n <Bar\n key={entry.key}\n dataKey={entry.key}\n name={entry.label}\n stackId=\"stack\"\n fill={colorAt(entry.colorIndex ?? index)}\n // Only the topmost segment is rounded, and which one that is depends\n // on the data, so none of them are.\n radius={0}\n {...MARK_PROPS}\n />\n ))}\n </RechartsBarChart>\n </ChartContainer>\n );\n}\n\nexport function LineChart(props: CartesianChartProps) {\n const { data, x, series, compareSeries, formatValue = formatNumber } = props;\n return (\n <ChartContainer\n height={props.height}\n formatValue={formatValue}\n label={accessibleLabel(series, props.label)}\n className={props.className}\n >\n <RechartsLineChart data={data}>\n <CartesianFrame x={x} formatValue={formatValue} />\n {ChartTooltip}\n {showsLegend(props) && ChartLegend}\n {series.map((entry, index) => (\n <Line\n key={entry.key}\n type=\"monotone\"\n dataKey={entry.key}\n name={entry.label}\n stroke={colorAt(entry.colorIndex ?? index)}\n strokeWidth={2}\n dot={false}\n {...MARK_PROPS}\n />\n ))}\n {compareSeries && (\n <Line\n type=\"monotone\"\n dataKey={compareSeries.key}\n name={compareSeries.label}\n {...COMPARE_LINE_PROPS}\n />\n )}\n </RechartsLineChart>\n </ChartContainer>\n );\n}\n\nexport function AreaChart(props: CartesianChartProps) {\n const { data, x, series, compareSeries, formatValue = formatNumber } = props;\n return (\n <ChartContainer\n height={props.height}\n formatValue={formatValue}\n label={accessibleLabel(series, props.label)}\n className={props.className}\n >\n <RechartsAreaChart data={data}>\n <CartesianFrame x={x} formatValue={formatValue} />\n {ChartTooltip}\n {showsLegend(props) && ChartLegend}\n {series.map((entry, index) => {\n const color = colorAt(entry.colorIndex ?? index);\n return (\n <Area\n key={entry.key}\n type=\"monotone\"\n dataKey={entry.key}\n name={entry.label}\n stroke={color}\n strokeWidth={2}\n fill={color}\n fillOpacity={0.15}\n {...MARK_PROPS}\n />\n );\n })}\n {compareSeries && (\n <Area\n type=\"monotone\"\n dataKey={compareSeries.key}\n name={compareSeries.label}\n fill=\"none\"\n {...COMPARE_LINE_PROPS}\n />\n )}\n </RechartsAreaChart>\n </ChartContainer>\n );\n}\n\nexport interface FunnelStep {\n label: string;\n value: number;\n}\n\nexport interface FunnelChartProps {\n data: FunnelStep[];\n formatValue?: ValueFormatter;\n height?: number;\n label?: string;\n className?: string;\n}\n\n/**\n * The one chart with no shadcn block, so it is assembled from Recharts' own\n * funnel elements. Steps keep their palette slot in the order they are given —\n * a funnel is read top to bottom, and a colour that moved between renders would\n * read as a different step.\n */\nexport function FunnelChart({\n data,\n formatValue = formatNumber,\n height,\n label,\n className,\n}: FunnelChartProps) {\n return (\n <ChartContainer\n height={height}\n formatValue={formatValue}\n label={label ?? data.map((step) => step.label).join(', ')}\n className={className}\n >\n <RechartsFunnelChart>\n {ChartTooltip}\n <Funnel dataKey=\"value\" nameKey=\"label\" data={data} {...MARK_PROPS}>\n {data.map((step, index) => (\n <Cell key={step.label} fill={colorAt(index)} />\n ))}\n <LabelList\n dataKey=\"label\"\n position=\"right\"\n className=\"fill-foreground\"\n stroke=\"none\"\n fontSize={12}\n />\n </Funnel>\n </RechartsFunnelChart>\n </ChartContainer>\n );\n}\n\nexport interface KpiCardProps {\n label: string;\n value: number;\n /** The same measure over the compared period. Drives the delta. */\n compareValue?: number;\n formatValue?: ValueFormatter;\n /** For measures that are better when lower — cost, churn, delay. */\n lowerIsBetter?: boolean;\n /** A bare trend line under the figure. */\n sparkline?: number[];\n className?: string;\n}\n\n/** The signed change, or null when there is no baseline to divide by. */\nexport function relativeDelta(value: number, compareValue: number | undefined): number | null {\n if (compareValue === undefined || compareValue === 0) return null;\n return (value - compareValue) / Math.abs(compareValue);\n}\n\nconst DELTA_FORMAT = new Intl.NumberFormat('fr-FR', {\n style: 'percent',\n maximumFractionDigits: 1,\n signDisplay: 'exceptZero',\n});\n\nexport function KpiCard({\n label,\n value,\n compareValue,\n formatValue = formatNumber,\n lowerIsBetter = false,\n sparkline,\n className,\n}: KpiCardProps) {\n const delta = relativeDelta(value, compareValue);\n const improved = delta === null ? null : delta > 0 !== lowerIsBetter;\n\n return (\n <Card className={className}>\n <CardContent className=\"space-y-1 p-4\">\n <p className=\"text-sm text-muted-foreground\">{label}</p>\n <p className=\"text-2xl font-semibold tabular-nums text-foreground\">{formatValue(value)}</p>\n {delta !== null && (\n <p\n className={cn(\n 'text-xs font-medium tabular-nums',\n // Direction is in the sign as well as the colour: a red figure and\n // a green one differ by more than hue for nobody who cannot see it.\n improved ? 'text-status-success' : 'text-status-blocked',\n )}\n >\n {DELTA_FORMAT.format(delta)}\n {compareValue !== undefined && (\n <span className=\"ml-1 font-normal text-muted-foreground\">\n vs {formatValue(compareValue)}\n </span>\n )}\n </p>\n )}\n {sparkline && sparkline.length > 1 && (\n <ChartContainer height={40} label={`Tendance — ${label}`} className=\"pt-1\">\n <RechartsLineChart data={sparkline.map((point, index) => ({ index, point }))}>\n <Line\n type=\"monotone\"\n dataKey=\"point\"\n stroke={colorAt(0)}\n strokeWidth={1.5}\n dot={false}\n {...MARK_PROPS}\n />\n </RechartsLineChart>\n </ChartContainer>\n )}\n </CardContent>\n </Card>\n );\n}\n","/**\n * Toast stack, lifted from the shell so an app page can announce an outcome the\n * same way the platform does.\n *\n * The shell copy painted with `green-*` / `red-*` from Tailwind's palette, which\n * ignores the instance theme entirely. Here it uses `--status-success` and\n * `--status-blocked`, so a rebranded instance and dark mode both carry through —\n * the same rule the SDK asks apps to follow.\n */\nimport { createContext, useCallback, useContext, useRef, useState, type ReactNode } from 'react';\nimport { cn } from './cn';\n\nexport interface ToastInput {\n title: string;\n description?: string;\n /** `info` exists because Pilotage's own stack had it — a neutral outcome is not a success. */\n variant?: 'success' | 'error' | 'info';\n}\n\ninterface ToastItem extends ToastInput {\n id: number;\n}\n\nconst ToastContext = createContext<((toast: ToastInput) => void) | null>(null);\n\n/** Returns a `toast({ title, description?, variant? })` function. */\nexport function useToast(): (toast: ToastInput) => void {\n const toast = useContext(ToastContext);\n if (!toast) throw new Error('useToast must be used within ToastProvider');\n return toast;\n}\n\n/** How long a toast stays up before it dismisses itself. */\nconst TOAST_TTL_MS = 4000;\n\n/**\n * The status hue is a border accent, not a wash: a toast floats over whatever is\n * on screen — including a modal's dark scrim — and a translucent tint composites\n * with it into mud. `bg-card` keeps it opaque, `--foreground` keeps the message\n * above 4.5:1, and the hue still reads at a glance down the left edge.\n */\nconst TONE: Record<NonNullable<ToastInput['variant']>, string> = {\n success: 'border-l-status-success',\n error: 'border-l-status-blocked',\n info: 'border-l-status-info',\n};\n\n/** Fixed bottom-right stack, auto-dismissing. */\nexport function ToastProvider({ children }: { children: ReactNode }) {\n const [toasts, setToasts] = useState<ToastItem[]>([]);\n const nextId = useRef(0);\n\n const toast = useCallback((input: ToastInput) => {\n const id = nextId.current++;\n setToasts((prev) => [...prev, { id, ...input }]);\n setTimeout(() => setToasts((prev) => prev.filter((t) => t.id !== id)), TOAST_TTL_MS);\n }, []);\n\n return (\n <ToastContext.Provider value={toast}>\n {children}\n <div className=\"pointer-events-none fixed bottom-4 right-4 z-[60] flex w-80 flex-col gap-2\">\n {toasts.map((t) => (\n <div\n key={t.id}\n role=\"status\"\n className={cn(\n 'pointer-events-auto rounded-lg border border-l-4 bg-card px-4 py-3 text-foreground shadow-md',\n TONE[t.variant ?? 'success'],\n )}\n >\n <p className=\"text-sm font-medium\">{t.title}</p>\n {t.description && (\n <p className=\"mt-0.5 break-all text-xs text-muted-foreground\">{t.description}</p>\n )}\n </div>\n ))}\n </div>\n </ToastContext.Provider>\n );\n}\n","/**\n * Hover tooltip, lifted from the shell.\n *\n * Deliberately CSS-only (`group-hover`) rather than another Base UI surface: it\n * carries no focus, no dismissal and no state, so a portal and a positioner would\n * be weight for nothing. If a tooltip ever needs to be keyboard-reachable or to\n * survive a scroll container, that is the moment to move it onto Base UI's.\n */\nimport * as React from 'react';\nimport { cn } from './cn';\n\nconst SIDES = {\n top: 'bottom-full left-1/2 -translate-x-1/2 mb-1.5',\n right: 'left-full top-1/2 -translate-y-1/2 ml-1.5',\n bottom: 'top-full left-1/2 -translate-x-1/2 mt-1.5',\n left: 'right-full top-1/2 -translate-y-1/2 mr-1.5',\n} as const;\n\nexport interface TooltipProps {\n label: React.ReactNode;\n children: React.ReactNode;\n side?: keyof typeof SIDES;\n className?: string;\n}\n\nexport function Tooltip({ label, children, side = 'top', className }: TooltipProps) {\n return (\n <span className=\"group/tt relative inline-flex\">\n {children}\n <span\n role=\"tooltip\"\n className={cn(\n 'pointer-events-none absolute z-50 whitespace-nowrap rounded-md bg-foreground px-2 py-1 text-xs font-medium text-background opacity-0 shadow-md transition-opacity group-hover/tt:opacity-100',\n SIDES[side],\n className,\n )}\n >\n {label}\n </span>\n </span>\n );\n}\n"]}
|