@apotech-os/ui-sdk 0.10.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cn.ts","../src/hooks.ts","../src/utils.ts","../src/components.tsx","../src/toast.tsx","../src/tooltip.tsx"],"names":["twMerge","clsx","createContext","useContext","useState","useRef","useCallback","useEffect","React","jsx","cva","jsxs","BaseTabs","Dialog","BaseSwitch","Textarea","Checkbox","BasePopover","Menu"],"mappings":"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","file":"index.cjs","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 { Popover as BasePopover } from '@base-ui/react/popover';\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-white 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 SelectProps extends React.SelectHTMLAttributes<HTMLSelectElement> {}\n\nexport const Select = React.forwardRef<HTMLSelectElement, SelectProps>(\n ({ className, children, ...props }, ref) => (\n <select\n ref={ref}\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 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 {children}\n </select>\n ),\n);\nSelect.displayName = 'Select';\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-foreground/40\" />\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// DateRangePicker\n// ---------------------------------------------------------------------------\n\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/** Minimal controlled date-range picker using two native date inputs. */\nexport function DateRangePicker({ value, onChange, className, disabled }: DateRangePickerProps) {\n return (\n <div className={cn('flex items-center gap-2', className)}>\n <input\n type=\"date\"\n disabled={disabled}\n value={value.from}\n max={value.to || undefined}\n onChange={(e) => onChange({ ...value, from: e.target.value })}\n className=\"flex h-9 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 disabled:cursor-not-allowed disabled:opacity-50\"\n />\n <span className=\"text-muted-foreground text-sm\">→</span>\n <input\n type=\"date\"\n disabled={disabled}\n value={value.to}\n min={value.from || undefined}\n onChange={(e) => onChange({ ...value, to: e.target.value })}\n className=\"flex h-9 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 disabled:cursor-not-allowed disabled:opacity-50\"\n />\n </div>\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>(\n function Textarea({ className, ...props }, ref) {\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// ---------------------------------------------------------------------------\n// Checkbox\n// ---------------------------------------------------------------------------\n\nexport interface CheckboxProps\n extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'type' | 'onChange'> {\n checked?: boolean;\n /** Preferred over onChange — receives the boolean directly. */\n onCheckedChange?: (checked: boolean) => void;\n label?: React.ReactNode;\n}\n\nexport const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(\n function Checkbox({ className, label, onCheckedChange, ...props }, ref) {\n const input = (\n <input\n ref={ref}\n type=\"checkbox\"\n className={cn(\n 'size-4 shrink-0 cursor-pointer rounded border-input accent-primary disabled:cursor-not-allowed disabled:opacity-50',\n className,\n )}\n onChange={(e) => onCheckedChange?.(e.target.checked)}\n {...props}\n />\n );\n if (!label) return input;\n return (\n <label className=\"inline-flex cursor-pointer items-center gap-2 text-sm\">\n {input}\n <span>{label}</span>\n </label>\n );\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-foreground/40\" />\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' ? (\n <IconCheck className=\"size-3.5\" />\n ) : (\n <IconCopy className=\"size-3.5\" />\n )}\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 * 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"],"names":["twMerge","clsx","createContext","useContext","useState","useRef","useCallback","useEffect","cva","React","jsx","jsxs","Textarea","Checkbox"],"mappings":"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","file":"index.cjs","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 { type VariantProps, cva } from 'class-variance-authority';\nimport * as React from 'react';\nimport { cn } from './cn';\nimport { copyToClipboard } from './utils';\n\n// ---------------------------------------------------------------------------\n// Button\n// ---------------------------------------------------------------------------\n\nconst 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-white 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\nconst 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 CardContent({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n return <div className={cn('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 <thead className={cn('[&_tr]:border-b', className)} {...props} />;\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 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 SelectProps extends React.SelectHTMLAttributes<HTMLSelectElement> {}\n\nexport const Select = React.forwardRef<HTMLSelectElement, SelectProps>(\n ({ className, children, ...props }, ref) => (\n <select\n ref={ref}\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 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 {children}\n </select>\n ),\n);\nSelect.displayName = 'Select';\n\n// ---------------------------------------------------------------------------\n// Tabs\n// ---------------------------------------------------------------------------\n\ninterface TabsContextValue {\n value: string;\n setValue: (v: string) => void;\n}\n\nconst TabsContext = React.createContext<TabsContextValue | null>(null);\n\nfunction useTabsContext(): TabsContextValue {\n const ctx = React.useContext(TabsContext);\n if (!ctx) throw new Error('Tabs sub-component must be used within <Tabs>');\n return ctx;\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 const [internal, setInternal] = React.useState(defaultValue ?? '');\n const current = value ?? internal;\n const setValue = (v: string) => {\n setInternal(v);\n onValueChange?.(v);\n };\n return (\n <TabsContext.Provider value={{ value: current, setValue }}>\n <div className={className}>{children}</div>\n </TabsContext.Provider>\n );\n}\n\nexport function TabsList({\n className,\n children,\n}: {\n className?: string;\n children: React.ReactNode;\n}) {\n return (\n <div className={cn('inline-flex items-center gap-1 rounded-lg bg-muted p-1', className)}>\n {children}\n </div>\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 const { value: current, setValue } = useTabsContext();\n const active = current === value;\n return (\n <button\n type=\"button\"\n onClick={() => setValue(value)}\n className={cn(\n 'rounded-md px-3 py-1.5 text-sm font-medium transition-colors',\n active\n ? 'bg-card text-foreground shadow-sm'\n : 'text-muted-foreground hover:text-foreground',\n className,\n )}\n >\n {children}\n </button>\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 const { value: current } = useTabsContext();\n if (current !== value) return null;\n return <div className={className}>{children}</div>;\n}\n\n// ---------------------------------------------------------------------------\n// Modal (controlled, no Radix)\n// ---------------------------------------------------------------------------\n\nexport interface ModalProps {\n open: boolean;\n onClose: () => void;\n title?: React.ReactNode;\n children: React.ReactNode;\n className?: string;\n}\n\nexport function Modal({ open, onClose, title, children, className }: ModalProps) {\n if (!open) return null;\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center p-4\">\n <button\n type=\"button\"\n aria-label=\"Close\"\n className=\"absolute inset-0 cursor-default bg-foreground/40\"\n onClick={onClose}\n />\n <div\n role=\"dialog\"\n aria-modal\n className={cn(\n 'relative z-10 w-full max-w-md rounded-xl border bg-card p-5 shadow-lg',\n className,\n )}\n >\n {title && <h2 className=\"mb-3 text-base font-semibold\">{title}</h2>}\n {children}\n </div>\n </div>\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\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 <button\n type=\"button\"\n role=\"switch\"\n aria-checked={checked}\n disabled={disabled}\n onClick={() => onCheckedChange?.(!checked)}\n className={cn(\n 'relative inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50',\n checked ? 'bg-primary' : 'bg-input',\n className,\n )}\n {...props}\n >\n <span\n className={cn(\n 'inline-block size-4 transform rounded-full bg-white shadow transition-transform',\n checked ? 'translate-x-4' : 'translate-x-0.5',\n )}\n />\n </button>\n );\n}\n\n// ---------------------------------------------------------------------------\n// DateRangePicker\n// ---------------------------------------------------------------------------\n\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/** Minimal controlled date-range picker using two native date inputs. */\nexport function DateRangePicker({ value, onChange, className, disabled }: DateRangePickerProps) {\n return (\n <div className={cn('flex items-center gap-2', className)}>\n <input\n type=\"date\"\n disabled={disabled}\n value={value.from}\n max={value.to || undefined}\n onChange={(e) => onChange({ ...value, from: e.target.value })}\n className=\"flex h-9 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 disabled:cursor-not-allowed disabled:opacity-50\"\n />\n <span className=\"text-muted-foreground text-sm\">→</span>\n <input\n type=\"date\"\n disabled={disabled}\n value={value.to}\n min={value.from || undefined}\n onChange={(e) => onChange({ ...value, to: e.target.value })}\n className=\"flex h-9 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 disabled:cursor-not-allowed disabled:opacity-50\"\n />\n </div>\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>(\n function Textarea({ className, ...props }, ref) {\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// ---------------------------------------------------------------------------\n// Checkbox\n// ---------------------------------------------------------------------------\n\nexport interface CheckboxProps\n extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'type' | 'onChange'> {\n checked?: boolean;\n /** Preferred over onChange — receives the boolean directly. */\n onCheckedChange?: (checked: boolean) => void;\n label?: React.ReactNode;\n}\n\nexport const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(\n function Checkbox({ className, label, onCheckedChange, ...props }, ref) {\n const input = (\n <input\n ref={ref}\n type=\"checkbox\"\n className={cn(\n 'size-4 shrink-0 cursor-pointer rounded border-input accent-primary disabled:cursor-not-allowed disabled:opacity-50',\n className,\n )}\n onChange={(e) => onCheckedChange?.(e.target.checked)}\n {...props}\n />\n );\n if (!label) return input;\n return (\n <label className=\"inline-flex cursor-pointer items-center gap-2 text-sm\">\n {input}\n <span>{label}</span>\n </label>\n );\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 * NOTE: no focus management. Autofocus the primary action yourself.\n */\nexport function SidePanel({\n open,\n onClose,\n title,\n description,\n children,\n className,\n}: SidePanelProps) {\n // Escape closes. A panel that covers the viewport makes a missing keyboard\n // exit far more noticeable than it is on a centred Modal.\n React.useEffect(() => {\n if (!open) return;\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') onClose();\n };\n window.addEventListener('keydown', onKeyDown);\n return () => window.removeEventListener('keydown', onKeyDown);\n }, [open, onClose]);\n\n if (!open) return null;\n return (\n <div className=\"fixed inset-0 z-50\">\n <button\n type=\"button\"\n aria-label=\"Fermer\"\n className=\"absolute inset-0 cursor-default bg-foreground/40\"\n onClick={onClose}\n />\n <aside\n role=\"dialog\"\n aria-modal\n className={cn(\n 'absolute inset-y-0 right-0 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 && <h2 className=\"text-base font-semibold\">{title}</h2>}\n {description && <p className=\"mt-0.5 text-xs text-muted-foreground\">{description}</p>}\n </div>\n <button\n type=\"button\"\n aria-label=\"Fermer\"\n className=\"-mr-1 shrink-0 rounded-md p-1 text-muted-foreground hover:bg-accent hover:text-foreground\"\n onClick={onClose}\n >\n <IconX className=\"size-4\" />\n </button>\n </header>\n <div className=\"flex min-h-0 flex-1 flex-col px-5 py-4\">{children}</div>\n </aside>\n </div>\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' ? (\n <IconCheck className=\"size-3.5\" />\n ) : (\n <IconCopy className=\"size-3.5\" />\n )}\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 const root = React.useRef<HTMLDivElement>(null);\n\n React.useEffect(() => {\n if (!open) return;\n const onPointerDown = (e: MouseEvent) => {\n if (!root.current?.contains(e.target as Node)) onOpenChange(false);\n };\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') onOpenChange(false);\n };\n document.addEventListener('mousedown', onPointerDown);\n document.addEventListener('keydown', onKeyDown);\n return () => {\n document.removeEventListener('mousedown', onPointerDown);\n document.removeEventListener('keydown', onKeyDown);\n };\n }, [open, onOpenChange]);\n\n return (\n <div ref={root} className=\"relative inline-block\">\n <button type=\"button\" aria-expanded={open} onClick={() => onOpenChange(!open)}>\n {trigger}\n </button>\n {open && (\n <div\n className={cn(\n 'absolute z-40 mt-1 min-w-48 rounded-md border bg-card p-2 shadow-lg',\n align === 'end' ? 'right-0' : 'left-0',\n className,\n )}\n >\n {children}\n </div>\n )}\n </div>\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 built on Popover. Selecting an item closes it. */\nexport function DropdownMenu({ trigger, items, align = 'end', className }: DropdownMenuProps) {\n const [open, setOpen] = React.useState(false);\n return (\n <Popover\n open={open}\n onOpenChange={setOpen}\n trigger={trigger}\n align={align}\n className={cn('p-1', className)}\n >\n <div role=\"menu\" className=\"flex flex-col\">\n {items.map((item, i) => (\n <button\n key={i}\n type=\"button\"\n role=\"menuitem\"\n disabled={item.disabled}\n className={cn(\n 'cursor-pointer rounded px-2 py-1.5 text-left text-sm hover:bg-accent disabled:pointer-events-none disabled:opacity-50',\n item.destructive && 'text-destructive',\n )}\n onClick={() => {\n setOpen(false);\n item.onSelect();\n }}\n >\n {item.label}\n </button>\n ))}\n </div>\n </Popover>\n );\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -1,6 +1,5 @@
1
1
  import { ClassValue } from 'clsx';
2
2
  import * as React from 'react';
3
- import { ReactNode } from 'react';
4
3
  import { AppErrorCode, AppRunRecord, AppRunStatus } from '@apotech-os/app-kit';
5
4
  export { AppRunRecord, AppRunStatus } from '@apotech-os/app-kit';
6
5
  import * as class_variance_authority_types from 'class-variance-authority/types';
@@ -160,9 +159,7 @@ declare function Badge({ className, variant, dot, children, ...props }: BadgePro
160
159
  declare function Card({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): React.JSX.Element;
161
160
  declare function CardHeader({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): React.JSX.Element;
162
161
  declare function CardTitle({ className, ...props }: React.HTMLAttributes<HTMLHeadingElement>): React.JSX.Element;
163
- declare function CardDescription({ className, ...props }: React.HTMLAttributes<HTMLParagraphElement>): React.JSX.Element;
164
162
  declare function CardContent({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): React.JSX.Element;
165
- declare function CardFooter({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): React.JSX.Element;
166
163
  declare const Input: React.ForwardRefExoticComponent<React.InputHTMLAttributes<HTMLInputElement> & React.RefAttributes<HTMLInputElement>>;
167
164
  declare function Table({ className, ...props }: React.HTMLAttributes<HTMLTableElement>): React.JSX.Element;
168
165
  declare function TableHeader({ className, ...props }: React.HTMLAttributes<HTMLTableSectionElement>): React.JSX.Element;
@@ -194,7 +191,7 @@ declare function TabsContent({ value, className, children, }: {
194
191
  value: string;
195
192
  className?: string;
196
193
  children: React.ReactNode;
197
- }): React.JSX.Element;
194
+ }): React.JSX.Element | null;
198
195
  interface ModalProps {
199
196
  open: boolean;
200
197
  onClose: () => void;
@@ -202,8 +199,7 @@ interface ModalProps {
202
199
  children: React.ReactNode;
203
200
  className?: string;
204
201
  }
205
- /** Centred blocking dialog. Base UI owns the focus trap, focus restore and Escape. */
206
- declare function Modal({ open, onClose, title, children, className }: ModalProps): React.JSX.Element;
202
+ declare function Modal({ open, onClose, title, children, className }: ModalProps): React.JSX.Element | null;
207
203
  interface SpinnerProps {
208
204
  className?: string;
209
205
  size?: 'sm' | 'md' | 'lg';
@@ -213,10 +209,6 @@ interface LinkProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
213
209
  variant?: 'default' | 'muted';
214
210
  }
215
211
  declare const Link: React.ForwardRefExoticComponent<LinkProps & React.RefAttributes<HTMLAnchorElement>>;
216
- /**
217
- * Do not pass `aria-label` when the switch sits inside a `<label>`: the label
218
- * already names it, and the two naming sources cancel out into no name at all.
219
- */
220
212
  interface SwitchProps {
221
213
  checked?: boolean;
222
214
  onCheckedChange?: (checked: boolean) => void;
@@ -262,10 +254,9 @@ interface SidePanelProps {
262
254
  * Children are laid out in a flex column filling the panel: put the scrollable
263
255
  * region in a `min-h-0 flex-1 overflow-y-auto` child and the footer after it.
264
256
  *
265
- * Focus is trapped inside while open and restored to the opener on close — Base
266
- * UI's dialog does both, which is what the hand-rolled version never did.
257
+ * NOTE: no focus management. Autofocus the primary action yourself.
267
258
  */
268
- declare function SidePanel({ open, onClose, title, description, children, className, }: SidePanelProps): React.JSX.Element;
259
+ declare function SidePanel({ open, onClose, title, description, children, className, }: SidePanelProps): React.JSX.Element | null;
269
260
  interface CopyButtonProps {
270
261
  value: string;
271
262
  label?: string;
@@ -303,45 +294,9 @@ interface DropdownMenuProps {
303
294
  align?: 'start' | 'end';
304
295
  className?: string;
305
296
  }
306
- /** Uncontrolled menu. Selecting an item closes it; arrow keys move between them. */
297
+ /** Uncontrolled menu built on Popover. Selecting an item closes it. */
307
298
  declare function DropdownMenu({ trigger, items, align, className }: DropdownMenuProps): React.JSX.Element;
308
299
 
309
- interface ToastInput {
310
- title: string;
311
- description?: string;
312
- /** `info` exists because Pilotage's own stack had it — a neutral outcome is not a success. */
313
- variant?: 'success' | 'error' | 'info';
314
- }
315
- /** Returns a `toast({ title, description?, variant? })` function. */
316
- declare function useToast(): (toast: ToastInput) => void;
317
- /** Fixed bottom-right stack, auto-dismissing. */
318
- declare function ToastProvider({ children }: {
319
- children: ReactNode;
320
- }): React.JSX.Element;
321
-
322
- /**
323
- * Hover tooltip, lifted from the shell.
324
- *
325
- * Deliberately CSS-only (`group-hover`) rather than another Base UI surface: it
326
- * carries no focus, no dismissal and no state, so a portal and a positioner would
327
- * be weight for nothing. If a tooltip ever needs to be keyboard-reachable or to
328
- * survive a scroll container, that is the moment to move it onto Base UI's.
329
- */
330
-
331
- declare const SIDES: {
332
- readonly top: "bottom-full left-1/2 -translate-x-1/2 mb-1.5";
333
- readonly right: "left-full top-1/2 -translate-y-1/2 ml-1.5";
334
- readonly bottom: "top-full left-1/2 -translate-x-1/2 mt-1.5";
335
- readonly left: "right-full top-1/2 -translate-y-1/2 mr-1.5";
336
- };
337
- interface TooltipProps {
338
- label: React.ReactNode;
339
- children: React.ReactNode;
340
- side?: keyof typeof SIDES;
341
- className?: string;
342
- }
343
- declare function Tooltip({ label, children, side, className }: TooltipProps): React.JSX.Element;
344
-
345
300
  /**
346
301
  * Browser helpers for app pages.
347
302
  *
@@ -371,4 +326,4 @@ declare function toCsv(rows: string[][]): string;
371
326
  */
372
327
  declare function downloadCsv(rows: string[][], filename: string): void;
373
328
 
374
- export { type AppApiClient, AppApiProvider, AppContextProvider, type AppContextValue, AppInvokeError, Badge, type BadgeProps, Button, type ButtonProps, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, type CheckboxProps, CopyButton, type CopyButtonProps, type DateRange, DateRangePicker, type DateRangePickerProps, DropdownMenu, type DropdownMenuItem, type DropdownMenuProps, Input, Link, type LinkProps, Modal, type ModalProps, Popover, type PopoverProps, Select, type SelectProps, SidePanel, type SidePanelProps, Spinner, type SpinnerProps, Switch, type SwitchProps, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, type TabsProps, TabsTrigger, Textarea, type TextareaProps, type ToastInput, ToastProvider, Tooltip, type TooltipProps, badgeVariants, buttonVariants, cn, copyToClipboard, downloadBlob, downloadCsv, toCsv, useAppApi, useAppContext, useAppRun, useAppRuns, useAppSettings, useToast };
329
+ export { type AppApiClient, AppApiProvider, AppContextProvider, type AppContextValue, AppInvokeError, Badge, type BadgeProps, Button, type ButtonProps, Card, CardContent, CardHeader, CardTitle, Checkbox, type CheckboxProps, CopyButton, type CopyButtonProps, type DateRange, DateRangePicker, type DateRangePickerProps, DropdownMenu, type DropdownMenuItem, type DropdownMenuProps, Input, Link, type LinkProps, Modal, type ModalProps, Popover, type PopoverProps, Select, type SelectProps, SidePanel, type SidePanelProps, Spinner, type SpinnerProps, Switch, type SwitchProps, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, type TabsProps, TabsTrigger, Textarea, type TextareaProps, cn, copyToClipboard, downloadBlob, downloadCsv, toCsv, useAppApi, useAppContext, useAppRun, useAppRuns, useAppSettings };