@burojs/ui-shadcn 0.7.0 → 0.8.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.
- package/dist/{bulk-summary-CrEij5vq.cjs → bulk-summary-2HLgz7Il.cjs} +31 -5
- package/dist/bulk-summary-2HLgz7Il.cjs.map +1 -0
- package/dist/{bulk-summary-BWSAS7k2.js → bulk-summary-D6A0ua21.js} +32 -6
- package/dist/bulk-summary-D6A0ua21.js.map +1 -0
- package/dist/{candidates-relation-picker-y5M6_oe4.cjs → candidates-relation-picker-C47mF260.cjs} +3 -3
- package/dist/{candidates-relation-picker-y5M6_oe4.cjs.map → candidates-relation-picker-C47mF260.cjs.map} +1 -1
- package/dist/{candidates-relation-picker-CS_JZ4Fd.js → candidates-relation-picker-CGXItMN0.js} +3 -3
- package/dist/{candidates-relation-picker-CS_JZ4Fd.js.map → candidates-relation-picker-CGXItMN0.js.map} +1 -1
- package/dist/{check-confirm-dialog-C-NHgMST.cjs → check-confirm-dialog-BT04Mieo.cjs} +13 -6
- package/dist/check-confirm-dialog-BT04Mieo.cjs.map +1 -0
- package/dist/{check-confirm-dialog-2j0gOd7x.js → check-confirm-dialog-CtiRzOAt.js} +14 -7
- package/dist/{check-confirm-dialog-2j0gOd7x.js.map → check-confirm-dialog-CtiRzOAt.js.map} +1 -1
- package/dist/{filter-builder-DFu0JP-1.cjs → filter-builder-ByGhxLf_.cjs} +127 -63
- package/dist/filter-builder-ByGhxLf_.cjs.map +1 -0
- package/dist/{filter-builder-DaWHUZuV.js → filter-builder-z3Axzf9Y.js} +114 -56
- package/dist/filter-builder-z3Axzf9Y.js.map +1 -0
- package/dist/{flow-runtime-BpmrIUb6.cjs → flow-runtime-BVFjMU5-.cjs} +6 -3
- package/dist/{flow-runtime-BpmrIUb6.cjs.map → flow-runtime-BVFjMU5-.cjs.map} +1 -1
- package/dist/{flow-runtime-DyqTmK3H.js → flow-runtime-DrUWyTS0.js} +6 -3
- package/dist/{flow-runtime-DyqTmK3H.js.map → flow-runtime-DrUWyTS0.js.map} +1 -1
- package/dist/{flow-screen-DCdli6Ha.js → flow-screen-3fk6J33y.js} +6 -4
- package/dist/flow-screen-3fk6J33y.js.map +1 -0
- package/dist/{flow-screen-Bcz9NF2V.cjs → flow-screen-6y5E_HT6.cjs} +5 -3
- package/dist/flow-screen-6y5E_HT6.cjs.map +1 -0
- package/dist/index.cjs +518 -107
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +187 -86
- package/dist/index.d.ts +187 -86
- package/dist/index.js +519 -108
- package/dist/index.js.map +1 -1
- package/dist/{inline-flow-host-3vw7LzzD.cjs → inline-flow-host-C4KmZIYE.cjs} +3 -3
- package/dist/{inline-flow-host-3vw7LzzD.cjs.map → inline-flow-host-C4KmZIYE.cjs.map} +1 -1
- package/dist/{inline-flow-host-C0rI9B7f.js → inline-flow-host-YnnvWjdU.js} +3 -3
- package/dist/{inline-flow-host-C0rI9B7f.js.map → inline-flow-host-YnnvWjdU.js.map} +1 -1
- package/dist/{lazy-relation-picker-dialog-Bt8lrEIu.cjs → lazy-relation-picker-dialog-BAKBRn3V.cjs} +2 -2
- package/dist/{lazy-relation-picker-dialog-Bt8lrEIu.cjs.map → lazy-relation-picker-dialog-BAKBRn3V.cjs.map} +1 -1
- package/dist/{lazy-relation-picker-dialog-CAScLPb2.js → lazy-relation-picker-dialog-DN4bvQfg.js} +2 -2
- package/dist/{lazy-relation-picker-dialog-CAScLPb2.js.map → lazy-relation-picker-dialog-DN4bvQfg.js.map} +1 -1
- package/dist/{page-flow-route-BHUEpn0I.js → page-flow-route-CtEfqAvU.js} +5 -6
- package/dist/page-flow-route-CtEfqAvU.js.map +1 -0
- package/dist/{page-flow-route-DS8IVTVH.cjs → page-flow-route-DEjAxHe3.cjs} +6 -7
- package/dist/page-flow-route-DEjAxHe3.cjs.map +1 -0
- package/dist/{place-node-CfzQvh4Y.js → place-node-BdxT-30h.js} +149 -108
- package/dist/place-node-BdxT-30h.js.map +1 -0
- package/dist/{place-node-CNb3w-c7.cjs → place-node-Bhl8B3fF.cjs} +163 -134
- package/dist/place-node-Bhl8B3fF.cjs.map +1 -0
- package/dist/{related-list-cards-CelMxl4q.cjs → related-list-cards-Bc_vfCE_.cjs} +3 -3
- package/dist/{related-list-cards-CelMxl4q.cjs.map → related-list-cards-Bc_vfCE_.cjs.map} +1 -1
- package/dist/{related-list-cards-BIqqY69Y.js → related-list-cards-BvkD5OcC.js} +3 -3
- package/dist/{related-list-cards-BIqqY69Y.js.map → related-list-cards-BvkD5OcC.js.map} +1 -1
- package/dist/related-list-timeline-DCrwN9oO.js +167 -0
- package/dist/related-list-timeline-DCrwN9oO.js.map +1 -0
- package/dist/related-list-timeline-k0DtnxTs.cjs +167 -0
- package/dist/related-list-timeline-k0DtnxTs.cjs.map +1 -0
- package/dist/{related-rows-MPnLCmPF.cjs → related-rows-BW9Jr07T.cjs} +3 -3
- package/dist/{related-rows-MPnLCmPF.cjs.map → related-rows-BW9Jr07T.cjs.map} +1 -1
- package/dist/{related-rows--uP2iKQC.js → related-rows-CPE-9FFr.js} +3 -3
- package/dist/{related-rows--uP2iKQC.js.map → related-rows-CPE-9FFr.js.map} +1 -1
- package/dist/{relation-many-picker-BJhaEqxz.js → relation-many-picker-BlrGRwMV.js} +10 -5
- package/dist/relation-many-picker-BlrGRwMV.js.map +1 -0
- package/dist/{relation-many-picker-DzuGJpEl.cjs → relation-many-picker-Br-zBHxT.cjs} +10 -5
- package/dist/relation-many-picker-Br-zBHxT.cjs.map +1 -0
- package/dist/{relation-picker-DaIMzf2H.cjs → relation-picker-ADjxI_TI.cjs} +11 -6
- package/dist/relation-picker-ADjxI_TI.cjs.map +1 -0
- package/dist/{relation-picker-dialog-DoEY8EkH.js → relation-picker-dialog-CyKliBkN.js} +2 -2
- package/dist/{relation-picker-dialog-DoEY8EkH.js.map → relation-picker-dialog-CyKliBkN.js.map} +1 -1
- package/dist/{relation-picker-dialog-9Vg5vvR1.cjs → relation-picker-dialog-DimVQF9Y.cjs} +2 -2
- package/dist/{relation-picker-dialog-9Vg5vvR1.cjs.map → relation-picker-dialog-DimVQF9Y.cjs.map} +1 -1
- package/dist/{relation-picker-D-tBBZW_.js → relation-picker-x7P5HKie.js} +11 -6
- package/dist/relation-picker-x7P5HKie.js.map +1 -0
- package/dist/{resource-page-router-Diw6S6TK.js → resource-page-router-BRpUnhay.js} +144 -17
- package/dist/resource-page-router-BRpUnhay.js.map +1 -0
- package/dist/{resource-page-router-C_kGW2o_.cjs → resource-page-router-qEd2xb55.cjs} +158 -19
- package/dist/resource-page-router-qEd2xb55.cjs.map +1 -0
- package/dist/use-record-subtitle-bfwIoUme.cjs +70 -0
- package/dist/use-record-subtitle-bfwIoUme.cjs.map +1 -0
- package/dist/use-record-subtitle-gIaCGgbI.js +53 -0
- package/dist/use-record-subtitle-gIaCGgbI.js.map +1 -0
- package/package.json +9 -9
- package/dist/bulk-summary-BWSAS7k2.js.map +0 -1
- package/dist/bulk-summary-CrEij5vq.cjs.map +0 -1
- package/dist/check-confirm-dialog-C-NHgMST.cjs.map +0 -1
- package/dist/filter-builder-DFu0JP-1.cjs.map +0 -1
- package/dist/filter-builder-DaWHUZuV.js.map +0 -1
- package/dist/flow-screen-Bcz9NF2V.cjs.map +0 -1
- package/dist/flow-screen-DCdli6Ha.js.map +0 -1
- package/dist/page-flow-route-BHUEpn0I.js.map +0 -1
- package/dist/page-flow-route-DS8IVTVH.cjs.map +0 -1
- package/dist/place-node-CNb3w-c7.cjs.map +0 -1
- package/dist/place-node-CfzQvh4Y.js.map +0 -1
- package/dist/related-list-timeline-CRh7xwLD.js +0 -141
- package/dist/related-list-timeline-CRh7xwLD.js.map +0 -1
- package/dist/related-list-timeline-DsLdi8sv.cjs +0 -141
- package/dist/related-list-timeline-DsLdi8sv.cjs.map +0 -1
- package/dist/relation-many-picker-BJhaEqxz.js.map +0 -1
- package/dist/relation-many-picker-DzuGJpEl.cjs.map +0 -1
- package/dist/relation-picker-D-tBBZW_.js.map +0 -1
- package/dist/relation-picker-DaIMzf2H.cjs.map +0 -1
- package/dist/resource-page-router-C_kGW2o_.cjs.map +0 -1
- package/dist/resource-page-router-Diw6S6TK.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"place-node-CfzQvh4Y.js","names":["isRecord","i18nPrefixToRef","Table","UITable","exhaustive","useNotImplemented","lazyViews"],"sources":["../src/shell/shell-context.tsx","../src/screen/tree-context.ts","../src/fields/display-value.ts","../src/data-table/annotate-if-clipped.ts","../src/fields/field-value-frame.tsx","../src/forms/field.tsx","../src/screen/field-leaf.tsx","../src/blocks/facts-view.tsx","../src/blocks/placement-frame.ts","../src/flows/app-flow-button.tsx","../src/flows/inline-flow-view.tsx","../src/quick/use-deep-link.ts","../src/blocks/placement-seeds.ts","../src/enum/enum-badge.tsx","../src/export/download.ts","../src/export/run-watcher.ts","../src/actions/action-overflow.tsx","../src/layout/record-targets.ts","../src/lib/typography.ts","../src/layout/document-title.tsx","../src/resource/resource-title.ts","../src/resource/page-header.tsx","../src/blocks/related-skeletons.tsx","../src/blocks/related-item.tsx","../src/primitives/tabs.tsx","../src/screen/node-parts.tsx","../src/frames/builtin-nodes.tsx","../src/primitives/checkbox.tsx","../src/lib/use-container-narrow.ts","../src/data-table/fill-column.ts","../src/data-table/data-table.tsx","../src/resource/column-header-menu.tsx","../src/resource/column-accessor.ts","../src/resource/column-target.ts","../src/data-table/use-buro-data-table.ts","../src/resource/list-error-state.tsx","../src/resource/use-table-layout.ts","../src/list-kit/cursor-load-more.tsx","../src/resource/resource-list.tsx","../src/blocks/related-list-unbound.tsx","../src/list-kit/pieces/bulk-reach.tsx","../src/list-kit/pieces/piece.tsx","../src/list-kit/pieces/pieces-context.tsx","../src/list-kit/pieces/list-body.tsx","../src/resource/form-context.tsx","../src/record/route-screen-context.ts","../src/screen/use-tabs-url-state.ts","../src/frames/node-host.tsx","../src/screen/nodes.tsx","../src/screen/screen-tree.tsx","../src/forms/declarative-form.tsx","../src/export/format-option-labels.ts","../src/export/export-dialog.tsx","../src/flows/bulk-flow-button.tsx","../src/actions/bulk-action-toolbar.tsx","../src/list-kit/pieces/list-bulk-bar.tsx","../src/data-table/data-table-view-options.tsx","../src/list-kit/columns-toggle.tsx","../src/list-kit/pieces/list-columns.tsx","../src/resource/create-button.tsx","../src/list-kit/pieces/list-create.tsx","../src/export/export-button.tsx","../src/list-kit/pieces/list-export.tsx","../src/list-kit/list-search-input.tsx","../src/list-kit/filter-builder/filter-region.tsx","../src/list-kit/pieces/list-filters.tsx","../src/list-kit/pieces/list-flows.tsx","../src/list-kit/pieces/list-live.tsx","../src/saved-views/saved-views-dropdown.tsx","../src/list-kit/pieces/list-saved-views.tsx","../src/list-kit/pieces/list-controls.tsx","../src/frames/builtin-list.tsx","../src/frames/builtin-page.tsx","../src/frames/builtin-peek.tsx","../src/record/frame-context.ts","../src/record/frame-pieces.tsx","../src/frames/builtin-record.tsx","../src/frames/builtin.ts","../src/frames/resolve.ts","../src/list-kit/list-frame-host.tsx","../src/list-kit/resource-list-surface.tsx","../src/fields/use-relation-picker.tsx","../src/blocks/link-write-summary.tsx","../src/blocks/link-attach.tsx","../src/quick/peek-filter.ts","../src/blocks/link-panel.tsx","../src/blocks/route-list-context.ts","../src/blocks/related-list-view.tsx","../src/blocks/related-record-view.tsx","../src/blocks/builtins.ts","../src/blocks/place-node.tsx"],"sourcesContent":["'use client';\nimport { createContext, useContext, useMemo, type ReactElement, type ReactNode } from 'react';\n\nexport interface ShellBrand {\n readonly name: string;\n readonly subtitle?: string;\n readonly logo?: ReactNode;\n /** Where the brand links to. Default `'/'`. */\n readonly homePath?: string;\n}\n\nexport interface ShellUser {\n readonly name: string;\n readonly email?: string;\n readonly avatarUrl?: string;\n readonly initials: string;\n}\n\n/** Maps the auth provider's identity to what the shell shows. `initials` is derived from `name`. */\nexport type ShellUserMapper = (identity: unknown) => Omit<ShellUser, 'initials'>;\n\nexport interface ShellContextValue {\n readonly brand?: ShellBrand;\n readonly mapUser: ShellUserMapper;\n /** Where sign-out and \"Sign in\" go. Default `'/login'`. */\n readonly loginPath: string;\n /** Set only when a command palette is mounted. */\n readonly openPalette?: () => void;\n /** The mounted palette's open state; `AppShell` sets it unless `palette={false}`. Read it with {@link usePaletteState}. */\n readonly palette?: PaletteState;\n}\n\nexport interface PaletteState {\n readonly open: boolean;\n readonly setOpen: (open: boolean) => void;\n}\n\nfunction str(value: unknown): string | undefined {\n if (typeof value === 'string') return value.length > 0 ? value : undefined;\n if (typeof value === 'number' || typeof value === 'bigint') return String(value);\n return undefined;\n}\n\n/** `name`, else `email`, else `id` for the name; `email`; `avatarUrl` else `avatar`. */\nexport function defaultUserMapper(identity: unknown): Omit<ShellUser, 'initials'> {\n const record: Record<string, unknown> =\n typeof identity === 'object' && identity !== null ? (identity as Record<string, unknown>) : {};\n const email = str(record.email);\n const avatarUrl = str(record.avatarUrl) ?? str(record.avatar);\n return {\n name: str(record.name) ?? email ?? str(record.id) ?? '',\n ...(email !== undefined ? { email } : {}),\n ...(avatarUrl !== undefined ? { avatarUrl } : {}),\n };\n}\n\nconst DEFAULT_VALUE: ShellContextValue = Object.freeze({\n mapUser: defaultUserMapper,\n loginPath: '/login',\n});\n\nconst ShellContext = createContext<ShellContextValue>(DEFAULT_VALUE);\n\nexport type ShellProviderProps = Partial<ShellContextValue> & { readonly children: ReactNode };\n\nexport function ShellProvider({\n brand,\n mapUser,\n loginPath,\n openPalette,\n palette,\n children,\n}: ShellProviderProps): ReactElement {\n // Keyed on the brand's fields, not its identity: an inline `brand={{ … }}` is a new object on\n // every render, and must not re-render every shell consumer when nothing in it changed.\n const brandName = brand?.name;\n const brandSubtitle = brand?.subtitle;\n const brandLogo = brand?.logo;\n const brandHomePath = brand?.homePath;\n const stableBrand = useMemo<ShellBrand | undefined>(\n () =>\n brandName === undefined\n ? undefined\n : {\n name: brandName,\n ...(brandSubtitle !== undefined ? { subtitle: brandSubtitle } : {}),\n ...(brandLogo !== undefined ? { logo: brandLogo } : {}),\n ...(brandHomePath !== undefined ? { homePath: brandHomePath } : {}),\n },\n [brandName, brandSubtitle, brandLogo, brandHomePath],\n );\n const setPaletteOpen = palette?.setOpen;\n const open = useMemo(\n () => openPalette ?? (setPaletteOpen !== undefined ? () => setPaletteOpen(true) : undefined),\n [openPalette, setPaletteOpen],\n );\n const value = useMemo<ShellContextValue>(\n () => ({\n ...(stableBrand !== undefined ? { brand: stableBrand } : {}),\n mapUser: mapUser ?? defaultUserMapper,\n loginPath: loginPath ?? '/login',\n ...(open !== undefined ? { openPalette: open } : {}),\n ...(palette !== undefined ? { palette } : {}),\n }),\n [stableBrand, mapUser, loginPath, open, palette],\n );\n return <ShellContext.Provider value={value}>{children}</ShellContext.Provider>;\n}\n\n/** Outside a `ShellProvider`: no brand, the default mapper, `/login`. */\nexport function useShell(): ShellContextValue {\n return useContext(ShellContext);\n}\n\n/**\n * The palette's `open` and `setOpen`, for a custom `AppShell palette={<MyPalette/>}`, which\n * receives no props. Throws outside an `AppShell` (or a `ShellProvider` given `palette`).\n */\nexport function usePaletteState(): PaletteState {\n const { palette } = useContext(ShellContext);\n if (palette === undefined) {\n throw new Error(\n '[buro] usePaletteState must be used inside <AppShell> (or <ShellProvider palette={…}>)',\n );\n }\n return palette;\n}\n","'use client';\nimport type { CompiledScreen, ScreenMode } from '@burojs/core';\nimport type { FieldBinding, FormController } from '@burojs/react';\nimport { type ReactNode, createContext, useContext, useEffect, useRef } from 'react';\n\n/**\n * Which test ids a field leaf emits: the record ids (`form-field:…`,\n * `show-field:…`), or a resource-less form's (`<prefix>:field:<name>:hint`,\n * `…:info`) and none of the record ones.\n */\nexport type LeafIdScheme =\n | 'record'\n | {\n readonly prefix: string;\n /** The input ids' prefix (`<inputIds>-<name>`), so a host can focus a field by name. */\n readonly inputIds?: string;\n };\n\n/** A per-field render override: the binding and the default leaf node. */\nexport type RenderFieldOverrides = Readonly<\n Record<string, (binding: FieldBinding, defaultNode: ReactNode) => ReactNode>\n>;\n\n/** What every node of one rendered screen tree reads. */\nexport interface ScreenTreeValue {\n /** The resource's canonical name: test ids and bundle keys use it. */\n readonly resource: string;\n readonly mode: ScreenMode;\n readonly compiled: CompiledScreen;\n readonly controller: FormController;\n readonly region: 'record' | 'form-body' | 'page-body';\n /**\n * The tree is inside the `<form>` (edit and create: a record's `body`, or a form body): a\n * panel's body is a `fieldset` (P6-17). A display slot is never in the form.\n */\n readonly form: boolean;\n readonly leafIds: LeafIdScheme;\n readonly renderField?: RenderFieldOverrides;\n /** A whole-form lock (`<DeclarativeForm disabled>`): every input renders disabled. */\n readonly disabled?: boolean;\n /** Fields whose leaves render absent: a peek's fields it may not show (P3-38, P6-66). */\n readonly hiddenFields?: ReadonlySet<string>;\n}\n\nexport const ScreenTreeContext = createContext<ScreenTreeValue | null>(null);\n\n/** The tree being rendered; a node component outside `ScreenTree` is a framework bug. */\nexport function useScreenTree(): ScreenTreeValue {\n const tree = useContext(ScreenTreeContext);\n if (tree === null) throw new Error('[burojs] A screen node rendered outside <ScreenTree>.');\n return tree;\n}\n\n/** Registers `reveal` for a node id while mounted; the latest callback is the one called. */\nexport function useReveal(nodeId: string, reveal: () => void): void {\n const { controller } = useScreenTree();\n const latest = useRef(reveal);\n latest.current = reveal;\n const { registerReveal } = controller;\n useEffect(() => registerReveal(nodeId, () => latest.current()), [registerReveal, nodeId]);\n}\n","/**\n * Render an arbitrary field value as display text.\n *\n * Exists because the same defect was fixed twice and missed once. `String(value)`\n * on an object yields the literal «[object Object]» — what a jsonb column becomes\n * on screen. The guard was added to `TextDisplay`, but `f.json` routes to\n * `TextareaDisplay`, which still had the bare `String(value)`; an acceptance\n * review found «[object Object]» on every `code_code` record, on the exact\n * resource the fix claimed to cover.\n *\n * One helper, used by both renderers, so the two cannot drift again.\n */\nexport function toDisplayText(value: unknown): { text: string; isStructured: boolean } {\n if (typeof value !== 'object' || value === null) {\n return { text: String(value), isStructured: false };\n }\n try {\n return { text: JSON.stringify(value, null, 2), isStructured: true };\n } catch {\n // Circular or otherwise unserialisable — a shape hint beats a lie.\n return {\n text: Array.isArray(value) ? `[${(value as unknown[]).length}]` : '{…}',\n isStructured: true,\n };\n }\n}\n","import type { PointerEvent } from 'react';\n\n/**\n * Give a clipped cell a native tooltip carrying its full text, so a value the\n * column is too narrow to show is still readable. «Production facility …» in a\n * Location column was otherwise unrecoverable without resizing the column.\n *\n * Three deliberate choices:\n *\n * - **On hover, not on render.** Measuring needs layout, and the row body is\n * memoized precisely so it does not re-render while the user works (see\n * `MemoRow`). A `ResizeObserver` or a state flag would defeat that; reading\n * `scrollWidth` in the pointerenter handler costs nothing until the pointer\n * actually arrives, and re-checks after a column resize for free.\n * - **Only when actually clipped.** A `title` on every cell would put a\n * tooltip under the pointer constantly, which is worse than no tooltip.\n * - **Descendants too.** The cell wrapper is not always the element that\n * clips: a `<Badge>` caps itself at `max-w-full` and truncates INSIDE, so\n * the wrapper fits perfectly while the text is still cut off.\n *\n * Writing `title` straight onto the node is intentional — it is ephemeral,\n * affects nothing React renders, and keeps this out of the render path.\n *\n * `onPointerEnter`, not `onMouseEnter`: this is a passive, non-actionable\n * enhancement (there is nothing to activate, nothing a screen reader user\n * would do with it), so it carries no interactive ARIA role — pointer events\n * cover mouse, pen, and touch alike, where `onMouseEnter` would only cover\n * mouse.\n */\nexport function annotateIfClipped(e: PointerEvent<HTMLElement>): void {\n const el = e.currentTarget;\n const clipped =\n el.scrollWidth > el.clientWidth ||\n Array.from(el.querySelectorAll<HTMLElement>('*')).some((c) => c.scrollWidth > c.clientWidth);\n const text = clipped ? (el.textContent ?? '').trim() : '';\n if (text) el.setAttribute('title', text);\n else el.removeAttribute('title');\n}\n","'use client';\nimport { displayClassOf, resolveSurfaceUi, type DisplayClass, type UiSurface } from '@burojs/core';\nimport { useClipboard, useOptionalT } from '@burojs/react';\nimport { IconCheck, IconCopy } from '@tabler/icons-react';\nimport {\n type MouseEvent,\n type ReactElement,\n type ReactNode,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport { annotateIfClipped } from '../data-table/annotate-if-clipped.js';\nimport { lowerLegacyField, type LegacyFieldLike } from './legacy-field.js';\n\n/** The classes whose stored value has one text a user would paste (REF-117 §4.2). */\nconst COPY_CLASSES: readonly DisplayClass[] = ['string', 'number', 'date'];\n\n/** How long the copied state (its icon) lasts; the announcement is made once, when it starts. */\nconst COPIED_MS = 2000;\n\nconst isRecord = (value: unknown): value is Readonly<Record<string, unknown>> =>\n value !== null && typeof value === 'object' && !Array.isArray(value);\n\nconst isEmpty = (value: unknown) => value === null || value === undefined || value === '';\n\n/**\n * The stored value as text (builder call C4): a string as it is, a number with `String`, a date\n * as its ISO string. Never the formatted text: what a user pastes is what the record holds.\n */\nfunction copyText(value: unknown): string {\n if (value instanceof Date) return value.toISOString();\n return typeof value === 'string' ? value : String(value);\n}\n\nexport interface FieldValueFrameProps {\n /** The field as the site holds it (a builder field or a canonical declaration), with its name. */\n readonly field: LegacyFieldLike & { readonly name: string };\n /** The stored value, which the copy action copies. */\n readonly value: unknown;\n /** The surface the display is drawn on: its `overflow` applies. */\n readonly surface: Exclude<UiSurface, 'input'>;\n /** A table cell's list entry, the last layer of the `column` surface. */\n readonly entry?: { readonly display?: unknown };\n readonly children: ReactNode;\n}\n\n/**\n * The host's frame around a field's display (REF-117 P8, §4.2, §4.3): it draws `children` and,\n * around them, what the field's `ui` asks of the host rather than of the implementation, so a\n * custom display gets it too.\n *\n * - **Copy.** A copy button beside the value when `ui.copy` is `true`, the field is a text,\n * number or date field, the value is not empty, and something can write the clipboard\n * (`useClipboard()`, builder call C5). It copies the stored value as text and announces\n * `field.copied` once.\n * - **Overflow.** The surface's `overflow`: `truncate` keeps the value on one line with the full\n * text on hover; `wrap` lets it take as many lines as it needs, an unbroken string breaking\n * anywhere. In a table cell, `wrap` also needs the cell to stop clipping: `ResourceList` marks\n * the column `meta.wrap` for that.\n *\n * With neither, it renders `children` alone, so a field that sets nothing keeps today's markup.\n */\nexport function FieldValueFrame({\n field,\n value,\n surface,\n entry,\n children,\n}: FieldValueFrameProps): ReactElement {\n const t = useOptionalT();\n const clipboard = useClipboard();\n const [copied, setCopied] = useState(false);\n useEffect(() => {\n if (!copied) return;\n const timer = setTimeout(() => setCopied(false), COPIED_MS);\n return () => clearTimeout(timer);\n }, [copied]);\n const ui = isRecord(field.ui) ? field.ui : undefined;\n const asksCopy = ui?.copy === true;\n // `displayClassOf` reads the semantic shape and `ui.enum`: the lowered declaration, with the\n // field's own `ui` (the lowering keeps only its implementation selections). Only a field that\n // asks for copy pays for it: every list cell renders this frame.\n const valueClass = useMemo(\n () =>\n asksCopy\n ? displayClassOf({ ...lowerLegacyField(field), ...(ui === undefined ? {} : { ui }) })\n : undefined,\n [asksCopy, field, ui],\n );\n const { overflow: declared } = resolveSurfaceUi(field, surface, entry);\n const copyable =\n asksCopy &&\n clipboard !== undefined &&\n !isEmpty(value) &&\n valueClass !== undefined &&\n COPY_CLASSES.includes(valueClass);\n if (!copyable && declared === undefined) return <>{children}</>;\n // Beside the copy button the value is a flex item, which never shrinks below its content on\n // its own: with no declared overflow it takes the surface's default as a shrinkable item, so\n // the button stays inside the cell or row. A list cell truncates (§4.3); a show row and a card\n // wrap, breaking an unbroken string (a code, an id) rather than pushing the button out.\n const overflow = declared ?? (surface === 'column' ? 'truncate' : 'wrap');\n const body =\n overflow === 'wrap' ? (\n <span\n className=\"min-w-0 whitespace-normal [overflow-wrap:anywhere]\"\n data-buro-overflow=\"wrap\"\n >\n {children}\n </span>\n ) : (\n <span\n className=\"inline-block min-w-0 max-w-full truncate align-bottom\"\n data-buro-overflow=\"truncate\"\n onPointerEnter={annotateIfClipped}\n >\n {children}\n </span>\n );\n if (!copyable) return <>{body}</>;\n const label = t('field.copy', { defaultValue: 'Copy' });\n const copy = (event: MouseEvent<HTMLButtonElement>) => {\n // The row's own click (navigation, a quick open) is not this button's.\n event.preventDefault();\n event.stopPropagation();\n clipboard(copyText(value)).then(\n () => setCopied(true),\n () => undefined,\n );\n };\n return (\n <span className=\"inline-flex min-w-0 max-w-full items-center gap-1 align-bottom\">\n {body}\n <button\n type=\"button\"\n data-testid={`field-copy:${field.name}`}\n aria-label={label}\n title={label}\n onClick={copy}\n className=\"inline-flex size-6 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n {copied ? (\n <IconCheck aria-hidden=\"true\" className=\"size-3.5\" />\n ) : (\n <IconCopy aria-hidden=\"true\" className=\"size-3.5\" />\n )}\n </button>\n <span aria-live=\"polite\" className=\"sr-only\">\n {copied ? t('field.copied', { defaultValue: 'Copied' }) : ''}\n </span>\n </span>\n );\n}\n","'use client';\nimport { i18nPrefixToRef, type EntityRef, type FixedFilterInput } from '@burojs/core';\nimport { type ReactElement, type ReactNode, useMemo } from 'react';\nimport { DocInfo } from '../doc/doc-info.js';\nimport {\n ResolvedFieldDisplay,\n ResolvedFieldInput,\n type ResolvedFieldDisplayProps,\n type ResolvedFieldInputProps,\n} from '../fields/resolved-field.js';\nimport { FieldValueFrame } from '../fields/field-value-frame.js';\nimport { Input } from '../primitives/input.js';\n\nexport { i18nPrefixToRef };\n\nfunction resolveRef(resource: EntityRef | undefined, i18nPrefix: string | undefined): EntityRef {\n if (resource !== undefined) return resource;\n if (i18nPrefix !== undefined) return i18nPrefixToRef(i18nPrefix);\n return { namespace: 'default', id: 'form' };\n}\n\nexport type FieldProps = Omit<ResolvedFieldInputProps, 'resource' | 'fallback'> & {\n readonly resource?: EntityRef;\n readonly i18nPrefix?: string;\n readonly fallback?: ReactNode;\n /**\n * A relation field's `filter` function RESOLVED against the form's values (design doc §5,\n * `@burojs/react`'s `FieldBinding.fixedFilters`). It reaches the select on its own channel (a\n * prop of the input, never `field.meta`, which a layer can write) and applies on top of the\n * field's `candidates`. `<DeclarativeForm>` never sets this explicitly: it spreads the whole\n * `FieldBinding` (`{...binding}`), which already carries `fixedFilters` when the field\n * declared a `filter` function.\n *\n * `FixedFilterInput`, not the bare AST — matches `FieldBinding.fixedFilters`\n * (`@burojs/react`) and `RelationPickerProps`/`RelationPickerDialogProps`\n * downstream, so `{...binding}`'s spread onto this prop keeps typechecking.\n */\n readonly fixedFilters?: readonly FixedFilterInput[];\n /**\n * Render the contextual-doc affordance for this field. Opt-in: the brick is\n * used inside app-owned layouts that may already place their own label row,\n * so an always-on icon would appear twice. `<DeclarativeForm>` does NOT use\n * this — it owns its label row and renders `DocInfo` there directly.\n */\n readonly doc?: { readonly address: string; readonly name: string; readonly testId?: string };\n};\n\n/**\n * Public, resource-independent single-field input brick over\n * `ResolvedFieldInput`. Callers scope a field's runtime i18n either with an\n * explicit `resource` `EntityRef` or with a lighter-weight `i18nPrefix`\n * (`\"namespace:id\"` or a bare id against the default namespace) — no\n * registered resource is required. `fallback` defaults to a plain `<Input>`\n * wired to the field's value/onChange/disabled state.\n */\nexport function Field({\n resource,\n i18nPrefix,\n fallback,\n fixedFilters,\n field,\n doc,\n ...rest\n}: FieldProps): ReactElement {\n const input = (\n <ResolvedFieldInput\n {...rest}\n field={field}\n {...(fixedFilters === undefined ? {} : { fixedFilters })}\n resource={resolveRef(resource, i18nPrefix)}\n fallback={\n fallback ?? (\n // Raw HTML <input> fallback: string-oriented only. A non-primitive\n // `value` (object/array — e.g. an unresolved relation or JSON field\n // with no matching implementation) coerces via String() to\n // \"[object Object]\" rather than something editable. Callers with\n // such a field should supply their own `fallback`.\n <Input\n id={rest.inputId}\n value={String(rest.value ?? '')}\n onChange={(event) => rest.onChange(event.target.value)}\n disabled={rest.disabled}\n />\n )\n }\n />\n );\n if (doc === undefined) return input;\n return (\n <div className=\"flex flex-col gap-1.5\">\n <div className=\"flex items-center gap-2\">\n <DocInfo address={doc.address} name={doc.name} testId={doc.testId} />\n </div>\n {input}\n </div>\n );\n}\n\nexport type FieldDisplayProps = Omit<\n ResolvedFieldDisplayProps,\n 'resource' | 'fallback' | 'uiSurface' | 'columnEntry'\n> & {\n readonly resource?: EntityRef;\n readonly i18nPrefix?: string;\n readonly fallback?: ReactNode;\n};\n\n/**\n * Public, resource-independent single-field display brick over\n * `ResolvedFieldDisplay`. See {@link Field} for the `resource`/`i18nPrefix`\n * resolution rule. `fallback` defaults to a `<span>` rendering the value, or\n * an em dash when the value is empty. It draws the record screens' `display`\n * surface, with the field's copy action and overflow around it (REF-117 P8).\n */\nexport function FieldDisplay({\n resource,\n i18nPrefix,\n fallback,\n value,\n ...rest\n}: FieldDisplayProps): ReactElement {\n const frameField = useMemo(() => ({ ...rest.field, name: rest.name }), [rest.field, rest.name]);\n return (\n <FieldValueFrame field={frameField} value={value} surface=\"display\">\n <ResolvedFieldDisplay\n {...rest}\n value={value}\n resource={resolveRef(resource, i18nPrefix)}\n fallback={fallback ?? <span>{value == null || value === '' ? '—' : String(value)}</span>}\n />\n </FieldValueFrame>\n );\n}\n","'use client';\nimport {\n LAYOUT_SIZES,\n declaredText,\n type LayoutSize,\n type PlanNode,\n formatEntityRef,\n i18nPrefixToRef,\n resolveFieldLabel,\n resolveFieldSlot,\n} from '@burojs/core';\nimport {\n type FieldBinding,\n resolveValidationMessage,\n useFieldImplementation,\n useFieldMeta,\n useFieldMetaSources,\n useChromeT,\n useI18nCaps,\n useOptionalT,\n useTestIds,\n} from '@burojs/react';\nimport { IconLock } from '@tabler/icons-react';\nimport { type ReactElement, type ReactNode, useId, useRef } from 'react';\nimport { DocInfo } from '../doc/doc-info.js';\nimport {\n type LegacyFieldLike,\n fieldDescription,\n lowerLegacyField,\n} from '../fields/legacy-field.js';\nimport { MetaPlaceholder, useFieldMetaDiagnostic } from '../fields/resolved-field.js';\nimport { Field, FieldDisplay } from '../forms/field.js';\nimport { Input } from '../primitives/input.js';\nimport { cn } from '../lib/cn.js';\nimport { reasonText } from '../lib/reason-text.js';\nimport { Label } from '../primitives/label.js';\nimport { useReveal, useScreenTree } from './tree-context.js';\n\nconst SIZES: ReadonlySet<string> = new Set(LAYOUT_SIZES);\n\n/** How many issues a record field shows before \"+N more\" (spec 4.6 leaves it to the kit). */\nconst SHOWN_ISSUES = 3;\n\n/** What a reveal may focus inside a composite input. */\nconst FOCUSABLE =\n 'input:not([type=\"hidden\"]):not([disabled]), textarea:not([disabled]), select:not([disabled]), button:not([disabled]), [contenteditable=\"true\"], [tabindex]:not([tabindex=\"-1\"])';\n\n/**\n * A leaf's effective size (P1b+P1c decision 29): the field's `ui.size`, then\n * its input implementation's `layout.size`, then `md`.\n */\nfunction useLeafSize(field: FieldBinding['field']): LayoutSize {\n const implementation = useFieldImplementation({\n field: lowerLegacyField(field as LegacyFieldLike),\n surface: 'input',\n });\n const declared = (field as { readonly ui?: { readonly size?: unknown } }).ui?.size;\n if (typeof declared === 'string' && SIZES.has(declared)) return declared as LayoutSize;\n return implementation.layout.size ?? 'md';\n}\n\n/**\n * A field's label in show, everywhere one is drawn (field leaves, facts): one size, one weight,\n * one colour (visual-quality spec, finding 2).\n */\nexport const FIELD_LABEL_SHOW = 'text-sm font-medium text-muted-foreground';\n\n/** The attributes every leaf element carries. */\nfunction leafAttributes(size: LayoutSize, weight: number | undefined) {\n return {\n 'data-buro-node': 'field',\n 'data-buro-size': size,\n ...(weight === undefined ? {} : { 'data-buro-weight': String(weight) }),\n } as const;\n}\n\n/**\n * One field leaf of a screen tree (P1b+P1c section 9): an input when the plan\n * makes it `active`, its display with the lock reason when `readonly`, its\n * display in show. The test ids are the old engine's (`form-field:…`,\n * `form-field-input:…`, `form-field-locked:…`, `show-field:…`).\n */\nexport function FieldLeaf({ node }: { readonly node: PlanNode }): ReactElement | null {\n const { leafIds } = useScreenTree();\n // A resource-less form's leaf (`<DeclarativeForm>`, `<DeclarativeDisplay>`) keeps its own ids.\n // A field whose only failure is its own `meta` (a schema refused it, P7 3.3) draws its label\n // and the misconfigured control: the implementation is never given a meta it was refused.\n if (\n node.state === 'failed' &&\n node.failedOn.length > 0 &&\n node.failedOn.every((name) => name.startsWith('meta:'))\n )\n return <MisconfiguredLeaf node={node} />;\n if (leafIds !== 'record')\n return <DeclarativeLeaf node={node} prefix={leafIds.prefix} inputIds={leafIds.inputIds} />;\n return <RecordLeaf node={node} />;\n}\n\n/** The leaf of a field whose `meta` was refused: its label, the reason in development. */\nfunction MisconfiguredLeaf({ node }: { readonly node: PlanNode }): ReactElement {\n const { leafIds, resource, mode, controller } = useScreenTree();\n const name = node.field!;\n const binding = controller.field(name);\n const caps = useI18nCaps(resource);\n const tid = useTestIds();\n const field = lowerLegacyField(binding.field as LegacyFieldLike);\n const surface = mode === 'show' ? 'display' : 'input';\n const resolved = useFieldImplementation({ field, surface });\n const sources = useFieldMetaSources({\n record: controller.record,\n values: controller.values,\n extra: controller.sources,\n });\n // The planner failed this leaf on meta ⊕ the surface's params (REF-117 §4.12): read the same record.\n const state = useFieldMeta(field, resolved.implementation, sources, resolved.params);\n useFieldMetaDiagnostic(state, binding.resource, name, field, surface);\n const label = resolveFieldLabel(caps, name, declaredText('field', binding.field, 'label'));\n const testId =\n leafIds === 'record' ? tid.formField(resource, mode, name) : `${leafIds.prefix}:field:${name}`;\n return (\n <div\n {...leafAttributes('md', undefined)}\n className=\"relative\"\n data-testid={testId}\n data-buro-field-meta=\"failed\"\n >\n <div data-buro-region=\"field-label\" className=\"text-sm font-medium leading-none\">\n {label}\n </div>\n <div data-buro-region=\"field-control\">\n <MetaPlaceholder state={state} />\n </div>\n </div>\n );\n}\n\n/** A record screen's leaf: the record test ids. */\nfunction RecordLeaf({ node }: { readonly node: PlanNode }): ReactElement | null {\n const { resource, mode, compiled, controller } = useScreenTree();\n const name = node.field!;\n const binding = controller.field(name);\n const size = useLeafSize(binding.field);\n const weight = compiled.nodes[node.index]?.options.weight;\n const caps = useI18nCaps(resource);\n const tid = useTestIds();\n const label = resolveFieldLabel(caps, name, declaredText('field', binding.field, 'label'));\n const attributes = leafAttributes(size, weight);\n const t = useOptionalT();\n // A restricted field (P5 spec 3.6): its label, that it is restricted and why. Never the value,\n // never an input; the same in show and in edit.\n if (node.restricted === true) {\n const rawReason = node.restrictedReason;\n const reason =\n rawReason === undefined || rawReason === ''\n ? undefined\n : reasonText(caps, rawReason, resource);\n const restrictedId = tid.formFieldRestricted(resource, mode, name);\n return (\n <div\n {...attributes}\n className=\"relative\"\n data-testid={restrictedId}\n data-buro-restricted=\"true\"\n >\n <div data-buro-region=\"field-label\" className=\"text-sm font-medium leading-none\">\n {label}\n </div>\n <div data-buro-region=\"field-control\" className=\"space-y-1 text-sm\">\n <p className=\"flex items-center gap-1 text-[13px] leading-snug text-muted-foreground\">\n <IconLock className=\"h-3 w-3 shrink-0\" aria-hidden=\"true\" />\n <span>{t('access.restricted', { defaultValue: 'No access' })}</span>\n {reason === undefined ? null : <span>{reason}</span>}\n </p>\n </div>\n </div>\n );\n }\n const record = controller.record;\n // A field its user may not edit is not held in form state (P5 decision 23): in edit it is\n // displayed from the projected record.\n const value =\n mode === 'show'\n ? (record?.[name] ?? controller.values[name])\n : mode === 'edit' && controller.plan?.fields[name] !== 'active'\n ? (record?.[name] ?? controller.values[name])\n : controller.values[name];\n const display = (\n <FieldDisplay\n resource={binding.resource}\n name={name}\n field={binding.field as never}\n value={value}\n metaSources={controller.sources}\n {...(record === undefined ? {} : { record })}\n fallback={\n value == null || value === '' ? (\n <span className=\"text-muted-foreground\">—</span>\n ) : (\n <span>{String(value)}</span>\n )\n }\n />\n );\n\n if (mode === 'show') {\n return (\n <dl {...attributes} data-testid={`show-field:${resource}:${name}`}>\n <dt\n data-buro-region=\"field-label\"\n className={cn('flex items-center gap-0.5', FIELD_LABEL_SHOW)}\n >\n <span className=\"min-w-0\">{label}</span>\n <DocInfo address={`${resource}/fields/${name}`} name={label} />\n </dt>\n <dd data-buro-region=\"field-control\" className=\"text-sm text-foreground\">\n {display}\n </dd>\n </dl>\n );\n }\n\n if (node.editable !== true) {\n // A field the form cannot write: its display, and the deny rule's reason beside it.\n const rawReason = node.lockReason;\n const reason = rawReason === undefined ? undefined : reasonText(caps, rawReason, resource);\n const locked = tid.formFieldLocked(resource, mode, name);\n return (\n <div {...attributes} className=\"relative\" data-testid={tid.formField(resource, mode, name)}>\n <div data-buro-region=\"field-label\" className=\"flex items-center gap-2\">\n {/* The editable field's label exactly: a field turning read-only changes nothing here. */}\n <Label>{label}</Label>\n <DocInfo\n address={`${resource}/fields/${name}`}\n name={label}\n testId={`${tid.formField(resource, mode, name)}:info`}\n />\n </div>\n <div data-buro-region=\"field-control\" data-testid={locked} className=\"space-y-1 text-sm\">\n {/* An input-height box where the input would be, so nothing moves when it becomes one. */}\n <div\n data-buro-readonly=\"\"\n className=\"flex min-h-9 items-center rounded-md border border-input bg-muted/40 px-3 py-1.5\"\n >\n {display}\n </div>\n {reason === undefined ? null : (\n <p className=\"flex items-center gap-1 text-[13px] leading-snug text-muted-foreground\">\n <IconLock className=\"h-3 w-3 shrink-0\" aria-hidden=\"true\" />\n {reason}\n <DocInfo address={`lock/${rawReason}`} name={reason} testId={`${locked}:info`} />\n </p>\n )}\n </div>\n </div>\n );\n }\n\n const inputId = `${mode}-${name}`;\n return (\n <ActiveLeaf\n node={node}\n binding={binding}\n label={label}\n attributes={attributes}\n inputId={inputId}\n />\n );\n}\n\n/** An editable leaf: label, input, one message slot; its reveal focuses the input. */\nfunction ActiveLeaf({\n node,\n binding,\n label,\n attributes,\n inputId,\n}: {\n readonly node: PlanNode;\n readonly binding: FieldBinding;\n readonly label: string;\n readonly attributes: ReturnType<typeof leafAttributes>;\n readonly inputId: string;\n}): ReactElement {\n const { resource, mode, controller, disabled: locked } = useScreenTree();\n const caps = useI18nCaps(resource);\n const tid = useTestIds();\n const name = binding.name;\n const record = controller.record;\n const root = useRef<HTMLDivElement>(null);\n useReveal(node.id, () => {\n const element = root.current;\n if (element === null) return;\n const byId = element.ownerDocument.getElementById(inputId);\n byId?.focus();\n if (byId !== null && element.ownerDocument.activeElement === byId) return;\n // A composite input renders a container under the id: focus the first control in it,\n // else the first in the leaf.\n const scope = byId ?? element.querySelector('[data-buro-region=\"field-control\"]') ?? element;\n scope.querySelector<HTMLElement>(FOCUSABLE)?.focus();\n });\n const messageId = `${mode}-${name}-msg`;\n const placeholder = resolveFieldSlot(caps, name, 'placeholder');\n const hint = resolveFieldSlot(caps, name, 'description', fieldDescription(binding.field));\n const chromeT = useChromeT();\n const fieldKey = `resources.${resource}.fields.${name}`;\n const text = (issue: FieldBinding['issues'][number]) =>\n resolveValidationMessage(\n {\n code: issue.code ?? '',\n message: issue.message,\n ...(issue.check === undefined ? {} : { check: issue.check }),\n },\n { has: caps.has, t: caps.t, fieldKey },\n );\n // The field's issues (its subtree's, error first): the first few, then how many more.\n const shown = binding.issues.slice(0, SHOWN_ISSUES);\n const more = binding.issues.length - shown.length;\n const firstError = shown.find((issue) => issue.severity === 'error');\n const errorText = firstError === undefined ? null : text(firstError);\n // The tree's whole-form lock too (a flow's host while its write runs, or its unknown screen).\n const disabled = binding.disabled || controller.isSubmitting || locked === true;\n const describedBy = errorText === null && hint ? messageId : undefined;\n const errorMessageId = errorText === null ? undefined : messageId;\n return (\n // biome-ignore lint/a11y/noStaticElementInteractions: the blur bubbles from the input inside (focusout); the wrapper is not a control\n <div\n ref={root}\n {...attributes}\n // `relative`: a Radix control's hidden native element anchors here, not on the page.\n className=\"relative\"\n data-testid={tid.formField(resource, mode, name)}\n onBlur={binding.onBlur}\n >\n <div data-buro-region=\"field-label\" className=\"flex items-center gap-2\">\n <Label id={`${inputId}-label`} htmlFor={inputId} required={binding.required}>\n {label}\n </Label>\n <DocInfo\n address={`${resource}/fields/${name}`}\n name={label}\n testId={`${tid.formField(resource, mode, name)}:info`}\n />\n </div>\n <div data-buro-region=\"field-control\" className=\"space-y-1\">\n <Field\n resource={binding.resource}\n name={name}\n inputId={inputId}\n // `for` names a labelable control only; a radio group is named by the label's id.\n labelId={`${inputId}-label`}\n field={binding.field as never}\n value={binding.value}\n onChange={binding.onChange}\n testId={tid.formFieldInput(resource, mode, name)}\n {...(placeholder === undefined ? {} : { placeholder })}\n required={binding.required}\n disabled={disabled}\n {...(mode === 'create' || record === undefined ? {} : { record })}\n form={controller.values}\n metaSources={controller.sources}\n {...(describedBy === undefined ? {} : { descriptionId: describedBy })}\n {...(errorMessageId === undefined ? {} : { errorId: errorMessageId })}\n errorMessage={errorText}\n issues={binding.issues}\n {...(binding.fixedFilters === undefined ? {} : { fixedFilters: binding.fixedFilters })}\n {...(binding.relationSeeds === undefined ? {} : { relationSeeds: binding.relationSeeds })}\n {...(binding.link === undefined ? {} : { link: binding.link })}\n fallback={\n <Input\n id={inputId}\n name={inputId}\n data-testid={tid.formFieldInput(resource, mode, name)}\n value={binding.value == null ? '' : String(binding.value)}\n placeholder={placeholder}\n required={binding.required}\n disabled={disabled}\n aria-required={binding.required}\n aria-invalid={errorText !== null || undefined}\n aria-describedby={describedBy}\n {...(errorMessageId === undefined ? {} : { 'aria-errormessage': errorMessageId })}\n onChange={(event) => binding.onChange(event.target.value)}\n />\n }\n />\n {shown.length > 0 ? (\n // One message slot (one id, one live region), named for its most severe issue.\n <div\n id={messageId}\n aria-live=\"polite\"\n className={cn(\n 'space-y-0.5 text-sm',\n errorText === null ? 'text-warning-emphasis' : 'text-destructive',\n )}\n data-testid={\n errorText === null\n ? `form-field-warning:${resource}:${mode}:${name}`\n : tid.formFieldError(resource, mode, name)\n }\n >\n {shown.map((issue, index) => (\n <p\n // biome-ignore lint/suspicious/noArrayIndexKey: the field's ordered issue list\n key={index}\n data-buro-severity={issue.severity}\n className={\n issue.severity === 'error' ? 'text-destructive' : 'text-warning-emphasis'\n }\n >\n {text(issue)}\n </p>\n ))}\n {more > 0 ? (\n <p\n className=\"text-muted-foreground\"\n data-testid={`form-field-more:${resource}:${mode}:${name}`}\n >\n {chromeT('validation.moreIssues', {\n count: more,\n defaultValue: '+{{count}} more',\n })}\n </p>\n ) : null}\n </div>\n ) : hint ? (\n <p\n id={messageId}\n data-testid={tid.formFieldHelp(resource, mode, name)}\n className=\"text-[13px] leading-snug text-muted-foreground\"\n >\n {hint}\n </p>\n ) : null}\n </div>\n </div>\n );\n}\n\n/**\n * A resource-less form's leaf (P1b+P1c S3e): the markup `<DeclarativeForm>`\n * and `<DeclarativeDisplay>` drew per field before they ran on the controller,\n * with their ids (`<prefix>:field:<name>:hint`, `…:info`) and none of the\n * record ones. In show it is a label and the display; otherwise a label, the\n * input (or the `renderField` override wrapping it), one message slot (error\n * over warning) and the hint.\n */\nfunction DeclarativeLeaf({\n node,\n prefix,\n inputIds,\n}: {\n readonly node: PlanNode;\n readonly prefix: string;\n readonly inputIds: string | undefined;\n}): ReactElement {\n const { mode, compiled, controller, renderField, disabled } = useScreenTree();\n const name = node.field!;\n const binding = controller.field(name);\n const size = useLeafSize(binding.field);\n const weight = compiled.nodes[node.index]?.options.weight;\n const attributes = leafAttributes(size, weight);\n const docRef = i18nPrefixToRef(prefix);\n // Short key for the default namespace, qualified otherwise: a bundle authored under\n // `resources.<bare scope>` must match.\n const docScope = docRef.namespace === 'default' ? docRef.id : formatEntityRef(docRef);\n const caps = useI18nCaps(docScope);\n // A validation message reads the ambient resource level, as the form's other texts do.\n const issueCaps = useI18nCaps();\n const uid = useId();\n const root = useRef<HTMLDivElement>(null);\n const inputId = `${inputIds ?? uid}-${name}`;\n useReveal(node.id, () => {\n const element = root.current;\n if (element === null) return;\n const byId = element.ownerDocument.getElementById(inputId);\n byId?.focus();\n if (byId !== null && element.ownerDocument.activeElement === byId) return;\n element.querySelector<HTMLElement>(FOCUSABLE)?.focus();\n });\n const label = resolveFieldLabel(caps, name, declaredText('field', binding.field, 'label'));\n const hint = resolveFieldSlot(caps, name, 'description', fieldDescription(binding.field));\n const info = (\n <DocInfo\n address={`${docScope}/fields/${name}`}\n name={label}\n testId={`${prefix}:field:${name}:info`}\n />\n );\n const hintNode =\n hint === undefined ? null : (\n <p\n data-buro-region=\"field-message\"\n className=\"text-xs text-muted-foreground\"\n data-testid={`${prefix}:field:${name}:hint`}\n >\n {hint}\n </p>\n );\n if (mode === 'show') {\n return (\n <div ref={root} {...attributes}>\n <div data-buro-region=\"field-label\" className=\"flex items-center gap-2\">\n <span className={FIELD_LABEL_SHOW}>{label}</span>\n {info}\n </div>\n <div data-buro-region=\"field-control\">\n <FieldDisplay\n name={name}\n value={binding.value}\n field={binding.field as never}\n i18nPrefix={prefix}\n metaSources={controller.sources}\n />\n </div>\n {hintNode}\n </div>\n );\n }\n const fieldKey = `resources.${prefix}.fields.${name}`;\n const text = (issue: NonNullable<FieldBinding['error']>) =>\n resolveValidationMessage(\n {\n code: issue.code ?? '',\n message: issue.message,\n ...(issue.check === undefined ? {} : { check: issue.check }),\n },\n { has: issueCaps.has, t: issueCaps.t, fieldKey },\n );\n const defaultNode: ReactNode = (\n <Field\n {...binding}\n field={binding.field as never}\n metaSources={controller.sources}\n inputId={inputId}\n labelId={`${inputId}-label`}\n i18nPrefix={prefix}\n disabled={disabled === true || binding.disabled}\n />\n );\n const override = renderField?.[name];\n const control = override === undefined ? defaultNode : override(binding, defaultNode);\n const warning = binding.warnings[0];\n return (\n // `relative`: a Radix control's hidden native element anchors here, not on the page.\n <div ref={root} {...attributes} className=\"relative\">\n <div data-buro-region=\"field-label\" className=\"flex items-center gap-2\">\n <Label id={`${inputId}-label`} htmlFor={inputId} required={binding.required}>\n {label}\n </Label>\n {info}\n </div>\n <div data-buro-region=\"field-control\">{control}</div>\n {binding.error ? (\n <p data-buro-region=\"field-message\" aria-live=\"polite\" className=\"text-sm text-destructive\">\n {text(binding.error)}\n </p>\n ) : warning ? (\n <p\n data-buro-region=\"field-message\"\n aria-live=\"polite\"\n className=\"text-sm text-warning-emphasis\"\n >\n {text(warning)}\n </p>\n ) : null}\n {hintNode}\n </div>\n );\n}\n","'use client';\nimport {\n type CustomQueryHandle,\n type EntityRef,\n formatEntityRef,\n humanizeKey,\n resolveContentSlot,\n declaredText,\n} from '@burojs/core';\nimport {\n type BlockViewProps,\n useApplicationSnapshot,\n useCustomQuery,\n useI18nCaps,\n useChromeT,\n useOptionalT,\n} from '@burojs/react';\nimport { type ReactElement, useMemo } from 'react';\nimport { toDisplayText } from '../fields/display-value.js';\nimport { FieldValueFrame } from '../fields/field-value-frame.js';\nimport { ResolvedFieldDisplay } from '../fields/resolved-field.js';\nimport { Button } from '../primitives/button.js';\nimport { Skeleton } from '../primitives/skeleton.js';\nimport { FIELD_LABEL_SHOW } from '../screen/field-leaf.js';\n\n/** The props of `buro:facts` as its view receives them (each schema's output). */\ninterface FactsViewProps {\n readonly query: EntityRef;\n readonly input?: Readonly<Record<string, unknown>>;\n readonly rows?: readonly string[];\n readonly view?: 'grid' | 'list';\n readonly title?: string;\n readonly missing?: string;\n readonly refetchInterval?: number | false;\n}\n\n/** A query field as its portable declaration holds it. */\ninterface QueryField {\n readonly name: string;\n readonly label?: unknown;\n}\n\n/** An input holding, at any depth, a value that cannot be a key (final review M5). */\nfunction holdsUnreadable(value: unknown, depth = 0): boolean {\n if (unreadable(value)) return true;\n if (depth >= 8 || value === null || typeof value !== 'object') return false;\n const entries = Array.isArray(value) ? value : Object.values(value);\n return entries.some((entry) => holdsUnreadable(entry, depth + 1));\n}\n\n/** An input value that cannot be a key: no read is sent for it (Known finding 1). */\nfunction unreadable(value: unknown): boolean {\n return (\n value === undefined ||\n value === null ||\n value === '' ||\n (typeof value === 'number' && Number.isNaN(value))\n );\n}\n\nfunction Notice({ children }: { readonly children: string }): ReactElement {\n return <p className=\"text-sm text-muted-foreground\">{children}</p>;\n}\n\n/**\n * The built-in `buro:facts` view (P7 3.8): one custom query's declared `fields` as label and value\n * pairs. It is mounted once the placement is decided (its `requires`, its `when` and its refs are\n * the planner's), so the read below is the first and only one. The query's output is not a\n * resource row, so P5's projection does not apply to it (P7-25); an `input` value the planner\n * resolved to nothing sends no read.\n */\nexport function FactsView({ props, empty }: BlockViewProps<unknown>): ReactElement {\n const own = props as unknown as FactsViewProps;\n const t = useOptionalT();\n const chromeT = useChromeT();\n const snapshot = useApplicationSnapshot();\n const queryId = formatEntityRef(own.query);\n const caps = useI18nCaps();\n const fields = useMemo(() => {\n const projection = snapshot.getProjection({ kind: 'custom-query', ref: own.query });\n const declared = (projection?.value as { readonly fields?: readonly QueryField[] } | undefined)\n ?.fields;\n return Array.isArray(declared) ? declared : [];\n }, [snapshot, own.query]);\n const input = own.input ?? {};\n const blocked = Object.values(input).some((value) => holdsUnreadable(value));\n const handle = useMemo(\n () => ({ kind: 'custom-query', ref: own.query }) as CustomQueryHandle<unknown, unknown>,\n [own.query],\n );\n // A blocked input is never read, and it may not be portable (a resolved `undefined`): the hook\n // gets an empty one, disabled.\n const result = useCustomQuery(handle, (blocked ? {} : input) as never, {\n enabled: !blocked,\n ...(own.refetchInterval === undefined ? {} : { refetchInterval: own.refetchInterval }),\n });\n const shown = useMemo(() => {\n const byName = new Map(fields.map((field) => [field.name, field]));\n const names = own.rows ?? fields.map((field) => field.name);\n return names.flatMap((name) => {\n const field = byName.get(name);\n return field === undefined ? [] : [field];\n });\n }, [fields, own.rows]);\n if (blocked)\n return <Notice>{own.missing ?? empty ?? t('facts.empty', { defaultValue: 'No data' })}</Notice>;\n if (result.isError) {\n return (\n <div\n role=\"alert\"\n className=\"flex flex-wrap items-center gap-2 rounded-md border border-dashed px-3 py-2 text-sm text-muted-foreground\"\n >\n <span>{t('block.failed', { defaultValue: 'This section could not be loaded.' })}</span>\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={() => void result.refetch()}>\n {chromeT('actions.retry', { defaultValue: 'Retry' })}\n </Button>\n </div>\n );\n }\n // One tile per fact while it loads, in the grid the facts will fill: nothing shifts on arrival.\n if (result.data === undefined)\n return own.view === 'list' ? (\n <Skeleton data-buro-skeleton=\"\" className=\"h-9 w-full\" />\n ) : (\n <div data-buro-facts=\"grid\">\n {shown.map((field) => (\n <Skeleton key={field.name} data-buro-skeleton=\"\" className=\"h-[4.25rem] rounded-lg\" />\n ))}\n </div>\n );\n const data = result.data as Readonly<Record<string, unknown>> | null;\n if (data === null || typeof data !== 'object' || shown.length === 0)\n return <Notice>{own.missing ?? empty ?? t('facts.empty', { defaultValue: 'No data' })}</Notice>;\n const pairs = shown.map((field) => {\n const value = data[field.name];\n const label = resolveContentSlot(\n caps,\n [`queries.${queryId}.fields.${field.name}.label`, `queries.${queryId}.fields.${field.name}`],\n {\n ...(declaredText('field', field, 'label') === undefined\n ? {}\n : { default: declaredText('field', field, 'label') as string }),\n humanize: () => humanizeKey(field.name),\n },\n );\n const body =\n value === null || value === undefined ? (\n <span className=\"text-muted-foreground\">—</span>\n ) : (\n <FieldValueFrame field={field as never} value={value} surface=\"display\">\n <ResolvedFieldDisplay\n resource={own.query}\n name={field.name}\n field={field as never}\n value={value}\n record={data}\n fallback={toDisplayText(value).text}\n />\n </FieldValueFrame>\n );\n return { name: field.name, label, body };\n });\n const heading =\n own.title === undefined ? null : <h3 className=\"text-sm font-semibold\">{own.title}</h3>;\n if (own.view === 'list')\n return (\n <div className=\"flex flex-col gap-2\">\n {heading}\n <dl data-buro-facts=\"list\" className=\"flex flex-col gap-1\">\n {pairs.map(({ name, label, body }) => (\n <div key={name} data-buro-fact={name} className=\"flex items-baseline gap-2\">\n <dt className={FIELD_LABEL_SHOW}>{label}</dt>\n <dd className=\"min-w-0 break-words text-sm\">{body}</dd>\n </div>\n ))}\n </dl>\n </div>\n );\n return (\n <div className=\"flex flex-col gap-2\">\n {heading}\n {/* The grid is the styling contract's (`[data-buro-facts=\"grid\"]`); a fact is a tile, the one\n place a tile is earned: the number is the block's whole point. */}\n <dl data-buro-facts=\"grid\">\n {pairs.map(({ name, label, body }) => (\n <div\n key={name}\n data-buro-fact={name}\n className=\"flex min-w-0 flex-col gap-1 rounded-lg border bg-card px-4 py-3 text-card-foreground\"\n >\n <dt className={FIELD_LABEL_SHOW}>{label}</dt>\n <dd className=\"min-w-0 break-words text-xl font-semibold tabular-nums\">{body}</dd>\n </div>\n ))}\n </dl>\n </div>\n );\n}\n","import type { ScreenSources } from '@burojs/core';\nimport { createContext, useContext } from 'react';\n\n/** The placement a block view is rendered for: its key and its `state` node option. Internal. */\nexport interface PlacementFrame {\n readonly key: string;\n readonly state?: 'memory' | 'url';\n /** Found through a host's `block()` prop: its key is derived, so its list state is memory. */\n readonly nested: boolean;\n /** The placement's declared `where` (portable, refs unresolved): what its seeds come from. */\n readonly where?: readonly unknown[];\n /** The screen's source closure: which inputs each `with` source reaches. */\n readonly closure?: Readonly<Record<string, readonly string[]>>;\n /** The resource whose screen holds the placement (a record screen's); absent on a page. */\n readonly owner?: string;\n /**\n * The sources of the screen around the placement (`FormController.sources`), which a condition\n * prop reads (T4 C43): the related list's `create.when`.\n */\n readonly sources?: ScreenSources;\n}\n\nexport const PlacementFrameContext = createContext<PlacementFrame | null>(null);\n\n/** The placement around a view, or `null` (the route list). Internal. */\nexport function usePlacementFrame(): PlacementFrame | null {\n return useContext(PlacementFrameContext);\n}\n\n/**\n * A placement's table layout list id (REF-117 §4.10, C18): `<owner resource>/<placement key path>`,\n * a nested placement's derived key (`host.prop.0`) joined with `/`. A placement with no owner (on a\n * page, not a record screen) has none, and keeps its layout in memory.\n */\nexport function placementLayoutId(\n frame: { readonly owner?: string; readonly key: string } | null,\n): string | undefined {\n return frame?.owner === undefined\n ? undefined\n : `${frame.owner}/${frame.key.split('.').join('/')}`;\n}\n","'use client';\nimport { useI18nCaps } from '@burojs/react';\nimport { resolveNavLabel } from '@burojs/core';\nimport { type ReactElement, useState } from 'react';\nimport { DisabledAction } from '../actions/action-button.js';\nimport { ActionInner } from '../actions/action-inner.js';\nimport { Button, type ButtonProps } from '../primitives/button.js';\nimport { useLinkComponent } from '../layout/link-component.js';\nimport { preloadFlowRuntime, RuntimeAppFlowRunner } from './load-runtime.js';\n\nexport interface AppFlowButtonProps {\n /** The entry `useAppActions()` returned for a `kind: 'flow'` app action. */\n readonly action: {\n readonly name: string;\n readonly label?: string;\n readonly icon?: string;\n readonly disabledReason?: string;\n /** A flow hosted on a custom page (P7 3.15): the control is a link to it, not a runner. */\n readonly hostHref?: string;\n };\n readonly variant?: ButtonProps['variant'];\n readonly size?: ButtonProps['size'];\n readonly className?: string;\n}\n\n/**\n * An app flow's control (P4-D: app flows are drawn). `useAppActions()` decides whether the\n * entry exists and whether it is disabled (the flow's gate); this button draws it, loads the\n * flow runtime on intent (a hover, a focus, at the latest the click) and runs the flow — its\n * host when it has a form or a review, else the send behind the confirm dialog. Busy from the\n * click until the interaction ends. Test id: `app-action:<name>`.\n */\nexport function AppFlowButton({\n action,\n variant = 'ghost',\n size = 'sm',\n className,\n}: AppFlowButtonProps): ReactElement {\n const caps = useI18nCaps();\n const [running, setRunning] = useState(false);\n const label = resolveNavLabel(caps, `appActions.${action.name}`, action.label);\n const testid = `app-action:${action.name}`;\n const Anchor = useLinkComponent();\n if (action.disabledReason !== undefined)\n return (\n <DisabledAction\n reason={action.disabledReason === '' ? undefined : action.disabledReason}\n label={label}\n icon={action.icon}\n testid={testid}\n size={size}\n variant={variant}\n className={className}\n actionName={action.name}\n surface=\"app\"\n />\n );\n if (action.hostHref !== undefined)\n return (\n <Button\n asChild\n variant={variant}\n size={size}\n className={className}\n data-testid={testid}\n data-buro-flow-state=\"ready\"\n >\n <Anchor href={action.hostHref}>\n <ActionInner icon={action.icon} label={label} />\n </Anchor>\n </Button>\n );\n return (\n <>\n <Button\n type=\"button\"\n variant={variant}\n size={size}\n className={className}\n data-testid={testid}\n disabled={running}\n aria-busy={running ? 'true' : undefined}\n onPointerEnter={preloadFlowRuntime}\n onFocus={preloadFlowRuntime}\n onClick={() => setRunning(true)}\n >\n <ActionInner icon={action.icon} label={label} />\n </Button>\n {running ? (\n <RuntimeAppFlowRunner\n name={action.name}\n label={label}\n testid={testid}\n onClose={() => setRunning(false)}\n />\n ) : null}\n </>\n );\n}\n","'use client';\nimport {\n canonicalEntityNodeKey,\n compileFlow,\n declaredText,\n type EntityRef,\n flowRecordOf,\n type FlowTarget,\n resolveNavLabel,\n} from '@burojs/core';\nimport {\n type BlockViewProps,\n useApp,\n useCurrentUserId,\n useI18nCaps,\n usePageFlowGate,\n useFlowRowResolver,\n policyRecordOf,\n useOptionalRecordFrame,\n useScreenState,\n useTestIds,\n} from '@burojs/react';\nimport { type ReactElement, useEffect, useMemo, useSyncExternalStore } from 'react';\nimport { usePlacementFrame } from '../blocks/placement-frame.js';\nimport { Skeleton } from '../primitives/skeleton.js';\nimport { AppFlowButton } from './app-flow-button.js';\nimport { FlowActionButton } from './flow-action-button.js';\nimport { FlowBoundary, loadFailedText, loadInlineFlowHost, useLoaded } from './load-runtime.js';\n\nconst NO_SUBSCRIBE = () => () => undefined;\nconst ZERO = () => 0;\n\n/**\n * The built-in `buro:inline-flow` view (P6 3.12): an item flow of the screen's own resource,\n * drawn in place. The gate is the placement's own (the planner already dropped a denied one)\n * conjoined with the flow's: nothing is read or drawn before it is decided; a flow whose gate\n * hides it leaves no trace. A flow without a form or a review is its button; a slot another\n * mounted screen already holds (a sheet over the page) is the button too.\n */\nexport function InlineFlowView({ props }: BlockViewProps<unknown>): ReactElement | null {\n const name = (props as { readonly flow?: unknown }).flow;\n // On a page the flow is named by a reference, and there is no record (P7 3.15).\n if (name !== null && typeof name === 'object')\n return <PageInlineFlow flow={name as PageFlowRef} />;\n return <RecordInlineFlow name={name} />;\n}\n\ntype PageFlowRef =\n | { readonly app: EntityRef }\n | { readonly resource: EntityRef; readonly flow: string };\n\nfunction RecordInlineFlow({ name }: { readonly name: unknown }): ReactElement | null {\n const frame = useOptionalRecordFrame();\n const placement = usePlacementFrame();\n const app = useApp();\n const tid = useTestIds();\n const holder = useScreenState()?.inline;\n // A discard (or any release) of this screen's leases re-renders the placement.\n useSyncExternalStore(\n holder?.subscribe ?? NO_SUBSCRIBE,\n holder?.version ?? ZERO,\n holder?.version ?? ZERO,\n );\n const userId = useCurrentUserId();\n const resource = frame?.resource ?? '';\n const flowName = typeof name === 'string' ? name : '';\n const resolve = useFlowRowResolver(resource);\n const def = app.registry.get(resource);\n const compiled = useMemo(() => {\n try {\n return def === undefined ? null : compileFlow(def as never, flowName);\n } catch {\n return null;\n }\n }, [def, flowName]);\n const id = frame?.recordId;\n // The gate and the flow read the record as read; what the form renders projects on its own\n // (P4 4.24 C2, P5 decision 12).\n const asRead = frame === null ? undefined : policyRecordOf(frame.controller, frame.record);\n const key = placement?.key ?? flowName;\n // A flow whose `when` turned false keeps its node while the input is dirty or its attempt\n // unresolved (3.12); a denied or clean one is released at once.\n const state =\n frame === null || id === undefined || asRead === undefined\n ? null\n : resolve(flowName, { ...asRead, id } as { id: string } & Record<string, unknown>);\n const kept = holder?.get(key);\n const stale =\n state?.state === 'absent' && state.cause === 'when' && kept !== undefined && kept.dirty;\n const gone = state?.state === 'absent' && !stale;\n useEffect(() => {\n if (gone) holder?.release(key);\n }, [gone, holder, key]);\n if (frame === null || asRead === undefined || id === undefined || compiled === null) return null;\n const row = { ...asRead, id } as { id: string } & Record<string, unknown>;\n const control = resolve(flowName, row);\n switch (control.state) {\n case 'undecided':\n case 'pending':\n return (\n <Skeleton\n className=\"h-24 w-full\"\n data-testid={tid.inlineFlow(compiled.flowId, key)}\n data-buro-flow-state=\"pending\"\n />\n );\n case 'absent':\n if (!stale || kept === undefined) return null;\n return (\n <InlineHostLoader\n resource={resource}\n name={flowName}\n {...hostRecord(flowRecordOf(compiled, row))}\n placementKey={key}\n lease={kept}\n stale\n onDiscard={() => holder?.release(key)}\n />\n );\n default:\n }\n const button = (\n <FlowActionButton resource={resource} actionName={flowName} record={row} scope=\"show\" />\n );\n // A pre-click check that starts blocking under unsaved input: the notice and Discard, not a\n // disabled button over a hidden form (3.12).\n if (control.state === 'disabled' && kept !== undefined && kept.dirty)\n return (\n <InlineHostLoader\n resource={resource}\n name={flowName}\n {...hostRecord(flowRecordOf(compiled, row))}\n placementKey={key}\n lease={kept}\n stale\n onDiscard={() => holder?.release(key)}\n />\n );\n if (control.state === 'disabled' || !compiled.hasHost) return button;\n const lease = holder?.acquire(key, compiled.flowId, id, userId ?? '');\n if (lease === 'held-elsewhere') return button;\n // A collection-level flow drawn on a record page runs with no record (spec 5.1); its lease\n // stays keyed by the placement.\n return (\n <InlineHostLoader\n resource={resource}\n name={flowName}\n {...hostRecord(flowRecordOf(compiled, control.record ?? row))}\n placementKey={key}\n {...(lease === undefined ? {} : { lease })}\n />\n );\n}\n\n/** The host's `record` prop: present only when the run receives one (an item flow). */\nconst hostRecord = (record: Readonly<Record<string, unknown>> | undefined) =>\n record === undefined ? {} : { record: record as never };\n\nfunction InlineHostLoader(\n props: Parameters<typeof import('./inline-flow-host.js').InlineFlowHost>[0],\n): ReactElement {\n const loaded = useLoaded(loadInlineFlowHost);\n if (loaded.error !== undefined)\n return (\n <p role=\"alert\" className=\"text-sm text-muted-foreground\">\n {loadFailedText((key: string) => key)}\n </p>\n );\n if (loaded.module === undefined) return <Skeleton className=\"h-24 w-full\" />;\n const Host = loaded.module.InlineFlowHost;\n return (\n <FlowBoundary\n fallback={() => (\n <p role=\"alert\" className=\"text-sm text-muted-foreground\">\n {loadFailedText((key: string) => key)}\n </p>\n )}\n >\n <Host {...props} />\n </FlowBoundary>\n );\n}\n\n/**\n * An app flow or a resource-level flow drawn in place on a custom page (P7 3.15). The gate is the\n * flow's own (`resolveFlowGate`, decided before anything is read): undecided is a skeleton,\n * absent leaves no trace. A flow without a form or a review is its button; one with a host holds\n * the page's lease for the flow, so a tab switch away and back finds the typed input.\n */\nfunction PageInlineFlow({ flow }: { readonly flow: PageFlowRef }): ReactElement | null {\n const placement = usePlacementFrame();\n const app = useApp();\n const caps = useI18nCaps();\n const tid = useTestIds();\n const holder = useScreenState()?.inline;\n useSyncExternalStore(\n holder?.subscribe ?? NO_SUBSCRIBE,\n holder?.version ?? ZERO,\n holder?.version ?? ZERO,\n );\n const userId = useCurrentUserId();\n const target = useMemo<FlowTarget>(\n () =>\n 'app' in flow\n ? { appAction: canonicalEntityNodeKey({ name: flow.app.id, ref: flow.app }) }\n : {\n resource: canonicalEntityNodeKey({ name: flow.resource.id, ref: flow.resource }),\n action: flow.flow,\n },\n [flow],\n );\n const { answer, compiled } = usePageFlowGate(target);\n const key = placement?.key ?? ('appAction' in target ? target.appAction : target.action);\n const gone = answer.state === 'absent' || answer.state === 'hidden';\n useEffect(() => {\n if (gone) holder?.release(key);\n }, [gone, holder, key]);\n if (compiled === null || gone) return null;\n if (answer.state === 'undecided')\n return (\n <Skeleton\n className=\"h-24 w-full\"\n data-testid={tid.inlineFlow(compiled.flowId, key)}\n data-buro-flow-state=\"pending\"\n />\n );\n const appAction =\n 'appAction' in target ? app.registry.appActions.get(target.appAction) : undefined;\n const label =\n appAction === undefined\n ? undefined\n : resolveNavLabel(\n caps,\n `appActions.${'appAction' in target ? target.appAction : ''}`,\n declaredText('flow', appAction, 'label'),\n );\n const button =\n 'appAction' in target ? (\n <AppFlowButton\n action={{\n name: target.appAction,\n label: declaredText('flow', appAction, 'label') ?? target.appAction,\n ...(appAction?.icon === undefined ? {} : { icon: appAction.icon }),\n ...(answer.state === 'disabled' ? { disabledReason: answer.reason ?? '' } : {}),\n }}\n variant=\"outline\"\n size=\"default\"\n />\n ) : (\n <FlowActionButton resource={target.resource} actionName={target.action} scope=\"page\" />\n );\n if (answer.state === 'disabled' || !compiled.hasHost) return button;\n const lease = holder?.acquire(key, compiled.flowId, 'page', userId ?? '');\n if (lease === 'held-elsewhere') return button;\n return (\n <InlineHostLoader\n target={target}\n placementKey={key}\n {...(label === undefined ? {} : { label })}\n {...(lease === undefined ? {} : { lease })}\n />\n );\n}\n","'use client';\nimport type { PlanNode, ScreenPlan } from '@burojs/core';\nimport {\n useEntryGate,\n useOptionalRouterAdapter,\n useQuickOpener,\n useSearchParamsWriter,\n} from '@burojs/react';\nimport {\n type Context,\n type ReactElement,\n type ReactNode,\n createContext,\n createElement,\n useContext,\n useEffect,\n useMemo,\n useRef,\n} from 'react';\n\nconst SUFFIX = '.open';\n\n/** The drawn placements of a route screen, by key: what the sweep asks before it drops a link. */\ninterface DeepLinkRegistry {\n register(key: string): () => void;\n has(key: string): boolean;\n}\n\nconst DeepLinkRegistryContext: Context<DeepLinkRegistry | null> =\n createContext<DeepLinkRegistry | null>(null);\n\nfunction notice(param: string, id: string, why: string): void {\n if (process.env.NODE_ENV === 'production') return;\n console.warn(`[burojs] ?${param}=${id} was dropped: ${why}.`);\n}\n\n/**\n * The deep link `?<key>.open=<id>` of a drawn placement (spec 4.8, P3-24/25): once the entry gate\n * has decided, an `open` answer opens the row's `quick.show` and the parameter is removed with a\n * `replace` (consumed once); any other answer removes it with one development notice; undecided\n * (the permission map loads) waits, and nothing is read meanwhile. `key` is the placement's key on\n * a route screen, or the resource's own namespace on the route list of a resource without a page.\n */\nexport function useDeepLinkOpen(key: string | null, target: string, enabled: boolean): void {\n const adapter = useOptionalRouterAdapter();\n const gate = useEntryGate();\n const open = useQuickOpener();\n const write = useSearchParamsWriter();\n const registry = useContext(DeepLinkRegistryContext);\n const param = key === null ? null : `${key}${SUFFIX}`;\n const id = param === null ? null : (adapter?.searchParams.get(param) ?? null);\n // A drawn placement says so: the sweep leaves its parameter to it.\n useEffect(() => {\n if (!enabled || key === null || registry === null) return;\n return registry.register(key);\n }, [enabled, key, registry]);\n const handled = useRef<string | null>(null);\n useEffect(() => {\n if (!enabled || param === null || id === null || adapter === null) return;\n const token = `${param}=${id}`;\n if (handled.current === token) return;\n const answer = gate(target, 'show');\n if (answer.state === 'undecided') return;\n handled.current = token;\n const drop = () => write((params) => params.delete(param), { history: 'replace' });\n if (id === '') {\n notice(param, id, 'it names no record');\n drop();\n return;\n }\n if (answer.state !== 'open') {\n notice(param, id, answer.why);\n drop();\n return;\n }\n open(target, id);\n drop();\n }, [enabled, param, id, adapter, gate, target, open, write]);\n}\n\n/** The keyed placements of a plan, by key. */\nfunction placements(plan: ScreenPlan): Map<string, PlanNode> {\n const out = new Map<string, PlanNode>();\n const walk = (nodes: readonly PlanNode[]) => {\n for (const node of nodes) {\n if (node.kind === 'place' && node.key !== undefined) out.set(node.key, node);\n walk(node.children);\n }\n };\n walk(Object.values(plan.slots).flat());\n return out;\n}\n\n/**\n * A route screen's sweep (spec 4.8): once the plan has settled for a key a `?<key>.open`\n * parameter names (its placement is not pending), a parameter whose placement is absent, not\n * drawn (its tab not chosen) or unknown is removed with one development notice. A drawn\n * placement consumes its own parameter (`useDeepLinkOpen`); a pending one keeps it.\n */\nexport function DeepLinkScope({\n plan,\n enabled,\n children,\n}: {\n readonly plan: ScreenPlan | null;\n readonly enabled: boolean;\n readonly children: ReactNode;\n}): ReactElement {\n const adapter = useOptionalRouterAdapter();\n const write = useSearchParamsWriter();\n const drawn = useRef(new Map<string, number>());\n const registry = useMemo<DeepLinkRegistry>(\n () => ({\n register(key) {\n drawn.current.set(key, (drawn.current.get(key) ?? 0) + 1);\n return () => {\n const left = (drawn.current.get(key) ?? 1) - 1;\n if (left <= 0) drawn.current.delete(key);\n else drawn.current.set(key, left);\n };\n },\n has: (key) => drawn.current.has(key),\n }),\n [],\n );\n const search = adapter?.searchParams.toString() ?? '';\n // biome-ignore lint/correctness/useExhaustiveDependencies: keyed by the query string, not the params object\n useEffect(() => {\n if (!enabled || plan === null || adapter === null) return;\n const named = [...adapter.searchParams.keys()].filter((name) => name.endsWith(SUFFIX));\n if (named.length === 0) return;\n const nodes = placements(plan);\n // A drawn placement registers in its own effect; give a placement that became ready in this\n // commit one task to say so before deciding that it is not drawn.\n const timer = setTimeout(() => {\n const stale: { param: string; id: string; why: string }[] = [];\n for (const param of named) {\n const key = param.slice(0, -SUFFIX.length);\n if (registry.has(key)) continue;\n const node = nodes.get(key);\n const id = adapter.searchParams.get(param) ?? '';\n if (node === undefined) {\n // The route list of a page: false resource reads its own namespace, which is no\n // placement of this screen; leave it alone.\n continue;\n }\n if (node.state === 'pending') continue;\n stale.push({\n param,\n id,\n why:\n node.state === 'absent'\n ? `the placement \"${key}\" is absent (${node.reason ?? 'not shown'})`\n : `the placement \"${key}\" is not drawn`,\n });\n }\n if (stale.length === 0) return;\n for (const entry of stale) notice(entry.param, entry.id, entry.why);\n write(\n (params) => {\n for (const entry of stale) params.delete(entry.param);\n },\n { history: 'replace' },\n );\n }, 0);\n return () => clearTimeout(timer);\n }, [enabled, plan, search, registry, write]);\n return createElement(DeepLinkRegistryContext.Provider, { value: registry }, children);\n}\n","/**\n * A `where` entry as a placement declares it: its `value` may be a portable ref. A group\n * (`and` / `or` / `not`) has no `field` and never seeds.\n */\nexport interface PortableWhereEntry {\n readonly field?: string;\n readonly op?: string;\n readonly value?: unknown;\n readonly and?: unknown;\n readonly or?: unknown;\n readonly not?: unknown;\n}\n\n/**\n * Inputs a seed never comes from: `route` (a URL value, or the opener's id inside a quick entry)\n * and `values` (the form's unsaved input in edit).\n */\nconst UNTRUSTED: readonly string[] = ['route', 'values'];\n\n/** A portable ref, `{ kind: 'ref', source, path }`. */\nfunction refSource(value: unknown): string | null {\n if (value === null || typeof value !== 'object') return null;\n const ref = value as { readonly kind?: unknown; readonly source?: unknown };\n return ref.kind === 'ref' && typeof ref.source === 'string' ? ref.source : null;\n}\n\n/** A value with no ref anywhere in it: a literal. */\nfunction isLiteral(value: unknown): boolean {\n if (value === null || typeof value !== 'object') return true;\n if (refSource(value) !== null) return false;\n return Object.values(value as Record<string, unknown>).every(isLiteral);\n}\n\n/**\n * The seeds a placement's \"+ Create\" passes to `quick.create` (spec 4.5, P3-18): from each\n * `where` entry with `op: 'eq'` whose resolved value is ready (not `null` or `undefined`) and\n * whose declared value is a literal, a ref into `record` or `user`, or a ref into a `with` source\n * whose inputs never reach `route` or `values` (`closure`, the screen's source closure). A value\n * derived from `route` — a URL value on a route screen, the opener's id inside a quick entry — or\n * from `values` — the user's unsaved input — seeds nothing: the seeds land in the caller's trusted\n * defaults tier. Only a top-level leaf on the target's own, undotted field seeds: a group's\n * leaves and a relation path (`customer_id.region`) never do (T4 C37).\n */\nexport function placementSeeds(\n where: readonly PortableWhereEntry[],\n resolved: readonly PortableWhereEntry[],\n closure: Readonly<Record<string, readonly string[]>>,\n): Readonly<Record<string, unknown>> {\n const seeds: Record<string, unknown> = {};\n where.forEach((entry, index) => {\n const value = resolved[index]?.value;\n if (entry.op !== 'eq' || value === null || value === undefined) return;\n if (typeof entry.field !== 'string' || entry.field.includes('.')) return;\n if (resolved[index]?.field !== entry.field) return;\n const source = refSource(entry.value);\n const trusted =\n source === null\n ? isLiteral(entry.value)\n : source === 'record' ||\n source === 'user' ||\n (!UNTRUSTED.includes(source) &&\n Object.hasOwn(closure, source) &&\n !(closure[source] ?? []).some((input) => UNTRUSTED.includes(input)));\n if (trusted) seeds[entry.field] = value;\n });\n return Object.freeze(seeds);\n}\n","'use client';\n\nimport type * as React from 'react';\nimport {\n type EnumNameOrRef,\n type EnumValue,\n enumFallbackKey,\n enumFallbackText,\n enumValueText,\n resolveContentSlot,\n resolveEnumLabel,\n} from '@burojs/core';\nimport { useApp, useEnumValues, useI18nCaps, type FieldPresentation } from '@burojs/react';\nimport { enumBindingKey } from '@burojs/core/internal';\nimport { Badge } from '../primitives/badge.js';\nimport { Icon } from '../primitives/icon.js';\n\n/** Icon + localized label body shared by the resolved + fallback badges. */\nfunction BadgeBody({ icon, label }: { icon?: string; label: string }): React.ReactElement {\n return (\n <span className=\"inline-flex items-center gap-1\">\n {icon ? <Icon name={icon} className=\"size-3.5 shrink-0\" /> : null}\n {label}\n </span>\n );\n}\n\nexport interface EnumBadgeProps<N extends string = string> {\n /**\n * Name of the enum registered via `defineEnum` + `app.use(...)`, checked against the\n * registered enums, or its entity ref `{ namespace, id }` (untyped).\n */\n enumName: EnumNameOrRef<N>;\n /** Raw value as stored on the record. */\n value: string | null | undefined;\n /** Test-id override. Defaults to `enum-badge:<enumName>:<value>`. */\n testid?: string;\n /** Custom class name passed through to the underlying Badge. */\n className?: string;\n /** `'plain'` drops the Badge wrapper and renders the label bare. */\n presentation?: FieldPresentation;\n}\n\n/**\n * Renders a status / type / kind badge by looking up the enum + value\n * from the app registry.\n *\n * Resolution order:\n * 1. Look up `app.registry.enums.get(enumName)`.\n * 2. Find the matching value entry inside the enum.\n * 3. Render `<Badge variant={value.color ?? 'outline'}>{value.label}</Badge>`.\n *\n * Fallbacks:\n * - Enum not registered → render plain `<span>` with the raw value.\n * No error — this is intentional so a half-shipped enum (e.g. waiting\n * for a follow-up registration) does not crash an admin page.\n * - Value is null/empty → render an em-dash placeholder.\n * - Value is unknown to the enum AND `enum.fallback` is set → render the\n * fallback label/color.\n * - Value is unknown AND no `fallback` declared → render the raw value\n * as a plain badge (variant `outline`).\n */\nexport function EnumBadge<const N extends string = string>({\n enumName: enumInput,\n value,\n testid,\n className,\n presentation,\n}: EnumBadgeProps<N>): React.ReactElement {\n // The name as the registry and the bundle key it: an entity ref as its canonical key.\n const enumName = enumBindingKey(enumInput) ?? '';\n const app = useApp();\n const caps = useI18nCaps();\n const def = app.registry.enums.get(enumName);\n const { values, isLoading, error } = useEnumValues(enumName);\n // Enum labels resolve from the `enums.<ns>.<value>` bundle; namespace defaults\n // to the enum name (overridable via `i18nNamespace`). Falls back to the inline\n // def label until the enum is migrated to the bundle (phase 4).\n const ns = (def as { i18nNamespace?: string } | undefined)?.i18nNamespace ?? enumName;\n const id = testid ?? `enum-badge:${enumName}:${String(value ?? 'null')}`;\n\n if (value == null || value === '') {\n return (\n <span data-testid={`${id}:empty`} className=\"text-muted-foreground\">\n —\n </span>\n );\n }\n\n if (!def) {\n // Enum not registered — degrade to plain text. Adopters get a console\n // warning the first time the lookup misses (cheap to do, not throttled\n // because dev-mode only).\n if (process.env.NODE_ENV !== 'production') {\n // eslint-disable-next-line no-console\n console.warn(\n `[EnumBadge] enum '${enumName}' not registered — rendering raw value '${value}'`,\n );\n }\n return (\n <span data-testid={`${id}:unregistered`} className={className}>\n {value}\n </span>\n );\n }\n\n // Loader-backed enum still resolving — render a small skeleton placeholder\n // so the table cell doesn't shift once the values arrive.\n if (isLoading) {\n // plain: a filled, fixed-height pill is exactly the chrome contract\n // points 1 and 3 rule out — no background/border shape, no fixed height.\n // An inline pulsing ellipsis carries the same \"still loading\" meaning\n // without either.\n if (presentation === 'plain') {\n return (\n <span\n data-testid={`${id}:loading`}\n className={`animate-pulse text-muted-foreground ${className ?? ''}`}\n aria-busy=\"true\"\n >\n …\n </span>\n );\n }\n return (\n <span\n data-testid={`${id}:loading`}\n className={`inline-block h-5 w-12 animate-pulse rounded bg-muted ${className ?? ''}`}\n aria-busy=\"true\"\n />\n );\n }\n\n // Loader rejected — graceful degradation: show the raw value as plain\n // text (same fail-soft policy as the unregistered branch above).\n if (error) {\n return (\n <span data-testid={`${id}:error`} className={className} title={error.message}>\n {value}\n </span>\n );\n }\n\n const entry: EnumValue | undefined = values?.find((v) => v.value === value);\n\n if (entry) {\n const body = (\n <BadgeBody\n icon={entry.icon}\n label={resolveEnumLabel(caps, ns, value, enumValueText(def, value) ?? entry.label)}\n />\n );\n // plain: the label and icon carry the whole meaning here — the colour is\n // decoration on top of a word that already says «Draft». Dropping the\n // Badge wrapper therefore loses nothing (contract point 4).\n if (presentation === 'plain') {\n return (\n <span data-testid={id} data-icon={entry.icon} className={className}>\n {body}\n </span>\n );\n }\n return (\n <Badge\n variant={entry.color ?? 'outline'}\n className={className}\n data-testid={id}\n data-icon={entry.icon}\n >\n {body}\n </Badge>\n );\n }\n\n // Value not in enum — fallback path. Its label is the slot\n // `enums.<ns>._fallback` (the underscore keeps it apart from a value named\n // `fallback`), the declared label its default, then the raw value.\n const declaredFallback = enumFallbackText(def);\n if (def?.fallback !== undefined || declaredFallback !== undefined) {\n const fallbackLabel =\n resolveContentSlot(caps, [enumFallbackKey(ns)], { default: declaredFallback }) ?? value;\n if (presentation === 'plain') {\n return (\n <span data-testid={`${id}:fallback`} className={className}>\n {fallbackLabel}\n </span>\n );\n }\n return (\n <Badge\n variant={def?.fallback?.color ?? 'outline'}\n className={className}\n data-testid={`${id}:fallback`}\n >\n {fallbackLabel}\n </Badge>\n );\n }\n\n if (presentation === 'plain') {\n return (\n <span data-testid={`${id}:unknown`} className={className}>\n {value}\n </span>\n );\n }\n return (\n <Badge variant=\"outline\" className={className} data-testid={`${id}:unknown`}>\n {value}\n </Badge>\n );\n}\n","import type { ExportArtifact } from '@burojs/core';\n\n/**\n * The ONLY place in the whole export feature allowed to touch\n * `URL.createObjectURL`/`revokeObjectURL` or an anchor click — `@burojs/core`\n * and `@burojs/export` are DOM-free by constraint (they run in workers/SSR\n * too), so the browser-only delivery step lives here, at the UI edge, behind\n * one narrow function `<ExportDialog>`'s succeeded view calls.\n *\n * A `blob` artifact never had a URL to begin with — one is minted here,\n * strictly for the duration of the click, then revoked immediately after so\n * this never leaks memory across repeated downloads. A `url` artifact\n * (already hosted, e.g. by REF-15's job storage) is opened the same way, via\n * a real anchor click rather than `window.open` — a `window.open` popup is\n * blocked by most browsers unless it happens inside the ORIGINAL user\n * gesture's call stack; routing both artifact kinds through one synchronous\n * anchor-click keeps that guarantee for the `url` case, which a router-level\n * `await` between the click and this call could otherwise break.\n */\nexport function downloadArtifact(artifact: ExportArtifact): void {\n const { href, revoke } =\n artifact.kind === 'blob'\n ? { href: URL.createObjectURL(artifact.blob), revoke: true as const }\n : { href: artifact.url, revoke: false as const };\n\n const anchor = document.createElement('a');\n anchor.href = href;\n anchor.rel = 'noopener noreferrer';\n if (artifact.kind === 'blob') {\n anchor.download = artifact.filename;\n } else {\n anchor.target = '_blank';\n }\n document.body.appendChild(anchor);\n anchor.click();\n document.body.removeChild(anchor);\n\n if (revoke) URL.revokeObjectURL(href);\n}\n","'use client';\nimport type { DataRuntimeContextValue } from '@burojs/react';\nimport {\n resolveErrorText,\n useDataRuntime,\n useExportRuns,\n useI18nCaps,\n useOptionalDataRuntime,\n useOptionalT,\n} from '@burojs/react';\nimport * as React from 'react';\nimport { toast } from '../notification/toaster.js';\nimport { downloadArtifact } from './download.js';\n\n/**\n * Per-app-runtime registry of \"which `runId` is a mounted `<ExportDialog>`\n * currently displaying\", keyed by `DataRuntimeContextValue` — the SAME\n * keying `use-export.ts`'s `getExportRunsStore` uses for `ExportRunsStore`,\n * so two apps (or two tests, each with their own `createDataRuntime()`\n * lease) never see each other's displayed runs.\n *\n * Run-scoped, NOT resource-scoped (fix round 1, Important 2): a resource can\n * have two independent dialogs open at once (the toolbar's filter-scope\n * export and the bulk bar's ids-scope export both target the same resource\n * but are two different runs) — resource-scoping made an unrelated run's\n * *own* dialog suppress the toast for a DIFFERENT, already-backgrounded run\n * of that same resource, permanently (see `useExportRunWatcher`'s ordering\n * note for why \"permanently\" was the actual bug, not merely \"late\"). Each\n * `<ExportDialog>` registers the ONE `runId` it is actually showing (see\n * `export-dialog.tsx`'s own `useTrackDisplayedRun` call), so the watcher can\n * suppress exactly that run and nothing else.\n */\nconst displayedRunCounts = new WeakMap<DataRuntimeContextValue, Map<string, number>>();\n\n/**\n * Per-app-runtime set of run ids whose OUTCOME has already been\n * communicated to the user — either by a fired toast, or by a dialog that\n * was displaying that exact run at the moment it settled. Keyed by\n * `DataRuntimeContextValue`, NOT held in component state (fix round 1,\n * Important 1): `useExportRuns()` is backed by one APP-WIDE\n * `ExportRunsStore` per runtime, and a run survives in it — by design, so\n * the dialog's own download button and a future REF-15 panel can still read\n * it — until dismissed or the lease is disposed\n * (`packages/react/src/export/runs-store.ts`). `<ExportRunWatcherMount>`\n * lives inside `<ResourceListPage>`, which unmounts on ordinary route\n * navigation; a component-local `useRef` would forget every run it had\n * already announced the moment the user navigates away and back, and the\n * eager re-check on remount would re-toast a run that finished while they\n * were gone. Keying this set by the RUNTIME instead makes \"already told the\n * user\" survive exactly as long as the run itself does.\n */\nconst announcedRuns = new WeakMap<DataRuntimeContextValue, Set<string>>();\n\nfunction displayedRunCountsFor(runtime: DataRuntimeContextValue): Map<string, number> {\n let map = displayedRunCounts.get(runtime);\n if (map === undefined) {\n map = new Map();\n displayedRunCounts.set(runtime, map);\n }\n return map;\n}\n\nfunction announcedRunsFor(runtime: DataRuntimeContextValue): Set<string> {\n let set = announcedRuns.get(runtime);\n if (set === undefined) {\n set = new Set();\n announcedRuns.set(runtime, set);\n }\n return set;\n}\n\nfunction isRunDisplayed(runtime: DataRuntimeContextValue, runId: string): boolean {\n return (displayedRunCountsFor(runtime).get(runId) ?? 0) > 0;\n}\n\n/**\n * Registers the ONE `runId` a mounted `<ExportDialog>` is currently\n * displaying against the shared per-runtime registry\n * {@link displayedRunCounts} reads from. `undefined` (no active run yet, or\n * the dialog is closed) is a no-op — nothing to register. Call from\n * `<ExportDialog>` itself (fix round 1, Important 2: moved out of\n * `ExportButton`/the bulk-bar entry, which had no way to know WHICH run\n * their own dialog was showing — only the dialog does), with\n * `open ? runEntry?.runId : undefined`.\n *\n * A `useEffect`, not a during-render write: mutating shared module state\n * while rendering is unsafe under StrictMode's double-invoked render pass\n * (it would double-increment before the matching decrement ever ran).\n *\n * Reference-counted rather than a plain \"set/unset\": two dialogs could in\n * principle end up momentarily registering the identical `runId` during a\n * remount race, and a bare overwrite would let the first one's cleanup\n * erase the second's still-live registration.\n *\n * Uses `useOptionalDataRuntime()`, not the hard `useDataRuntime()` — unlike\n * `useResourceExport`/`useExportRuns` (frozen, `packages/react/src/export/`),\n * this hook is entirely OUR code, and `<ExportDialog>` is mounted (and unit-\n * tested, e.g. `export-dialog.test.tsx`) with `useResourceExport` itself\n * MOCKED and no real `dataRuntime` at all. There is nothing to register\n * against without a runtime, so `null` is simply a no-op, exactly like\n * `<ResourceListPage>`'s own compat-mode guard for the hard export hooks.\n */\nexport function useTrackDisplayedRun(runId: string | undefined): void {\n const runtime = useOptionalDataRuntime();\n React.useEffect(() => {\n if (runId === undefined || runtime === null) return;\n const map = displayedRunCountsFor(runtime);\n map.set(runId, (map.get(runId) ?? 0) + 1);\n return () => {\n const current = map.get(runId) ?? 0;\n if (current <= 1) map.delete(runId);\n else map.set(runId, current - 1);\n };\n }, [runtime, runId]);\n}\n\n/**\n * Background-completion toasts (Task 8). Watches every export run for THIS\n * app (`useExportRuns()` — one shared `ExportRunsStore` per\n * `DataRuntimeContextValue`) and, the moment a run settles into a terminal\n * state, decides EXACTLY ONCE what the user learns about it:\n *\n * - if `<ExportDialog>` is displaying that SAME run right now, nothing —\n * the dialog's own success/download or error view already told them;\n * - otherwise, `succeeded` → a success toast with a Download action,\n * `failed` → an error toast, `canceled` → nothing (partial files are\n * never delivered, and a user-initiated cancel needs no completion\n * announcement — the dialog's own \"Stop export\" already confirmed the\n * action live).\n *\n * That decision is recorded in the shared, runtime-keyed\n * {@link announcedRuns} set — never in component state, so it survives this\n * hook unmounting and remounting with the run still un-dismissed (fix round\n * 1, Important 1) — and, critically, is recorded ONLY once one of those two\n * \"the user was told something\" branches is actually reached (fix round 1,\n * Important 2's ordering fix): a run whose dialog is showing a DIFFERENT run\n * is never marked, so it still gets its toast; nothing is ever marked on a\n * path where nobody was informed.\n */\nexport function useExportRunWatcher(): void {\n const runtime = useDataRuntime();\n const runs = useExportRuns();\n const t = useOptionalT();\n const caps = useI18nCaps();\n\n React.useEffect(() => {\n const announced = announcedRunsFor(runtime);\n const unsubscribes = runs.map((run) => {\n const check = (): void => {\n if (announced.has(run.runId)) return;\n const state = run.handle.getState();\n if (state.status === 'running') return; // not terminal yet — no decision to make\n\n if (isRunDisplayed(runtime, run.runId)) {\n // THIS run's own dialog is showing it right now — that IS the\n // notification. Mark it told, permanently: once marked here, a\n // later close of that same dialog must never retroactively fire a\n // toast (the guard above already prevents re-entry regardless).\n announced.add(run.runId);\n return;\n }\n\n announced.add(run.runId);\n if (state.status === 'succeeded') {\n const artifact = state.artifact;\n toast.success(t('export.toast.succeeded'), {\n action: {\n label: t('export.toast.download'),\n onClick: () => downloadArtifact(artifact),\n },\n });\n } else if (state.status === 'failed') {\n toast.error(\n t('export.toast.failed', { params: { message: resolveErrorText(state.error, caps) } }),\n );\n }\n // 'canceled': no toast, by contract — the \"Stop export\" click that\n // caused this already told the user synchronously; still marked\n // announced immediately above so this branch is never re-entered.\n };\n // A run can already be terminal by the time this effect (re)subscribes\n // — e.g. it settled while no watcher was mounted at all (the user\n // navigated away and the page unmounted), or between one `runs`\n // snapshot and the next. Firing once eagerly on (re)subscribe is what\n // catches both cases; the guard above keeps it a no-op for every run\n // this runtime's shared set has already recorded.\n check();\n return run.handle.subscribe(check);\n });\n return () => {\n for (const unsubscribe of unsubscribes) unsubscribe();\n };\n }, [runs, runtime, t, caps]);\n}\n","'use client';\nimport { routeResourceKey } from '@burojs/core';\nimport type { ResourceNameOrRef, ScreenSources } from '@burojs/core';\nimport { isBuiltinItemAction, recordEntries } from '@burojs/core';\nimport { recordKeyOf, useApp, useChromeT, useItemActions, useTestIds } from '@burojs/react';\nimport { IconDots } from '@tabler/icons-react';\nimport { createContext, Fragment, useContext, useState } from 'react';\nimport { cn } from '../lib/cn.js';\nimport { Button } from '../primitives/button.js';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '../primitives/dropdown-menu.js';\nimport { FlowMenuItem, useHostedFlow } from '../flows/flow-action-button.js';\nimport { preloadFlowRuntime, RuntimeFlowRunner } from '../flows/load-runtime.js';\nimport { ActionButton } from './action-button.js';\n\nexport interface ActionOverflowProps<N extends string = string> {\n resource: ResourceNameOrRef<N>;\n record: { id: string } & Record<string, unknown>;\n /**\n * Which surface is rendering. Any string: the core's surface vocabulary is\n * an augmentable interface, so an adopter panel passes its own name and gets\n * the same resolved list.\n */\n surface: string;\n className?: string;\n /**\n * Flows this screen presents inline (P6 3.12): their own button is not drawn here, the\n * placement is their control on this screen.\n */\n hideFlows?: (name: string) => boolean;\n /**\n * A row in a narrow list: every action goes into the one menu, so the actions column is a single\n * control wide. Default: {@link RowActionsCollapseContext}.\n */\n collapse?: boolean;\n /**\n * The sources of the screen the actions are drawn on (a record screen's header or frame:\n * `FormController.sources`): an action's `when` reads them besides `record` (T4 D9 part 4). The\n * screen loads what its item actions' `when`s read (its show and edit demand them), so a `with`\n * source no node reads still decides here. Absent in a record's menu (a row, an overlay's item\n * menu): a `when` there reads `record` only, and a ref to any other source hides the action.\n */\n sources?: ScreenSources;\n}\n\n/**\n * A row in a narrow list (`ResourceList` measures its own width): every row action goes into the\n * one menu. A context, not a cell prop, because the table's memoized rows do not re-render when a\n * column definition changes.\n */\nexport const RowActionsCollapseContext = createContext(false);\n\n/**\n * Collapses an entity's actions into an overflow menu so tables and detail\n * toolbars don't bloat with a button per action.\n *\n * Resolves its own list via `useItemActions` — hidden/denied actions are\n * already absent, order is already applied, and each entry already carries\n * its resolved `placement`/`density`. `'standalone'` entries render as their\n * own control (at their resolved density — icon-only on a row, icon+label on\n * a toolbar); everything else collapses into one menu after them, with the\n * destructive tail set off by a separator. Menu items reuse\n * `<ActionButton asMenuItem>` for a link or a modal and `<FlowMenuItem>` for a\n * flow, whose run continues outside the dropdown. Tone is NOT\n * hardcoded here (no more `variant=\"ghost\"`): it comes from each action's own\n * `variant`, exactly like the menu items already respected it — a hardcoded\n * `ghost` used to strip a destructive standalone action of its destructive\n * look.\n */\nexport function ActionOverflow<const N extends string = string>({\n resource: resourceInput,\n record,\n surface,\n className,\n hideFlows,\n collapse,\n sources,\n}: ActionOverflowProps<N>): React.ReactElement | null {\n const resource = routeResourceKey(resourceInput);\n const chromeT = useChromeT();\n const tid = useTestIds();\n const recordKey = String(recordKeyOf(useApp().registry.get(resource), record) ?? '');\n const collapsedRows = useContext(RowActionsCollapseContext);\n // A flow selected from the menu runs here, outside the menu (P4 spec 4.15): the menu closes\n // normally, and the run — its host, its confirm, its outcome — outlives it.\n const [flowFor, setFlowFor] = useState<{\n readonly name: string;\n readonly record: typeof record;\n } | null>(null);\n // ONE list. The container no longer partitions a caller-supplied array and\n // no longer re-filters by availability: `useItemActions` already dropped\n // everything hidden or denied, which is what stopped the old code from\n // rendering an empty menu.\n const actions = useShownItemActions(resource, record, surface, hideFlows, sources);\n\n if (actions.length === 0) return null;\n\n const isRow = surface === 'row';\n const folded = isRow && (collapse ?? collapsedRows);\n const standalone = folded ? [] : actions.filter((a) => a.placement === 'standalone');\n const menu = folded ? actions : actions.filter((a) => a.placement === 'menu');\n const menuTestId = isRow\n ? tid.listRowActionsMenu(resource, recordKey)\n : tid.formActionsMenu(resource, surface);\n // The destructive tail gets a rule above it. Computed off the RESOLVED list,\n // not off a hardcoded 'delete', so an adopter's own destructive action is\n // grouped the same way.\n const firstDestructive = menu.findIndex((a) => a.variant === 'destructive');\n\n // A flow's run is owned HERE, not by its menu item: its host, its confirm dialog and its\n // outcome are Radix layers that must not live inside the open menu (two competing focus\n // scopes), so the menu closes normally on select and this sibling takes over.\n //\n // The dropdown below is `modal={false}` for the same reason: a modal Radix menu locks\n // `pointer-events` on the body and marks everything outside itself `aria-hidden`, which would\n // swallow the flow's dialog rendered as its sibling.\n const overlays = (\n <>\n {flowFor != null ? (\n <RuntimeFlowRunner\n resource={resource}\n actionName={flowFor.name}\n record={flowFor.record}\n scope={surface}\n onClose={() => setFlowFor(null)}\n />\n ) : null}\n </>\n );\n\n const buttons = standalone.map((a) => (\n <ActionButton\n key={a.name}\n resource={resource}\n actionName={a.name}\n record={record}\n scope={surface}\n {...(sources === undefined ? {} : { sources })}\n // `density` is only ever null when `placement === 'menu'`\n // (`ItemActionPlacement`'s own invariant, enforced by\n // `resolveActionDensity`) — this entry came from the `standalone`\n // filter above, so it is never null here. No `?? 'regular'`\n // fallback: that would be dead code masking a real core bug if the\n // invariant ever broke. `<ActionButton>`'s own `density ?? 'regular'`\n // default (each leaf renderer) stays — it protects a direct\n // `<ActionButton>` caller that supplies no density at all.\n density={a.density!}\n />\n ));\n\n return (\n // A record's actions wrap onto a second line where the width runs out (a quick sheet is\n // narrower than a page); a row's strip never wraps (its column is sized to it).\n <div\n className={cn(\n 'flex items-center',\n isRow ? 'justify-end gap-1' : 'flex-wrap gap-2',\n className,\n )}\n >\n {isRow && buttons.length > 0 ? (\n // Revealed on the row's hover or keyboard focus (always on a touch screen, which has no\n // hover). Opacity, not display: the strip keeps its box, so nothing shifts as it shows.\n <span\n data-buro-row-standalone=\"\"\n className=\"flex items-center gap-1 opacity-0 transition-opacity group-hover/row:opacity-100 group-focus-within/row:opacity-100 [@media(hover:none)]:opacity-100\"\n >\n {buttons}\n </span>\n ) : (\n buttons\n )}\n {menu.length > 0 && (\n <DropdownMenu\n modal={false}\n // A menu opening is the sign a user may run one of its flows: their runtime loads now.\n onOpenChange={(open) => {\n if (open && menu.some((entry) => entry.flow !== undefined)) preloadFlowRuntime();\n }}\n >\n <DropdownMenuTrigger asChild>\n {isRow ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-7\"\n data-testid={menuTestId}\n aria-label={chromeT('actions.more', { defaultValue: 'More' })}\n >\n <IconDots className=\"h-4 w-4\" aria-hidden=\"true\" />\n </Button>\n ) : (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"gap-1.5\"\n data-testid={menuTestId}\n >\n <IconDots className=\"h-4 w-4\" aria-hidden=\"true\" />\n {chromeT('actions.more', { defaultValue: 'More' })}\n </Button>\n )}\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {menu.map((a, index) => (\n <Fragment key={a.name}>\n {index === firstDestructive && index > 0 && (\n <DropdownMenuSeparator\n data-testid={\n isRow\n ? `list-row-actions-separator:${resource}:${recordKey}`\n : `form-actions-separator:${resource}:${surface}`\n }\n />\n )}\n {a.flow === undefined ? (\n <ActionButton\n resource={resource}\n actionName={a.name}\n record={record}\n scope={surface}\n {...(sources === undefined ? {} : { sources })}\n asMenuItem\n />\n ) : (\n <FlowMenuItem\n resource={resource}\n actionName={a.name}\n record={record}\n scope={surface}\n control={a.flow}\n // A flow of this menu runs: the others are busy until it is over (M4).\n active={flowFor !== null}\n onRun={() =>\n setFlowFor({\n name: a.name,\n record: (a.flow?.record as typeof record | undefined) ?? record,\n })\n }\n />\n )}\n </Fragment>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n {overlays}\n </div>\n );\n}\n\n/**\n * The item actions `<ActionOverflow>` draws on `surface`: `useItemActions`' list, minus a\n * built-in Edit that leads nowhere (spec 4.3). Also read by a record frame's runtime check of\n * `<RecordActions/>`.\n */\nexport function useShownItemActions(\n resource: string,\n record: { id: string } & Record<string, unknown>,\n surface: string,\n hideFlows?: (name: string) => boolean,\n /** The screen's sources an action's `when` reads, where the actions are drawn on a screen. */\n sources?: ScreenSources,\n) {\n const resolved = useItemActions({\n resource,\n record,\n surface,\n ...(sources === undefined ? {} : { sources }),\n });\n // The built-in Edit of a resource with neither an edit page nor a quick edit leads nowhere\n // (spec 4.3): it is not drawn at all, so it leaves no empty slot or menu behind.\n const def = useApp().registry.get(resource);\n const editNowhere =\n def !== undefined &&\n isBuiltinItemAction(\n (def.actions?.item as readonly { readonly name?: string }[] | undefined)?.find(\n (action) => action.name === 'edit',\n ),\n 'edit',\n ) &&\n !recordEntries(def).page.edit &&\n recordEntries(def).quick.edit === null;\n const shown = editNowhere ? resolved.filter((a) => a.name !== 'edit') : resolved;\n return hideFlows === undefined\n ? shown\n : shown.filter((a) => a.flow === undefined || !hideFlows(a.name));\n}\n","import {\n type AppRuntime,\n type RouteDescriptor,\n type ScreenMode,\n hasRecordPage,\n resolveStaticAvailability,\n} from '@burojs/core';\nimport { resolveRoute } from '@burojs/react';\n\ntype Registry = AppRuntime['registry'];\n\n/**\n * Whether the resource's record route for `action` renders a record page: the\n * one availability test behind the router's gate (`<ResourcePageRouter>`\n * renders not-found otherwise), the header's choice of the record trail\n * (`recordTrailRoute`) and `isShowAvailable`, so those three cannot disagree. The test is the\n * resource's `operations` and its page switch `views.show.page`\n * (`hasRecordPage`): a `page: false` resource has no record route at all.\n */\nexport function recordRouteAvailable(\n registry: Registry,\n resource: string,\n action: ScreenMode,\n): boolean {\n if (resolveStaticAvailability(registry, resource, action).state !== 'available') return false;\n const def = registry.get(resource);\n return def !== undefined && hasRecordPage(def, action);\n}\n\n/** Whether the resource has a show page. */\nexport function isShowAvailable(registry: Registry, resource: string): boolean {\n return recordRouteAvailable(registry, resource, 'show');\n}\n\nexport function showTarget(resource: string, id: string): RouteDescriptor {\n return { resource, action: 'show', params: { id } };\n}\n\nexport function listTarget(resource: string): RouteDescriptor {\n return { resource, action: 'list' };\n}\n\n/**\n * Where a record page returns to — after a save or a create, and from the edit\n * back-link and Cancel: the record's show page when the resource has one, else\n * the list.\n */\nexport function recordReturnTarget(\n registry: Registry,\n resource: string,\n id: string,\n): RouteDescriptor {\n return isShowAvailable(registry, resource) ? showTarget(resource, id) : listTarget(resource);\n}\n\n/**\n * The edit page's back-link: `backHref` when the caller gives one, else the\n * record page's return target — the record's show page when the resource has\n * one, else the list — resolved through the registry (nesting-aware).\n */\nexport function editBackHref(\n registry: Registry,\n resource: string,\n id: string,\n backHref?: string,\n): string {\n return backHref ?? resolveRoute(recordReturnTarget(registry, resource, id), registry);\n}\n","/**\n * Canonical typography scale for the Buro playground / framework UI.\n *\n * Pick the constant that matches the *role* of the element (page title,\n * card-in-grid title, body text) rather than picking a Tailwind size by\n * appearance. This keeps the scale consistent across components and\n * makes future global tweaks a single-file change.\n *\n * **Scale at a glance**\n *\n * role | size | weight | tracking | typical use\n * ----------------|-------|-----------|-------------------|----------------------------------\n * h1 | 2xl | semibold | tracking-tight | page title (PageHeader)\n * h2 | xl | semibold | tracking-tight | sub-page section heading\n * h3 | lg | semibold | tracking-tight | card-as-hero title; in-card section\n * h4 | base | semibold | tracking-tight | sub-section inside a card\n * cardTitleHero | 2xl | semibold | tracking-tight | shadcn Card hero variant (CardTitle)\n * cardTitleGrid | sm | medium | — | Card-in-grid (Cards 01 dashboard)\n * body | base | normal | — | default paragraph\n * small | sm | normal | — | secondary text\n * muted | sm | normal | — | secondary muted (text-muted-foreground)\n * caption | 11px | semibold | uppercase + wider | sidebar caption / popover header\n *\n * Note: the existing `<CardTitle>` primitive defaults to `cardTitleHero`\n * (canonical shadcn). When using Card in a tight grid (e.g., dashboard\n * Cards 01 layout), pass `className={typography.cardTitleGrid}` to\n * override.\n *\n * Adopters can re-export their own constants on top of this module — the\n * exports are pure strings, no runtime cost.\n */\nexport const typography = {\n h1: 'text-2xl font-semibold tracking-tight',\n h2: 'text-xl font-semibold tracking-tight',\n h3: 'text-lg font-semibold tracking-tight',\n h4: 'text-base font-semibold tracking-tight',\n cardTitleHero: 'text-2xl font-semibold leading-none tracking-tight',\n cardTitleGrid: 'text-sm font-medium',\n body: 'text-base',\n small: 'text-sm',\n muted: 'text-sm text-muted-foreground',\n caption: 'text-[11px] font-semibold uppercase tracking-wider text-muted-foreground',\n} as const;\n\nexport type TypographyKey = keyof typeof typography;\n","'use client';\nimport { createContext, useCallback, useContext, useEffect, useRef, type ReactNode } from 'react';\n\nimport { useShell } from '../shell/shell-context.js';\n\ntype SetTitle = (title: string) => void;\nconst DocumentTitleContext = createContext<SetTitle | null>(null);\n\n/**\n * Register the desired `document.title` for the current page (suffixed with ` · <brand name>` under a `ShellProvider` brand). Under a\n * `DocumentTitleProvider` the title is applied AND DEFENDED against Next's\n * metadata writes (Next re-applies the root `metadata.title` to `<title>` on\n * soft navigations — same-URL clicks, `?query` changes, post-hydration ticks —\n * which otherwise resets the tab to the app default). WITHOUT a provider it\n * falls back to a plain one-shot `document.title` write (unchanged legacy\n * behavior, so PageHeader still works standalone / in tests).\n */\nexport function useDocumentTitle(title: string | undefined): void {\n const set = useContext(DocumentTitleContext);\n const brandName = useShell().brand?.name;\n const full = title == null || brandName === undefined ? title : `${title} · ${brandName}`;\n useEffect(() => {\n if (full == null) return;\n if (set) set(full);\n else if (typeof document !== 'undefined') document.title = full;\n }, [set, full]);\n}\n\n/**\n * Owns `document.title`: applies the registered title and re-asserts it via a\n * MutationObserver whenever something (Next's metadata system) changes `<title>`\n * to anything else. Mount ONCE around the app shell. Router-agnostic — no\n * next/react-router import.\n *\n * `routeKey` (typically the pathname, WITHOUT `?search`) lets a real page\n * change release the pinned title. Without this, a route that never calls\n * `useDocumentTitle` (no `PageHeader` — e.g. an embedded-only fallback panel,\n * or an unmatched custom-page fallback) would inherit the PREVIOUS page's\n * pinned title and the MutationObserver would actively defend that stale\n * value, fighting even Next's own default write — worse than the pre-guard\n * behavior, where a titleless route was merely passively stale. When\n * `routeKey` changes, `wantRef` is cleared so the titleless route falls back\n * to `<title>`'s own value (Next's metadata default) instead. The clear\n * happens DURING RENDER (comparing against a `prevKeyRef`), not in an effect:\n * this provider sits ABOVE `PageHeader` in the tree, so a parent effect would\n * run AFTER the child's `useDocumentTitle` effect and wipe the incoming\n * page's just-set title. A render-phase compare runs before any child effect,\n * so the release lands first and the incoming page's title (if any) is set\n * after it. Same-key rerenders (e.g. a `?tab=` change, or a same-URL click)\n * leave `wantRef` untouched, so the guard keeps defending the current title.\n */\nexport function DocumentTitleProvider({\n routeKey,\n children,\n}: {\n routeKey?: string;\n children: ReactNode;\n}) {\n const wantRef = useRef<string | null>(null);\n const prevKeyRef = useRef<string | undefined>(routeKey);\n if (routeKey !== prevKeyRef.current) {\n prevKeyRef.current = routeKey;\n wantRef.current = null;\n }\n\n const setTitle = useCallback<SetTitle>((title) => {\n wantRef.current = title;\n if (typeof document !== 'undefined' && document.title !== title) {\n document.title = title;\n }\n }, []);\n\n useEffect(() => {\n if (typeof document === 'undefined' || typeof MutationObserver === 'undefined') return;\n const reassert = () => {\n const want = wantRef.current;\n if (want != null && document.title !== want) document.title = want;\n };\n const obs = new MutationObserver(reassert);\n // Observe head subtree: catches both a <title> text mutation and a full\n // <title> element replacement (Next may do either).\n obs.observe(document.head, { childList: true, subtree: true, characterData: true });\n return () => obs.disconnect();\n }, []);\n\n return <DocumentTitleContext.Provider value={setTitle}>{children}</DocumentTitleContext.Provider>;\n}\n","import { type I18nCaps, resolveContentSlot } from '@burojs/core';\n\n/** Which heading of a resource's record pages: its create page, or its edit page (named or not). */\nexport type ResourceTitleSlot = 'createTitle' | 'editTitle' | 'editTitleNamed';\n\n/**\n * The heading of a create or edit page: the resource's own `createTitle` / `editTitle` /\n * `editTitleNamed` text (`resources.<r>.<slot>`) when it has one, else the kit's\n * `pageHeader.<slot>` default. Only the resource's own entry is read: a title is about one\n * resource, so the app-wide `resources._` level does not apply. `label` is the singular label\n * the kit's default and a declared title's `{{label}}` take; `name` is the record's name.\n */\nexport function resolveResourceTitle(\n caps: I18nCaps,\n t: (key: string, options?: { params?: Record<string, unknown> }) => string,\n resource: string,\n slot: ResourceTitleSlot,\n params: { readonly label: string; readonly name?: string },\n): string {\n const own = resolveContentSlot(caps, [`resources.${resource}.${slot}`], {\n params: { ...params },\n });\n return own ?? t(`pageHeader.${slot}`, { params: { ...params } });\n}\n","'use client';\nimport { routeResourceKey } from '@burojs/core';\nimport type { ResourceNameOrRef } from '@burojs/core';\nimport type { ReactNode } from 'react';\nimport { resolveResourceLabel } from '@burojs/core';\nimport {\n recordKeyOf,\n useApp,\n useI18nCaps,\n useProjectedTitle,\n usePublishDocVariant,\n useT,\n} from '@burojs/react';\nimport { ActionOverflow } from '../actions/action-overflow.js';\nimport { editBackHref } from '../layout/record-targets.js';\nimport { cn } from '../lib/cn.js';\nimport { typography } from '../lib/typography.js';\nimport { useLinkComponent } from '../layout/link-component.js';\nimport { useDocumentTitle } from '../layout/document-title.js';\nimport { resolveResourceTitle } from './resource-title.js';\n\nexport interface PageHeaderProps<N extends string = string> {\n /** Resource name (matches the registry key). Used for back-link target + label resolution. */\n resource: ResourceNameOrRef<N>;\n /**\n * Page mode. Drives default title:\n * - 'list' → labelPlural\n * - 'show' → label + ': ' + recordName\n * - 'edit' → 'Edit ' + label + ': ' + recordName\n * - 'create' → 'Create ' + label\n */\n mode: 'list' | 'show' | 'edit' | 'create';\n /** Display name of the current record (for show/edit). */\n recordName?: string;\n /**\n * Override the back-link href. By default points to the resource's basePath\n * (or `/{resource}` fallback) for show/edit/create.\n */\n backHref?: string;\n /** Override the back-link label. Defaults to labelPlural. */\n backLabel?: string;\n /** Slot for action buttons (Edit/Delete/+Create) on the right. */\n actions?: ReactNode;\n /** Override the rendered title text. */\n title?: string;\n /**\n * Optional breadcrumb slot rendered above the title. When provided,\n * the back-link is suppressed in favour of the breadcrumb (the two\n * are functionally redundant — a breadcrumb's leading link points\n * at the same URL as the back-link, with more spatial context).\n * Pass `<Breadcrumbs resource={resource} pageLabel={recordName} />` from\n * `@burojs/ui-shadcn` for the canonical resource-rooted layout.\n */\n breadcrumbs?: ReactNode;\n /**\n * Render the textual `← Back to …` link on detail pages. Defaults to FALSE.\n *\n * An app shell that already renders breadcrumbs in its top bar (the common\n * layout, and what the playground does) makes this link a third redundant nav\n * row stacked under the crumb — the exact \"breadcrumbs twice plus a title\"\n * clutter this default removes. Opt in when a page has no breadcrumb above it.\n */\n backLink?: boolean;\n /**\n * Render the page title as a VISIBLE heading. Defaults to FALSE.\n *\n * The title almost always restates the trailing breadcrumb directly above it\n * («Documents › Order codes №53» followed by an h1 «Order codes №53»), and an\n * h1 plus its margins costs ~70px of vertical space on every screen — space a\n * dense admin table wants back.\n *\n * The heading is NOT removed: it stays in the DOM as `sr-only`, because a page\n * without an h1 breaks heading-based navigation for screen-reader users, and\n * the title moves to `document.title` so the browser tab identifies the page.\n * Same computed string, three surfaces instead of one.\n */\n visibleTitle?: boolean;\n /**\n * Replace the resource label used to BUILD the title, without replacing the\n * title template. `title` overrides the whole string; this keeps the\n * localized «Create: {{label}}» / «Edit {{label}}» phrasing and only\n * swaps in a more specific noun (e.g. the picked document type). Callers\n * therefore don't have to reimplement the i18n template to say\n * «Create: Order codes».\n */\n labelOverride?: string;\n className?: string;\n}\n\nexport function PageHeader<const N extends string = string>({\n resource: resourceInput,\n mode,\n recordName,\n backHref,\n backLabel,\n actions,\n title,\n breadcrumbs,\n backLink = false,\n visibleTitle = false,\n labelOverride,\n className,\n}: PageHeaderProps<N>): React.ReactElement | null {\n const resource = routeResourceKey(resourceInput);\n const app = useApp();\n const t = useT();\n const def = app.registry.get(resource);\n const caps = useI18nCaps(resource);\n const RouterLink = useLinkComponent();\n\n const resourceSingle = resolveResourceLabel(caps, resource, 'single', def);\n const labelSingle = labelOverride ?? resourceSingle;\n // Deliberately NOT derived from `labelSingle`: the plural names the\n // COLLECTION the back-link returns to («Back to Documents»), which is still\n // the resource's list even when the title is about one specific type — a\n // typed override must not turn that into «Back to Order codes».\n const labelPlural = resolveResourceLabel(caps, resource, 'plural', def);\n\n const computedTitle =\n title ??\n (mode === 'list'\n ? labelPlural\n : mode === 'show'\n ? // Just the record's own title. Prefixing it with the resource label\n // (\"Document: Order codes №53\") duplicates what the breadcrumb above\n // already says and pushes the meaningful part to the right.\n (recordName ?? labelSingle)\n : mode === 'edit'\n ? recordName\n ? resolveResourceTitle(caps, t, resource, 'editTitleNamed', {\n label: labelSingle,\n name: recordName,\n })\n : resolveResourceTitle(caps, t, resource, 'editTitle', { label: labelSingle })\n : resolveResourceTitle(caps, t, resource, 'createTitle', { label: labelSingle }));\n\n // Back-link: list mode has no back; show/edit/create go back to the\n // list. Breadcrumbs are functionally a richer back-link, so when the\n // caller provides a breadcrumb slot we suppress the text back-link\n // to avoid two redundant nav affordances stacked on top of each\n // other.\n // The tab is now the primary place the page announces itself, so it has to\n // stay in step with the heading — one computed value, set here rather than\n // duplicated per route. Delegated to useDocumentTitle: under a\n // DocumentTitleProvider (the playground admin shell) it's applied AND\n // defended against Next's re-application of the root metadata title on\n // soft navigations; standalone it's a plain one-shot document.title write.\n const fullTitle = app?.name ? `${computedTitle} · ${app.name}` : computedTitle;\n useDocumentTitle(fullTitle);\n\n const showBack = backLink && mode !== 'list' && !breadcrumbs;\n const computedBackHref = backHref ?? def?.basePath ?? `/${resource}`;\n const computedBackLabel = backLabel ?? labelPlural;\n\n return (\n <div className={cn('space-y-2', visibleTitle || actions ? 'mb-4' : 'mb-2', className)}>\n {breadcrumbs}\n {showBack && (\n <RouterLink\n href={computedBackHref}\n className=\"text-sm text-muted-foreground hover:text-foreground inline-flex items-center gap-1 focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring rounded\"\n data-testid={`page-back:${resource}`}\n >\n ← {t('pageHeader.backTo', { params: { label: computedBackLabel } })}\n </RouterLink>\n )}\n {/*\n `flex-wrap` matters on phones: a detail toolbar (pinned action + \"…\" +\n Edit + Delete) next to a long title does not fit 390px, and without\n wrapping it forced the WHOLE PAGE into horizontal scroll — the heading,\n the tabs and every field row shifted with it. Wrapping lets the actions\n drop under the title instead. `min-w-0` lets the title itself shrink so\n it truncates rather than pushing the buttons off-screen.\n */}\n {/* An sr-only heading with no actions beside it would still render a\n flex row with gaps and margins — a blank strip where the h1 used to\n be, which defeats the point of reclaiming the space. */}\n {visibleTitle || actions ? (\n <div\n className={cn(\n 'flex flex-wrap items-center gap-2',\n // An `sr-only` heading occupies no width, so `justify-between` had\n // nothing to push against and the toolbar collapsed to the LEFT\n // edge of the page — the reported \"actions are nailed to the left\".\n // With no visible title the toolbar is the row's only content and\n // belongs at the trailing edge.\n visibleTitle ? 'justify-between' : 'justify-end',\n )}\n >\n <h1 className={visibleTitle ? cn(typography.h1, 'min-w-0 break-words') : 'sr-only'}>\n {computedTitle}\n </h1>\n {actions && <div className=\"flex flex-wrap items-center gap-2\">{actions}</div>}\n </div>\n ) : (\n <h1 className=\"sr-only\">{computedTitle}</h1>\n )}\n </div>\n );\n}\n\n/**\n * The show-page `<PageHeader>`: the breadcrumb, the record's title and the resolved\n * `<ActionOverflow surface=\"show\">` item-action list, then any `extraActions`.\n */\nexport function ShowPageHeader<const N extends string = string>({\n resource: resourceInput,\n record,\n extraActions,\n breadcrumbs,\n}: {\n resource: ResourceNameOrRef<N>;\n record: { id: string } & Record<string, unknown>;\n extraActions?: ReactNode;\n breadcrumbs?: ReactNode;\n}): React.ReactElement | null {\n const resource = routeResourceKey(resourceInput);\n const app = useApp();\n const def = app.registry.get(resource);\n // Hook must run before any early return (rules of hooks). Resolves\n // `recordTitle(record)` → `record[displayField]` → `#id`.\n const recordName = useProjectedTitle(resource, recordKeyOf(def, record), record);\n // Tell the breadcrumb trail which KIND of record this is, so its help offers\n // the type's articles alongside the resource's. The trail lives in the app\n // header — a sibling, not an ancestor — hence a store rather than context.\n usePublishDocVariant(resource, record);\n if (!def) return null;\n return (\n <PageHeader\n resource={resource}\n mode=\"show\"\n recordName={recordName}\n // Breadcrumbs are OPT-IN: a default one here would duplicate the app\n // shell's own top-bar crumb.\n breadcrumbs={breadcrumbs}\n actions={\n <>\n <ActionOverflow resource={resource} record={record} surface=\"show\" />\n {extraActions}\n </>\n }\n />\n );\n}\n\n/**\n * The edit-page `<PageHeader>`: the back-link, the record's title and the resolved\n * `<ActionOverflow surface=\"edit\">` item-action list.\n */\nexport function EditPageHeader<const N extends string = string>({\n resource: resourceInput,\n record,\n backHref,\n breadcrumbs,\n}: {\n resource: ResourceNameOrRef<N>;\n record: { id: string } & Record<string, unknown>;\n backHref?: string;\n breadcrumbs?: ReactNode;\n}): React.ReactElement {\n const resource = routeResourceKey(resourceInput);\n const app = useApp();\n const def = app.registry.get(resource);\n const caps = useI18nCaps(resource);\n // Same resolution as the show header: recordTitle → displayField → #id.\n const recordKey = recordKeyOf(def, record);\n const recordName = useProjectedTitle(resource, recordKey, record);\n\n return (\n <PageHeader\n resource={resource}\n mode=\"edit\"\n recordName={recordName}\n backHref={editBackHref(app.registry, resource, String(recordKey ?? ''), backHref)}\n breadcrumbs={breadcrumbs}\n backLabel={\n recordName\n ? `${resolveResourceLabel(caps, resource, 'single', def)}: ${recordName}`\n : undefined\n }\n // `<ActionOverflow>` resolves its own list and returns null when it's\n // empty, so no length guard is needed here.\n actions={<ActionOverflow resource={resource} record={record} surface=\"edit\" />}\n />\n );\n}\n","'use client';\nimport type { ReactElement } from 'react';\nimport { Skeleton } from '../primitives/skeleton.js';\n\n/** The cards' grid; the cards themselves draw in it. */\nexport const RELATED_GRID_CLASS = 'grid grid-cols-1 gap-3 @md:grid-cols-2 @3xl:grid-cols-3';\n\n/** The cards' loading state: the grid with placeholder cards. */\nexport function RelatedCardsSkeleton(): ReactElement {\n return (\n <div className=\"@container\" data-buro-skeleton=\"\">\n <div className={RELATED_GRID_CLASS}>\n {Array.from({ length: 3 }, (_, index) => (\n <Skeleton key={index} className=\"h-24 w-full rounded-lg\" />\n ))}\n </div>\n </div>\n );\n}\n\n/** The timeline's loading state. */\nexport function RelatedTimelineSkeleton(): ReactElement {\n return (\n <div className=\"flex flex-col gap-2\" data-buro-skeleton=\"\">\n <Skeleton className=\"h-4 w-40\" />\n {Array.from({ length: 3 }, (_, index) => (\n <Skeleton key={index} className=\"h-10 w-full\" />\n ))}\n </div>\n );\n}\n","'use client';\nimport {\n type BlockProp,\n type CompiledScreen,\n type AnyBlockHandle,\n formatEntityRef,\n type PlanNode,\n validatePlacementProps,\n} from '@burojs/core';\nimport { type BlockViewProps, usePlacement } from '@burojs/react';\nimport {\n Component,\n type ErrorInfo,\n type ReactElement,\n type ReactNode,\n Suspense,\n useMemo,\n} from 'react';\nimport { useScreenTree } from '../screen/tree-context.js';\nimport { selectImplementation, viewOf } from './place-node.js';\n\n/**\n * The item of a `related-list` placement as its view receives it (P6 3.13): the planned item\n * node, not an element. The list draws it once per row with the row bound to the `item` source,\n * so nothing here is rendered until a row is.\n */\nexport interface ItemHandle {\n readonly kind: 'item-handle';\n readonly node: PlanNode;\n}\n\nexport const itemHandle = (node: PlanNode): ItemHandle =>\n Object.freeze({ kind: 'item-handle', node });\n\nexport function isItemHandle(value: unknown): value is ItemHandle {\n return (\n value !== null && typeof value === 'object' && (value as ItemHandle).kind === 'item-handle'\n );\n}\n\ntype Row = Readonly<Record<string, unknown>>;\ntype Definitions = Readonly<Record<string, BlockProp<unknown, unknown>>>;\n\ninterface Ref {\n readonly kind: 'ref';\n readonly source: string;\n readonly path: readonly string[];\n}\n\nconst isRef = (value: unknown): value is Ref =>\n value !== null &&\n typeof value === 'object' &&\n (value as { kind?: unknown }).kind === 'ref' &&\n typeof (value as { source?: unknown }).source === 'string' &&\n Array.isArray((value as { path?: unknown }).path);\n\n/** One path of the bound row. The row is the whole value of `ref('item')`. */\nfunction readRow(row: Row, path: readonly string[]): unknown {\n let current: unknown = row;\n for (const segment of path) {\n if (current === null || typeof current !== 'object') return undefined;\n current = (current as Record<string, unknown>)[segment];\n }\n return current;\n}\n\n/**\n * A prop value with every ref read: `item` is the bound row, any other source is not available\n * to an item and reads nothing (the prop then fails its schema, and the list falls back to the\n * default item).\n */\nfunction bind(value: unknown, row: Row): unknown {\n if (isRef(value)) return value.source === 'item' ? readRow(row, value.path) : undefined;\n if (Array.isArray(value)) return value.map((entry) => bind(entry, row));\n if (value !== null && typeof value === 'object') {\n const out: Record<string, unknown> = {};\n for (const [key, entry] of Object.entries(value)) out[key] = bind(entry, row);\n return out;\n }\n return value;\n}\n\n/** What a placement writes for a prop, else its definition's ref default (a literal is validation's). */\nfunction written(\n props: Readonly<Record<string, unknown>>,\n name: string,\n definition: BlockProp<unknown, unknown>,\n): unknown {\n if (Object.hasOwn(props, name)) return props[name];\n const fallback = definition.defaultValue;\n return fallback?.kind === 'ref'\n ? { kind: 'ref', source: fallback.source, path: fallback.path }\n : undefined;\n}\n\n/** The first `item` field a ref reads, or undefined. */\nfunction itemField(value: unknown): string | undefined {\n if (isRef(value)) return value.source === 'item' ? value.path[0] : undefined;\n if (Array.isArray(value)) {\n for (const entry of value) {\n const found = itemField(entry);\n if (found !== undefined) return found;\n }\n return undefined;\n }\n if (value !== null && typeof value === 'object')\n for (const entry of Object.values(value)) {\n const found = itemField(entry);\n if (found !== undefined) return found;\n }\n return undefined;\n}\n\n/** Item props that failed validation, warned once each: a developer's schema mismatch, not an access answer. */\nconst warned = new Set<string>();\n\nfunction warnInvalid(label: string, validation: ReturnType<typeof validatePlacementProps>): void {\n if (process.env.NODE_ENV === 'production' || validation.status !== 'failed') return;\n const key = `${label}:${validation.prop}`;\n if (warned.has(key)) return;\n warned.add(key);\n console.warn(\n `[burojs] The item block ${label} of a related list does not accept its row, so the list draws the default item: the prop \"${validation.prop}\" ${validation.reason}.`,\n );\n}\n\nconst NO_NAMES: ReadonlySet<string> = new Set();\n\n/** The `block()` props of a node: those its nested placements fill. */\nfunction nestedNames(node: PlanNode, compiled: CompiledScreen): ReadonlySet<string> {\n const names = new Set<string>();\n for (const child of node.children) {\n const host = compiled.nodes[child.index]?.placement?.host;\n if (host !== undefined) names.add(host.prop);\n }\n return names;\n}\n\n/** The validated props of an item node for one row, or why it cannot be drawn. */\nfunction itemProps(\n block: AnyBlockHandle,\n raw: Readonly<Record<string, unknown>>,\n row: Row,\n /** The props that hold nested placements: drawn by the nodes below, never validated here. */\n nested: ReadonlySet<string> = NO_NAMES,\n): ReturnType<typeof validatePlacementProps> {\n const values: Record<string, unknown> = {};\n for (const [name, definition] of Object.entries(block.props as Definitions)) {\n if (nested.has(name)) continue;\n const value = bind(written(raw, name, definition), row);\n if (value !== undefined) values[name] = value;\n }\n return validatePlacementProps(block, values);\n}\n\n/**\n * Whether the item is drawn for this list at all, decided once for every row (P6-53): drawn only\n * when the planner decided it (its state is `ready`: a denied, undecided or failed `requires`\n * draws the default item), when no required prop reads a field the viewer may not see for every\n * row (`hidden` is an every-row question, so a rule reading the record counts as hiding it),\n * and when the first projected row satisfies its props.\n */\nexport function useItemDrawn(\n handle: ItemHandle | undefined,\n hidden: (field: string) => boolean,\n probe: Row | undefined,\n): boolean {\n const { compiled, controller } = useScreenTree();\n const placed = handle === undefined ? undefined : controller.placement(handle.node.key ?? '');\n const definition = placed?.definition;\n const blockName = placed === undefined ? 'item' : formatEntityRef(placed.block);\n const raw =\n handle === undefined ? undefined : compiled.nodes[handle.node.index]?.placement?.props;\n return useMemo(() => {\n if (handle === undefined || definition === undefined || raw === undefined) return false;\n if (handle.node.state !== 'ready') return false;\n const props = definition.props as Definitions;\n for (const [name, prop] of Object.entries(props)) {\n if (prop.isOptional) continue;\n const field = itemField(written(raw, name, prop));\n if (field !== undefined && hidden(field)) return false;\n }\n if (probe === undefined) return true;\n const validation = itemProps(definition, raw, probe, nestedNames(handle.node, compiled));\n warnInvalid(blockName, validation);\n return validation.status !== 'failed';\n }, [handle, definition, blockName, raw, hidden, probe, compiled]);\n}\n\nclass ItemBoundary extends Component<\n { readonly fallback: ReactNode; readonly children: ReactNode },\n { readonly failed: boolean }\n> {\n override state = { failed: false };\n\n static getDerivedStateFromError(): { readonly failed: boolean } {\n return { failed: true };\n }\n\n override componentDidCatch(error: unknown, info: ErrorInfo): void {\n if (process.env.NODE_ENV !== 'production')\n console.error(\n '[burojs] The item of a related list threw while rendering.',\n error,\n info.componentStack,\n );\n }\n\n override render(): ReactNode {\n return this.state.failed ? this.props.fallback : this.props.children;\n }\n}\n\n/**\n * One row of the list drawn through its item block: the item placement's props resolved with\n * `item` bound to `row` (the projected row, never the raw one), validated against the block's\n * schemas, the nested placements below it drawn the same way. A row whose props do not validate\n * draws `fallback`.\n */\nexport function RelatedItem({\n handle,\n row,\n fallback,\n}: {\n readonly handle: ItemHandle;\n readonly row: Row;\n readonly fallback: ReactNode;\n}): ReactElement {\n return (\n <ItemBoundary fallback={fallback}>\n <Suspense fallback={null}>\n <ItemNode node={handle.node} row={row} fallback={fallback} />\n </Suspense>\n </ItemBoundary>\n );\n}\n\nfunction ItemNode({\n node,\n row,\n fallback,\n}: {\n readonly node: PlanNode;\n readonly row: Row;\n readonly fallback: ReactNode;\n}): ReactNode {\n const { compiled, controller } = useScreenTree();\n const placement = usePlacement(node.key ?? '', controller);\n const definition = controller.placement(node.key ?? '')?.definition;\n const raw = compiled.nodes[node.index]?.placement?.props;\n const implementation = selectImplementation(\n formatEntityRef(placement.block),\n placement.appImplementation,\n );\n const validation = useMemo(\n () =>\n definition === undefined || raw === undefined\n ? undefined\n : itemProps(definition, raw, row, nestedNames(node, compiled)),\n [definition, raw, row, node, compiled],\n );\n if (node.state === 'absent') return null;\n if (node.state !== 'ready') return fallback;\n if (validation !== undefined) warnInvalid(formatEntityRef(placement.block), validation);\n if (\n placement.state !== 'ready' ||\n implementation === undefined ||\n validation === undefined ||\n validation.status !== 'ready'\n )\n return fallback;\n const props: Record<string, unknown> = { ...validation.props };\n const lists = new Map<string, ReactElement[]>();\n for (const child of node.children) {\n const host = compiled.nodes[child.index]?.placement?.host;\n if (host === undefined) continue;\n const element = (\n <ItemNode key={`${child.index}:${child.id}`} node={child} row={row} fallback={null} />\n );\n if (host.index === undefined) props[host.prop] = element;\n else {\n const list = lists.get(host.prop) ?? [];\n list[host.index] = element as ReactElement;\n lists.set(host.prop, list);\n }\n }\n for (const [name, list] of lists) props[name] = list.filter((entry) => entry !== undefined);\n const View = viewOf(implementation);\n const viewProps: BlockViewProps<unknown> = {\n props: props as BlockViewProps<unknown>['props'],\n data: {} as BlockViewProps<unknown>['data'],\n t: placement.viewProps?.t ?? ((name: string) => name),\n ...(placement.viewProps?.empty === undefined ? {} : { empty: placement.viewProps.empty }),\n };\n return <View {...viewProps} />;\n}\n","'use client';\n\nimport * as React from 'react';\nimport * as TabsPrimitive from '@radix-ui/react-tabs';\nimport { cn } from '../lib/cn.js';\n\n/**\n * Thin shadcn-ui-style wrapper around `@radix-ui/react-tabs`. Exposed as\n * a primitive so feature components (e.g. the screen tree's tabs node) can compose\n * the standard accessible Tabs pattern without re-implementing radix\n * boilerplate.\n *\n * Controlled-vs-uncontrolled: pass `value`+`onValueChange` for URL-synced\n * tabs (the playground show page does this with `?tab=` query state); pass\n * `defaultValue` for purely-local tab state.\n */\nconst Tabs = TabsPrimitive.Root;\n\nexport type TabsListProps = React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>;\n\nconst TabsList = React.forwardRef<React.ElementRef<typeof TabsPrimitive.List>, TabsListProps>(\n ({ className, ...props }, ref) => (\n <TabsPrimitive.List\n ref={ref}\n className={cn(\n 'inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground',\n className,\n )}\n {...props}\n />\n ),\n);\nTabsList.displayName = TabsPrimitive.List.displayName;\n\nexport type TabsTriggerProps = React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>;\n\nconst TabsTrigger = React.forwardRef<\n React.ElementRef<typeof TabsPrimitive.Trigger>,\n TabsTriggerProps\n>(({ className, ...props }, ref) => (\n <TabsPrimitive.Trigger\n ref={ref}\n className={cn(\n 'inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all',\n 'focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n 'disabled:pointer-events-none disabled:opacity-50',\n 'data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-xs',\n className,\n )}\n {...props}\n />\n));\nTabsTrigger.displayName = TabsPrimitive.Trigger.displayName;\n\nexport type TabsContentProps = React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>;\n\nconst TabsContent = React.forwardRef<\n React.ElementRef<typeof TabsPrimitive.Content>,\n TabsContentProps\n>(({ className, ...props }, ref) => (\n <TabsPrimitive.Content\n ref={ref}\n className={cn(\n 'mt-4 ring-offset-background focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n className,\n )}\n {...props}\n />\n));\nTabsContent.displayName = TabsPrimitive.Content.displayName;\n\nexport { Tabs, TabsList, TabsTrigger, TabsContent };\n","'use client';\nimport { type PlanNode, resolveTextSlot, type TextSlot } from '@burojs/core';\nimport type { FrameNodeAttributes } from '@burojs/react';\nimport { useI18nCaps, useOptionalT } from '@burojs/react';\nimport type { ReactElement } from 'react';\nimport { DocInfo } from '../doc/doc-info.js';\nimport { Skeleton } from '../primitives/skeleton.js';\nimport { useScreenTree } from './tree-context.js';\n\n/** The attributes of the styling contract every node element carries (P1b+P1c section 9). */\nexport function nodeAttributes(\n node: PlanNode,\n kind: string = node.kind,\n tone?: string,\n): FrameNodeAttributes {\n return {\n 'data-buro-node': kind,\n ...(node.key === undefined ? {} : { 'data-buro-key': node.key }),\n ...(tone === undefined ? {} : { 'data-buro-tone': tone }),\n ...(node.state === 'pending' || node.state === 'failed'\n ? { 'data-buro-state': node.state }\n : {}),\n };\n}\n\n/**\n * A node text: its bundle key `resources.<r>.nodes.<key>.<slot>` (or the\n * entry's plain string), never a `common.*` or `resources._.*` fallback\n * (P1b+P1c decision 14), else the compiled default.\n */\nexport function useNodeText(): (slot: TextSlot | undefined) => string | undefined {\n const caps = useI18nCaps();\n return (slot) => (slot === undefined ? undefined : resolveTextSlot(caps, slot));\n}\n\n/** The «i» of a keyed panel, tabs or steps node: its doc address, no test id of its own. */\nexport function NodeInfo({ node, name }: { readonly node: PlanNode; readonly name: string }) {\n const { resource } = useScreenTree();\n if (node.key === undefined) return null;\n return (\n <span data-buro-region=\"info\" className=\"inline-flex\">\n <DocInfo address={`${resource}/nodes/${node.key}`} name={name} />\n </span>\n );\n}\n\n/** A node's «i» element, or `null` for a node without a key (it has no doc address). */\nexport function nodeInfo(node: PlanNode, name: string): ReactElement | null {\n return node.key === undefined ? null : <NodeInfo node={node} name={name} />;\n}\n\n/** What a pending node draws inside its kept box: a skeleton, visible while the box is not. */\nexport function PendingSkeleton(): ReactElement {\n return <Skeleton data-buro-skeleton=\"\" className=\"h-9 w-full\" />;\n}\n\n/** A badge with the number of errors under a keyed node; nothing when there are none. */\nexport function ErrorBadge({ count }: { readonly count: number }): ReactElement | null {\n const t = useOptionalT();\n if (count === 0) return null;\n return (\n <span\n role=\"img\"\n aria-label={t('screen.errorCount', { count, defaultValue: `${count} errors` })}\n className=\"ml-1.5 inline-flex min-w-5 items-center justify-center rounded-full bg-destructive px-1.5 text-[11px] font-semibold leading-5 text-destructive-foreground tabular-nums\"\n >\n {count}\n </span>\n );\n}\n","'use client';\nimport {\n type PanelFrameViewProps,\n type StepsFrameViewProps,\n type TabsFrameViewProps,\n useOptionalT,\n} from '@burojs/react';\nimport { IconChevronRight } from '@tabler/icons-react';\nimport { Fragment, type ReactElement, type Ref } from 'react';\nimport { Button } from '../primitives/button.js';\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from '../primitives/tabs.js';\nimport { ErrorBadge } from '../screen/node-parts.js';\n\n/**\n * `buro:panel`: a `section` with the title row (the collapse toggle, the title, the error count\n * of a closed panel, the «i») and the framework's body. `stepPanel` is the kit's own extension\n * for a step of a non-wizard steps node, which always shows its count.\n */\nexport function BuroPanelFrame({\n body,\n title,\n description,\n collapsible,\n open,\n onToggle,\n errorCount,\n titleId,\n bodyId,\n info,\n nodeAttributes,\n stepPanel = false,\n}: PanelFrameViewProps & { readonly stepPanel?: boolean }): ReactElement {\n const t = useOptionalT();\n return (\n // Named by its heading when it has one, so it is a region a screen reader can list.\n <section {...nodeAttributes} {...(title === undefined ? {} : { 'aria-labelledby': titleId })}>\n {title === undefined && info === null && !collapsible ? null : (\n <div data-buro-region=\"panel-title\" className=\"flex items-center gap-1\">\n {collapsible ? (\n <button\n type=\"button\"\n aria-expanded={open}\n aria-controls={bodyId}\n aria-label={\n open\n ? t('screen.collapse', { defaultValue: 'Collapse' })\n : t('screen.expand', { defaultValue: 'Expand' })\n }\n onClick={() => onToggle(!open)}\n className=\"inline-flex size-6 items-center justify-center rounded text-muted-foreground hover:bg-muted\"\n >\n <IconChevronRight\n className={\n open ? 'h-4 w-4 rotate-90 transition-transform' : 'h-4 w-4 transition-transform'\n }\n aria-hidden=\"true\"\n />\n </button>\n ) : null}\n {title === undefined ? null : (\n <h3 id={titleId} className=\"text-sm font-semibold\">\n {title}\n </h3>\n )}\n {collapsible && !open ? <ErrorBadge count={errorCount} /> : null}\n {stepPanel ? <ErrorBadge count={errorCount} /> : null}\n {info}\n </div>\n )}\n {description === undefined ? null : (\n <p className=\"text-sm text-muted-foreground\">{description}</p>\n )}\n {body}\n </section>\n );\n}\n\n/** `buro:tabs`: a Radix tab strip with each tab's error count; one tab draws no strip. */\nexport function BuroTabsFrame({\n tabs,\n active,\n onSelect,\n info,\n nodeAttributes,\n}: TabsFrameViewProps): ReactElement {\n if (tabs.length === 1)\n return (\n <div {...nodeAttributes}>\n <div data-buro-region=\"tab-panel\">{tabs[0]!.panel}</div>\n </div>\n );\n return (\n <Tabs {...nodeAttributes} value={active} onValueChange={onSelect}>\n <div className=\"flex items-center gap-2\">\n <TabsList data-buro-region=\"tabs-list\">\n {tabs.map((tab) => (\n <TabsTrigger key={tab.key} value={tab.key} data-buro-key={tab.key}>\n {tab.title}\n <ErrorBadge count={tab.errorCount} />\n </TabsTrigger>\n ))}\n </TabsList>\n {info}\n </div>\n {/* No `forceMount`: Radix still mounts every panel's box (only the active one holds content,\n demand is the framework's), and marks the inactive ones `hidden`, which `forceMount`\n would clear — leaving each empty panel's margin in the layout and its `tabpanel` exposed. */}\n {tabs.map((tab) => (\n <TabsContent\n key={tab.key}\n value={tab.key}\n data-buro-region=\"tab-panel\"\n data-buro-key={tab.key}\n >\n {tab.panel}\n </TabsContent>\n ))}\n </Tabs>\n );\n}\n\n/**\n * `buro:steps`: outside a wizard, every step's panel stacked; inside (a create's steps, P1b+P1c\n * decision 11), the step list, the current step under its heading, and the Back / Next rail —\n * the frame's Submit is the last step's.\n */\nexport function BuroStepsFrame({\n wizard,\n steps,\n goTo,\n back,\n next,\n headingRef,\n info,\n nodeAttributes,\n liveRegion = null,\n}: StepsFrameViewProps & {\n /** The kit's own extension: the framework's live region, drawn inside the wizard's root. */\n readonly liveRegion?: ReactElement | null;\n}): ReactElement {\n const t = useOptionalT();\n if (!wizard)\n return (\n <div {...nodeAttributes}>\n {info}\n {steps.map((step) => (\n <Fragment key={step.key}>{step.panel}</Fragment>\n ))}\n </div>\n );\n const index = steps.findIndex((step) => step.state === 'current');\n const current = steps[index];\n if (current === undefined) return <div {...nodeAttributes} />;\n const keepFocus = (event: { preventDefault(): void }) => event.preventDefault();\n return (\n <div {...nodeAttributes} className=\"flex flex-col gap-4\">\n {steps.length > 1 ? (\n <nav aria-label={t('steps.progress', { defaultValue: 'Progress' })}>\n <ol data-buro-region=\"steps-list\" className=\"flex flex-wrap items-center gap-2\">\n {steps.map((step, at) => (\n <li key={step.key}>\n <button\n type=\"button\"\n aria-current={step.state === 'current' ? 'step' : undefined}\n disabled={step.state === 'locked'}\n onClick={() => goTo(step.key)}\n className=\"inline-flex items-center gap-1.5 rounded-md border px-2.5 py-1 text-sm aria-[current=step]:border-primary aria-[current=step]:font-semibold disabled:opacity-50\"\n >\n <span className=\"tabular-nums\">{at + 1}.</span>\n <span>{step.title}</span>\n <ErrorBadge count={step.errorCount} />\n </button>\n </li>\n ))}\n </ol>\n </nav>\n ) : null}\n {liveRegion}\n <section {...current.nodeAttributes}>\n <div data-buro-region=\"panel-title\" className=\"flex items-center gap-1\">\n <h2\n ref={headingRef as Ref<HTMLHeadingElement>}\n id={current.titleId}\n tabIndex={-1}\n className=\"text-base font-semibold outline-none\"\n >\n {current.title}\n </h2>\n {current.info}\n </div>\n {current.description === undefined ? null : (\n <p className=\"text-sm text-muted-foreground\">{current.description}</p>\n )}\n {current.panel}\n </section>\n {steps.length > 1 ? (\n <div className=\"flex gap-2\">\n {index > 0 ? (\n <Button type=\"button\" variant=\"outline\" onMouseDown={keepFocus} onClick={back}>\n {t('steps.back', { defaultValue: 'Back' })}\n </Button>\n ) : null}\n {index < steps.length - 1 ? (\n <Button type=\"button\" className=\"ml-auto\" onMouseDown={keepFocus} onClick={next}>\n {t('steps.next', { defaultValue: 'Next' })}\n </Button>\n ) : null}\n </div>\n ) : null}\n </div>\n );\n}\n","'use client';\n\nimport * as React from 'react';\nimport * as CheckboxPrimitive from '@radix-ui/react-checkbox';\nimport { IconCheck, IconMinus } from '@tabler/icons-react';\nimport { cn } from '../lib/cn.js';\n\nexport type CheckboxProps = React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>;\n\nconst Checkbox = React.forwardRef<React.ElementRef<typeof CheckboxPrimitive.Root>, CheckboxProps>(\n ({ className, checked, ...props }, ref) => (\n <CheckboxPrimitive.Root\n ref={ref}\n // A fixed corner: `rounded-sm` follows the theme's `--radius`, and at a large radius the box\n // turned round and read as a radio button. `align-middle` with a mark that fits inside the\n // border: an inline box with content takes its baseline from that content, so a checked box\n // sat lower than an empty one and grew its line — a table row got taller when selected.\n className={cn(\n 'peer inline-flex h-4 w-4 shrink-0 items-center justify-center align-middle rounded-[4px] border border-primary ring-offset-background focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground data-[state=indeterminate]:bg-primary data-[state=indeterminate]:text-primary-foreground',\n className,\n )}\n checked={checked}\n {...props}\n >\n <CheckboxPrimitive.Indicator className={cn('flex items-center justify-center text-current')}>\n {/* Some, not all: a dash. A check here read as \"all selected\" with one row picked. */}\n {checked === 'indeterminate' ? (\n <IconMinus data-icon=\"minus\" className=\"size-3.5\" />\n ) : (\n <IconCheck data-icon=\"check\" className=\"size-3.5\" />\n )}\n </CheckboxPrimitive.Indicator>\n </CheckboxPrimitive.Root>\n ),\n);\nCheckbox.displayName = CheckboxPrimitive.Root.displayName;\n\nexport { Checkbox };\n","'use client';\nimport { useEffect, useState } from 'react';\n\n/**\n * Whether an element is narrower than `maxRem` root ems: its own inline size, not the viewport's,\n * so a list in a 380px sheet on a 1280px page lays out as it would on a phone. Returns a callback\n * ref (the element may mount after the first render) and the answer; `false` where there is no\n * `ResizeObserver` (SSR) and until the first measurement.\n */\nexport function useContainerNarrow(\n maxRem = 40,\n): readonly [(element: HTMLElement | null) => void, boolean] {\n const [element, setElement] = useState<HTMLElement | null>(null);\n const [narrow, setNarrow] = useState(false);\n useEffect(() => {\n if (element === null || typeof ResizeObserver === 'undefined') return;\n const rootPx = Number.parseFloat(getComputedStyle(document.documentElement).fontSize) || 16;\n const observer = new ResizeObserver((entries) => {\n const entry = entries[entries.length - 1];\n if (entry === undefined) return;\n const size = entry.contentBoxSize?.[0]?.inlineSize ?? entry.contentRect.width;\n setNarrow(size < maxRem * rootPx);\n });\n observer.observe(element);\n return () => observer.disconnect();\n }, [element, maxRem]);\n return [setElement, narrow] as const;\n}\n","/** What the spare-width rule reads of one visible column, in display order. */\nexport interface FillCandidate {\n readonly id: string;\n /** The column's effective `ui.column.fill`. */\n readonly fill: boolean;\n /** Whether the user may drag its width. */\n readonly resize: boolean;\n /** Its upper bound, when it has one. */\n readonly max?: number;\n readonly pinned: boolean;\n /** The select or actions column. */\n readonly service: boolean;\n}\n\n/**\n * The column that takes a table's spare width, the filler (REF-117 §4.8):\n *\n * 1. the first unpinned column marked `fill`;\n * 2. else the last unpinned resizable column with no `max` (owner decision Q2);\n * 3. else none: the table keeps the sum of its widths.\n *\n * Pinned columns never fill (their sticky offsets come from TanStack sizes, so a pinned filler\n * hands the role on), and neither do the service columns. `columns` holds the visible columns only.\n */\nexport function fillColumnId(columns: readonly FillCandidate[]): string | undefined {\n const eligible = columns.filter((c) => !c.pinned && !c.service);\n const declared = eligible.find((c) => c.fill);\n if (declared !== undefined) return declared.id;\n for (let i = eligible.length - 1; i >= 0; i--) {\n const c = eligible[i]!;\n if (c.resize && c.max === undefined) return c.id;\n }\n return undefined;\n}\n","'use client';\nimport {\n type CSSProperties,\n type ReactNode,\n memo,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport {\n type Cell,\n type Column,\n type Row,\n type Table as TanStackTable,\n flexRender,\n} from '@tanstack/react-table';\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '../primitives/table.js';\nimport { useOptionalT, useRouteNavigate } from '@burojs/react';\nimport { cn } from '../lib/cn.js';\nimport { annotateIfClipped } from './annotate-if-clipped.js';\nimport { fillColumnId } from './fill-column.js';\nimport { useToBrowserHref } from '../lib/external-href.js';\n\n/**\n * Sticky-column styles with an edge shadow (#17), ported from the reference\n * admin table. Gated on horizontal overflow: when everything fits there is\n * no sticky positioning and no shadow. The shadow is drawn only on the EDGE\n * pinned column — the last left-pinned / first right-pinned — so a block of\n * pinned columns reads as one raised panel.\n *\n * Offset comes from a CSS variable set once on the table root\n * (`--col-{id}-left` / `--col-{id}-right`, written in `DataTable`'s\n * `columnSizeVars` alongside the width vars below) — the SAME \"commit once\n * to a var on the table root\" pattern already used for width. This matters\n * for more than consistency: a pinned column's offset is the cumulative\n * SIZE of every earlier same-side pinned column (`getStart`/`getAfter`), so\n * resizing a non-terminal pinned column shifts every LATER same-side pinned\n * cell's offset. If that offset were baked into each cell's inline style\n * (as it used to be), a LIVE resize drag (`columnResizeMode: 'onChange'`\n * commits sizing every mousemove tick) would need every later pinned cell\n * to re-render on every tick to stay aligned — reintroducing the exact\n * per-tick, all-rows re-render `DataTableBody`'s memo exists to eliminate.\n * Routing it through a var instead means the browser applies the new\n * offset directly, with ZERO cell re-renders, on every tick — identical to\n * how width already works.\n */\n/**\n * Elevation for the edge of a pinned column, as a pseudo-element.\n *\n * `box-shadow` on a table cell is not paintable under\n * `border-collapse: collapse` (Tailwind Preflight's default), so the depth cue\n * that tells the user \"the rest of the table is scrolling UNDER this column\"\n * has to be a real child box. An `::after` strip just outside the cell's edge\n * paints in every engine and in both themes.\n *\n * Returns '' for cells that are not the boundary of a pinned group, so the\n * gradient appears exactly once per side.\n */\nfunction pinEdgeClass(isLastLeft: boolean, isFirstRight: boolean): string {\n /*\n OUTSIDE the cell, and that is the whole point of this function.\n\n A shadow says which surface is raised. The pinned column is the raised one —\n the rest of the table scrolls UNDER it — so the shadow belongs ON THE\n SCROLLING CONTENT, darkest against the pinned edge and fading away from it.\n\n It used to be drawn INSIDE the pinned cell (`right-0`, transparent → dark),\n which darkened the last 12px of the pinned column itself and left the\n scrolling side untouched. That reads as a stripe painted onto the pinned\n column, not as depth: it says the pinned column is the thing being covered.\n\n Placing it outside was avoided because a resizable table put\n `overflow-hidden` on the cell, which clips a pseudo-element beyond the\n edge. That clip is no longer on the pinned edge cell — the inner\n `truncate` wrapper already clips the content, so the cell does not need to\n (see the call sites).\n */\n if (isLastLeft) {\n return 'after:pointer-events-none after:absolute after:inset-y-0 after:left-full after:z-10 after:w-1.5 after:bg-gradient-to-r after:from-overlay/[0.07] after:to-transparent dark:after:from-overlay/30';\n }\n if (isFirstRight) {\n return 'after:pointer-events-none after:absolute after:inset-y-0 after:right-full after:z-10 after:w-1.5 after:bg-gradient-to-l after:from-overlay/[0.07] after:to-transparent dark:after:from-overlay/30';\n }\n return '';\n}\n\n/** Same guards as `getPinStyles` — the edge only exists when the column is\n * pinned AND the table actually overflows. */\nfunction pinEdgeClassFor<TRow>(\n column: {\n getIsPinned: () => false | 'left' | 'right';\n getIsLastColumn: (p: 'left') => boolean;\n getIsFirstColumn: (p: 'right') => boolean;\n },\n overflowing: boolean,\n): string {\n const pinned = column.getIsPinned();\n if (!pinned || !overflowing) return '';\n return pinEdgeClass(\n pinned === 'left' && column.getIsLastColumn('left'),\n pinned === 'right' && column.getIsFirstColumn('right'),\n );\n}\n\nfunction getPinStyles<TRow>(\n column: Column<TRow>,\n overflowing: boolean,\n fill = false,\n): CSSProperties {\n // Width comes from a CSS variable set once on the table root (the TanStack\n // performant-resize pattern): the browser applies width changes during a drag\n // without re-rendering every cell. Every column carries an explicit width\n // except the FILLER (REF-117 §4.8, `fillColumnId`): the table is\n // `table-layout:fixed` at `width: max(100%, <sum of the widths>px)`, so the\n // one width-less column takes whatever the container has beyond the sum, and\n // never less than its own width, which the sum already counts. With no\n // filler the table is exactly the sum and the space after it stays empty.\n // A filler is never pinned, so it never needs the sticky styles below.\n if (fill) return {};\n const explicitWidth: CSSProperties = { width: `calc(var(--col-${column.id}-size) * 1px)` };\n const pinned = column.getIsPinned();\n if (!pinned || !overflowing) {\n return explicitWidth;\n }\n const isLastLeft = pinned === 'left' && column.getIsLastColumn('left');\n const isFirstRight = pinned === 'right' && column.getIsFirstColumn('right');\n return {\n position: 'sticky',\n zIndex: 1,\n // MUST be `var(--background)`, not `hsl(var(--background))`. Since the\n // token-contract refactor, `--background` carries the FULL `hsl(...)`\n // value itself (`hsl(0 0% 100%)`, not a bare triplet) — wrapping it in\n // another `hsl(...)` here nests it invalidly (`hsl(hsl(...))`), which\n // makes `background` invalid at computed-value time and resets to its\n // initial value (transparent), so the sticky column renders TRANSPARENT\n // and the horizontally-scrolled-under columns bleed through it (the\n // \"Location/Actions\" collision an acceptance review caught, this\n // time reproduced by the style-baseline gate on the token-notation change).\n background: 'var(--background)',\n // `, 0` fallback: harmless before the table-root vars are painted, or for\n // a pinned column on a non-resizable table (the vars are only written\n // when `enableColumnResizing` is on — see `columnSizeVars` — matching\n // the pre-existing width var's same constraint).\n left: pinned === 'left' ? `calc(var(--col-${column.id}-left, 0) * 1px)` : undefined,\n right: pinned === 'right' ? `calc(var(--col-${column.id}-right, 0) * 1px)` : undefined,\n ...explicitWidth,\n /*\n ⚠️ NO `boxShadow` here — it would be dead CSS.\n\n Tailwind's Preflight sets `table { border-collapse: collapse }`, and\n under collapsed borders Blink does not paint box-shadow on `<td>`/`<th>`\n at all. A previous pass set a perfectly reasonable elevation here and it\n rendered NOTHING: screenshotting the pinned edge with the shadow on and\n then with `box-shadow: none !important` produced byte-identical PNGs,\n and even a forced `30px 0 0 0 red` changed no pixels. It looked correct\n in computed styles, which is exactly why it survived review.\n\n The elevation lives on a pseudo-element instead — see\n `pinEdgeClass()`. A child box paints regardless of border-collapse.\n */\n };\n}\n\n/**\n * Per-column presentational escape hatch: a column may carry\n * `meta: { className, noRowNav, noClip }`.\n *\n * - `className` is applied to BOTH its `<th>` and its `<td>` so the pair\n * stays aligned (width, text-align, …). Used by `ResourceList` to keep the\n * collapsed actions column at its natural kebab width instead of letting\n * it share the table's even column distribution.\n * - `noRowNav` stamps the `<td>` with `data-no-row-nav`, which `activateRow`\n * already allowlists (see its doc comment) but which, before this flag\n * existed, no column ever set. It exists because whole-row navigation\n * (`rowHref`) only excludes clicks on actual interactive elements\n * (`a, button, …`) — a click that lands on a *cell's padding* rather than\n * the control inside it (e.g. the actions column's kebab button, which is\n * 32×32 inside a wider `<td>`) still falls through and navigates. Marking\n * the whole cell, not just the control, closes that gap. Kept as a single\n * boolean rather than a general \"arbitrary props on cells\" mechanism:\n * this is the one DOM attribute `activateRow` understands, so that's all\n * `meta` needs to carry.\n * - `noClip` says the cell holds CONTROLS, not text, so it must never be\n * clipped. See {@link columnMetaNoClip}.\n * - `wrap` says the column's values wrap (a field's `overflow: 'wrap'`,\n * REF-117 §4.3). See {@link columnMetaWrap}.\n */\nfunction columnMetaClassName(meta: unknown): string | undefined {\n const cls = (meta as { className?: unknown } | undefined)?.className;\n return typeof cls === 'string' ? cls : undefined;\n}\n\nfunction columnMetaNoRowNav(meta: unknown): boolean {\n return (meta as { noRowNav?: unknown } | undefined)?.noRowNav === true;\n}\n\n/**\n * \"This column's content is controls, not text — never clip it.\"\n *\n * A resizable table is `table-layout: fixed`, so every cell is exactly as wide\n * as its column says and content that does not fit has to go somewhere. For\n * TEXT the answer is the `truncate` wrapper below: hide the overflow, show an\n * ellipsis, and hand the full string back through the hover `title`. Nothing is\n * lost, because the value is still readable another way.\n *\n * For a CONTROL the same answer is a silent failure, and it produced F1 in\n * `docs/superpowers/specs/2026-08-15-marketplace-ops-follow-ups.md`. Measured,\n * at a 1280px viewport, on a row-actions column carrying three standalone\n * buttons plus an overflow kebab in a 64px column: `<ActionOverflow>` lays its\n * strip out `flex … justify-end`, so content that does not fit overflows past\n * the cell's START edge — and `truncate` (`overflow: hidden`) then clipped the\n * first button away entirely. It was still in the DOM, still `opacity: 1`,\n * still `pointer-events: auto`, and its `getBoundingClientRect()` still\n * reported a healthy 18×32 box, so Playwright judged it VISIBLE and then timed\n * out clicking it: `document.elementFromPoint` at that box's centre returned\n * the neighbouring date cell's own wrapper, because the button was clipped out\n * of hit-testing. A user's pointer lands exactly where Playwright's did.\n *\n * ⚠️ The z-index was never the problem, and raising it does not help — proven\n * in-page before this fix: with the pinned `<td>` forced to `z-index: 50` the\n * hit test still returned the date cell, while setting the wrapper to\n * `overflow: visible` (nothing else) made the button reachable at once. Pinning\n * puts the actions cell ABOVE its neighbours already; the button was simply not\n * inside its own cell any more.\n *\n * So a `noClip` column trades a cosmetic overflow for a reachable control: if\n * its width is ever too small for what it holds, the controls spill visibly\n * over the neighbouring cell (and, when pinned, paint above it) instead of\n * disappearing. `ResourceList` sizes its actions column to fit\n * (`actionsColumnSize`), so the spill is a backstop for the widths that\n * arithmetic cannot know — an adopter's `regular`-density row action, a custom\n * `renderCell`, a long translated label — not the normal case.\n */\nfunction columnMetaNoClip(meta: unknown): boolean {\n return (meta as { noClip?: unknown } | undefined)?.noClip === true;\n}\n\n/**\n * \"This column's values wrap onto as many lines as they need\" (a field's\n * `overflow: 'wrap'`, REF-117 §4.3, builder call C6). The BODY cell takes the\n * `noClip` path: no `overflow-hidden` on the cell and no inner `truncate`\n * wrapper, so the field's frame can break the text. The header is untouched\n * and stays clipped: only the values wrap, never the column's label.\n */\nfunction columnMetaWrap(meta: unknown): boolean {\n return (meta as { wrap?: unknown } | undefined)?.wrap === true;\n}\n\n/** `meta.fill`: the column asks for the table's spare width (REF-117 §4.8, `fillColumnId`). */\nfunction columnMetaFill(meta: unknown): boolean {\n return (meta as { fill?: unknown } | undefined)?.fill === true;\n}\n\n/**\n * The visible column that takes the table's spare width, if any (`fillColumnId`). Only a\n * resizable table has one: a non-resizable table carries no widths at all.\n */\nfunction tableFillColumnId<TRow>(table: TanStackTable<TRow>): string | undefined {\n if (table.options.enableColumnResizing !== true) return undefined;\n return fillColumnId(\n table.getVisibleLeafColumns().map((c) => {\n const max = c.columnDef.maxSize;\n return {\n id: c.id,\n fill: columnMetaFill(c.columnDef.meta),\n resize: c.getCanResize(),\n // TanStack's own default is `Number.MAX_SAFE_INTEGER`, which is no bound at all.\n ...(max !== undefined && max < Number.MAX_SAFE_INTEGER ? { max } : {}),\n pinned: c.getIsPinned() !== false,\n service: c.id.startsWith('__'),\n };\n }),\n );\n}\n\n/** Shared props for a single `<TableCell>`'s markup — used by both memoized\n * cell variants below (`MemoCell` and `SelectionCell`). */\ninterface CellSharedProps<TRow> {\n cell: Cell<TRow, unknown>;\n resizable: boolean;\n overflowing: boolean;\n /** The cell's column is the table's filler (`fillColumnId`): it carries no explicit width. */\n fill: boolean;\n /**\n * ⚠️ Pin side, captured at RENDER time by the row — deliberately a prop and\n * not read off `cell.column` inside the comparator.\n *\n * TanStack reuses the same `column` object across renders, so\n * `prev.cell.column.getIsPinned()` and `next.cell.column.getIsPinned()` both\n * return the CURRENT value and always compare equal. A comparator written\n * that way looks like it checks pin state and silently never does — which is\n * exactly the bug this prop exists to fix, so it must not be reintroduced.\n */\n pinned: false | 'left' | 'right';\n testId?: string;\n /**\n * Selection cell only: makes the WHOLE cell a hit area. The column is 44px\n * wide and the checkbox inside it is ~16px, so without this two thirds of\n * the cell fall through to the row's `rowHref` navigation — which unmounts\n * the list and drops the accumulated selection.\n */\n onCellClick?: (e: React.MouseEvent<HTMLTableCellElement>) => void;\n /**\n * Stamps `data-no-row-nav`, which `activateRow` already honours. Required\n * whenever `onCellClick` is set: the cell's click still bubbles to the row,\n * so without it the row would navigate on top of the cell's own handling.\n */\n noRowNav?: boolean;\n}\n\n/**\n * The `<TableCell>` markup itself — IDENTICAL to the previous inline render.\n * Pulled into a plain function (not a component) so `MemoCell` and\n * `SelectionCell` below can share it without duplicating JSX; which one\n * wraps it in `memo` (and what that memo depends on) is the whole point of\n * this file's re-render fix — see their doc comments.\n *\n * This calls `flexRender(cell.column.columnDef.cell, cell.getContext())` —\n * whatever a caller's `columnDef.cell` (or, in `ResourceList`, its\n * `renderCell` override — see that prop's doc) returns runs INSIDE\n * `MemoCell`'s frozen boundary for a data/action column. A `cell` render fn\n * that isn't a pure function of the cell's own `row`/`column`/`value` — e.g.\n * one that reads locale, a feature flag, or any other external reactive\n * state inline — will go stale exactly like the built-in\n * `DateDisplay`/`NumberDisplay` did before they were fixed to self-subscribe\n * (`useLocale()`) instead of resolving state inline.\n */\nfunction renderCellMarkup<TRow>({\n cell,\n resizable,\n overflowing,\n fill,\n testId,\n onCellClick,\n noRowNav,\n}: CellSharedProps<TRow>): React.ReactElement {\n /*\n The LIVE column — `cell.column` can be a cached object predating the current\n pinning state (see the `pinned` prop's note at the call site). Resolved once\n here because both the pin styles and the edge shadow must read the same\n source of truth, or the header pins and the body does not.\n */\n const liveColumn = cell.getContext().table.getColumn(cell.column.id) ?? cell.column;\n const pinEdge = pinEdgeClassFor(liveColumn, overflowing);\n // Controls, not text — see `columnMetaNoClip`. Both the cell's own\n // `overflow-hidden` and the inner `truncate` wrapper are dropped for such a\n // column, because either one alone still clips. A wrapping column\n // (`columnMetaWrap`) drops both for the same reason: either one keeps it on\n // one line.\n const noClip =\n columnMetaNoClip(cell.column.columnDef.meta) || columnMetaWrap(cell.column.columnDef.meta);\n return (\n <TableCell\n data-testid={testId}\n data-no-row-nav={columnMetaNoRowNav(cell.column.columnDef.meta) || noRowNav ? '' : undefined}\n onClick={onCellClick}\n /*\n The LIVE column — `cell.column` can be a cached object predating the\n current pinning state (see the `pinned` prop's note at the call site).\n Styles must come from the same source of truth the header uses, or the\n header pins and the body does not.\n */\n style={getPinStyles(liveColumn, overflowing, fill)}\n className={cn(\n /*\n Fixed-layout tables (resizing on) must clip overflowing cell content,\n or an unbroken value like a marking code\n (`0104820000846134215egimM…`) spills past its column and overlaps the\n next one.\n\n EXCEPT on the pinned edge, whose shadow is drawn just outside the\n cell and would be clipped away by it. Safe to drop there: the inner\n `truncate` wrapper below is itself `overflow: hidden`, so the content\n is clipped either way — the cell-level rule was belt-and-braces, and\n only on this one cell does it cost something.\n */\n resizable && !pinEdge && !noClip && 'overflow-hidden',\n // `relative` so the pinned-edge pseudo-element has a containing block.\n pinEdge && 'relative',\n pinEdge,\n columnMetaClassName(cell.column.columnDef.meta),\n onCellClick && 'cursor-pointer',\n )}\n >\n {resizable && !noClip ? (\n <div className=\"truncate\" onPointerEnter={annotateIfClipped}>\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </div>\n ) : (\n flexRender(cell.column.columnDef.cell, cell.getContext())\n )}\n </TableCell>\n );\n}\n\ninterface MemoCellProps<TRow> extends CellSharedProps<TRow> {\n /** The row's data object — see `MemoRow`'s comparator doc for why this\n * (not the TanStack `row`/`cell` wrapper objects) is the identity to key\n * skip-detection on. */\n rowOriginal: TRow;\n}\n\nfunction MemoCellInner<TRow>(props: MemoCellProps<TRow>): React.ReactElement {\n return renderCellMarkup(props);\n}\n\n/**\n * Memoized data/action cell (#1 in the render-perf plan). Deliberately does\n * NOT compare `isSelected` — that's what lets the `ActionOverflow` kebab\n * (and every other data cell) skip re-rendering when a row's selection\n * toggles. Keyed on `rowOriginal` rather than the TanStack `cell` wrapper's\n * identity: TanStack's `getCoreRowModel` rebuilds EVERY `Row`/`Cell` object\n * from scratch whenever the table's `data` array reference changes at all\n * (even for records that didn't change), so comparing wrapper identity would\n * defeat the memo for exactly the case that matters most — a query refetch\n * that only touched one record. `rowOriginal` is the actual data object,\n * which stays referentially stable across an immutable partial-array update\n * for every row except the one that changed.\n *\n * Does NOT need to know about pinned-column offsets either: those are a CSS\n * var on the table root now (see `getPinStyles`), so a pinned resize updates\n * this cell's sticky position purely via CSS, with no re-render at all —\n * an earlier version of this fix threaded a `pinnedOffset` prop through here\n * instead, which worked but meant a LIVE pinned-column drag changed\n * `columnLayoutKey` on every mousemove tick, defeating `MemoRow`'s skip for\n * that interaction. The CSS-var route avoids that entirely.\n */\nconst MemoCell = memo(\n MemoCellInner,\n (prev, next) =>\n prev.rowOriginal === next.rowOriginal &&\n prev.cell.column.id === next.cell.column.id &&\n prev.resizable === next.resizable &&\n /*\n ⚠️ `overflowing` only matters to a PINNED cell.\n\n Both `getPinStyles` and `pinEdgeClassFor` bail to the plain width when the\n column is not pinned, so for an unpinned cell this flag cannot change a\n single rendered byte. Comparing it unconditionally made every cell in the\n table re-render whenever the table crossed its overflow threshold — which\n hiding a column does routinely, because it changes the table's width.\n\n Measured on /document_document at 100 rows, hiding one column: the cell\n comparator ran 1 400 times and `overflowing` differed in 700 of them, for\n 3 300 DOM mutations — 33 per row, to remove one cell per row. Paging and\n sorting were already near-minimal (3 per row) precisely because they do\n not change the table's width.\n */\n ((!prev.pinned && !next.pinned) || prev.overflowing === next.overflowing) &&\n /*\n ⚠️ Pin state MUST be compared, and was not.\n\n `getPinStyles()` bakes `position` / `left` / `background` into the cell's\n inline style at render time, so a cell that skips re-rendering keeps the\n OLD pin styles. Pinning a column therefore moved only the `<th>`: the\n header became `position: sticky` while its `<td>`s stayed `static`, so the\n frozen header floated above a DIFFERENT column's values until the page was\n reloaded. To an operator that reads as corrupted data, not as a styling\n bug. Unpinning desynced the same way in reverse.\n\n The row above does re-render (its `columnLayoutKey` includes pin side) —\n every cell inside it was skipping.\n */\n prev.pinned === next.pinned &&\n // The filler drops its explicit width, so a cell that changes role must re-render.\n prev.fill === next.fill &&\n prev.testId === next.testId,\n) as typeof MemoCellInner;\n\ninterface SelectionCellProps<TRow> extends CellSharedProps<TRow> {\n isSelected: boolean;\n}\n\nfunction SelectionCellInner<TRow>(props: SelectionCellProps<TRow>): React.ReactElement {\n const row = props.cell.row;\n const toggle = (e: React.MouseEvent<HTMLTableCellElement>): void => {\n // The checkbox handles its own click. Without this guard the cell handler\n // runs a second, redundant toggle — harmless in value, but a duplicate\n // emission to a controlled owner.\n if ((e.target as HTMLElement | null)?.closest('[role=\"checkbox\"]')) return;\n row.toggleSelected(!row.getIsSelected());\n };\n return renderCellMarkup({ ...props, onCellClick: toggle, noRowNav: true });\n}\n\n/**\n * The row-selection checkbox cell (see `DataTableProps.selectionColumnId`).\n * Its column's `cell` render fn reads `row.getIsSelected()` imperatively\n * (resource-list's `SELECT_COL_ID` columnDef), so — unlike `MemoCell` —\n * it MUST re-render whenever `isSelected` changes, even on a row whose\n * `row`/`cell` wrappers and data are otherwise unchanged (select-all leaves\n * `MemoRow`'s wrapper skip-check untouched: same `row.original`, same\n * columns; only `isSelected` flips). Uses the default shallow comparator —\n * `isSelected` is a normal prop like any other here.\n */\nconst SelectionCell = memo(SelectionCellInner) as typeof SelectionCellInner;\n\n/** Props for `MemoRow` — see its comparator doc for why `row` itself is NOT\n * the skip-detection key. */\ninterface DataRowProps<TRow> {\n row: Row<TRow>;\n isSelected: boolean;\n resizable: boolean;\n overflowing: boolean;\n /** Serialized `id:pinnedSide` of every visible leaf column, recomputed by\n * `DataTable` on every render. Column hide/show/reorder/pin don't touch\n * `row.original` or `isSelected`, so without this in the comparator a\n * column-visibility change on an otherwise-untouched row would silently\n * skip — stale DOM showing a hidden column's cell. Deliberately does NOT\n * include pinned column SIZING (offset) — that's a CSS var now (see\n * `getPinStyles`), so a pinned-column resize/drag doesn't need to\n * invalidate this at all; folding it in here used to make a live pinned\n * drag change this key on every mousemove tick, which defeated `MemoRow`'s\n * skip for that interaction (the exact per-tick, all-rows re-render the\n * body memo exists to eliminate). */\n columnLayoutKey: string;\n /** The table's filler column (`fillColumnId`), whose cells carry no explicit width. */\n fillColumnId?: string;\n /** Column id of the row-selection checkbox column, if any (resource-list\n * passes its `SELECT_COL_ID`). That one cell renders via `SelectionCell`\n * (live on `isSelected`); every other cell renders via `MemoCell`\n * (frozen across selection changes). Generic `DataTable` doesn't know or\n * care what the id string means — it's just the opt-in marker. */\n selectionColumnId?: string;\n getCellTestId?: (row: TRow, columnId: string) => string | undefined;\n getRowTestId?: (row: TRow) => string | undefined;\n rowHref?: (row: TRow) => string | undefined;\n /** A row opener that may take a plain click instead of `rowHref` (see `DataTableProps`). */\n onRowOpen?: (row: TRow) => boolean;\n activateRow: (row: Row<TRow>, e: React.MouseEvent<HTMLTableRowElement>) => void;\n rowClassName?: ((row: Row<TRow>) => string | undefined) | string;\n}\n\n/**\n * A single data row, split out of `DataTableBodyInner` purely so it can be\n * wrapped in `React.memo` (see `MemoRow` below). Markup, testids, and\n * behaviour are IDENTICAL to the previous inline render — this only changes\n * WHEN each piece re-executes, not what it renders.\n */\nfunction DataRowInner<TRow>({\n row,\n isSelected,\n resizable,\n overflowing,\n fillColumnId,\n selectionColumnId,\n getCellTestId,\n getRowTestId,\n rowHref,\n onRowOpen,\n activateRow,\n rowClassName,\n}: DataRowProps<TRow>): React.ReactElement {\n const clickable = rowHref !== undefined || onRowOpen !== undefined;\n return (\n <TableRow\n data-state={isSelected ? 'selected' : undefined}\n data-testid={getRowTestId?.(row.original)}\n onClick={clickable ? (e) => activateRow(row, e) : undefined}\n // Middle-click fires `auxclick`, not `click` — route it here so a\n // wheel-click opens the row in a new tab like a real link.\n onAuxClick={clickable ? (e) => (e.button === 1 ? activateRow(row, e) : undefined) : undefined}\n className={cn(typeof rowClassName === 'function' ? rowClassName(row) : rowClassName)}\n >\n {row.getVisibleCells().map((cell) =>\n selectionColumnId != null && cell.column.id === selectionColumnId ? (\n <SelectionCell\n key={cell.id}\n cell={cell}\n isSelected={isSelected}\n resizable={resizable}\n overflowing={overflowing}\n fill={cell.column.id === fillColumnId}\n /*\n ⚠️ Resolved through the LIVE table, not `cell.column`.\n\n `row.getVisibleCells()` hands back cached cells whose `column`\n object can predate the current `columnPinning` state — measured\n directly: after pinning GTIN, the header's column reported\n 'left' while the cell's reported false, so `getPinStyles`\n early-exited and the body kept `position: static` under a frozen\n header sitting over a DIFFERENT column's values. `getColumn(id)`\n goes to the table, which is current.\n */\n pinned={cell.getContext().table.getColumn(cell.column.id)?.getIsPinned() ?? false}\n testId={getCellTestId?.(row.original, cell.column.id)}\n />\n ) : (\n <MemoCell\n key={cell.id}\n cell={cell}\n rowOriginal={row.original}\n resizable={resizable}\n overflowing={overflowing}\n fill={cell.column.id === fillColumnId}\n // Live table, not the cached `cell.column` — see the note above.\n pinned={cell.getContext().table.getColumn(cell.column.id)?.getIsPinned() ?? false}\n testId={getCellTestId?.(row.original, cell.column.id)}\n />\n ),\n )}\n </TableRow>\n );\n}\n\n/**\n * Memoized row wrapper (#1 in the render-perf plan — the core fix). Custom\n * comparator, NOT default shallow: it keys skip-detection on `row.original`\n * (see `MemoCell`'s doc for why the `row` wrapper's own identity is the\n * wrong signal) plus every prop that can legitimately change a row's\n * output — `isSelected`, sizing/overflow flags, the column-layout\n * signature, and the callback props (which MUST be referentially stable\n * across unrelated renders — see `activateRow`'s `useCallback` in\n * `DataTable` and the `volatileRef`-backed callbacks in `resource-list` —\n * or this memo never skips).\n *\n * Composes with `DataTableBody`'s existing resize-skip memo: that one\n * short-circuits the WHOLE body during a live column-resize drag; this one\n * skips individual rows on every other kind of unrelated render (filter\n * visibility, sidebar toggle) and lets `MemoCell`/`SelectionCell` further\n * narrow which CELLS re-render when a row's own props do change (e.g.\n * select-all: the `<tr>` re-renders for `data-state`, but only\n * `SelectionCell` actually re-executes — `MemoCell`, including the\n * `ActionOverflow` kebab, stays frozen).\n */\nconst MemoRow = memo(\n DataRowInner,\n (prev, next) =>\n prev.row.original === next.row.original &&\n prev.row.id === next.row.id &&\n prev.isSelected === next.isSelected &&\n prev.resizable === next.resizable &&\n prev.overflowing === next.overflowing &&\n prev.columnLayoutKey === next.columnLayoutKey &&\n // The filler moves with the column definitions too, which the layout key does not see.\n prev.fillColumnId === next.fillColumnId &&\n prev.selectionColumnId === next.selectionColumnId &&\n prev.getCellTestId === next.getCellTestId &&\n prev.getRowTestId === next.getRowTestId &&\n prev.rowHref === next.rowHref &&\n prev.onRowOpen === next.onRowOpen &&\n prev.activateRow === next.activateRow &&\n prev.rowClassName === next.rowClassName,\n) as typeof DataRowInner;\n\n/** Props for the memoized `<DataTableBody>` — see the comparator below for why `isResizing` is included. */\ninterface DataTableBodyProps<TRow> {\n rows: Row<TRow>[];\n isLoading: boolean;\n loadingRowCount: number;\n visibleColumnCount: number;\n emptyState?: ReactNode;\n /** Resolved `t('table.empty', ...)` string — resolved by the parent so this memoized body needs no `useT`. */\n emptyText: string;\n resizable: boolean;\n overflowing: boolean;\n /** See `DataRowProps.columnLayoutKey`. */\n columnLayoutKey: string;\n /** See `DataRowProps.fillColumnId`. */\n fillColumnId?: string;\n /** See `DataRowProps.selectionColumnId`. */\n selectionColumnId?: string;\n getCellTestId?: (row: TRow, columnId: string) => string | undefined;\n getRowTestId?: (row: TRow) => string | undefined;\n rowHref?: (row: TRow) => string | undefined;\n onRowOpen?: (row: TRow) => boolean;\n activateRow: (row: Row<TRow>, e: React.MouseEvent<HTMLTableRowElement>) => void;\n rowClassName?: ((row: Row<TRow>) => string | undefined) | string;\n /** Whether a column-resize drag is currently live. Read only by the memo comparator below. */\n isResizing: boolean;\n}\n\n/**\n * The `<TableBody>` content, split out of `DataTable` purely so it can be\n * wrapped in `React.memo` (see `DataTableBody` below). Markup, testids, and\n * behaviour are IDENTICAL to the previous inline render — rows now render\n * via `MemoRow` (see above) instead of inline JSX so a body re-render\n * (which still happens on every non-resize table state change, same as\n * before) can skip individual rows/cells that didn't actually change.\n */\nfunction DataTableBodyInner<TRow>({\n rows,\n isLoading,\n loadingRowCount,\n visibleColumnCount,\n emptyState,\n emptyText,\n resizable,\n overflowing,\n columnLayoutKey,\n fillColumnId,\n selectionColumnId,\n getCellTestId,\n getRowTestId,\n rowHref,\n onRowOpen,\n activateRow,\n rowClassName,\n}: DataTableBodyProps<TRow>): React.ReactElement {\n return (\n <TableBody>\n {isLoading ? (\n // Skeleton rows. We render `loadingRowCount` rows with\n // `visibleColumnCount` cells each so the layout doesn't pop\n // when real rows arrive.\n Array.from({ length: loadingRowCount }).map((_, i) => (\n <TableRow key={`skeleton-${i}`} aria-busy=\"true\">\n {Array.from({ length: Math.max(1, visibleColumnCount) }).map((__, j) => (\n <TableCell key={`skeleton-${i}-${j}`}>\n <div className=\"h-4 w-3/4 animate-pulse rounded bg-muted\" />\n </TableCell>\n ))}\n </TableRow>\n ))\n ) : rows.length === 0 ? (\n <TableRow>\n <TableCell colSpan={Math.max(1, visibleColumnCount)} className=\"h-24 text-center\">\n {emptyState ?? <span className=\"text-muted-foreground\">{emptyText}</span>}\n </TableCell>\n </TableRow>\n ) : (\n rows.map((row) => (\n <MemoRow\n key={row.id}\n row={row}\n isSelected={row.getIsSelected()}\n resizable={resizable}\n overflowing={overflowing}\n columnLayoutKey={columnLayoutKey}\n fillColumnId={fillColumnId}\n selectionColumnId={selectionColumnId}\n getCellTestId={getCellTestId}\n getRowTestId={getRowTestId}\n rowHref={rowHref}\n onRowOpen={onRowOpen}\n activateRow={activateRow}\n rowClassName={rowClassName}\n />\n ))\n )}\n </TableBody>\n );\n}\n\n/**\n * Memoized wrapper around `DataTableBodyInner`. The comparator skips\n * re-rendering the body ONLY while a column-resize drag is live — the hot\n * path where every mousemove would otherwise re-render all rows for no\n * visual change (cell widths come from the CSS vars on the table root, see\n * `getPinStyles`). Any NON-resize render behaves exactly as before (the\n * comparator returns `false`, i.e. \"props are NOT equal, re-render\").\n *\n * `React.memo` doesn't preserve generics on its own — the cast back to\n * `typeof DataTableBodyInner` recovers `<TRow>` inference at call sites\n * without resorting to `any` on the public surface.\n */\nconst DataTableBody = memo(DataTableBodyInner, (prev, next) => {\n if (!next.isResizing) return false;\n return (\n prev.rows === next.rows &&\n prev.overflowing === next.overflowing &&\n prev.isLoading === next.isLoading &&\n prev.columnLayoutKey === next.columnLayoutKey &&\n prev.fillColumnId === next.fillColumnId &&\n prev.selectionColumnId === next.selectionColumnId\n );\n}) as typeof DataTableBodyInner;\n\n/**\n * Presentational `<DataTable>` over a TanStack Table v8 instance.\n *\n * Unlike the shadcn-Tasks single-file orchestrator, this component is\n * intentionally kept agnostic about state ownership: callers create the\n * table via `useBuroDataTable(...)` (or vanilla `useReactTable`) and\n * pass the resulting instance in. Composition with the toolbar /\n * pagination / view-options siblings happens in the caller.\n *\n * Testids: resource-agnostic. Callers supply optional `tableTestId`,\n * `getRowTestId(row)`, and `getCellTestId(row, columnId)` callbacks.\n * The future ResourceList migration will plug in the existing\n * `list-table:<resource>` / `list-row:<resource>:<id>` /\n * `list-cell:<resource>:<id>:<col>` patterns via these hooks so the\n * 119+ e2e specs that depend on those testids stay green.\n *\n * Loading state: when `isLoading` is true, the body renders\n * `loadingRowCount` skeleton rows shaped like real rows (same column\n * count). Skeleton cells use a muted block so e2e specs can grep for\n * `[aria-busy=\"true\"]` without depending on row data.\n *\n * Empty / error states: caller-provided `<ReactNode>` slots — keeps\n * the contract simple and lets the parent decide CTA copy / illustration.\n */\nexport interface DataTableProps<TRow> {\n /** TanStack Table v8 instance (typically from `useBuroDataTable`). */\n table: TanStackTable<TRow>;\n\n /** Testid for the `<table>` element. */\n tableTestId?: string;\n\n /** Per-row testid generator. Receives the row's `original` record. */\n getRowTestId?: (row: TRow) => string | undefined;\n\n /** Per-cell testid generator. Receives the row's record and the column id. */\n getCellTestId?: (row: TRow, columnId: string) => string | undefined;\n\n /** When true, body renders a skeleton instead of real rows. */\n isLoading?: boolean;\n loadingRowCount?: number;\n\n /** Slot for the empty state when there are no rows + not loading. */\n emptyState?: ReactNode;\n\n /** Slot for an error banner replacing the body when set. */\n errorState?: ReactNode;\n\n /** Accessible label for screen readers. */\n ariaLabel?: string;\n\n /**\n * Per-row className extension. Receives the TanStack `Row<TRow>` so\n * the caller can vary styling by row state (e.g. `cursor-pointer`\n * when the row has a clickable target, archived/muted treatment for\n * soft-deleted rows). Composed with the TableRow primitive's own\n * classes via `cn`.\n */\n rowClassName?: ((row: Row<TRow>) => string | undefined) | string;\n\n /**\n * Whole-row navigation target (#4). When provided, clicking anywhere on a row\n * (except an interactive element — link, button, checkbox, kebab — or while\n * selecting text) navigates to `rowHref(row)`. Cmd/Ctrl-click and middle-click\n * open it in a NEW TAB, matching native link behaviour. Client-side nav uses\n * `useRouteNavigate()` (the `RouterAdapter`). The row's own ID cell stays a\n * real anchor for keyboard / copy-link, so this is a mouse-affordance layer on\n * top.\n */\n rowHref?: (row: TRow) => string | undefined;\n\n /**\n * A row opener asked before `rowHref` on a plain click (P3-17): `true` means it handled the\n * row (a quick entry opened) and the row does not navigate. A modified click (Cmd/Ctrl,\n * middle) still opens `rowHref` in a new tab.\n */\n onRowOpen?: (row: TRow) => boolean;\n\n /**\n * Enable drag-to-reorder on column headers (#17). When set, headers become\n * draggable and dropping one onto another calls `onColumnReorder(from, to)`.\n * Pinned columns are not draggable (they stay fixed).\n */\n onColumnReorder?: (fromColumnId: string, toColumnId: string) => void;\n\n /**\n * Column id of the row-selection checkbox column, when the caller has one\n * (resource-list passes its `SELECT_COL_ID`). See `DataRowProps` above for\n * why this needs to be threaded through explicitly: it's the one cell that\n * must keep re-rendering when a row's `isSelected` flips, while every\n * other cell (notably the actions kebab) skips. Omit it and every cell —\n * including any selection checkbox — freezes across selection-only\n * renders instead.\n */\n selectionColumnId?: string;\n\n className?: string;\n}\n\nexport function DataTable<TRow>({\n table,\n tableTestId,\n getRowTestId,\n getCellTestId,\n isLoading = false,\n loadingRowCount = 5,\n emptyState,\n errorState,\n rowClassName,\n ariaLabel,\n onColumnReorder,\n rowHref,\n onRowOpen,\n selectionColumnId,\n className,\n}: DataTableProps<TRow>): React.ReactElement {\n const t = useOptionalT();\n const navigate = useRouteNavigate();\n // A new tab is outside the router: its URL keeps the router's basename.\n const toBrowser = useToBrowserHref();\n\n // Whole-row activation (#4). Navigates to `rowHref(row)` unless the click\n // landed on something interactive, or the user was selecting text. Cmd/Ctrl or\n // middle-click open a new tab (native-link parity); a plain click navigates\n // client-side through the RouterAdapter.\n //\n // Wrapped in `useCallback` (NOT a fresh closure per render like the\n // previous inline definition) so it's referentially stable across\n // unrelated `DataTable` renders — `MemoRow`'s comparator includes it, and\n // an unstable callback here would defeat the row memo on every render\n // regardless of what else changed. Depends only on `rowHref` (stable when\n // the caller routes it through a ref — see resource-list) and `navigate`.\n const activateRow = useCallback(\n (row: Row<TRow>, e: React.MouseEvent<HTMLTableRowElement>): void => {\n const target = e.target as HTMLElement | null;\n // React dispatches synthetic events along the REACT tree, not the DOM\n // tree. Content rendered through a `Portal` (Dialog, DropdownMenu,\n // Select, Tooltip) lives under `document.body` in the DOM but is still\n // a React descendant of whatever cell renders it, so a click inside a\n // portalled dialog still bubbles here. Reject anything that isn't a DOM\n // descendant of this row FIRST — before asking whether it's on an\n // \"interactive\" element — so the whole portalled subtree is out of\n // scope, not just the specific controls the allowlist below happens to\n // name. `e.currentTarget` is the `<tr>` itself.\n if (target && !e.currentTarget.contains(target)) return;\n // Don't hijack clicks on real controls (the ID anchor, relation links, the\n // row checkbox, the actions kebab, form controls) — they handle themselves.\n if (\n target?.closest(\n 'a, button, input, label, select, textarea, [role=\"checkbox\"], [role=\"menuitem\"], [data-no-row-nav]',\n )\n ) {\n return;\n }\n // A click that ends a text selection shouldn't navigate.\n if (typeof window !== 'undefined' && (window.getSelection?.()?.toString().length ?? 0) > 0) {\n return;\n }\n const modified = e.metaKey || e.ctrlKey || e.button === 1;\n if (!modified && onRowOpen?.(row.original) === true) return;\n const href = rowHref?.(row.original);\n if (!href) return;\n if (modified) {\n e.preventDefault();\n if (typeof window !== 'undefined') window.open(toBrowser(href), '_blank', 'noopener');\n return;\n }\n navigate(href);\n },\n [rowHref, onRowOpen, navigate, toBrowser],\n );\n const rows = table.getRowModel().rows;\n const headerGroups = table.getHeaderGroups();\n const visibleColumnCount = table.getVisibleLeafColumns().length;\n // Serialized visible-column layout (id + pinned side), recomputed every\n // render — cheap (a handful of columns) and compares by VALUE, not\n // reference, so `MemoRow` only sees it as \"changed\" when a column was\n // actually hidden/shown/reordered/pinned. Without this, hiding a column\n // wouldn't touch `row.original` or `isSelected`, and an untouched row\n // would incorrectly skip re-rendering — stale DOM still showing the\n // hidden column's cell.\n //\n // Deliberately does NOT include pinned column SIZING/offset — that's a\n // CSS var now (`--col-{id}-left` / `--col-{id}-right`, see\n // `columnSizeVars` below and `getPinStyles`), so a pinned-column resize\n // updates the affected cells' sticky position purely via CSS, with zero\n // row/cell re-renders. Folding the offset in here (an earlier version of\n // this fix did) meant a LIVE pinned-column drag changed this key on every\n // mousemove tick, which defeated `MemoRow`'s skip and reintroduced the\n // exact per-tick, all-rows re-render the body memo exists to eliminate.\n // The filler (REF-117 §4.8) — recomputed every render, like the key below, since it moves with\n // visibility, pinning and the column definitions alike.\n // The body and rows compare it as `fillColumnId` (its cells drop their explicit width).\n const fillId = tableFillColumnId(table);\n const columnLayoutKey = table\n .getVisibleLeafColumns()\n .map((c) => `${c.id}:${c.getIsPinned() || ''}`)\n .join('|');\n const resizable = table.options.enableColumnResizing === true;\n // The sum of the visible widths, the filler's own included as its floor. Read live, so a drag\n // moves the table's width with the dragged column.\n const widthSum = resizable\n ? table.getVisibleLeafColumns().reduce((sum, c) => sum + c.getSize(), 0)\n : 0;\n const hasPinned =\n table.getState().columnPinning != null &&\n (table.getState().columnPinning.left?.length || table.getState().columnPinning.right?.length);\n\n // Per-column CSS variables, set once on the table root so a resize drag\n // updates styling without re-rendering every cell (TanStack's performant\n // pattern). Reading columnSizing + columnSizingInfo + columnPinning\n // establishes reactivity so the map recomputes on committed sizes AND live\n // during a drag, and whenever pinning changes.\n const sizingState = table.getState().columnSizing;\n const sizingInfo = table.getState().columnSizingInfo;\n const pinningState = table.getState().columnPinning;\n // The column definitions too: a definition's own `size` can change without any sizing state\n // moving (a list's actions column narrows with its container).\n const columnDefs = table.options.columns;\n const columnSizeVars = useMemo(() => {\n const vars: Record<string, string> = {};\n if (resizable) {\n for (const header of table.getFlatHeaders()) {\n vars[`--col-${header.column.id}-size`] = String(header.column.getSize());\n }\n }\n // Pinned-column sticky offsets, as CSS vars — same pattern as the width\n // vars above (see `getPinStyles`'s doc for why this matters beyond\n // consistency: it's what lets a live pinned-column drag update every\n // later same-side pinned cell with ZERO re-renders). Computed for every\n // pinned leaf regardless of `resizable`/`overflowing` — cheap (a\n // handful of columns at most), and `getPinStyles` only ever reads them\n // when the table is actually overflowing.\n for (const c of table.getVisibleLeafColumns()) {\n const pinned = c.getIsPinned();\n if (pinned === 'left') vars[`--col-${c.id}-left`] = String(c.getStart('left'));\n else if (pinned === 'right') vars[`--col-${c.id}-right`] = String(c.getAfter('right'));\n }\n return vars;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [resizable, sizingState, sizingInfo, pinningState, visibleColumnCount, columnDefs]);\n\n // Horizontal-overflow detection — sticky styling only activates when the\n // table is actually wider than its scroll container. The\n // `<Table>` primitive already provides the `overflow-auto` scroll container\n // (the table's parentElement), so we measure against that. Uses a\n // ResizeObserver on the scroller — a plain `window.resize` listener misses the\n // sidebar collapsing/expanding, which changes the container width but not the\n // window's.\n const tableRef = useRef<HTMLTableElement>(null);\n // #17 resize-vs-reorder guard. A header is HTML5-`draggable` for reorder, and\n // the resize grip lives INSIDE that header, so a mousedown on the grip also\n // arms a native column drag — the resize \"sticks\" to a drag ghost and you\n // can't size the column until you release and re-grab. Set on grip\n // mousedown/touchstart so the header's `onDragStart` can bail; cleared on\n // pointer up (the resize itself ends on the document's mouseup too).\n const resizingRef = useRef(false);\n useEffect(() => {\n const clear = () => {\n resizingRef.current = false;\n // Safety net: TanStack ends a resize on a document mouseup; if that\n // never arrives (pointer released off-page over devtools/OS chrome, or\n // the tab is hidden/blurred mid-drag), `isResizingColumn` stays truthy\n // forever — and the memoized `DataTableBody` skips re-renders while a\n // resize is \"live\", so a later selection/column change would silently\n // freeze stale until a refresh. Clear it on any drag-end SIGNAL (not\n // just mouseup/touchend) so it can never get stuck. Guarded so the\n // normal path — TanStack already cleared it on its own mouseup — is a\n // no-op and doesn't force an extra render on every plain click.\n if (table.getState().columnSizingInfo.isResizingColumn) {\n table.setColumnSizingInfo((prev) => ({ ...prev, isResizingColumn: false }));\n }\n };\n window.addEventListener('mouseup', clear);\n window.addEventListener('touchend', clear);\n window.addEventListener('blur', clear);\n document.addEventListener('visibilitychange', clear);\n return () => {\n window.removeEventListener('mouseup', clear);\n window.removeEventListener('touchend', clear);\n window.removeEventListener('blur', clear);\n document.removeEventListener('visibilitychange', clear);\n };\n }, [table]);\n const [overflowing, setOverflowing] = useState(false);\n useEffect(() => {\n if (!hasPinned) {\n setOverflowing(false);\n return;\n }\n const check = () => {\n const tbl = tableRef.current;\n const scroller = tbl?.parentElement;\n if (!tbl || !scroller) return;\n setOverflowing(tbl.offsetWidth > scroller.clientWidth);\n };\n check();\n const id = setTimeout(check, 100);\n const tbl = tableRef.current;\n const scroller = tbl?.parentElement;\n const ro = typeof ResizeObserver !== 'undefined' ? new ResizeObserver(check) : null;\n // Observe BOTH the scroll container AND the table itself. Watching only the\n // container misses the case that actually creates the overflow: resizing a\n // COLUMN grows the table's own width while the container's stays fixed, so\n // the container-only observer never fired and the sticky pins didn't engage\n // until some unrelated re-render (hide/show a column) re-ran this effect.\n // The table's ResizeObserver fires on every resize frame, so pins now turn\n // sticky the instant the widths overflow. (Sticky positioning doesn't change\n // offsetWidth, so this can't feed back into a loop.)\n if (scroller) ro?.observe(scroller);\n if (tbl) ro?.observe(tbl);\n window.addEventListener('resize', check);\n return () => {\n clearTimeout(id);\n ro?.disconnect();\n window.removeEventListener('resize', check);\n };\n }, [hasPinned, rows.length, visibleColumnCount]);\n\n // Error takes precedence: caller renders the error UI in place of the\n // table body. Header still renders so column structure stays visible.\n if (errorState) {\n return (\n <div className={cn('space-y-2', className)}>\n <Table data-testid={tableTestId} aria-label={ariaLabel}>\n <TableHeader>\n {headerGroups.map((hg) => (\n <TableRow key={hg.id}>\n {hg.headers.map((header) => (\n <TableHead key={header.id} colSpan={header.colSpan}>\n {header.isPlaceholder\n ? null\n : flexRender(header.column.columnDef.header, header.getContext())}\n </TableHead>\n ))}\n </TableRow>\n ))}\n </TableHeader>\n </Table>\n {errorState}\n </div>\n );\n }\n\n return (\n <Table\n ref={tableRef}\n data-testid={tableTestId}\n aria-label={ariaLabel}\n className={className}\n // The spare-width rule (REF-117 §4.8): with a filler, `max(100%, <sum>px)` fills the\n // container and the width-less filler takes the slack; past the container the table grows\n // and the wrapper scrolls. Without one the table is exactly the sum of its widths: no\n // `min-width: 100%`, which would spread the slack over every column, icons included.\n style={\n resizable\n ? {\n ...columnSizeVars,\n width: fillId !== undefined ? `max(100%, ${widthSum}px)` : `${widthSum}px`,\n tableLayout: 'fixed',\n }\n : undefined\n }\n >\n <TableHeader>\n {headerGroups.map((hg) => (\n <TableRow key={hg.id}>\n {hg.headers.map((header) => {\n // Derive aria-sort from TanStack column state when sortable —\n // preserves the existing ResourceList accessibility contract\n // (and the preflight-sort.spec.ts assertion).\n const sorted = header.column.getCanSort() ? header.column.getIsSorted() : false;\n const ariaSort: 'ascending' | 'descending' | 'none' | undefined =\n header.column.getCanSort()\n ? sorted === 'asc'\n ? 'ascending'\n : sorted === 'desc'\n ? 'descending'\n : 'none'\n : undefined;\n // Every column with resizing enabled gets a grip — including the\n // first/ID column. Service columns opt out via enableResizing:false\n // (getCanResize()), not by being a special \"flex\" column.\n const canResize = resizable && header.column.getCanResize();\n // Reorderable only when a handler is set AND the column isn't\n // pinned (pinned columns stay put) or a service column.\n const canReorder =\n onColumnReorder != null &&\n !header.column.getIsPinned() &&\n !header.column.id.startsWith('__');\n return (\n <TableHead\n key={header.id}\n colSpan={header.colSpan}\n aria-sort={ariaSort}\n style={getPinStyles(header.column, overflowing, header.column.id === fillId)}\n className={cn(\n 'relative',\n /*\n Clip the header label too, so a long column title doesn't\n run into its neighbour in the fixed layout — but not on\n the pinned edge, where the clip would eat the shadow that\n now falls OUTSIDE the cell. The `truncate` on the label\n itself still does the clipping either way.\n */\n /*\n A `noClip` column is exempt on both counts, so its `<th>`\n and its `<td>` stay the same shape (see\n `columnMetaNoClip`) — a header that holds a control has\n the same reachability problem a body cell does.\n */\n resizable &&\n !columnMetaNoClip(header.column.columnDef.meta) &&\n (pinEdgeClassFor(header.column, overflowing)\n ? '[&>*:not([data-testid^=col-resize])]:truncate'\n : 'overflow-hidden [&>*:not([data-testid^=col-resize])]:truncate'),\n canReorder && 'cursor-grab',\n pinEdgeClassFor(header.column, overflowing),\n columnMetaClassName(header.column.columnDef.meta),\n )}\n draggable={canReorder || undefined}\n onDragStart={\n canReorder\n ? (e) => {\n // A resize started on the grip → cancel the drag the\n // browser is trying to begin on this draggable header.\n if (resizingRef.current) {\n e.preventDefault();\n return;\n }\n e.dataTransfer.setData('text/plain', header.column.id);\n }\n : undefined\n }\n onDragOver={canReorder ? (e) => e.preventDefault() : undefined}\n onDrop={\n canReorder\n ? (e) => {\n e.preventDefault();\n const from = e.dataTransfer.getData('text/plain');\n if (from && from !== header.column.id)\n onColumnReorder(from, header.column.id);\n }\n : undefined\n }\n >\n {header.isPlaceholder\n ? null\n : flexRender(header.column.columnDef.header, header.getContext())}\n {canResize && (\n // WAI-ARIA APG \"Resizable Grid\" pattern: a column-resize grip\n // is a `separator` between two columns, keyboard-operable via\n // the arrow keys and describing its current/min/max width so\n // it isn't a bare static `div` with only a mouse handler.\n <div\n role=\"separator\"\n aria-orientation=\"vertical\"\n aria-label={t('table.resizeColumn', { defaultValue: 'Resize column' })}\n aria-valuenow={Math.round(header.column.getSize())}\n aria-valuemin={header.column.columnDef.minSize ?? 20}\n aria-valuemax={header.column.columnDef.maxSize ?? Number.MAX_SAFE_INTEGER}\n tabIndex={0}\n onMouseDown={(e) => {\n resizingRef.current = true;\n header.getResizeHandler()(e);\n }}\n onTouchStart={(e) => {\n resizingRef.current = true;\n header.getResizeHandler()(e);\n }}\n onKeyDown={(e) => {\n if (e.key !== 'ArrowLeft' && e.key !== 'ArrowRight') return;\n e.preventDefault();\n const min = header.column.columnDef.minSize ?? 20;\n const max = header.column.columnDef.maxSize ?? Number.MAX_SAFE_INTEGER;\n const step = e.key === 'ArrowRight' ? 10 : -10;\n table.setColumnSizing((prev) => ({\n ...prev,\n [header.column.id]: Math.min(\n max,\n Math.max(min, header.column.getSize() + step),\n ),\n }));\n }}\n draggable={false}\n onDragStart={(e) => e.preventDefault()}\n data-testid={`col-resize:${header.column.id}`}\n className={cn(\n 'absolute right-0 top-0 h-full w-1 cursor-col-resize touch-none select-none opacity-0 transition-opacity hover:opacity-100 focus-visible:opacity-100',\n header.column.getIsResizing() ? 'bg-primary opacity-100' : 'bg-border',\n )}\n />\n )}\n </TableHead>\n );\n })}\n </TableRow>\n ))}\n </TableHeader>\n <DataTableBody\n rows={rows}\n isLoading={isLoading}\n loadingRowCount={loadingRowCount}\n visibleColumnCount={visibleColumnCount}\n emptyState={emptyState}\n emptyText={t('table.empty', { defaultValue: 'No records' })}\n resizable={resizable}\n overflowing={overflowing}\n columnLayoutKey={columnLayoutKey}\n fillColumnId={fillId}\n selectionColumnId={selectionColumnId}\n isResizing={Boolean(sizingInfo.isResizingColumn)}\n getCellTestId={getCellTestId}\n getRowTestId={getRowTestId}\n rowHref={rowHref}\n onRowOpen={onRowOpen}\n activateRow={activateRow}\n rowClassName={rowClassName}\n />\n </Table>\n );\n}\n","'use client';\nimport type * as React from 'react';\nimport {\n IconArrowDown,\n IconArrowLeft,\n IconArrowRight,\n IconArrowUp,\n IconSelector,\n IconEyeOff,\n IconPinned,\n IconPinnedOff,\n IconX,\n} from '@tabler/icons-react';\nimport { useOptionalT } from '@burojs/react';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '../primitives/dropdown-menu.js';\nimport { cn } from '../lib/cn.js';\n\nexport type PinSide = 'left' | 'right' | false;\nexport type SortDirection = 'asc' | 'desc' | null;\n\n/**\n * Column header as a MENU (#17): clicking a header\n * opens a dropdown to sort (explicit asc/desc, not a blind toggle), pin the\n * column left/right, or hide it — instead of a single click cycling the sort.\n */\nexport interface ColumnHeaderMenuProps {\n label: React.ReactNode;\n /** Current sort direction for THIS column, or null when it isn't the sort key. */\n sortDirection: SortDirection;\n sortable: boolean;\n onSort?: (direction: SortDirection) => void;\n pinned: PinSide;\n onPin?: (side: PinSide) => void;\n canHide: boolean;\n onHide?: () => void;\n /** Reorder this column one slot. `canMoveLeft/Right` gate the items. */\n onMove?: (dir: 'left' | 'right') => void;\n canMoveLeft?: boolean;\n canMoveRight?: boolean;\n testid?: string;\n}\n\nexport function ColumnHeaderMenu({\n label,\n sortDirection,\n sortable,\n onSort,\n pinned,\n onPin,\n canHide,\n onHide,\n onMove,\n canMoveLeft,\n canMoveRight,\n testid,\n}: ColumnHeaderMenuProps): React.ReactElement {\n const t = useOptionalT();\n const tr = (key: string, fallback: string) => t?.(key, { defaultValue: fallback }) ?? fallback;\n\n const SortGlyph =\n sortDirection === 'asc' ? IconArrowUp : sortDirection === 'desc' ? IconArrowDown : IconSelector;\n const canMove = onMove && (canMoveLeft || canMoveRight);\n const hasActions = sortable || onPin || canMove || (canHide && onHide);\n\n // Nothing actionable → render a plain label (no menu affordance).\n if (!hasActions) return <>{label}</>;\n\n return (\n // Non-modal: a modal dropdown locks `pointer-events` on <body> during its\n // close animation, so a rapid re-open (sorting a column twice in a row)\n // could miss the next trigger click. A header menu never needs to trap the\n // page anyway.\n <DropdownMenu modal={false}>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n data-testid={testid}\n className=\"-mx-1 inline-flex items-center gap-1.5 rounded px-1 transition-colors hover:text-foreground focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring data-[state=open]:text-foreground\"\n >\n <span className=\"truncate\">{label}</span>\n <span\n className={cn(\n 'inline-flex shrink-0',\n sortDirection ? 'text-foreground' : 'text-muted-foreground/70',\n )}\n aria-hidden=\"true\"\n >\n <SortGlyph className=\"size-3.5\" />\n </span>\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n align=\"start\"\n className=\"w-48\"\n /*\n ⚠️ Restore focus to the trigger BY TESTID, not by the node reference\n Radix captured.\n\n Sorting re-renders the header, so by the time the menu closes the\n element Radix saved has been replaced and its `.focus()` is a no-op —\n focus lands on <body>. A keyboard-only acceptance pass measured the\n cost: 40 Tab presses to get back to the same header button, on an\n action an operator performs dozens of times a day. Same fall-through\n after closing the menu with Escape.\n\n The testid is stable across the remount, so re-querying finds the NEW\n node. `preventDefault` stops Radix's own restore from fighting this.\n */\n onCloseAutoFocus={(event) => {\n if (!testid) return;\n event.preventDefault();\n // One frame, so the re-render caused by the chosen action has landed. Only when focus\n // has nowhere better to be: the menu closes after its exit animation, and by then the\n // user may already have opened something else (another menu, a dialog), which a\n // restore would close by stealing its focus.\n requestAnimationFrame(() => {\n const active = document.activeElement;\n if (active !== null && active !== document.body) return;\n document.querySelector<HTMLElement>(`[data-testid=\"${CSS.escape(testid)}\"]`)?.focus();\n });\n }}\n >\n {/* Grouped into labeled sections (Sort / Pin / Move / Hide) so\n item labels can stay short — the section header carries the verb,\n avoiding long strings like \"Move left\" that forced a wide menu. */}\n {sortable && onSort && (\n <DropdownMenuGroup>\n <DropdownMenuLabel className=\"text-xs font-medium text-muted-foreground\">\n {tr('columnMenu.sortSection', 'Sort')}\n </DropdownMenuLabel>\n <DropdownMenuItem\n onClick={() => onSort('asc')}\n data-testid={testid ? `${testid}:sort-asc` : undefined}\n >\n <IconArrowUp className=\"mr-2 size-4 text-muted-foreground\" />\n {tr('columnMenu.sortAsc', 'Ascending')}\n </DropdownMenuItem>\n <DropdownMenuItem\n onClick={() => onSort('desc')}\n data-testid={testid ? `${testid}:sort-desc` : undefined}\n >\n <IconArrowDown className=\"mr-2 size-4 text-muted-foreground\" />\n {tr('columnMenu.sortDesc', 'Descending')}\n </DropdownMenuItem>\n {sortDirection && (\n <DropdownMenuItem onClick={() => onSort(null)}>\n <IconX className=\"mr-2 size-4 text-muted-foreground\" />\n {tr('columnMenu.clearSort', 'Clear')}\n </DropdownMenuItem>\n )}\n </DropdownMenuGroup>\n )}\n {onPin && (\n <>\n {sortable && onSort && <DropdownMenuSeparator />}\n <DropdownMenuGroup>\n <DropdownMenuLabel className=\"text-xs font-medium text-muted-foreground\">\n {tr('columnMenu.pinSection', 'Pin')}\n </DropdownMenuLabel>\n {pinned !== 'left' && (\n <DropdownMenuItem\n onClick={() => onPin('left')}\n data-testid={testid ? `${testid}:pin-left` : undefined}\n >\n <IconPinned className=\"mr-2 size-4 text-muted-foreground\" />\n {tr('columnMenu.pinLeft', 'Left')}\n </DropdownMenuItem>\n )}\n {pinned !== 'right' && (\n <DropdownMenuItem onClick={() => onPin('right')}>\n <IconPinned className=\"mr-2 size-4 -scale-x-100 text-muted-foreground\" />\n {tr('columnMenu.pinRight', 'Right')}\n </DropdownMenuItem>\n )}\n {pinned !== false && (\n <DropdownMenuItem\n onClick={() => onPin(false)}\n data-testid={testid ? `${testid}:unpin` : undefined}\n >\n <IconPinnedOff className=\"mr-2 size-4 text-muted-foreground\" />\n {tr('columnMenu.unpin', 'Unpin')}\n </DropdownMenuItem>\n )}\n </DropdownMenuGroup>\n </>\n )}\n {canMove && (\n <>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuLabel className=\"text-xs font-medium text-muted-foreground\">\n {tr('columnMenu.moveSection', 'Move')}\n </DropdownMenuLabel>\n {canMoveLeft && (\n <DropdownMenuItem\n onClick={() => onMove?.('left')}\n data-testid={testid ? `${testid}:move-left` : undefined}\n >\n <IconArrowLeft className=\"mr-2 size-4 text-muted-foreground\" />\n {tr('columnMenu.moveLeft', 'Left')}\n </DropdownMenuItem>\n )}\n {canMoveRight && (\n <DropdownMenuItem\n onClick={() => onMove?.('right')}\n data-testid={testid ? `${testid}:move-right` : undefined}\n >\n <IconArrowRight className=\"mr-2 size-4 text-muted-foreground\" />\n {tr('columnMenu.moveRight', 'Right')}\n </DropdownMenuItem>\n )}\n </DropdownMenuGroup>\n </>\n )}\n {canHide && onHide && (\n <>\n <DropdownMenuSeparator />\n <DropdownMenuItem onClick={onHide} data-testid={testid ? `${testid}:hide` : undefined}>\n <IconEyeOff className=\"mr-2 size-4 text-muted-foreground\" />\n {tr('columnMenu.hide', 'Hide column')}\n </DropdownMenuItem>\n </>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n","import type { RowRecord } from '@burojs/react';\n\n/**\n * How a list column reads its value from a row. A dotted column (`code_id.gtin`) reads the flat\n * key the provider returns (`row['code_id.gtin']`) through `accessorFn`: TanStack splits a dotted\n * `accessorKey` into nested access (`row.code_id.gtin`), which finds nothing.\n */\nexport function columnAccessor(\n column: string,\n): { readonly accessorFn: (row: RowRecord) => unknown } | { readonly accessorKey: string } {\n return column.includes('.') ? { accessorFn: (row) => row[column] } : { accessorKey: column };\n}\n","import type { EntityRef, I18nCaps, Registry } from '@burojs/core';\nimport { resolveColumnField } from '@burojs/react';\n\n/** The field a dotted list column draws, read across its to-one relations. */\nexport interface ColumnTarget {\n /** The target field's declaration: its renderer, size and label. */\n readonly field: unknown;\n /** The target field's name on its own resource (the column's last segment). */\n readonly name: string;\n /** The registry name of the resource holding the field. */\n readonly resource: string;\n readonly ref: EntityRef;\n}\n\n/**\n * The target of a dotted column of `resource` (`code_id.gtin` → `code_code.gtin`), or undefined\n * for a column that names no field across declared to-one relations.\n */\nexport function columnTarget(\n registry: Pick<Registry, 'get'>,\n resource: string,\n column: string,\n): ColumnTarget | undefined {\n if (!column.includes('.')) return undefined;\n const resolved = resolveColumnField(registry, resource, column);\n if (resolved === undefined) return undefined;\n const ref = registry.get(resolved.resource as never)?.ref ?? {\n namespace: 'default',\n id: resolved.resource,\n };\n return {\n field: resolved.field,\n name: column.slice(column.lastIndexOf('.') + 1),\n resource: resolved.resource,\n ref,\n };\n}\n\n/** `caps` reading a field's content (`fields.<name>.*`) of another resource. */\nexport function capsOf(caps: I18nCaps, resource: string): I18nCaps {\n return {\n has: (key, options) => caps.has(key, { ...options, resource: options?.resource ?? resource }),\n t: (key, options) => caps.t(key, { ...options, resource: options?.resource ?? resource }),\n };\n}\n","'use client';\nimport {\n type ColumnDef,\n type ColumnFiltersState,\n type ColumnOrderState,\n type ColumnPinningState,\n type ColumnSizingState,\n type OnChangeFn,\n type PaginationState,\n type Row,\n type RowSelectionState,\n type SortingState,\n type Table,\n type Updater,\n type VisibilityState,\n getCoreRowModel,\n getFacetedRowModel,\n getFacetedUniqueValues,\n useReactTable,\n} from '@tanstack/react-table';\nimport type { ErasedResourceHandle, FilterOperator, SortExpression } from '@burojs/core';\nimport { useMemo } from 'react';\n\n/**\n * Options for `useBuroDataTable` — the bridge between a native Buro\n * list controller and TanStack Table v8.\n *\n * Architectural contract (preserved across the Stage-1 migration):\n * - The hook stays presentational. Sorting / pagination / column-visibility\n * / selection state ALL live in the parent (which feeds them to\n * `useList` for the actual fetch).\n * - Server-side mode: `manualSorting`, `manualFiltering`,\n * `manualPagination` are forced on. Row models are computed from the\n * page `useList` returned, not on the full result set.\n * - `pageCount` is derived from `total` (from `useList`) and `pagination.pageSize`.\n * When `total` is undefined the hook returns `pageCount: -1` — TanStack's\n * own convention for \"unknown page count\" — rather than guessing from\n * `data.length` (the current page's length, not the total row count).\n * Callers get a working table that can still page forward; they just\n * cannot render a last-page jump or a grand total.\n * - `getRowId` defaults to `(r) => String(r.id)`. This is mandatory for\n * stable testid generation (every list-row testid in the e2e suite is\n * `list-row:<resource>:<id>`) and for selection state to survive the\n * refetch that happens on page / sort / filter change.\n */\nexport interface UseBuroDataTableOptions<TRow> {\n /** Current page of rows from the native list controller. */\n data: TRow[];\n\n /** Column definitions. Use `meta.testid` to drive future testid generation. */\n columns: ColumnDef<TRow, unknown>[];\n\n /** Total row count from the controller — required for accurate `pageCount`. */\n total?: number;\n\n /** Defaults to `(r) => String(r.id)`. */\n getRowId?: (row: TRow, index: number, parent?: Row<TRow>) => string;\n\n /** TanStack pagination state, owned by the caller. */\n pagination: PaginationState;\n onPaginationChange: OnChangeFn<PaginationState>;\n\n /** TanStack sorting state, owned by the caller. */\n sorting: SortingState;\n onSortingChange: OnChangeFn<SortingState>;\n\n /**\n * Optional column-filters state. `useBuroDataTable` no longer ships a\n * bridge to native filter expressions (that lived in\n * `tanStackFiltersToExpression` / `filterExpressionsToTanStack`, both\n * removed — the framework's filters now live in `FilterRegion`, not\n * TanStack `ColumnFiltersState`). This passthrough stays for adopters\n * composing their OWN table out of the standalone `data-table/*`\n * filter components (`DataTableTextFilter`, `DataTableOperatorFilter`,\n * etc.), which write straight to TanStack's `column.setFilterValue`\n * and need a controlled `columnFilters` state to read that back from.\n */\n columnFilters?: ColumnFiltersState;\n onColumnFiltersChange?: OnChangeFn<ColumnFiltersState>;\n\n /** Optional column-visibility state. */\n columnVisibility?: VisibilityState;\n onColumnVisibilityChange?: OnChangeFn<VisibilityState>;\n\n /** Optional row-selection state. */\n rowSelection?: RowSelectionState;\n onRowSelectionChange?: OnChangeFn<RowSelectionState>;\n\n /** When false, the per-row checkbox column is omitted by callers. */\n enableRowSelection?: boolean;\n\n /** Optional column-pinning state (#17). Left/right sticky columns. */\n columnPinning?: ColumnPinningState;\n onColumnPinningChange?: OnChangeFn<ColumnPinningState>;\n\n /** Optional column-sizing state (#17). Pixel widths per column. */\n columnSizing?: ColumnSizingState;\n onColumnSizingChange?: OnChangeFn<ColumnSizingState>;\n\n /** Optional column-order state (#17). */\n columnOrder?: ColumnOrderState;\n onColumnOrderChange?: OnChangeFn<ColumnOrderState>;\n\n /** Turn on interactive column resizing (#17). Off by default (BC). */\n enableColumnResizing?: boolean;\n}\n\n/**\n * Builds a TanStack Table v8 instance wired to native server-side data\n * flow. The caller drives state via the callbacks; this hook does NOT\n * own state, so it is safe to compose with the existing `useList` hook\n * without an extra source of truth.\n *\n * Returns the `Table<TRow>` instance for direct consumption by the\n * data-table composition components (DataTable, DataTableViewOptions,\n * etc.).\n */\nexport function useBuroDataTable<TRow>(opts: UseBuroDataTableOptions<TRow>): Table<TRow> {\n const {\n data,\n columns,\n total,\n getRowId,\n pagination,\n onPaginationChange,\n sorting,\n onSortingChange,\n columnFilters,\n onColumnFiltersChange,\n columnVisibility,\n onColumnVisibilityChange,\n rowSelection,\n onRowSelectionChange,\n enableRowSelection,\n columnPinning,\n onColumnPinningChange,\n columnSizing,\n onColumnSizingChange,\n columnOrder,\n onColumnOrderChange,\n enableColumnResizing,\n } = opts;\n\n // Server-side `pageCount`. `pageCount: -1` is the TanStack convention\n // for \"unknown count\" — adopters that cannot supply `total` get a\n // working table with infinite-scroll-style pagination semantics.\n const pageCount = useMemo<number>(() => {\n if (total == null) return -1;\n if (pagination.pageSize <= 0) return -1;\n return Math.max(1, Math.ceil(total / pagination.pageSize));\n }, [total, pagination.pageSize]);\n\n const resolvedGetRowId = useMemo<NonNullable<UseBuroDataTableOptions<TRow>['getRowId']>>(\n () =>\n getRowId ??\n ((row) => {\n const id = (row as { id?: unknown }).id;\n return id == null ? '' : String(id);\n }),\n [getRowId],\n );\n\n // A column's declared `size` doubles as its resize FLOOR unless it declares an\n // explicit `minSize`: the base width the app chose is the smallest sensible\n // width, so the user can widen but not shrink a column below its content. (#17)\n const normalizedColumns = useMemo(\n () =>\n columns.map((c) =>\n c.size != null && (c as { minSize?: number }).minSize == null\n ? { ...c, minSize: c.size }\n : c,\n ),\n [columns],\n );\n\n return useReactTable<TRow>({\n data,\n columns: normalizedColumns,\n // Unset content columns default to a sensible base + a floor well above\n // TanStack's tiny 20px, so a column never collapses to nothing.\n defaultColumn: { size: 160, minSize: 90 },\n pageCount,\n state: {\n pagination,\n sorting,\n ...(columnFilters !== undefined ? { columnFilters } : {}),\n ...(columnVisibility !== undefined ? { columnVisibility } : {}),\n ...(rowSelection !== undefined ? { rowSelection } : {}),\n ...(columnPinning !== undefined ? { columnPinning } : {}),\n ...(columnSizing !== undefined ? { columnSizing } : {}),\n ...(columnOrder !== undefined ? { columnOrder } : {}),\n },\n enableRowSelection: enableRowSelection ?? rowSelection !== undefined,\n ...(enableColumnResizing\n ? { enableColumnResizing: true, columnResizeMode: 'onChange' as const }\n : {}),\n getRowId: resolvedGetRowId,\n onPaginationChange,\n onSortingChange,\n ...(onColumnFiltersChange ? { onColumnFiltersChange } : {}),\n ...(onColumnVisibilityChange ? { onColumnVisibilityChange } : {}),\n ...(onRowSelectionChange ? { onRowSelectionChange } : {}),\n ...(onColumnPinningChange ? { onColumnPinningChange } : {}),\n ...(onColumnSizingChange ? { onColumnSizingChange } : {}),\n ...(onColumnOrderChange ? { onColumnOrderChange } : {}),\n // Server-side: the runtime fetches one page at a time, so we must not\n // sort / filter / paginate the in-memory rows again client-side.\n manualPagination: true,\n manualSorting: true,\n manualFiltering: true,\n getCoreRowModel: getCoreRowModel(),\n // Faceted models stay client-side: they reflect the values present\n // on the CURRENT page only, which is the right scope for the\n // upcoming `<DataTableFacetedFilter>` UI on a server-driven list.\n getFacetedRowModel: getFacetedRowModel(),\n getFacetedUniqueValues: getFacetedUniqueValues(),\n });\n}\n\n/**\n * Convert a native `SortExpression` (server shape)\n * into TanStack's `SortingState`. Lossless one-to-one mapping.\n */\nexport function buroSortingToTanStack(\n sorters: SortExpression<ErasedResourceHandle> | undefined,\n): SortingState {\n if (!sorters || sorters.length === 0) return [];\n return sorters.map((s) => ({ id: s.field, desc: s.direction === 'desc' }));\n}\n\n/**\n * Convert TanStack's `SortingState` back into a native `SortExpression`.\n * Lossless inverse of `buroSortingToTanStack`.\n */\nexport function tanStackSortingToBuro(state: SortingState): SortExpression<ErasedResourceHandle> {\n return state.map((s) => ({ field: s.id, direction: s.desc ? 'desc' : 'asc' }));\n}\n\n/**\n * Practical operator vocabulary. Excludes the logical connectives `or` /\n * `and` (those belong on `ConditionalFilter`, not on a single column) and\n * the rarely-used case-sensitive `*s` variants the filter UI does not yet\n * expose. Stage-2 callers can widen this when they wire a column that\n * needs one.\n *\n * Moved to `@burojs/core` (B1.1) so the framework's list controller can\n * depend on it without importing `@burojs/ui-shadcn`. Re-exported from\n * this module path — not merely from this package's `index.ts` — because\n * several files import `FilterOperator` directly from\n * `./use-buro-data-table.js`.\n */\nexport type { FilterOperator };\n\n/**\n * Resolves a TanStack `Updater<T>` value (which can be a function or\n * a plain value) against a previous state — used by callers writing\n * onXxxChange callbacks that want to forward the update plus their\n * own derived state changes.\n *\n * @example\n * ```tsx\n * onSortingChange={(updater) => {\n * const next = resolveUpdater(updater, sorting);\n * setSorting(next);\n * setPage(1); // also reset pagination on sort change\n * }}\n * ```\n */\nexport function resolveUpdater<T>(updater: Updater<T>, prev: T): T {\n return typeof updater === 'function' ? (updater as (p: T) => T)(prev) : updater;\n}\n","'use client';\nimport { LoadError } from '../load-error/load-error-view.js';\n\nexport interface ListErrorStateProps {\n /** Whatever the query threw. */\n error: unknown;\n /** When provided, a Retry button is rendered and calls this. */\n onRetry?: () => void;\n /** Resource name, used to build the retry button's test id. */\n resource?: string;\n /** Overrides the default heading (the `list.errorTitle` bundle entry). */\n title?: string;\n className?: string;\n}\n\n/**\n * The canonical \"this list failed to load\" panel: icon, heading, an\n * actionable sentence, and a Retry button.\n *\n * ⚠️ Extracted from `<ResourceList>` because it was trapped inside it. The\n * `schedules` list is rendered by a level-3 body slot, which is the whole\n * point of slots — but the slot then had to hand-roll its own error branch,\n * and hand-rolled it worse: a bare red card printing\n *\n * «Could not load schedules. Temporal GET\n * /namespaces/default/schedules?maximumPageSize=10 -> 502»\n *\n * — a raw internal HTTP trace under a Russian sentence, with NO way to retry.\n * When Temporal was briefly down, the only recovery was reloading the page.\n *\n * A slot author should not have to re-derive an error state the framework\n * already knows how to render, so this is now shared by both. It is the `list`\n * surface of `<LoadError>`: the sentence is the error's own text (its code's, its\n * message reference's), a plain-language sentence for a dead network or an\n * unavailable service, or `list.errorBody`; an HTTP trace or a thrown message is\n * never the sentence. The raw text stays reachable under «Details», in\n * development, for whoever has to file the bug.\n */\nexport function ListErrorState(props: ListErrorStateProps): React.ReactElement {\n const { error, onRetry, resource, title, className } = props;\n return (\n <LoadError\n surface=\"list\"\n error={error}\n {...(onRetry === undefined ? {} : { retry: onRetry })}\n {...(resource === undefined ? {} : { resource })}\n {...(title === undefined ? {} : { title })}\n {...(className === undefined ? {} : { className })}\n />\n );\n}\n","'use client';\nimport {\n type TableLayoutValue,\n type UseUiSettingsSingletonResult,\n tableLayoutSetting,\n useOptionalUiSettings,\n} from '@burojs/react';\nimport type {\n ColumnOrderState,\n ColumnPinningState,\n ColumnSizingState,\n Updater,\n} from '@tanstack/react-table';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\n\n/** How a stored width is read for one column: its floor, its cap, whether the user may drag it. */\nexport interface TableLayoutColumnRule {\n readonly min: number;\n readonly max: number | undefined;\n readonly resize: boolean;\n}\n\nexport interface UseTableLayoutOptions {\n /** The listed resource's canonical key. */\n readonly resource: string;\n /** The list id (C18); absent: the layout lives in memory for the mount. */\n readonly layoutId: string | undefined;\n /** A column's sizing rule, or `undefined` for a column the list no longer has. */\n readonly rule: (column: string) => TableLayoutColumnRule | undefined;\n /** The pinning before the user pins anything. Stable across renders. */\n readonly defaultPinning: TableLayoutValue['pinning'];\n /** A token bump from the Columns menu: `sizes` clears the widths, `all` the whole layout. */\n readonly resetLayout: { readonly token: number; readonly mode: 'sizes' | 'all' } | undefined;\n}\n\nexport interface TableLayoutState {\n readonly columnSizing: ColumnSizingState;\n readonly setColumnSizing: (updater: Updater<ColumnSizingState>) => void;\n readonly columnOrder: ColumnOrderState;\n readonly setColumnOrder: (updater: Updater<ColumnOrderState>) => void;\n readonly columnPinning: ColumnPinningState;\n readonly setColumnPinning: (updater: Updater<ColumnPinningState>) => void;\n}\n\n/**\n * Width writes are debounced: a drag reports every frame, the store gets the last one. A move or a\n * pin is one discrete change and is written at once (with any width still pending), so a page left\n * right after it keeps it.\n */\nconst WRITE_DEBOUNCE_MS = 200;\n\ntype Settings = UseUiSettingsSingletonResult<TableLayoutValue>;\n\n/**\n * Runs a store mutation now — synchronously, so a write flushed on unmount reaches the lease\n * before the lease's own deferred disposal — and reports a successful answer. A refused, failed\n * or throwing mutation keeps the in-memory layout.\n */\nfunction mutate(\n run: () => Promise<{ readonly status: string }>,\n ok: (status: string) => boolean,\n then: () => void,\n): void {\n try {\n void run().then(\n (result) => {\n if (ok(result.status)) then();\n },\n () => undefined,\n );\n } catch {\n // The in-memory layout stays.\n }\n}\n\nfunction resolve<T>(updater: Updater<T>, current: T): T {\n return typeof updater === 'function' ? (updater as (old: T) => T)(current) : updater;\n}\n\nfunction sameNames(a: readonly string[], b: readonly string[]): boolean {\n return a.length === b.length && a.every((name, index) => name === b[index]);\n}\n\n/**\n * What the user changed before the setting's first snapshot settled: only these axes (and only\n * these widths) are laid over the stored layout once it arrives (§4.10, C21).\n */\ninterface HeldEdits {\n readonly key: unknown;\n /** A reset `all` was asked: the base is the declared layout, not the stored one. */\n resetAll: boolean;\n /** A reset `sizes` was asked: the stored widths are dropped. */\n resetSizes: boolean;\n /** Widths the user set (`undefined`: cleared), by column. */\n readonly sizes: Map<string, number | undefined>;\n order?: TableLayoutValue['order'];\n pinning?: TableLayoutValue['pinning'];\n}\n\n/**\n * The stored widths as the table reads them (§4.7 rule 5, §4.10): a column the list no longer\n * has, or one with `resize: false`, is ignored; every other width is clamped to `[min, max]`.\n */\nfunction readSizes(\n sizes: Readonly<Record<string, number>>,\n rule: (column: string) => TableLayoutColumnRule | undefined,\n): ColumnSizingState {\n const out: ColumnSizingState = {};\n for (const [column, size] of Object.entries(sizes)) {\n const of = rule(column);\n if (of === undefined || !of.resize) continue;\n out[column] = Math.min(Math.max(size, of.min), of.max ?? Number.POSITIVE_INFINITY);\n }\n return out;\n}\n\n/**\n * One table's column layout — widths, order, pinning — in the `buro/table-layout` UI setting\n * (REF-117 §4.10), keyed by the resource and the list id.\n *\n * - The table renders the declared layout at once and the stored one when the setting's first\n * snapshot settles (C21): the default store reads storage a microtask late.\n * - A change shows at once (in memory). A width is written to the store 200 ms after the last\n * drag frame; a move or a pin at once. A pending write is flushed on unmount. Until the store\n * confirms it, the in-memory layout wins over the snapshot, so an earlier read settling late\n * never undoes the user's drag.\n * - A change (or a reset) made while the snapshot is still `pending` writes nothing: when it\n * settles, only the axes the user touched — the widths they set, the order, the pinning — are\n * laid over the stored layout, and that is stored. One the list unmounts before then is lost.\n * - A reset acts on a token bump during this mount, never on the token the list mounts with.\n * - Without a list id, or without a `UiSettingsProvider`, the layout lives in memory for the mount\n * and nothing is written anywhere.\n */\nexport function useTableLayout({\n resource,\n layoutId,\n rule,\n defaultPinning,\n resetLayout,\n}: UseTableLayoutOptions): TableLayoutState {\n const params = useMemo(\n () => (layoutId === undefined ? null : { resource, list: layoutId }),\n [resource, layoutId],\n );\n const settings = useOptionalUiSettings(tableLayoutSetting, params) as Settings | undefined;\n const settingsRef = useRef(settings);\n settingsRef.current = settings;\n const key = layoutId === undefined ? undefined : `${resource}\\u0000${layoutId}`;\n\n const fallback = useMemo<TableLayoutValue>(\n () => ({ sizes: {}, order: [], pinning: defaultPinning }),\n [defaultPinning],\n );\n // The user's layout not yet confirmed by the store (or the only one, without a store). Held with\n // the key it belongs to, so a list that changes its id drops the other list's edits at once.\n const [local, setLocal] = useState<{ readonly key: unknown; readonly value: TableLayoutValue }>();\n const stored = settings?.snapshot.entries[0]?.value;\n // Until the first snapshot settles, `entries` say nothing about what is stored: a change made\n // then is held and laid over the stored layout when it arrives, never written over it.\n const settled = settings === undefined || !settings.snapshot.pending;\n const held = useRef<HeldEdits | null>(null);\n const layout =\n (local !== undefined && local.key === key ? local.value : undefined) ?? stored ?? fallback;\n const latest = useRef(layout);\n latest.current = layout;\n const sizing = useMemo(() => readSizes(layout.sizes, rule), [layout.sizes, rule]);\n const sizingRef = useRef(sizing);\n sizingRef.current = sizing;\n\n // Bumped on every change: a store answer for an older change must not drop a newer one.\n const generation = useRef(0);\n const timer = useRef<ReturnType<typeof setTimeout> | null>(null);\n const pending = useRef<{ readonly target: Settings; readonly value: TableLayoutValue } | null>(\n null,\n );\n\n const confirm = useCallback((sent: number) => {\n if (generation.current === sent && pending.current === null) setLocal(undefined);\n }, []);\n\n const write = useCallback(\n (target: Settings, value: TableLayoutValue) => {\n const scopeId = target.snapshot.entries[0]?.scope.id ?? target.snapshot.writeScopes[0]?.id;\n if (scopeId === undefined) return;\n const sent = generation.current;\n mutate(\n () => target.set({ scopeId, value }),\n (status) => status === 'created' || status === 'updated',\n () => confirm(sent),\n );\n },\n [confirm],\n );\n\n /** Stores `next`: written, or the entry removed when `next` is the declared layout. */\n const store = useCallback(\n (target: Settings, next: TableLayoutValue) => {\n const declared =\n Object.keys(next.sizes).length === 0 &&\n next.order.length === 0 &&\n sameNames(next.pinning.left, defaultPinning.left) &&\n sameNames(next.pinning.right, defaultPinning.right);\n if (!declared) {\n write(target, next);\n return;\n }\n const entry = target.snapshot.entries[0];\n if (entry === undefined) {\n // Nothing stored and nothing to store: the snapshot (empty) is the layout again.\n setLocal(undefined);\n return;\n }\n const sent = generation.current;\n mutate(\n () => target.remove({ id: entry.id }),\n (status) => status === 'removed',\n () => confirm(sent),\n );\n },\n [defaultPinning, write, confirm],\n );\n\n const flush = useCallback(() => {\n if (timer.current !== null) clearTimeout(timer.current);\n timer.current = null;\n const due = pending.current;\n pending.current = null;\n if (due !== null) write(due.target, due.value);\n }, [write]);\n\n const change = useCallback(\n (next: TableLayoutValue, debounced: boolean, touch: (edits: HeldEdits) => void) => {\n latest.current = next;\n generation.current += 1;\n setLocal({ key, value: next });\n const target = settingsRef.current;\n if (target === undefined) return;\n if (target.snapshot.pending || (held.current !== null && held.current.key === key)) {\n // Not settled yet (or settled but not replayed yet): remember what changed, write nothing.\n const edits =\n held.current !== null && held.current.key === key\n ? held.current\n : {\n key,\n resetAll: false,\n resetSizes: false,\n sizes: new Map<string, number | undefined>(),\n };\n held.current = edits;\n touch(edits);\n return;\n }\n pending.current = { target, value: next };\n if (!debounced) {\n flush();\n return;\n }\n if (timer.current !== null) clearTimeout(timer.current);\n timer.current = setTimeout(flush, WRITE_DEBOUNCE_MS);\n },\n [key, flush],\n );\n\n // A pending write lands before the list goes away or changes its id.\n // biome-ignore lint/correctness/useExhaustiveDependencies: flushed per list id, not per callback\n useEffect(() => flush, [key]);\n\n // The first settled snapshot: the edits held until now are laid over the stored layout and\n // stored, so a stored order, pinning or width the user did not touch survives.\n // biome-ignore lint/correctness/useExhaustiveDependencies: runs when the snapshot settles\n useEffect(() => {\n const edits = held.current;\n if (edits === null) return;\n if (edits.key !== key) {\n held.current = null;\n return;\n }\n const target = settingsRef.current;\n if (!settled || target === undefined) return;\n held.current = null;\n const base = edits.resetAll ? fallback : (stored ?? fallback);\n const sizes: Record<string, number> =\n edits.resetAll || edits.resetSizes ? {} : { ...readSizes(base.sizes, rule) };\n for (const [column, size] of edits.sizes) {\n if (size === undefined) delete sizes[column];\n else sizes[column] = size;\n }\n const next: TableLayoutValue = {\n sizes,\n order: edits.order ?? base.order,\n pinning: edits.pinning ?? base.pinning,\n };\n latest.current = next;\n generation.current += 1;\n setLocal({ key, value: next });\n store(target, next);\n }, [settled, key]);\n\n // The Columns menu's reset: `sizes` clears the widths, `all` removes the stored layout. Only a\n // token bump during this mount resets: a list remounted under a controller that reset earlier\n // shows the layout stored since.\n const resetToken = resetLayout?.token ?? 0;\n const seenToken = useRef(resetToken);\n // biome-ignore lint/correctness/useExhaustiveDependencies: fires on a token bump only\n useEffect(() => {\n if (resetToken === seenToken.current) return;\n seenToken.current = resetToken;\n const all = resetLayout?.mode === 'all';\n const next: TableLayoutValue = all ? fallback : { ...latest.current, sizes: {} };\n if (timer.current !== null) clearTimeout(timer.current);\n timer.current = null;\n pending.current = null;\n latest.current = next;\n generation.current += 1;\n setLocal({ key, value: next });\n const target = settingsRef.current;\n if (target === undefined) return;\n if (target.snapshot.pending || (held.current !== null && held.current.key === key)) {\n // Not settled yet: the reset is replayed over the stored layout once it arrives.\n const prior = held.current !== null && held.current.key === key ? held.current : undefined;\n held.current = all\n ? { key, resetAll: true, resetSizes: false, sizes: new Map() }\n : {\n key,\n resetAll: prior?.resetAll ?? false,\n resetSizes: true,\n sizes: new Map(),\n ...(prior?.order === undefined ? {} : { order: prior.order }),\n ...(prior?.pinning === undefined ? {} : { pinning: prior.pinning }),\n };\n return;\n }\n store(target, next);\n }, [resetToken]);\n\n const setColumnSizing = useCallback(\n (updater: Updater<ColumnSizingState>) => {\n const before = sizingRef.current;\n const sizes = resolve(updater, before);\n sizingRef.current = sizes;\n change({ ...latest.current, sizes }, true, (edits) => {\n for (const column of new Set([...Object.keys(before), ...Object.keys(sizes)])) {\n if (before[column] !== sizes[column]) edits.sizes.set(column, sizes[column]);\n }\n });\n },\n [change],\n );\n const setColumnOrder = useCallback(\n (updater: Updater<ColumnOrderState>) => {\n const order = resolve(updater, latest.current.order as string[]);\n change({ ...latest.current, order }, false, (edits) => {\n edits.order = order;\n });\n },\n [change],\n );\n const setColumnPinning = useCallback(\n (updater: Updater<ColumnPinningState>) => {\n const resolved = resolve(updater, latest.current.pinning as ColumnPinningState);\n const pinning = { left: resolved.left ?? [], right: resolved.right ?? [] };\n change({ ...latest.current, pinning }, false, (edits) => {\n edits.pinning = pinning;\n });\n },\n [change],\n );\n\n return {\n columnSizing: sizing,\n setColumnSizing,\n columnOrder: layout.order as ColumnOrderState,\n setColumnOrder,\n columnPinning: layout.pinning as ColumnPinningState,\n setColumnPinning,\n };\n}\n","'use client';\nimport { useT } from '@burojs/react';\nimport { Button } from '../primitives/button.js';\n\n/**\n * Props of {@link CursorLoadMore}.\n *\n * Deliberately shaped as three scalars rather than taking the controller's\n * `cursor` group whole: the group's `next` is an opaque TOKEN (useful to a\n * consumer that wants to log or deep-link it) while this control only ever\n * needs to know whether there IS one. Spreading `cursor` in would also make\n * the component unusable by a surface that paginates a nested/embedded list\n * outside `useResourceList` — the workflows page does exactly that.\n */\nexport interface CursorLoadMoreProps {\n /** Render the button at all. `false` renders nothing (see the docblock). */\n hasMore: boolean;\n /** A load-more fetch is in flight — disables the button and swaps the label. */\n loading?: boolean;\n /** Fetch the next page. Wire to `cursor.loadMore()`. */\n onMore: () => void;\n}\n\n/**\n * The \"load more\" footer for a **cursor (opaque-token) paginated** list —\n * the counterpart of the numbered pager `<ResourceList>` renders for offset\n * providers.\n *\n * ```tsx\n * const { rows, cursor } = useResourceListContext();\n * // …the table…\n * {cursor && (\n * <CursorLoadMore\n * hasMore={cursor.next !== null}\n * loading={cursor.isLoadingMore}\n * onMore={cursor.loadMore}\n * />\n * )}\n * ```\n *\n * ⚠️ **Renders `null` when `hasMore` is false**, so an exhausted cursor\n * leaves no dead control behind — the caller does not need its own guard.\n * That is also what makes \"the button is gone\" a usable end-of-list\n * assertion in tests.\n *\n * Why it lives in the framework rather than in the app that first needed it\n * (core flexibility program, Task B5.3): it has **zero coupling to any\n * provider**. It knows nothing about Temporal, tokens, or where the next\n * page comes from — only \"is there more\" / \"is it coming\" / \"go get it\". A\n * cursor list is now a first-class declared mode\n * (`views.list.pagination: 'cursor'`), so the control that drives one\n * belongs beside the pager it replaces.\n *\n * @see ResourceListController.cursor in `@burojs/react`\n */\nexport function CursorLoadMore({\n hasMore,\n loading,\n onMore,\n}: CursorLoadMoreProps): React.ReactElement | null {\n const t = useT();\n if (!hasMore) return null;\n return (\n <div className=\"flex justify-center py-4\">\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n disabled={loading}\n onClick={onMore}\n data-testid=\"cursor-load-more\"\n >\n {loading ? t('pagination.loadingMore') : t('pagination.loadMore')}\n </Button>\n </div>\n );\n}\n","'use client';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport type { ColumnDef, Row, RowSelectionState, SortingState, Table } from '@tanstack/react-table';\nimport {\n IconChevronLeft,\n IconChevronsLeft,\n IconChevronsRight,\n IconChevronRight,\n IconFilterX,\n IconInbox,\n IconLoader2,\n} from '@tabler/icons-react';\nimport {\n type CompiledFlow,\n type DtoSource,\n compileFlow,\n declaredField,\n isColumnSortable,\n planItemActions,\n resolveFieldLabel,\n resolveResourceLabel,\n type PlannableAction,\n declaredText,\n routeResourceKey,\n type ResourceNameOrRef,\n type ColumnEntry,\n type ResolvedColumnUi,\n columnName,\n resolveColumnUi,\n} from '@burojs/core';\nimport {\n FlowRowBatchContext,\n QUICK_ANCHOR_ATTRIBUTE,\n columnTypeWidth,\n useApp,\n useFlowRowBatch,\n useI18nCaps,\n useListAccess,\n useLocale,\n useChromeT,\n usePathAccess,\n useOptionalT,\n useTestIds,\n useViewRow,\n} from '@burojs/react';\nimport { Button } from '../primitives/button.js';\nimport { Checkbox } from '../primitives/checkbox.js';\nimport {\n Table as UITable,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '../primitives/table.js';\nimport { ActionOverflow, RowActionsCollapseContext } from '../actions/action-overflow.js';\nimport { useContainerNarrow } from '../lib/use-container-narrow.js';\nimport { useLinkComponent } from '../layout/link-component.js';\nimport { ResolvedFieldDisplay } from '../fields/resolved-field.js';\nimport { FieldValueFrame } from '../fields/field-value-frame.js';\nimport { ClaimedQuickLink } from '../fields/claimed-quick-link.js';\nimport { relationLinkClassName } from '../fields/relation-display.js';\nimport { DataTable } from '../data-table/data-table.js';\nimport { ColumnHeaderMenu } from './column-header-menu.js';\nimport { columnAccessor } from './column-accessor.js';\nimport { capsOf, columnTarget } from './column-target.js';\nimport { useBuroDataTable } from '../data-table/use-buro-data-table.js';\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '../primitives/select.js';\nimport { cn } from '../lib/cn.js';\nimport { ListErrorState } from './list-error-state.js';\nimport { type TableLayoutColumnRule, useTableLayout } from './use-table-layout.js';\nimport { CursorLoadMore } from '../list-kit/cursor-load-more.js';\n\ntype RowRecord = { id: string } & Record<string, unknown>;\n\nexport interface ResourceListProps<N extends string = string> {\n resource: ResourceNameOrRef<N>;\n data?: RowRecord[];\n total?: number;\n page?: number;\n pageSize?: number;\n /**\n * Called when the user picks a different page size. The size selector is\n * rendered ONLY when this is supplied — a list whose host does not persist\n * page size should not offer a control that silently resets on navigation.\n */\n onPageSize?: (size: number) => void;\n /**\n * Ask the host for the row count of the CURRENTLY described set (Task\n * B4.3). Rendered ONLY when this is supplied and `total` is unknown — the\n * same \"no control the host cannot honour\" gate `onPageSize` above uses.\n *\n * This component is presentational by contract, so the trigger arrives as\n * a prop rather than being read from `useResourceListContext()`:\n * `useResourceListContext()` THROWS outside a provider\n * (`list-kit/context.tsx`), and `<ResourceList>` must stay usable\n * standalone — a `related-list` placement mounts one with a hand-rolled count and\n * no controller at all.\n *\n * ⚠️ Answering moves the user, on purpose. The host writes the answer into\n * `total`, which flips `knownTotal` and with it four behaviours that are\n * dead on an unknown-total list: `pagination.showing` replaces the\n * range-only readout, the first/last jump buttons appear, `hasNextPage`\n * switches from \"this page is full\" to `page < totalPages`, and the\n * out-of-range clamp navigates a stale `?page=20` to the last real page.\n * That last one is the point of offering the trigger on a wrong page at\n * all.\n */\n onRequestCount?: () => void;\n /**\n * A count request is in flight. The trigger keeps its place and its width;\n * only its label is swapped for a spinner, and it stops accepting clicks.\n */\n isCountingRows?: boolean;\n /** Page-size choices. Defaults to a standard admin ladder. */\n pageSizeOptions?: number[];\n onPage?: (n: number) => void;\n /**\n * Opaque-token pagination. When supplied, the numbered pager is replaced by\n * a load-more control: a token list has no page index to jump to. Absent →\n * the offset pager renders exactly as before.\n */\n loadMore?: { hasMore: boolean; loading: boolean; onMore: () => void };\n selectable?: boolean;\n /**\n * The row-actions column (each row's item actions). `false` draws none: a read-only list\n * offers nothing to do with a row but open it. A function draws its own controls in the column\n * instead of the item actions (a link panel's Detach); keep its identity stable, the columns\n * are rebuilt when it changes.\n */\n rowActions?: boolean | ((row: RowRecord) => React.ReactNode);\n /**\n * Accumulating selection owned by the caller. When provided the component\n * is CONTROLLED: this is the WHOLE selected set (ids that are not on the\n * current page included), the component keeps no selection state of its\n * own, and every change — including the page-scoped header checkbox — is\n * reported through `onSelectionChange` as the new whole set.\n *\n * Omit it for the uncontrolled behaviour: the component owns the selection\n * and drops it whenever `data` changes identity.\n *\n * ⚠️ A controlled caller MUST commit every emission it receives through\n * `onSelectionChange` back into this prop: skip one and the `emittedRef`\n * bridge (below) stays armed against a base the DOM never reflected, so\n * the next toggle composes against a phantom selection instead of what's\n * actually checked.\n */\n selectedIds?: string[];\n onSelectionChange?: (ids: string[]) => void;\n className?: string;\n /** When true, show skeleton rows instead of the table. */\n isLoading?: boolean;\n /** When non-null, show an error state. */\n error?: { message: string } | Error | null;\n /**\n * Optional retry callback. When provided AND `error` is set, the\n * error-state panel renders a \"Retry\" button that invokes this\n * callback. The typical wiring is `onRetry={() => query.refetch()}`\n * when the parent uses the framework's `useList` (or an equivalent\n * `refetch()` method on the data source).\n */\n onRetry?: () => void;\n /** Render an inline \"+ Create\" button in the empty state. */\n createHref?: string;\n /** Whether the list is currently filtered (changes empty-state copy). */\n isFiltered?: boolean;\n /**\n * Called when the user clicks the \"Clear filter\" button in the empty state. The button is drawn\n * exactly when this is given: the caller decides whether there is anything to reset (a list\n * that starts filtered has rows narrowed and nothing to reset). `isFiltered` only picks the\n * wording.\n */\n onClearFilter?: () => void;\n /**\n * Replacement for the \"no rows\" rendering, forwarded to\n * `<DataTable emptyState>`.\n *\n * ⚠️ This changes the SHAPE of the empty list, not just its copy. Left\n * undefined (the default, and what every caller did before the slot work)\n * this component early-returns a standalone panel INSTEAD of the table —\n * dashed border, icon, heading, and one of three CTAs (\"Clear filter\" when\n * filtered / \"+ Create\" when genuinely empty / \"back to page 1\" on an\n * out-of-range page). Supplying a node skips that panel entirely: the\n * table renders with its header row and the node fills a single body cell\n * spanning every column, so the column headers survive but none of the\n * CTAs do — the caller owns whatever recovery affordance the state needs.\n *\n * The footer/pagination is still hidden while there are no rows.\n */\n emptyState?: React.ReactNode;\n /**\n * Another drawing of the same rows in place of the table (a `related-list` with `view: 'cards'`\n * or `'timeline'`, P6 3.13). Everything around the rows stays this component's: the loading,\n * error and empty states, the numbered pager or load-more footer, the on-demand count. The\n * table's own affordances (selection, column menu, sort headers) do not exist on it.\n */\n rowsView?: {\n readonly render: (rows: RowRecord[]) => React.ReactNode;\n /** Drawn while the first page loads, in place of the table skeleton. */\n readonly skeleton: React.ReactNode;\n };\n /**\n * If provided, each row becomes a clickable link to this href.\n * Receives the row record; returns the navigation target.\n * Default behavior: rows are not clickable. Set to `(row) => '/{resource}/{row.id}'`\n * for typical show-page navigation.\n */\n rowHref?: (row: RowRecord) => string | undefined;\n /**\n * A row's quick opener (P3-17): when it returns a function, a plain click on the row or its\n * first cell calls it instead of navigating; the first cell keeps the `rowHref` anchor (marked\n * for the opener) when there is one, and is a button when there is none. `null`: the row\n * follows `rowHref`.\n */\n rowQuick?: (row: RowRecord) => (() => void) | null;\n /**\n * Changes whenever `rowHref` or `rowQuick` would answer differently for the same row (an\n * access answer arrived): the memoized rows and cells re-render.\n */\n rowLinkKey?: unknown;\n /**\n * Per-cell custom renderer override. Returns `undefined` to fall back to\n * the default field-type-based display. Use for badges, links, or any\n * custom visual treatment that depends on column + value + row.\n *\n * MUST be a pure function of `(col, value, row)` — the cell it renders runs\n * inside `<DataTable>`'s memoized row/cell (`MemoRow`/`MemoCell` in\n * data-table.tsx), which intentionally skips re-rendering when a row's own\n * data and selection state haven't changed. If the returned output depends\n * on EXTERNAL reactive state (locale, a feature flag, anything read outside\n * `col`/`value`/`row`), it will go stale under that memo the same way the\n * built-in `DateDisplay`/`NumberDisplay` renderers did before they were\n * fixed to self-subscribe to locale. Delegate any such state-dependent\n * text to a component that subscribes to it itself (`useLocale()` /\n * `useOptionalT()` — see `EnumDisplay`/`BooleanDisplay`/`DateDisplay` for\n * the pattern) rather than resolving it inline in this callback.\n */\n renderCell?: (col: string, value: unknown, row: RowRecord) => React.ReactNode | undefined;\n /** Current native sort expression. The header exposes the first sort key. */\n sort?: readonly { field: string; direction: 'asc' | 'desc' }[];\n /**\n * Sort request from a column header. `direction` is EXPLICIT when the header\n * menu picks «ascending/descending/reset» (`'asc'`/`'desc'`/`null`); it\n * is omitted when a caller wants the legacy 3-click toggle. Consumers should\n * honour an explicit direction and fall back to toggling when it's undefined.\n */\n onSort?: (field: string, direction?: 'asc' | 'desc' | null) => void;\n /**\n * Whether a column offers sort (T4 D7). The list kit passes the controller's\n * `sorting.sortable`; when omitted, core's `isColumnSortable` decides — nothing sorts by\n * default, a field's `sort` or the app's `lists.sortable` turns a column on, and a link never\n * sorts. A column offers sort only when this says yes AND `onSort` is supplied.\n */\n sortable?: (column: string) => boolean;\n /**\n * Hide a column from a column-header menu. Receives the column name; the\n * parent removes it from the visible-columns list. When omitted, the header\n * menu shows no «hide» item.\n */\n onHideColumn?: (field: string) => void;\n /**\n * Columns that may NOT be hidden — the header menu omits «hide» for these.\n * Without it every column is treated as hideable (when `onHideColumn` is set).\n */\n requiredColumns?: string[];\n /**\n * Bump to reset the persisted column layout (#17). `resetLayout.mode`:\n * - `'sizes'` — clear user-resized widths only.\n * - `'all'` — clear widths AND pinning AND order back to defaults.\n * The token is what triggers it; increment it on each reset click.\n */\n resetLayout?: { token: number; mode: 'sizes' | 'all' };\n /**\n * Override for the column list rendered in the table. When omitted,\n * the table falls back to `def.views.list.columns` (or all field\n * keys). When provided, the table renders EXACTLY this set in the\n * given order — useful for the user-toggleable Columns menu (see\n * `views.list.optionalColumns` / `requiredColumns`).\n */\n columns?: string[];\n /**\n * Each data column's resolved presentation by name (REF-117 §4.9, P10): its width (`default`,\n * `min`, `max`), whether it resizes, its alignment, and its cell display (implementation,\n * params, transform, overflow). The list controller's `columns.ui`, which `ListBody` passes.\n * A column it does not cover, or every column when it is omitted (a standalone mount),\n * resolves here with core's `resolveColumnUi` over its field and its `views.list` entry, so\n * a field's `ui.column` holds either way. A width is a default, not a floor: the floor is\n * `min` (C13).\n */\n columnUi?: Readonly<Record<string, ResolvedColumnUi>>;\n /**\n * Where the user's column layout (widths, order, pinning) is stored: the list id of the\n * `buro/table-layout` UI setting, beside the resource (REF-117 §4.10, C18). The route list passes\n * `'route'`, a placement `<owner resource>/<placement key path>`. A list rendered by hand passes\n * its own stable id to keep the layout across mounts; without one, the layout lasts for the mount.\n * Nothing is stored without a `UiSettingsProvider` either.\n */\n layoutId?: string;\n /**\n * Optional callback that hands the parent the underlying TanStack\n * `Table` instance. Fires once after the table is mounted (and\n * again with `null` on unmount). Use this when the parent needs to\n * read selection state for components that live OUTSIDE the table\n * (e.g. `<BulkActionToolbar>` which calls\n * `table.getFilteredSelectedRowModel().rows`). The id-array\n * `onSelectionChange` callback remains the recommended way to\n * trigger a parent re-render on selection changes — `tableRef`\n * gives access to the rows, not a re-render signal.\n */\n tableRef?: (table: Table<RowRecord> | null) => void;\n}\n\n/**\n * The on-demand row-count trigger (Task B4.3) — one affordance, two homes.\n *\n * Loading is a swap IN PLACE: the label stays in the flow with\n * `visibility:hidden` so the control keeps its exact width, and the spinner is\n * centred on top of it. Nothing around the button moves — which matters most\n * in the empty-state CTA row, where a shrinking button would slide its\n * neighbour sideways for the length of a query measured in tens of seconds.\n * `visibility:hidden` also drops the label from the accessibility tree, so the\n * accessible name is pinned with `aria-label`.\n */\nfunction CountRowsTrigger({\n label,\n loading,\n onClick,\n testid,\n variant,\n className,\n}: {\n label: string;\n loading: boolean;\n onClick: () => void;\n testid: string;\n variant: 'link' | 'outline';\n className?: string;\n}): React.ReactElement {\n return (\n <Button\n type=\"button\"\n variant={variant}\n size=\"sm\"\n data-testid={testid}\n onClick={onClick}\n disabled={loading}\n aria-label={label}\n aria-busy={loading || undefined}\n className={cn('relative', className)}\n >\n <span className={loading ? 'invisible' : undefined}>{label}</span>\n {loading && (\n <IconLoader2 className=\"absolute inset-0 m-auto size-3.5 animate-spin\" aria-hidden=\"true\" />\n )}\n </Button>\n );\n}\n\nconst SELECT_COL_ID = '__select__';\nconst ACTIONS_COL_ID = '__actions__';\n/** The pinning before the user pins anything: the select box and the id left, the actions right. */\nconst DEFAULT_PINNING = Object.freeze({\n left: Object.freeze([SELECT_COL_ID, 'id']),\n right: Object.freeze([ACTIONS_COL_ID]),\n});\n\n/**\n * Geometry of the row-action strip, in px. Three constants rather than one\n * magic number, because {@link actionsColumnSize} is arithmetic over them and\n * each one mirrors a class written somewhere else — a reader has to be able to\n * check the sum against the markup.\n */\n/** `size-7` — `resolveControlChrome`'s compact size on a row, and the overflow kebab's. */\nconst ROW_ACTION_CONTROL_PX = 28;\n/** `gap-1` on `<ActionOverflow>`'s row container and on its standalone strip. */\nconst ROW_ACTION_GAP_PX = 4;\n/** `p-2` on the `<td>`, both sides. */\nconst ACTIONS_CELL_PADDING_PX = 16;\n/**\n * The width this column had unconditionally before F1, kept as a FLOOR so the\n * one-kebab table — every resource that adds no standalone row action, i.e.\n * most of them — renders byte-identically to before.\n */\nconst ACTIONS_COL_MIN_PX = 64;\n\n/**\n * How wide the row-actions column has to be to hold what this resource\n * declares.\n *\n * ⚠️ THIS USED TO BE A FLAT `size: 64`, and that is the whole of F1\n * (`docs/superpowers/specs/2026-08-15-marketplace-ops-follow-ups.md`). The\n * number came with the comment \"now that the cell is a single kebab\", which was\n * true when it was written and stopped being true the moment a resource\n * declared row-standalone actions: `order` in `examples/marketplace-ops` puts\n * `ship`, `cancel` and `refund` directly in the row and keeps `edit`/`delete`\n * in the menu, so the strip needs FOUR 32px controls and three 8px gaps — 168px\n * of a 64px column. Measured consequences, at a 1280px viewport:\n *\n * - the buttons are flex items, so they shrank from 32px to 16-18px — visibly\n * deformed even in the rows where they still worked;\n * - `justify-end` sends the remaining ~22px of overflow past the cell's START\n * edge, so the FIRST button ended up outside its own `<td>` entirely;\n * - the cell's `truncate` wrapper then clipped it out of hit-testing, so a\n * click never landed (see `columnMetaNoClip` in `data-table.tsx` for the\n * hit-test evidence and for the backstop that keeps such a control\n * reachable even when the arithmetic below cannot know the width).\n *\n * The count is record-INDEPENDENT on purpose. `planItemActions` is the same\n * pure function `useItemActions` plans each row with, minus the per-record\n * capability/visibility filtering that only ever REMOVES controls. So this is\n * the maximum any row can render: never too narrow, and at most one control too\n * wide on a table where every row happens to be denied something. A width that\n * changed per page of data would be worse than slightly generous — the column\n * would jump as the user pages.\n *\n * KNOWN LIMIT, deliberately not guessed at: a standalone row action declared\n * `regular` (icon + LABEL, e.g. `surfaces: { row: 'regular' }`), or `compact`\n * with no icon (which `resolveControlChrome` degrades to a labelled button),\n * is as wide as its translated text and this function cannot know that. Those\n * columns come out too narrow, and `noClip` below is what keeps them usable:\n * the strip spills visibly instead of vanishing. Sizing them properly needs a\n * measured auto-fit, which is a bigger mechanism than this defect justifies.\n */\nfunction actionsColumnSize(items: readonly PlannableAction[] | undefined): number {\n const plan = planItemActions(items ?? [], 'row');\n const standalone = plan.filter((p) => p.placement === 'standalone').length;\n // The overflow kebab is one more control, and exactly one however many\n // actions collapse into it.\n const controls = standalone + (plan.some((p) => p.placement === 'menu') ? 1 : 0);\n if (controls === 0) return ACTIONS_COL_MIN_PX;\n const strip =\n controls * ROW_ACTION_CONTROL_PX + (controls - 1) * ROW_ACTION_GAP_PX + ACTIONS_CELL_PADDING_PX;\n return Math.max(ACTIONS_COL_MIN_PX, strip);\n}\n\n/** A data column's text alignment, in the writing direction (REF-117 §4.7, C14). */\nconst ALIGN_CLASS: Readonly<Record<ResolvedColumnUi['align'], string>> = {\n start: 'text-start',\n center: 'text-center',\n end: 'text-end',\n};\n\n/** A column of a resource the registry does not hold: the fallback width, start-aligned. */\nconst STANDALONE_COLUMN_UI: ResolvedColumnUi = Object.freeze({\n default: 160,\n min: 90,\n align: 'start',\n resize: true,\n fill: false,\n display: Object.freeze({ params: Object.freeze({}) }),\n});\n\nexport function ResourceList<const N extends string = string>({\n resource: resourceInput,\n data,\n total,\n page = 1,\n pageSize = 10,\n onPageSize,\n onRequestCount,\n isCountingRows = false,\n pageSizeOptions = [10, 25, 50, 100],\n onPage,\n loadMore,\n selectable = false,\n rowActions = true,\n selectedIds,\n onSelectionChange,\n className,\n isLoading = false,\n error = null,\n onRetry,\n createHref,\n isFiltered = false,\n onClearFilter,\n emptyState,\n rowsView,\n rowHref,\n rowQuick,\n rowLinkKey,\n renderCell,\n sort,\n onSort,\n sortable,\n onHideColumn,\n requiredColumns,\n resetLayout,\n columns: columnsOverride,\n columnUi,\n layoutId,\n tableRef,\n}: ResourceListProps<N>): React.ReactElement {\n const resource = routeResourceKey(resourceInput);\n const app = useApp();\n const tid = useTestIds();\n const t = useOptionalT();\n const chromeT = useChromeT();\n const locale = useLocale();\n /**\n * Group the digits in the footer readout. Without this an on-demand count\n * on `code_code` prints «of 9841924`» — nine digits with no grouping, which\n * is the one number on the page a user actually has to READ. The docblock\n * on that readout has always described the intended output as «of 9 800 000»;\n * only the formatting was missing. Locale-aware on purpose: RU groups with a\n * non-breaking space, EN with commas, and the switch is live.\n */\n const nf = useMemo(() => new Intl.NumberFormat(locale), [locale]);\n const i18nCaps = useI18nCaps(resource);\n const def = app.registry.get(resource);\n const resourceRef = def?.ref ?? { namespace: 'default', id: resource };\n const RouterLink = useLinkComponent();\n // Uncontrolled fallback. A controlled caller (`selectedIds`) never writes here.\n const [ownSelection, setOwnSelection] = useState<RowSelectionState>({});\n const controlled = selectedIds !== undefined;\n const controlledSelection = useMemo<RowSelectionState>(() => {\n const next: RowSelectionState = {};\n for (const id of selectedIds ?? []) next[id] = true;\n return next;\n }, [selectedIds]);\n const rowSelection = controlled ? controlledSelection : ownSelection;\n // Bridges the gap between an emitted change and the owner's committed prop.\n // Two clicks in one tick (e2e does exactly this) would otherwise both\n // resolve against the same stale prop and the first would be lost. Cleared\n // as soon as a new `selectedIds` identity arrives — the prop always wins.\n const emittedRef = useRef<RowSelectionState | null>(null);\n useEffect(() => {\n emittedRef.current = null;\n }, [controlledSelection]);\n\n // Reset selection whenever the visible data array reference changes.\n // The `controlled` guard isn't a correctness gate — `rowSelection` never\n // reads `ownSelection` in controlled mode, so this write is invisible\n // either way — it just skips a pointless `setOwnSelection({})` + re-render\n // on every page/filter/sort change for a controlled caller.\n useEffect(() => {\n if (controlled) return;\n // No explicit onSelectionChange([]) here — clearing `ownSelection` makes the\n // notify-effect below emit [] on its own. Calling it here too would double-emit.\n setOwnSelection({});\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [data]);\n\n /*\n THE SECOND `kind: 'column'` ENFORCEMENT CALL SITE (SP5 task 2) — the table\n itself. `useResourceList`'s `isColVisibleHere` is the first; it gates what\n the Columns menu OFFERS, and it is not in this path at all when a host\n renders `<ResourceList>` directly with a `columns` prop (which is exactly\n what `columnsOverride` is, and what every test in this package does). A\n denial that only lived in the controller would therefore be bypassable by\n passing the column in explicitly.\n\n Checked BEFORE the `!field` early-return on purpose: a column that names no\n field is a legitimate host-rendered column (`renderCell`), and a rule must\n be able to gate it too.\n */\n // The one list predicate (P5 spec 3.7): field view in any-record reach plus `column` rules.\n // A pending decision renders the skeleton over the whole declared set, never a narrower one.\n const listAccess = useListAccess(resource);\n // A dotted column naming a field across relations is decided like the controller decides it:\n // its head, its full key, and the field of every hop. The row's projection keeps keys that name\n // no field of its own, so the table must not draw what this predicate hides.\n const pathAccess = usePathAccess(resource);\n const accessPending = listAccess.status === 'pending' || pathAccess.pending;\n const declaredColumnKeys = useMemo<string[]>(() => {\n if (!def) return [];\n return [\n ...(columnsOverride ?? def.views?.list?.columns?.map(columnName) ?? Object.keys(def.fields)),\n ];\n }, [def, columnsOverride]);\n const visibleColumnKeys = useMemo<string[]>(\n () =>\n accessPending\n ? []\n : declaredColumnKeys.filter(\n (col) =>\n listAccess.columnVisible(col) &&\n (columnTarget(app.registry, resource, col) === undefined ||\n (listAccess.columnVisible(col.split('.')[0] as string) && pathAccess.visible(col))),\n ),\n [accessPending, declaredColumnKeys, listAccess, pathAccess, app, resource],\n );\n const skeletonColumnKeys = accessPending ? declaredColumnKeys : visibleColumnKeys;\n\n const rows = useMemo<RowRecord[]>(() => data ?? [], [data]);\n\n // The row flows' pre-click read (P4 spec 4.17, I8): one batched read per page, keyed by the\n // page's own ids, and only when a row flow's `when` or pre-click check reads past the list DTO.\n const rowFlows = useMemo<CompiledFlow[]>(() => {\n if (!def) return [];\n const items = (def.actions?.item ?? []) as readonly PlannableAction[];\n const out: CompiledFlow[] = [];\n for (const placement of planItemActions(items, 'row')) {\n const action = items.find((entry) => entry.name === placement.name);\n if ((action as { readonly kind?: unknown } | undefined)?.kind !== 'flow') continue;\n try {\n out.push(compileFlow(def as never, placement.name));\n } catch {\n // An uncompilable flow is absent on the row as well.\n }\n }\n return out;\n }, [def]);\n const pageIds = useMemo(() => rows.map((row) => String(row.id)), [rows]);\n const rowBatch = useFlowRowBatch(resource, pageIds, rowFlows);\n const rowBatchState = rowBatch.state;\n const flowRowBatch = useMemo(\n () => ({ resource, state: rowBatchState }),\n [resource, rowBatchState],\n );\n\n // UNKNOWN TOTAL IS NOT ONE PAGE.\n //\n // `total` is absent whenever the provider skips the count query — which is\n // exactly what the biggest tables do, because counting 28.9M rows took ~55s\n // and hung the page. The old expression fell back to `rows.length`, so a full\n // first page of 10 became \"10 / 10 = 1 page\", the pager was hidden entirely,\n // and the user could never reach row 11 of nine million. The list looked\n // complete while silently truncating.\n //\n // With no count we cannot know the last page, but we can know whether THIS\n // page is full: a full page means there is plausibly more, a short page means\n // we have reached the end. That is the standard unknown-total pagination\n // contract — range without a grand total, Next while full, no jump-to-end.\n const knownTotal = typeof total === 'number';\n const totalPages = knownTotal ? Math.max(1, Math.ceil(total / pageSize)) : undefined;\n const pageIsFull = rows.length >= pageSize;\n const hasNextPage = knownTotal ? page < (totalPages as number) : pageIsFull;\n // The footer is shown whenever the list has rows — NOT only when there's more\n // than one page. Even a single-record list benefits from it: it reports the\n // total count and, crucially, offers the page-size selector. Otherwise a list\n // of 45 rows at pageSize 50 fits on one page, hides the footer, and the user\n // has no way to shrink the page size to fit the viewport. The nav buttons\n // simply disable on a single page — that is expected, not a defect.\n // NOTE: this is deliberately `rows.length > 0` alone. An earlier version added\n // `|| page > 1` to keep a way back off an empty out-of-range page, but that\n // disjunct was never reachable — the `rows.length === 0` branch below RETURNS\n // before the footer renders. An empty page past the first is handled there\n // instead, by the `list-empty-first-page` recovery button.\n const showPager = rows.length > 0;\n\n // Auto-correct an out-of-range page when the total is known: a stale\n // `?page=20` on a 3-page list snaps to the last real page so the user sees\n // data, not a dead empty page. `total===0` clamps to page 1, where the empty\n // state (not the footer) takes over. Idempotent — once page ≤ totalPages the\n // condition is false. Unknown-total lists can't compute the last page, so\n // they instead get the one-click `list-empty-first-page` button in the\n // empty state (stepping back one page per fetch would cost 17 round-trips\n // from `?page=20`).\n useEffect(() => {\n // NOT while loading: on a cold deep-link to `?page=2`, `query.data` is\n // briefly empty and the host passes `total = rows.length = 0`, which is a\n // valid number → knownTotal, totalPages=1 → this would spuriously clamp\n // page 2 to 1 BEFORE the real count arrives. Wait for real data.\n if (isLoading || !onPage || !knownTotal) return;\n const tp = totalPages as number;\n if (page > tp) onPage(tp);\n }, [isLoading, onPage, knownTotal, totalPages, page]);\n\n const resourceLabel = resolveResourceLabel(i18nCaps, resource, 'plural', def);\n const recordSingular = resolveResourceLabel(i18nCaps, resource, 'single', def);\n const ariaLabel = resourceLabel;\n // Computed in render (not the memo) so it re-translates on locale change; the\n // resolved string is fed into the memo's dep list below.\n const actionsHeader = chromeT('actions.column', { defaultValue: 'Actions' });\n\n // Volatile props read via a ref inside the column render functions, so the\n // `tableColumns` memo does NOT rebuild when these change identity. The\n // playground passes fresh inline callbacks (`renderCell`, `rowHref`, `onSort`,\n // …) every render; if they were memo deps, columns would rebuild on every\n // parent render — including a graphql-ws subscription tick — which rebuilds\n // TanStack's column model and UNMOUNTS an open column-header menu mid-click.\n // The header/cell renders run fresh on every table render regardless, so they\n // still see the latest values through the ref.\n // View code reads a row projected in any-record reach (P5 spec 3.6.6): `renderCell`, the cell\n // renderers and `rowHref` (an href reaches the DOM and the status bar). The quick opener and\n // the item actions keep the row as read: they are policy.\n const viewRow = useViewRow(resource);\n const volatileRef = useRef({\n onSort,\n sortable,\n onHideColumn,\n requiredColumns,\n renderCell,\n rowHref,\n rowQuick,\n sort,\n i18nCaps,\n viewRow,\n });\n volatileRef.current = {\n onSort,\n sortable,\n onHideColumn,\n requiredColumns,\n renderCell,\n rowHref,\n rowQuick,\n sort,\n i18nCaps,\n viewRow,\n };\n\n // Stable callbacks for `<DataTable>`'s row/cell memoization (table render\n // perf #1). `DataTable` wraps rows/cells in `React.memo`, keyed in part on\n // these callback props — an unstable (fresh-per-render) callback here\n // defeats that memo on every single ResourceList render, same as an\n // unstable `tableColumns` dep would defeat the column memo above. `tid` is\n // itself stable (`useTestIds()` memoizes with an empty dep array), so\n // these only need `resource` + `tid` as deps; `rowHref` is read through\n // `volatileRef` (like the column cell renderers above) so the wrapper's\n // OWN identity never changes even though the playground passes a fresh\n // `rowHref` closure every render.\n const getRowTestId = useCallback(\n (row: RowRecord) => tid.listRow(resource, row.id),\n [resource, tid],\n );\n const getCellTestId = useCallback(\n (row: RowRecord, columnId: string) => {\n if (columnId === SELECT_COL_ID || columnId === ACTIONS_COL_ID) return undefined;\n return tid.listCell(resource, row.id, columnId);\n },\n [resource, tid],\n );\n // biome-ignore lint/correctness/useExhaustiveDependencies: a new identity per rowLinkKey re-renders the memoized rows\n const stableRowHref = useCallback(\n (record: RowRecord) => volatileRef.current.rowHref?.(volatileRef.current.viewRow(record)),\n [rowLinkKey],\n );\n // biome-ignore lint/correctness/useExhaustiveDependencies: a new identity per rowLinkKey re-renders the memoized rows\n const stableRowOpen = useCallback(\n (record: RowRecord) => {\n const open = volatileRef.current.rowQuick?.(record) ?? null;\n if (open === null) return false;\n open();\n return true;\n },\n [rowLinkKey],\n );\n // A `rowHref` prop being SET does not mean every row has somewhere to go —\n // the availability gate (Task 8) can return `''` for a record whose show\n // and edit are both unavailable. `rowClassName` must therefore check the\n // PER-ROW result, not just whether the callback exists, or a row with no\n // destination would still show a pointer cursor. Stable via `volatileRef`\n // for the same row/cell-memo reason as `stableRowHref` above.\n // biome-ignore lint/correctness/useExhaustiveDependencies: a new identity per rowLinkKey re-renders the memoized rows\n const stableRowClassName = useCallback(\n (row: Row<RowRecord>) =>\n volatileRef.current.rowHref?.(volatileRef.current.viewRow(row.original)) ||\n (volatileRef.current.rowQuick?.(row.original) ?? null) !== null\n ? 'cursor-pointer'\n : undefined,\n [rowLinkKey],\n );\n\n // Build TanStack ColumnDef array. Done unconditionally (even when we\n // early-return for loading/empty) because hooks must run on every\n // render path; the columns array is cheap to recompute.\n // The list's own width decides its narrow layout (finding 8): one action menu per row, a\n // compact pager. Measured on the list root, so a list in a sheet collapses like a phone's.\n const [listRoot, narrow] = useContainerNarrow();\n // Each data column's presentation (REF-117 §4.9, P10): the host's `columnUi` (the controller's\n // `columns.ui`), else resolved here from the field and its `views.list` entry with the same\n // type widths the controller uses, so a standalone mount honours `ui.column` too.\n const columnUiOf = useMemo(() => {\n const entries = new Map<string, ColumnEntry>();\n for (const entry of [\n ...(def?.views?.list?.columns ?? []),\n ...(def?.views?.list?.optionalColumns ?? []),\n ]) {\n const name = columnName(entry);\n if (!entries.has(name)) entries.set(name, entry);\n }\n return (col: string): ResolvedColumnUi =>\n columnUi?.[col] ??\n (def === undefined\n ? STANDALONE_COLUMN_UI\n : resolveColumnUi(def, entries.get(col) ?? col, app.registry, columnTypeWidth));\n }, [app, def, columnUi]);\n // #17, REF-117 §4.10 — the column layout (widths, order, pinning) in the `buro/table-layout`\n // UI setting, keyed by the resource and the list id (`layoutId`); in memory without one. A\n // stored width is read through the column's rule: a column the list no longer has, or one with\n // `resize: false`, ignores it, and every other is clamped to `[min, max]`.\n const layoutRule = useMemo(() => {\n const known = new Set<string>([\n ...declaredColumnKeys,\n ...(def?.views?.list?.columns ?? []).map(columnName),\n ...(def?.views?.list?.optionalColumns ?? []).map(columnName),\n ...Object.keys(def?.fields ?? {}),\n ]);\n return (col: string): TableLayoutColumnRule | undefined => {\n if (!known.has(col)) return undefined;\n const ui = columnUiOf(col);\n return { min: ui.min, max: ui.max, resize: ui.resize };\n };\n }, [declaredColumnKeys, def, columnUiOf]);\n const {\n columnSizing,\n setColumnSizing,\n columnOrder,\n setColumnOrder,\n columnPinning,\n setColumnPinning,\n } = useTableLayout({\n resource,\n layoutId,\n rule: layoutRule,\n defaultPinning: DEFAULT_PINNING,\n resetLayout,\n });\n const tableColumns = useMemo<ColumnDef<RowRecord, unknown>[]>(() => {\n const cols: ColumnDef<RowRecord, unknown>[] = [];\n\n if (selectable) {\n cols.push({\n id: SELECT_COL_ID,\n enableSorting: false,\n enableHiding: false,\n enableResizing: false,\n size: 44,\n header: ({ table }) => (\n <Checkbox\n checked={\n table.getIsAllPageRowsSelected()\n ? true\n : table.getIsSomePageRowsSelected()\n ? 'indeterminate'\n : false\n }\n onCheckedChange={(v) => table.toggleAllPageRowsSelected(v === true)}\n aria-label={t('table.selectAllRows')}\n />\n ),\n cell: ({ row }) => (\n <Checkbox\n checked={row.getIsSelected()}\n onCheckedChange={(v) => row.toggleSelected(v === true)}\n data-testid={tid.listRowCheckbox(resource, row.original.id)}\n aria-label={t('table.selectRow')}\n />\n ),\n });\n }\n\n for (const col of visibleColumnKeys) {\n // A dotted column draws a field across to-one relations: its renderer, size and label are the\n // target field's, and its value sits under the dotted key itself. A field only a type declares\n // draws through its declaration too (`declaredField`: the base fields, then each type's).\n const target = columnTarget(app.registry, resource, col);\n const field = (\n target !== undefined\n ? target.field\n : def === undefined\n ? undefined\n : declaredField(def as unknown as DtoSource, col)\n ) as\n | {\n type?: import('@burojs/core').FieldDeclaration['type'];\n format?: string;\n kind?: string;\n declaration?: import('@burojs/core').FieldDeclaration;\n meta?: Record<string, unknown>;\n ui?: Record<string, unknown>;\n }\n | undefined;\n const declaredLabel = declaredText('field', field, 'label');\n const headerLabel =\n target === undefined\n ? resolveFieldLabel(volatileRef.current.i18nCaps, col, declaredLabel)\n : resolveFieldLabel(\n capsOf(volatileRef.current.i18nCaps, target.resource),\n target.name,\n declaredLabel,\n );\n const ui = columnUiOf(col);\n // The field as the cell's frame reads it (copy, overflow): its own name, since a dotted\n // column draws the target's field (REF-117 P8).\n const frameField = {\n ...(field ?? { type: 'unknown' }),\n name: target === undefined ? col : target.name,\n };\n // The column's resolved display (every `column` layer, the list entry's last) as the cell's\n // own entry: re-applied over the field's layers it resolves to itself, so the cell draws\n // the entry's implementation, params, transform and overflow. One object per column, so\n // the surface cache keeps hitting across cells.\n const cellEntry = { display: ui.display };\n // `overflow: 'wrap'` on the column surface: the body cell stops clipping (C6).\n const wraps = ui.display.overflow === 'wrap';\n // Whether the column sorts (T4 D7): the host's answer (the list controller's\n // `sorting.sortable`), else core's `isColumnSortable` — the one rule either way. Nothing\n // sorts by default; a link or a column that is no declared field never does.\n const columnSortable =\n volatileRef.current.sortable?.(col) ??\n (def !== undefined && isColumnSortable(def, col, app, app.registry));\n cols.push({\n id: col,\n ...columnAccessor(col),\n // Every width explicit (C13): the default is where the column starts, `min` its floor,\n // so `useBuroDataTable`'s \"size is the floor\" never applies to a data column.\n size: ui.default,\n minSize: ui.min,\n maxSize: ui.max ?? Number.MAX_SAFE_INTEGER,\n enableResizing: ui.resize,\n enableSorting: columnSortable && Boolean(volatileRef.current.onSort),\n enableHiding: true,\n // `className` lands on the header and on every body cell (logical start / end, so a\n // right-to-left locale mirrors it). `fill` asks for the table's spare width (§4.8): the\n // table's `fillColumnId` decides, since a pinned or hidden column hands the role on.\n meta: {\n testid: col,\n className: ALIGN_CLASS[ui.align],\n ...(wraps ? { wrap: true } : {}),\n ...(ui.fill ? { fill: true } : {}),\n },\n // Header is a MENU (#17): sort asc/desc/clear, pin left/right/unpin, hide\n // — instead of a blind click-to-toggle. Pin flows through the column's\n // own TanStack API (`column.pin`), which routes to our persisted\n // columnPinning; sort + hide route to the parent callbacks.\n header: ({ column, table }) => {\n const v = volatileRef.current;\n // Reorder among this column's SECTION peers, in visual order, visible\n // only, service columns (__…) excluded. A pinned column reorders\n // WITHIN its pinned group; a center column reorders in the flow. The\n // previous build filtered out `getIsPinned()`, so pinned columns had\n // no «move» items at all — pin two columns and you couldn't swap them.\n const pinSide = column.getIsPinned(); // 'left' | 'right' | false\n const sectionCols =\n pinSide === 'left'\n ? table.getLeftLeafColumns()\n : pinSide === 'right'\n ? table.getRightLeafColumns()\n : table.getCenterLeafColumns();\n const peerIds = sectionCols\n .filter((c) => c.getIsVisible() && !c.id.startsWith('__'))\n .map((c) => c.id);\n const pos = peerIds.indexOf(col);\n const move = (dir: 'left' | 'right') => {\n const to = dir === 'left' ? pos - 1 : pos + 1;\n if (pos < 0 || to < 0 || to >= peerIds.length) return;\n if (pinSide) {\n // The pinning array's order IS the pinned group's visual order\n // (getLeft/RightLeafColumns map the array 1:1), so swap there and\n // route it through our persisted columnPinning.\n const pinning = table.getState().columnPinning;\n const side = [...(pinSide === 'left' ? (pinning.left ?? []) : (pinning.right ?? []))];\n const a = side.indexOf(peerIds[pos]!);\n const b = side.indexOf(peerIds[to]!);\n if (a < 0 || b < 0) return;\n [side[a], side[b]] = [side[b]!, side[a]!];\n table.setColumnPinning({ ...pinning, [pinSide]: side });\n } else {\n const full = table.getVisibleLeafColumns().map((c) => c.id);\n const a = full.indexOf(peerIds[pos]!);\n const b = full.indexOf(peerIds[to]!);\n const next = [...full];\n [next[a], next[b]] = [next[b]!, next[a]!];\n table.setColumnOrder(next);\n }\n };\n return (\n <ColumnHeaderMenu\n label={headerLabel}\n sortable={columnSortable && Boolean(v.onSort)}\n sortDirection={v.sort?.[0]?.field === col ? v.sort[0].direction : null}\n onSort={columnSortable && v.onSort ? (dir) => v.onSort?.(col, dir) : undefined}\n pinned={column.getIsPinned()}\n onPin={(side) => column.pin(side)}\n canHide={Boolean(v.onHideColumn) && !v.requiredColumns?.includes(col)}\n onHide={v.onHideColumn ? () => v.onHideColumn?.(col) : undefined}\n onMove={move}\n canMoveLeft={pos > 0}\n canMoveRight={pos >= 0 && pos < peerIds.length - 1}\n testid={`list-sort:${resource}:${col}`}\n />\n );\n },\n cell: ({ row }) => {\n const raw = row.original;\n const record = volatileRef.current.viewRow(raw);\n const value = record[col];\n // Per-cell consumer override takes precedence over default renderer.\n const customCell = volatileRef.current.renderCell?.(col, value, record);\n const cellInner =\n customCell !== undefined ? (\n customCell\n ) : (\n <ResolvedFieldDisplay\n resource={target === undefined ? resourceRef : target.ref}\n name={target === undefined ? col : target.name}\n field={field ?? { type: 'unknown' }}\n value={value}\n record={record}\n uiSurface=\"column\"\n columnEntry={cellEntry}\n fallback={<span>{String(value ?? '')}</span>}\n />\n );\n // The field's frame (copy, overflow) goes around the row link, so its copy button is\n // never inside the anchor. A consumer's own cell draws exactly what it returned.\n const framed = (node: React.ReactNode) =>\n customCell !== undefined ? (\n node\n ) : (\n <FieldValueFrame field={frameField} value={value} surface=\"column\" entry={cellEntry}>\n {node}\n </FieldValueFrame>\n );\n // Make the first content cell a real link for keyboard /\n // screen-reader navigation. Route it through the injected\n // `LinkComponent` (next/link, react-router, …) so the drill-in\n // stays client-side — a raw <a> would trigger a full document\n // reload under an SPA router.\n const href = volatileRef.current.rowHref?.(record);\n const indexInVisible = visibleColumnKeys.indexOf(col);\n const isFirstContentCell = indexInVisible === 0;\n const quick = isFirstContentCell ? (volatileRef.current.rowQuick?.(raw) ?? null) : null;\n // A quick row (P3-17): the page anchor claimed for the opener, or a button without one.\n if (quick !== null)\n return framed(\n href ? (\n <ClaimedQuickLink href={href} className={relationLinkClassName} onOpen={quick}>\n {cellInner}\n </ClaimedQuickLink>\n ) : (\n <button\n type=\"button\"\n {...{ [QUICK_ANCHOR_ATTRIBUTE]: '' }}\n className={`${relationLinkClassName} text-left`}\n onClick={(e) => {\n e.stopPropagation();\n quick();\n }}\n >\n {cellInner}\n </button>\n ),\n );\n return framed(\n isFirstContentCell && href ? (\n <RouterLink\n href={href}\n className={relationLinkClassName}\n onClick={(e) => e.stopPropagation()}\n >\n {cellInner}\n </RouterLink>\n ) : (\n cellInner\n ),\n );\n },\n });\n }\n\n // Drawn unless the list is read-only (`rowActions: false`): every resource has at least the\n // built-in Edit and Delete, so a guard on the declared actions would only ever hide the\n // column for a resource that opted BOTH built-ins out — and `<ActionOverflow>` already\n // returns null in that case.\n if (!rowActions) return cols;\n cols.push({\n id: ACTIONS_COL_ID,\n enableSorting: false,\n enableResizing: false,\n // Wide enough for what THIS resource declares, not a flat 64 — see\n // `actionsColumnSize` for the measurements behind that (F1).\n size:\n narrow || typeof rowActions === 'function'\n ? ROW_ACTION_CONTROL_PX + ACTIONS_CELL_PADDING_PX\n : actionsColumnSize(def?.actions?.item),\n enableHiding: false,\n // No visible header — the kebab column needs no «Actions» label; it\n // only wastes space and reads as noise. The accessible name lives on\n // each row's action trigger. Kept as an sr-only string for AT.\n header: () => <span className=\"sr-only\">{actionsHeader}</span>,\n // `w-0` + `whitespace-nowrap` collapses the column to its natural width\n // on a NON-resizable table (no `table-layout: fixed`, so no inline width\n // var to override it) and right-aligns the strip, so the data columns\n // get the freed space.\n // `noRowNav: true` stamps the whole `<td>` (not just the buttons inside\n // it) as out of bounds for whole-row navigation — the cell's padding is\n // still bigger than the 32×32 controls, and a mis-click there used to\n // navigate away instead of doing nothing.\n // `noClip: true` is the F1 fix's backstop: this cell holds CONTROLS, so\n // it must spill visibly rather than clip one out of hit-testing. See\n // `columnMetaNoClip` in `data-table.tsx`.\n // `py-0.5`: a 28px control in the cell's `p-2` made a row 45px against a text row's 39px; with\n // the vertical padding trimmed the text sets the row's height. The horizontal `p-2` stays\n // (`ACTIONS_CELL_PADDING_PX`).\n meta: { className: 'w-0 whitespace-nowrap py-0.5 text-right', noRowNav: true, noClip: true },\n // Standalone row actions render inline; everything else collapses into a\n // single kebab, so the column stays bounded regardless of action count.\n cell: ({ row }) =>\n typeof rowActions === 'function' ? (\n rowActions(row.original)\n ) : (\n <ActionOverflow resource={resource} record={row.original} surface=\"row\" />\n ),\n });\n\n return cols;\n // Volatile props (onSort/sort/renderCell/rowHref/onHideColumn/\n // requiredColumns) are intentionally NOT deps — read via volatileRef so a\n // parent re-render doesn't rebuild columns and unmount an open header menu.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n // `i18nCaps` IS a dep: its identity changes only when the active locale\n // changes (see useI18nCaps memo), so column HEADER LABELS re-resolve on a\n // live language switch. It does not churn on ordinary parent re-renders, so\n // an open header menu still survives those.\n }, [\n app,\n selectable,\n rowActions,\n resourceRef,\n visibleColumnKeys,\n def,\n resource,\n tid,\n RouterLink,\n actionsHeader,\n i18nCaps,\n rowLinkKey,\n narrow,\n columnUiOf,\n ]);\n\n // Bridge external selection state to TanStack's RowSelectionState shape.\n // We keep the caller's id-string contract (Array<string>) on the\n // onSelectionChange boundary; internally TanStack uses\n // {[rowId]: true}.\n //\n // Crucial in both branches below: never resolve `next` against the\n // closure-captured `rowSelection`. On rapid back-to-back clicks (e.g. e2e\n // tests calling click() twice without a microtask flush) that loses the\n // first toggle, because the second click's handler closure still sees the\n // pre-first-click selection. Uncontrolled uses the FUNCTIONAL form of\n // `setOwnSelection`; controlled uses `emittedRef` (see its declaration\n // above) since there is no local setState to resolve against.\n const handleSelectionChange = (\n updater: RowSelectionState | ((prev: RowSelectionState) => RowSelectionState),\n ) => {\n if (controlled) {\n // Resolve against the last value we emitted when the owner has not\n // committed it yet, so back-to-back toggles compose instead of racing.\n const base = emittedRef.current ?? rowSelection;\n const next = typeof updater === 'function' ? updater(base) : updater;\n emittedRef.current = next;\n // Safe here and NOT in the setState updater below: this runs in an event\n // handler, not the render phase.\n onSelectionChange?.(Object.keys(next).filter((k) => next[k]));\n return;\n }\n // The caller is NOT notified from inside the updater. A useState updater is\n // not an event-handler callback: React runs it during the RENDER phase (and\n // twice under StrictMode), so calling the parent's setState there is a\n // setState-during-render — \"Cannot update a component (ResourceListBody)\n // while rendering a different component (ResourceList)\". Notification\n // happens in the effect below, off committed state.\n setOwnSelection((prev) => (typeof updater === 'function' ? updater(prev) : updater));\n };\n\n // Uncontrolled only. Deliberately keyed on committed `ownSelection`:\n // `onSelectionChange` is left out of the deps on purpose because callers\n // commonly pass an inline arrow, and depending on it would re-emit every\n // render and loop. A controlled caller is notified straight from the\n // handler above — emitting [] here on mount would wipe its selection.\n useEffect(() => {\n if (controlled) return;\n onSelectionChange?.(Object.keys(ownSelection).filter((k) => ownSelection[k]));\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [ownSelection]);\n\n const table = useBuroDataTable<RowRecord>({\n data: rows,\n columns: tableColumns,\n total,\n pagination: { pageIndex: Math.max(0, page - 1), pageSize },\n onPaginationChange: () => {\n // Pagination is parent-driven via onPage; ignore TanStack's own\n // updaters here. The Prev/Next buttons below call onPage directly.\n },\n sorting: useMemo<SortingState>(\n () => (sort?.[0] ? [{ id: sort[0].field, desc: sort[0].direction === 'desc' }] : []),\n [sort],\n ),\n onSortingChange: () => {\n // Sort is parent-driven via onSort; the sortable header's button\n // calls onSort directly. We do NOT toggle TanStack's own sort\n // state here — preserves the existing 3-click cycle ownership.\n },\n rowSelection,\n onRowSelectionChange: handleSelectionChange,\n enableRowSelection: selectable,\n columnPinning,\n onColumnPinningChange: setColumnPinning,\n columnSizing,\n onColumnSizingChange: setColumnSizing,\n columnOrder,\n onColumnOrderChange: setColumnOrder,\n enableColumnResizing: true,\n });\n\n // Hand the table instance up to callers that need to read TanStack\n // selection / filter / sort state for components living outside the\n // table (e.g. `<BulkActionToolbar>` reading\n // `table.getFilteredSelectedRowModel().rows`). Fires once after\n // mount with the live table; fires again with `null` on unmount so\n // callers can drop their reference.\n useEffect(() => {\n tableRef?.(table);\n return () => {\n tableRef?.(null);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [table]);\n\n if (!def) {\n return <div data-testid={tid.listEmpty(resource)}>{t('list.notRegistered')}</div>;\n }\n\n // Loading state — skeleton rendered inside the same Table primitives\n // the real list uses, so the loading shimmer matches the rendered\n // table's geometry exactly: same row height, same cell padding,\n // same columns. Replacing the prior generic flex bars eliminates\n // the visual jump when data arrives. Each cell holds an\n // `animate-pulse rounded bg-muted/60` block sized to the column\n // role: a 4×4 square for the checkbox/actions columns; a wider\n // bar for content columns. Headers carry their own muted bars so\n // the skeleton reads as \"table loading\", not \"blank screen\".\n if ((isLoading || accessPending) && rowsView !== undefined)\n return (\n <div\n className={cn('space-y-2', className)}\n role=\"status\"\n aria-busy=\"true\"\n aria-live=\"polite\"\n data-testid=\"loading\"\n >\n <span className=\"sr-only\">{t('list.loading', { params: { items: resourceLabel } })}</span>\n {rowsView.skeleton}\n </div>\n );\n if (isLoading || accessPending) {\n const skeletonRows = 5;\n return (\n <div\n className={cn('space-y-2', className)}\n role=\"status\"\n aria-busy=\"true\"\n aria-live=\"polite\"\n data-testid=\"loading\"\n >\n <span className=\"sr-only\">{t('list.loading', { params: { items: resourceLabel } })}</span>\n <UITable>\n <TableHeader>\n <TableRow>\n {selectable && (\n <TableHead className=\"w-10\">\n <div className=\"size-4 animate-pulse rounded bg-muted/60\" />\n </TableHead>\n )}\n {skeletonColumnKeys.map((col) => (\n <TableHead key={col}>\n <div className=\"h-3.5 w-20 animate-pulse rounded bg-muted/60\" />\n </TableHead>\n ))}\n <TableHead className=\"w-16 text-right\">\n <div className=\"ml-auto h-3.5 w-12 animate-pulse rounded bg-muted/60\" />\n </TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {Array.from({ length: skeletonRows }, (_, i) => (\n <TableRow key={i}>\n {selectable && (\n <TableCell className=\"w-10\">\n <div className=\"size-4 animate-pulse rounded bg-muted/60\" />\n </TableCell>\n )}\n {skeletonColumnKeys.map((col) => (\n <TableCell key={col}>\n <div className=\"h-4 w-full max-w-[16rem] animate-pulse rounded bg-muted/60\" />\n </TableCell>\n ))}\n <TableCell className=\"w-16\">\n <div className=\"ml-auto size-7 animate-pulse rounded bg-muted/60\" />\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </UITable>\n </div>\n );\n }\n\n if (error) {\n // Icon + heading + friendly body + optional Retry. Extracted to\n // `<ListErrorState>` so level-3 body slots can render the SAME panel\n // instead of hand-rolling a worse one — see that file for what the\n // `schedules` slot was showing before it existed.\n return (\n <ListErrorState error={error} onRetry={onRetry} resource={resource} className={className} />\n );\n }\n\n // `emptyState === undefined` is the ONLY guard added here for the list\n // slots (B3.2), and it is deliberately a guard rather than a restructure:\n // absent the prop this branch is byte-identical to what it always was.\n // When a caller DOES supply one, skipping the early return is the whole\n // point — control falls through to `<DataTable emptyState>` below, which\n // has rendered the node in a full-width body cell since it was written\n // and which no caller had ever been able to reach.\n if (rows.length === 0 && emptyState === undefined) {\n // Empty-state polish: split the icon, heading, body, and CTA\n // into a clear vertical hierarchy. Two flavours:\n // - filtered-no-match: IconFilterX icon, \"No matching <plural>\" h3,\n // body explains the filter, \"Clear filter\" outline button.\n // - genuinely empty: IconInbox icon, \"No <plural> yet\" h3, friendly\n // body inviting creation, \"+ Create <singular>\" primary\n // button (when `createHref` is provided).\n // Both flavours are OVERRIDDEN when `page > 1`: this branch returns\n // before the `showPager`-gated footer further down (`:878`), so an\n // out-of-range page (e.g. a stale `?page=20`) would otherwise be a\n // dead end — no pager, and the unknown-total clamp can't help (it's\n // gated on `knownTotal`, `:312`). Neither \"no records yet\" nor \"no\n // matching records\" is honest here — the list may well have data,\n // just not on this page — so heading/body switch to the \"wrong page\"\n // copy and the CTA offers a single-click way back to page 1.\n const isWrongPage = page > 1;\n const EmptyIcon = isFiltered ? IconFilterX : IconInbox;\n const items = resourceLabel.toLowerCase();\n // The five `list.empty*` texts read the resource level first (`resources.<r>.list.*`, a\n // resource's `texts.list`), then `resources._.list` and `common.list` (phase 3 plan ruling 16).\n // `pagination.emptyPage` stays shared. The list gets no `ResourceContext`: chrome keys such as\n // `actions.cancel` would then meet a flow's entry at `resources.<r>.actions.cancel`.\n const heading = isWrongPage\n ? t('pagination.emptyPage')\n : isFiltered\n ? t('list.emptyFilteredTitle', { resource, params: { items } })\n : t('list.emptyTitle', { resource, params: { items } });\n // The wrong-page flavour deliberately has NO body: its heading already says\n // the whole story and the recovery button below says what to do, so a\n // paragraph would just repeat the heading verbatim.\n const body = isWrongPage\n ? null\n : isFiltered\n ? t('list.emptyFilteredBody', { resource, params: { items } })\n : createHref\n ? t('list.emptyBody', {\n resource,\n params: { item: recordSingular.toLowerCase() },\n })\n : // No create here: inviting the user to create one would be a dead end.\n t('list.emptyBodyReadOnly', { resource, params: { items } });\n // Zero rows does not mean \"no more data\" for a cursor list: server-side\n // filtering can legitimately leave the CURRENT token's page empty while a\n // later token still has matches (`hasMore: true` has no dependency on\n // `rows.length` — see the `loadMore` docblock above). So the panel and\n // the load-more control render TOGETHER here rather than one replacing\n // the other: the panel explains this page is empty, the control offers\n // the next one. `<CursorLoadMore>` already no-ops when `hasMore` is\n // false, so this is a no-op appendage on an honestly-exhausted list.\n return (\n <>\n <div\n className={cn(\n 'flex flex-col items-center justify-center gap-3 px-6 py-16 rounded-lg border border-dashed text-center',\n className,\n )}\n data-testid={tid.listEmpty(resource)}\n >\n <div className=\"rounded-full bg-muted p-3 text-muted-foreground\">\n <EmptyIcon className=\"size-6\" aria-hidden=\"true\" />\n </div>\n <div className=\"space-y-1\">\n <h3 className=\"text-base font-semibold tracking-tight\">{heading}</h3>\n {body ? <p className=\"max-w-sm text-sm text-muted-foreground\">{body}</p> : null}\n </div>\n <div className=\"flex justify-center gap-2 pt-2\">\n {onClearFilter && (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n data-testid={`list-clear-filter:${resource}`}\n onClick={onClearFilter}\n >\n {t('list.clearFilter')}\n </Button>\n )}\n {/* NOT on a wrong page: \"+ Create\" implies the list is empty, but an\n out-of-range page says nothing about whether records exist — the\n list may be full. Offering it there is the same false claim the\n heading above was fixed to stop making. */}\n {!isFiltered && !isWrongPage && createHref && (\n <RouterLink href={createHref}>\n <Button type=\"button\" size=\"sm\" data-testid={`list-empty-create:${resource}`}>\n {t('list.create', { params: { item: recordSingular } })}\n </Button>\n </RouterLink>\n )}\n {isWrongPage && onPage && (\n <Button\n type=\"button\"\n size=\"sm\"\n data-testid={`list-empty-first-page:${resource}`}\n onClick={() => onPage(1)}\n >\n {t('pagination.firstPage')}\n </Button>\n )}\n {/* The count is LOAD-BEARING here and nowhere else in this panel.\n An out-of-range page is empty precisely because nothing knows\n where the list ends: the clamp at the top of this component is\n gated on `knownTotal` and is therefore dead. Answering the count\n un-gates it, and the user is snapped to the LAST real page —\n a second recovery route, and the opposite one to «Back to start».\n That makes the two co-equal choices, so this reads as the\n established secondary action of this row (the same treatment\n `list-clear-filter` above uses) rather than as the footer's\n sentence-continuation link.\n\n ⚠️ NOT offered on the page-1 empty state: with server-side\n filtering an empty first page IS the count — the answer is\n always 0, and the panel already says so.\n ⚠️ Supplying `emptyState` skips this whole branch (see the guard\n at the top of it), so a B3 list-body slot adopter gets no\n affordance at zero rows. Out of scope here; noted so the next\n reader does not think it was missed. */}\n {isWrongPage && !knownTotal && onRequestCount && (\n <CountRowsTrigger\n label={t('pagination.countRows')}\n loading={isCountingRows}\n onClick={onRequestCount}\n testid={`list-count:${resource}`}\n variant=\"outline\"\n />\n )}\n </div>\n </div>\n {loadMore && (\n <CursorLoadMore\n hasMore={loadMore.hasMore}\n loading={loadMore.loading}\n onMore={loadMore.onMore}\n />\n )}\n </>\n );\n }\n\n return (\n <FlowRowBatchContext.Provider value={flowRowBatch}>\n <RowActionsCollapseContext.Provider value={narrow}>\n {rowBatch.reader}\n <div ref={listRoot} className={cn('space-y-4', className)}>\n {rowsView !== undefined ? (\n rowsView.render(rows)\n ) : (\n <DataTable\n table={table}\n tableTestId={tid.listTable(resource)}\n ariaLabel={ariaLabel}\n // Reachable only via the `emptyState` prop above: without it this\n // component early-returns its own panel before ever rendering the\n // table, which is why `DataTable`'s prop sat unused until B3.2.\n emptyState={emptyState}\n onColumnReorder={(fromId, toId) => {\n // Seed the order from the CURRENT visible leaf order (columnOrder may\n // be empty, meaning \"natural order\"), then move `from` to `to`'s slot.\n const current = table.getState().columnOrder;\n const base =\n current.length > 0 ? current : table.getVisibleLeafColumns().map((c) => c.id);\n const next = base.filter((id) => id !== fromId);\n const at = next.indexOf(toId);\n next.splice(at < 0 ? next.length : at, 0, fromId);\n setColumnOrder(next);\n }}\n getRowTestId={getRowTestId}\n getCellTestId={getCellTestId}\n // Row click affordance: when the consumer provides a `rowHref`,\n // most rows carry a clickable first-cell anchor — surface that\n // to the rest of the row by adding `cursor-pointer` so users see\n // the row is clickable wherever they hover, not just over the\n // title cell. The actual click is still handled by the anchor\n // for proper href semantics + middle-click + copy-link support.\n // Per-row, not per-callback: `rowHref` can return `''` for a\n // record the availability gate has no destination for (Task 8),\n // and that row must NOT look clickable either.\n rowClassName={rowHref || rowQuick ? stableRowClassName : undefined}\n // #4 — whole-row click navigates (Cmd/Ctrl/middle-click → new tab). The\n // first cell stays a real anchor for keyboard/copy-link; this adds the\n // mouse affordance across the rest of the row. Routed through the\n // stable `stableRowHref` wrapper (reads `rowHref` via `volatileRef`)\n // so its identity doesn't change every render — see the row/cell\n // memoization in `DataTable`.\n rowHref={rowHref ? stableRowHref : undefined}\n onRowOpen={rowQuick ? stableRowOpen : undefined}\n // Row-selection checkbox column id (table render perf #1): tells\n // `DataTable` which cell must keep re-rendering on `isSelected`\n // changes while every other cell (the actions kebab, data cells)\n // stays memoized-frozen across selection-only renders.\n selectionColumnId={selectable ? SELECT_COL_ID : undefined}\n />\n )}\n\n {/* Cursor (opaque-token) lists have no page index to jump to, so they get\n a load-more footer instead of the numbered pager below. `loadMore`\n wins over `showPager` on purpose — it is a plain prop, not read from\n the controller, so this component stays mountable standalone (see\n the `loadMore` docblock above).\n\n ⚠️ Deliberately NOT gated on `showPager` (`rows.length > 0`):\n `hasMore` comes from the cursor token, which has no relationship to\n how many rows the CURRENT page happens to hold — server-side\n filtering can legitimately return zero rows for this token while a\n later token still has matches. Consulting row count here would\n strand that case. `<CursorLoadMore>` already no-ops on\n `hasMore: false`, so this stays correctly silent once the list is\n actually exhausted. (The zero-rows-AND-no-custom-emptyState case is\n handled earlier, at the empty-state early return, where the panel\n and this same control render together.) */}\n {loadMore && (\n <CursorLoadMore\n hasMore={loadMore.hasMore}\n loading={loadMore.loading}\n onMore={loadMore.onMore}\n />\n )}\n {showPager && !loadMore && (\n <div className=\"flex items-center justify-between border-t pt-3 text-sm\">\n {/* \"Showing X–Y of Z\" — admin-grade range readout, more\n human than the prior \"Page X of Y (Z total)\" form. The\n range uses the page index + pageSize math; clamps the\n upper bound at total when the last page is partial. */}\n {/* `aria-live` so the answer to an on-demand count is announced: the\n readout rewrites itself from «Showing 1–10» to «Showing 1–10 of\n 9 800 000» with no focus change and nothing else to notice. */}\n <div className=\"text-muted-foreground tabular-nums\" aria-live=\"polite\">\n {knownTotal\n ? t('pagination.showing', {\n params: {\n from: nf.format((page - 1) * pageSize + 1),\n to: nf.format(Math.min(page * pageSize, total as number)),\n total: nf.format(total as number),\n },\n })\n : /* Without a count, printing «of 10» would state a total that is\n off by nine million. Show the range only. */\n t('pagination.showingUnknownTotal', {\n params: {\n from: nf.format((page - 1) * pageSize + 1),\n to: nf.format((page - 1) * pageSize + rows.length),\n },\n })}\n {/* The trigger sits at the END of that sentence, in the very spot\n where «of {{total}}» prints once the count lands — so \"the\n number appears where you asked for it\" is literal, and the\n trigger disappears because the `knownTotal` branch above takes\n over. It is styled as prose, not as a control: the four pager\n buttons opposite are all boxed `outline sm`, and a fifth boxed\n control would read as a button bar. `link` is the only boxless\n variant; matching the readout's size and muted colour makes it\n a continuation of the sentence rather than a new element. */}\n {!knownTotal && onRequestCount && (\n <CountRowsTrigger\n label={t('pagination.countRows')}\n loading={isCountingRows}\n onClick={onRequestCount}\n testid={`list-count:${resource}`}\n variant=\"link\"\n className=\"ml-1.5 h-auto p-0 align-baseline text-sm font-normal text-muted-foreground underline underline-offset-4 hover:text-foreground\"\n />\n )}\n </div>\n <div className=\"flex items-center gap-2\">\n {/* Ten rows over hundreds of pages is a daily tax for anyone\n scanning records; the size selector is the cheapest fix. Hidden\n unless the host can persist the choice (see `onPageSize`). */}\n {onPageSize && (\n <div className=\"flex items-center gap-2\">\n <span className={narrow ? 'sr-only' : 'text-muted-foreground'}>\n {t('pagination.rowsPerPage', { defaultValue: 'Rows per page' })}\n </span>\n <Select value={String(pageSize)} onValueChange={(v) => onPageSize(Number(v))}>\n <SelectTrigger\n className=\"h-8 w-[4.5rem]\"\n data-testid={`list-page-size:${resource}`}\n >\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {pageSizeOptions.map((n) => (\n <SelectItem key={n} value={String(n)}>\n {n}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n )}\n <span className={cn('text-muted-foreground tabular-nums', narrow && 'hidden')}>\n {knownTotal\n ? t('pagination.pageOf', {\n params: { page: nf.format(page), total: nf.format(totalPages as number) },\n })\n : t('pagination.pageOnly', { params: { page: nf.format(page) } })}\n </span>\n {/* First/last jumps: 270 pages reachable only by Back/Forward means\n 199 clicks to reach page 200. Rendered only when they would do\n something a neighbour button cannot. */}\n {knownTotal && (totalPages as number) > 2 && (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n data-testid={`list-pagination-first:${resource}`}\n aria-label={t('pagination.firstPage')}\n disabled={page <= 1}\n onClick={() => onPage?.(1)}\n className=\"h-8 w-8 p-0\"\n >\n <IconChevronsLeft className=\"size-4\" aria-hidden=\"true\" />\n </Button>\n )}\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n data-testid={tid.listPaginationPrev(resource)}\n disabled={page <= 1}\n onClick={() => onPage?.(page - 1)}\n // Narrow, an icon: the words made the pager wider than a phone.\n className={cn('h-8 gap-1', narrow && 'w-8 p-0')}\n >\n <IconChevronLeft className=\"size-4\" aria-hidden=\"true\" />\n <span className={narrow ? 'sr-only' : undefined}>{t('pagination.prev')}</span>\n </Button>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n data-testid={tid.listPaginationNext(resource)}\n disabled={!hasNextPage}\n onClick={() => onPage?.(page + 1)}\n className={cn('h-8 gap-1', narrow && 'w-8 p-0')}\n >\n <span className={narrow ? 'sr-only' : undefined}>{t('pagination.next')}</span>\n <IconChevronRight className=\"size-4\" aria-hidden=\"true\" />\n </Button>\n {/* No jump-to-end without a known end. */}\n {knownTotal && (totalPages as number) > 2 && (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n data-testid={`list-pagination-last:${resource}`}\n aria-label={t('pagination.lastPage')}\n disabled={page >= (totalPages as number)}\n onClick={() => onPage?.(totalPages as number)}\n className=\"h-8 w-8 p-0\"\n >\n <IconChevronsRight className=\"size-4\" aria-hidden=\"true\" />\n </Button>\n )}\n </div>\n </div>\n )}\n </div>\n </RowActionsCollapseContext.Provider>\n </FlowRowBatchContext.Provider>\n );\n}\n","'use client';\nimport type { ScopeSource } from '@burojs/core';\nimport { useOptionalT } from '@burojs/react';\nimport type { ReactElement } from 'react';\n\n/**\n * A related list bound to no rows (a `where` value that resolved to nothing, a link panel whose\n * record is not read yet): the empty state, and no request.\n */\nexport function UnboundRelatedList(props: {\n readonly resource: string;\n readonly title?: string | undefined;\n /** The placement's own empty text (`BlockViewProps.empty`), in place of the kit's. */\n readonly empty?: string;\n}): ReactElement {\n const t = useOptionalT();\n return (\n <div className=\"flex flex-col gap-2\" data-testid={`list-unbound:${props.resource}`}>\n {props.title === undefined ? null : <h3 className=\"text-sm font-semibold\">{props.title}</h3>}\n <p className=\"text-sm text-muted-foreground\">\n {props.empty ?? t('table.empty', { defaultValue: 'No records' })}\n </p>\n </div>\n );\n}\n\n/**\n * Where a placement's reads take their scope from: its own `scope`, else `'none'` on a record's\n * card (a tab lists what belongs to the record, whatever the session's scope) and `'session'` on\n * a custom page, which has no record around it.\n */\nexport function placementScope(\n scope: ScopeSource | undefined,\n owner: string | undefined,\n): ScopeSource {\n return scope ?? (owner === undefined ? 'session' : 'none');\n}\n","'use client';\nimport { isFlowAction } from '@burojs/core/internal';\nimport {\n useApp,\n useCapability,\n useFlowRowResolver,\n useOptionalDataRuntime,\n useResourceExport,\n} from '@burojs/react';\nimport type { ReactElement } from 'react';\n\n/**\n * Whether a declared bulk flow of `resource` would be drawn in the selection bar: the bar's own\n * gate (`BulkFlowButton`), asked without a record. A disabled flow is drawn (inert, with its\n * reason), so it counts; a hidden or absent one does not.\n */\nexport function useBulkFlowReachable(resource: string): boolean {\n const app = useApp();\n const control = useFlowRowResolver(resource);\n const bulk = (app.registry.get(resource)?.actions.bulk ?? []) as readonly unknown[];\n return bulk.some(\n (action) =>\n isFlowAction(action) &&\n control((action as { readonly name: string }).name, undefined).state !== 'absent',\n );\n}\n\n/** The bar's built-in Export gate (`BulkExportButtonActive`): an exporter and the `export` right. */\nfunction ExportReach(props: {\n readonly resource: string;\n readonly children: (reachable: boolean) => ReactElement;\n}): ReactElement {\n const { available } = useResourceExport(props.resource);\n const capability = useCapability('run', {\n resource: props.resource,\n target: { kind: 'action', name: 'export' },\n mode: 'list',\n });\n return props.children(available && capability.allowed);\n}\n\n/**\n * Renders `children` with whether the built-in bulk Export is reachable. Without a data runtime\n * there is no export (the bar draws none either), and its hooks are not called.\n */\nexport function BulkExportReach(props: {\n readonly resource: string;\n readonly children: (reachable: boolean) => ReactElement;\n}): ReactElement {\n const hasDataRuntime = useOptionalDataRuntime() !== null;\n return hasDataRuntime ? <ExportReach {...props} /> : props.children(false);\n}\n","'use client';\nimport { type FramePiece, useFramePiece } from '@burojs/react';\nimport type { ReactElement } from 'react';\n\n/**\n * A list piece as a frame places it: its view in a frame, a marker under `checkFrame` (which\n * renders a frame alone, without the list controller the pieces read).\n */\nexport function listPiece(\n name: FramePiece,\n View: () => ReactElement | null,\n): () => ReactElement | null {\n function Piece(): ReactElement | null {\n const check = useFramePiece(name);\n if (check?.stub === true) return <span data-check-piece={name} />;\n return <View />;\n }\n Piece.displayName = name;\n return Piece;\n}\n","'use client';\nimport { type ReactNode, createContext, useContext, useEffect, useMemo, useRef } from 'react';\nimport type { SearchDecl } from '@burojs/core';\nimport type { SavedViewEntry } from '@burojs/react';\nimport type { ComponentType, ReactElement } from 'react';\nimport type { ItemHandle } from '../../blocks/related-item.js';\nimport type { ResourceListProps } from '../../resource/resource-list.js';\n\n/** The names of the list pieces a frame arranges (P7-33). */\nexport type ListPieceName =\n | 'filters'\n | 'flows'\n | 'live'\n | 'saved-views'\n | 'columns'\n | 'export'\n | 'create'\n | 'body'\n | 'bulk-bar';\n\n/**\n * A link panel's writes: Attach (drawn in the placement's header) and Detach (selection, a row\n * button and the bulk bar of a read-only list).\n */\nexport interface ListLinkEditing {\n readonly attach?: { readonly onAttach: () => void; readonly busy?: boolean };\n /** Resolves to the row ids that left (they leave the selection). */\n readonly detach?: {\n readonly onDetach: (\n rows: readonly Readonly<Record<string, unknown>>[],\n ) => Promise<readonly string[]>;\n };\n}\n\n/** What the route and placement lists share with their pieces: everything that is not the controller. */\nexport interface ListSurfaceValue {\n readonly resource: string;\n /** The route list (saved views, create, the page header) rather than a `related-list` placement. */\n readonly route: boolean;\n /** The table draws rows, columns, selection and the bulk bar; cards and timeline do not. */\n readonly tableView: boolean;\n /** The placement's own search box declaration; the route list reads `views.list.search`. */\n readonly searchDecl: SearchDecl | undefined;\n /** `list.filters.<r>`: replaces the contents of the filter region. */\n readonly FiltersSlot: ComponentType | undefined;\n readonly savedViewsUi: {\n readonly canSaveCurrent: boolean;\n readonly canFork: boolean;\n readonly onSaveCurrent: () => void;\n readonly onManage: () => void;\n readonly onRenameEntry: (entry: SavedViewEntry) => void;\n readonly onForkEntry: (entry: SavedViewEntry) => void;\n readonly onDeleteEntry: (entry: SavedViewEntry) => void;\n };\n readonly openCreate: (() => void) | undefined;\n readonly createAvailable: boolean;\n readonly createPage: boolean;\n /** What a row opens, and how the cards or timeline draw the rows: straight to `<ResourceList>`. */\n readonly rowProps: Partial<Pick<ResourceListProps, 'rowHref' | 'rowQuick' | 'rowLinkKey'>>;\n /**\n * How cards or a timeline draw the rows, given the planned item block (the route list's comes\n * from its frame's plan, `ListItemContext`; a placement's is its own prop). Absent for a table.\n */\n readonly rowsViewFor:\n | ((item: ItemHandle | undefined) => ResourceListProps['rowsView'])\n | undefined;\n readonly emptyState: ReactNode;\n /** The route's cell ladder: a typed discriminator, an enum badge, then `renderCell` / `list.cell.<r>`. */\n readonly renderCell: NonNullable<ResourceListProps['renderCell']>;\n /** A read-only list: no row actions, no selection, no bulk bar. */\n readonly readOnly: boolean;\n /** The list draws its export control. */\n readonly exportable: boolean;\n /** The table's layout list id (`ResourceListSurfaceProps.layoutId`); absent: kept in memory. */\n readonly layoutId?: string;\n /**\n * A read-only link panel's Detach (Attach is drawn by the surface's header). Its `onDetach`\n * here already takes the rows that left out of the selection.\n */\n readonly linkEditing?: ListLinkEditing;\n}\n\nconst SurfaceContext = createContext<ListSurfaceValue | null>(null);\n\n/**\n * The route list's planned item block, provided by the frame host that plans the list's screen\n * (P7-36); `undefined` where there is none, and the rows then draw their default item.\n * @internal\n */\nexport const ListItemContext = createContext<ItemHandle | undefined>(undefined);\n\ninterface PieceCounts {\n readonly counts: Map<ListPieceName, number>;\n readonly register: (name: ListPieceName) => () => void;\n}\n\nconst PiecesContext = createContext<PieceCounts | null>(null);\n\n/**\n * Provides the surface's shared value to the pieces and counts how many times each is mounted\n * (a frame that omits or repeats a piece is reported by the surface, P7-34). Registration is\n * effect-based and balanced, so StrictMode's simulated unmount and remount leave one count per\n * mounted instance, not two (Known finding 20).\n * @internal\n */\nexport function ListPiecesProvider(props: {\n readonly value: ListSurfaceValue;\n readonly counts?: (counts: ReadonlyMap<ListPieceName, number>) => void;\n readonly children: ReactNode;\n}): ReactElement {\n const { value, children } = props;\n const registry = useRef<PieceCounts | null>(null);\n if (registry.current === null) {\n const counts = new Map<ListPieceName, number>();\n registry.current = {\n counts,\n register: (name) => {\n counts.set(name, (counts.get(name) ?? 0) + 1);\n return () => {\n counts.set(name, (counts.get(name) ?? 1) - 1);\n };\n },\n };\n }\n const stable = useMemo(() => registry.current as PieceCounts, []);\n return (\n <PiecesContext.Provider value={stable}>\n <SurfaceContext.Provider value={value}>{children}</SurfaceContext.Provider>\n </PiecesContext.Provider>\n );\n}\n\n/** The mount counts so far, by piece (the surface reads them after its frame has mounted). @internal */\nexport function useListPieceCounts(): () => ReadonlyMap<ListPieceName, number> {\n const pieces = useContext(PiecesContext);\n return () => pieces?.counts ?? new Map();\n}\n\n/** Registers one mounted piece instance. @internal */\nexport function usePieceMount(name: ListPieceName): void {\n const pieces = useContext(PiecesContext);\n useEffect(() => pieces?.register(name), [pieces, name]);\n}\n\n/** The surface's shared value; throws outside a list. @internal */\nexport function useListSurface(): ListSurfaceValue {\n const value = useContext(SurfaceContext);\n if (value === null)\n throw new Error('A list piece (ListControls, ListBody, …) renders inside a resource list.');\n return value;\n}\n\n/**\n * Draws its children as the table, whatever `views.list.initial.view` says: cards and a timeline read\n * their rows through the screen tree, which the built-in fallback arrangement does not have.\n * Only the surface value changes; the mount counts stay the surface's own.\n * @internal\n */\nexport function ForceTableView(props: { readonly children: ReactNode }): ReactElement {\n const value = useListSurface();\n const forced = useMemo(() => ({ ...value, tableView: true, rowsViewFor: undefined }), [value]);\n return <SurfaceContext.Provider value={forced}>{props.children}</SurfaceContext.Provider>;\n}\n","'use client';\nimport { type ReactElement, useContext, useMemo, useState } from 'react';\nimport { IconUnlink } from '@tabler/icons-react';\nimport { policyRowsOf, useOptionalT, useResourceListContext } from '@burojs/react';\nimport { Button } from '../../primitives/button.js';\nimport { ResourceList } from '../../resource/resource-list.js';\nimport { UnboundRelatedList } from '../../blocks/related-list-unbound.js';\nimport { BulkExportReach, useBulkFlowReachable } from './bulk-reach.js';\nimport { listPiece } from './piece.js';\nimport { ListItemContext, useListSurface, usePieceMount } from './pieces-context.js';\n\n/** A link panel row's Detach: confirms (the panel's) and removes this row's link. */\nfunction LinkDetachRowButton(props: {\n readonly row: Readonly<Record<string, unknown>> & { readonly id: string };\n}): ReactElement | null {\n const { resource, linkEditing } = useListSurface();\n const t = useOptionalT();\n const [busy, setBusy] = useState(false);\n const detach = linkEditing?.detach;\n if (detach === undefined) return null;\n const label = t('field.link.detach', { defaultValue: 'Detach' });\n return (\n <Button\n type=\"button\"\n size=\"icon\"\n variant=\"ghost\"\n className=\"size-7\"\n aria-label={label}\n title={label}\n disabled={busy}\n data-testid={`list-link-detach:${resource}:${props.row.id}`}\n onClick={(event) => {\n event.stopPropagation();\n setBusy(true);\n void detach.onDetach([props.row]).finally(() => setBusy(false));\n }}\n >\n <IconUnlink className=\"size-4\" aria-hidden=\"true\" />\n </Button>\n );\n}\n\n/** A stable renderer for the row-actions column of a link panel (the column rebuilds on a new one). */\nconst linkDetachRow = (row: Readonly<Record<string, unknown>> & { readonly id: string }) => (\n <LinkDetachRowButton row={row} />\n);\n\n/**\n * The rows: the table, or cards or a timeline over the same controller, with the empty state,\n * the pager (or \"load more\") and the on-demand count.\n */\nfunction ListBodyView() {\n usePieceMount('body');\n const list = useResourceListContext();\n const {\n resource,\n route,\n tableView,\n createAvailable,\n createPage,\n rowProps,\n rowsViewFor,\n emptyState,\n renderCell,\n readOnly,\n linkEditing,\n layoutId,\n } = useListSurface();\n // A read-only list selects and acts on rows only for a link panel's Detach.\n const detachable = readOnly && linkEditing?.detach !== undefined;\n // Rows are selectable only when the selection bar has something to offer them.\n const flowReachable = useBulkFlowReachable(resource);\n const selectable = (exportReachable: boolean) =>\n tableView && (detachable || (!readOnly && (flowReachable || exportReachable)));\n const item = useContext(ListItemContext);\n const rowsView = useMemo(() => rowsViewFor?.(item), [rowsViewFor, item]);\n const { query, pagination, cursor, count, columns, selection, filters, sorting, routing } = list;\n // The table keeps the rows as read: selection, the quick opener and item-action gates are\n // policy, and its cells project each row on their own (`viewRow`).\n const rows = policyRowsOf(list, list.rows);\n // A selected option reads a user or scope value that is not there (T4 D6, C17): the list\n // requests nothing, so it shows the unbound state in place of its rows. The filter bar stays,\n // so the user can change the selection.\n if (query.unbound) return <UnboundRelatedList resource={resource} />;\n const view = (exportReachable: boolean) => (\n <ResourceList\n resource={resource}\n data={rows}\n total={pagination.total}\n page={pagination.page}\n pageSize={pagination.pageSize}\n pageSizeOptions={pagination.pageSizeOptions}\n onPage={pagination.setPage}\n // `setPageSize` anchors back to page 1 itself: row 41 of the old\n // size may not exist under the new one.\n onPageSize={pagination.setPageSize}\n // Cursor (token) pagination — `controller.cursor` is non-null exactly\n // when the resource declares `views.list.pagination: 'cursor'`; the\n // `pagination.*` props above stay wired but go inert in that mode,\n // since `<ResourceList>` prefers `loadMore` over the numbered pager\n // whenever it is present.\n loadMore={\n cursor === null\n ? undefined\n : {\n hasMore: cursor.next !== null,\n loading: cursor.isLoadingMore,\n onMore: cursor.loadMore,\n }\n }\n // On-demand count (B4.3). `undefined` — not a no-op callback — when\n // the resolved provider implements no `getCount` or has already\n // answered \"this cannot be counted here at all\": that is the prop's\n // own render gate, so an unavailable count renders nothing at all.\n // The answer itself needs no wiring; it writes through to\n // `pagination.total` above.\n onRequestCount={count.available ? count.request : undefined}\n isCountingRows={count.isLoading}\n columns={columns.visible}\n columnUi={columns.ui}\n isLoading={query.isLoading}\n error={query.error}\n onRetry={query.refetch}\n createHref={route && createAvailable && createPage ? routing.createHref : undefined}\n {...rowProps}\n {...(rowsView === undefined ? {} : { rowsView })}\n selectable={selectable(exportReachable)}\n rowActions={detachable ? linkDetachRow : !readOnly}\n selectedIds={selection.ids}\n onSelectionChange={selection.set}\n isFiltered={filters.isFiltered}\n // The reset returns to `initial`, so it is offered only while there is something to reset;\n // `isFiltered` above only picks the wording.\n onClearFilter={filters.canReset ? filters.reset : undefined}\n // Undefined for every caller that doesn't override it, which is\n // what keeps the standard empty-state panel the default.\n emptyState={emptyState}\n sort={sorting.value ?? []}\n requiredColumns={columns.required}\n resetLayout={columns.resetLayout}\n // Where the user's widths, order and pinning are stored (REF-117 §4.10).\n layoutId={layoutId}\n // Header-menu «hide» — no-ops on a required column.\n onHideColumn={columns.hide}\n // The 3-click toggle (new field → asc → desc → null) plus the\n // header menu's explicit-direction path.\n onSort={sorting.toggle}\n // Which columns offer sort: the controller's one rule (T4 D7).\n sortable={sorting.sortable}\n renderCell={renderCell}\n />\n );\n return <BulkExportReach resource={resource}>{view}</BulkExportReach>;\n}\n\nexport const ListBody: () => ReactElement | null = listPiece('ListBody', ListBodyView);\n","'use client';\nimport type { FormController } from '@burojs/react';\nimport { createContext, useContext, useMemo, useRef } from 'react';\n\n/**\n * Minimal form-control handle exposed to field renderers so a field can update\n * SIBLING fields (a field renderer otherwise only sees its own value). Used for\n * reactive prefills — e.g. picking a product on a GTIN field also fills the\n * «Product name» / «Code type» fields (#2). Every form host provides it:\n * `<RecordScreen>`, a flow's form and `<DeclarativeForm>`.\n */\nexport interface FormControl {\n /** Merge a patch of `{ fieldName: value }` into the form's live values. */\n setValues: (patch: Record<string, unknown>) => void;\n}\n\nconst FormControlContext = createContext<FormControl | null>(null);\n\nexport const FormControlProvider = FormControlContext.Provider;\n\n/**\n * The handle a form host provides over its controller: each entry is set through the same\n * `setValue` the user's typing uses. Stable across renders; it always reaches the latest\n * controller.\n */\nexport function useFormControlOf(controller: Pick<FormController, 'setValue'>): FormControl {\n const latest = useRef(controller);\n latest.current = controller;\n return useMemo(\n () => ({\n setValues: (patch) => {\n for (const [name, value] of Object.entries(patch)) latest.current.setValue(name, value);\n },\n }),\n [],\n );\n}\n\n/** Read the surrounding form's control handle, or `null` outside a form. */\nexport function useFormControl(): FormControl | null {\n return useContext(FormControlContext);\n}\n","import { createContext, useContext } from 'react';\n\n/**\n * Set by the record route around the screen it renders: the next `<RecordScreen>` below it is a\n * route screen. That screen claims it (its descendants see `false`), so a screen nested inside\n * it — a dialog, a popover — is not one. Internal.\n */\nexport const RouteScreenClaimContext = createContext(false);\n\n/** Whether the `<RecordScreen>` around the caller is the route's own screen. Internal. */\nexport const RouteScreenContext = createContext(false);\n\n/**\n * Set by a quick entry around the screen it renders: the next `<RecordScreen>` below it is the\n * entry's own (it reads the entry's `route`, and the host draws its title). That screen claims it,\n * so a screen nested inside it is not one. Internal.\n */\nexport const QuickScreenClaimContext = createContext(false);\n\n/** Whether the screen around the caller is a route screen (`state: 'url'` is honoured there). */\nexport function useIsRouteScreen(): boolean {\n return useContext(RouteScreenContext);\n}\n","'use client';\nimport {\n type ScreenOpenState,\n useOptionalRecordFrame,\n useOptionalRouterAdapter,\n useSearchParamsWriter,\n} from '@burojs/react';\nimport { useCallback, useMemo, useState } from 'react';\nimport { useIsRouteScreen } from '../record/route-screen-context.js';\n\nconst CLOSED: ScreenOpenState = Object.freeze({\n containers: Object.freeze({}),\n collapsed: Object.freeze([]),\n});\n\n/**\n * A record screen's open panels (P1b+P1c decision 10). Called by\n * `<RecordScreen>` and the page host above their screen state, so it needs no\n * compiled screen: the state is held in memory, and on a route screen (the\n * caller's claim, `isRouteScreen`) in show and edit under a router every\n * search parameter is overlaid as `containers[param] = value`. Off a route\n * screen — a quick entry, a dialog, any screen rendered beside the page's own —\n * the page's query is not read (P3-35). A keyed tabs\n * node's compiled id is its key, and the planner ignores an entry that names\n * no container or an absent panel, so a list-state parameter, an old `?tab=`\n * or a denied `?sections=secret` falls back to the first permitted panel.\n * Because the URL is read on every render, Back and Forward re-plan.\n */\nexport function useTabsUrlState(\n mode: 'show' | 'edit' | 'create',\n isRouteScreen: boolean,\n): {\n readonly open: ScreenOpenState;\n readonly onOpenChange: (next: ScreenOpenState) => void;\n} {\n const adapter = useOptionalRouterAdapter();\n const [memory, setMemory] = useState<ScreenOpenState>(CLOSED);\n // A create's steps read `containers` as the current step: memory only.\n const params =\n adapter === null || mode === 'create' || !isRouteScreen ? null : adapter.searchParams;\n const search = params?.toString() ?? '';\n // biome-ignore lint/correctness/useExhaustiveDependencies: keyed by the query string, not the params object\n const open = useMemo<ScreenOpenState>(() => {\n if (params === null) return memory;\n const containers: Record<string, string> = { ...memory.containers };\n for (const [name, value] of params) containers[name] = value;\n return Object.freeze({ ...memory, containers: Object.freeze(containers) });\n }, [memory, params === null, search]);\n return { open, onOpenChange: setMemory };\n}\n\n/**\n * How a keyed tabs node writes its panel: `?<tabsKey>=<panelKey>`, pushed in\n * show and replaced in edit (a reveal always replaces), the default panel\n * never written. `null` off a route screen (a `<RecordScreen>` outside its\n * route, a quick entry), without a router adapter and in create: the tabs\n * node then keeps its panel in the screen state and the page's URL is left\n * alone (P3-35).\n */\nexport function useTabsUrlSelect():\n | ((tabsKey: string, panelKey: string, isDefault: boolean, reveal?: boolean) => void)\n | null {\n const frame = useOptionalRecordFrame();\n const adapter = useOptionalRouterAdapter();\n const write = useSearchParamsWriter();\n // A page is a route screen with no record frame (P2 4.6): it writes as a show does.\n const routeScreen = useIsRouteScreen();\n const mode = frame?.mode ?? (routeScreen ? 'show' : undefined);\n const select = useCallback(\n (tabsKey: string, panelKey: string, isDefault: boolean, reveal = false) =>\n write(\n (params) => {\n if (isDefault) params.delete(tabsKey);\n else params.set(tabsKey, panelKey);\n },\n { history: mode === 'show' && !reveal ? 'push' : 'replace' },\n ),\n [write, mode],\n );\n if (!routeScreen || adapter === null || mode === 'create') return null;\n return select;\n}\n","'use client';\nimport { formatEntityRef, type PlanNode } from '@burojs/core';\nimport {\n type FrameStep,\n type FrameTab,\n type PanelFrameViewProps,\n type StepsFrameViewProps,\n type TabsFrameViewProps,\n useFrameImplementations,\n useFrameT,\n useOptionalT,\n useScreenState,\n} from '@burojs/react';\nimport {\n type ComponentType,\n type ReactElement,\n type ReactNode,\n Suspense,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n} from 'react';\nimport { nodeAttributes, nodeInfo, PendingSkeleton, useNodeText } from '../screen/node-parts.js';\nimport { useReveal, useScreenTree } from '../screen/tree-context.js';\nimport { useTabsUrlSelect } from '../screen/use-tabs-url-state.js';\nimport { BuroPanelFrame, BuroStepsFrame, BuroTabsFrame } from './builtin-nodes.js';\nimport { resolveFrameView } from './resolve.js';\n\n/**\n * How a host renders a panel's children (the node dispatch lives in `screen/nodes.tsx`); `owner`\n * is the panel, whose `empty` stands in when no child is drawn.\n */\nexport type RenderChildren = (nodes: readonly PlanNode[], owner?: PlanNode) => ReactNode;\n\nconst BUILTIN_NODE_VIEWS = {\n panel: BuroPanelFrame,\n tabs: BuroTabsFrame,\n steps: BuroStepsFrame,\n} as const;\n\n/**\n * The view a node host draws and its frame id: the node's effective frame (its own ← the app's\n * ← `buro:<kind>`, resolved by the compiler) looked up like a record frame; `builtin` when the\n * view is the kit's own (it then takes the kit's extensions). A panel drawn by its steps\n * container is always the built-in one.\n */\nfunction useNodeView<K extends keyof typeof BUILTIN_NODE_VIEWS>(\n node: PlanNode,\n kind: K,\n containerDrawn = false,\n): {\n // biome-ignore lint/suspicious/noExplicitAny: a node view of the resolved kind\n readonly view: ComponentType<any>;\n readonly id: string;\n readonly builtin: boolean;\n} {\n const { compiled } = useScreenTree();\n const catalog = useFrameImplementations();\n const ref = containerDrawn ? undefined : compiled.nodes[node.index]?.frame;\n return useMemo(() => {\n if (ref === undefined)\n return { view: BUILTIN_NODE_VIEWS[kind], id: `buro:${kind}`, builtin: true };\n const resolved = resolveFrameView(ref, catalog, kind);\n return {\n view: resolved.view,\n id: formatEntityRef(ref),\n builtin: resolved.view === BUILTIN_NODE_VIEWS[kind],\n };\n }, [ref, catalog, kind]);\n}\n\n/**\n * The framework's body element of a panel or a step: in a form (edit, create, inside the\n * `<form>`) a `fieldset` labelled by the title, elsewhere a `div`; the region names are\n * unchanged (P6-17).\n */\nfunction PanelBody({\n id,\n region,\n form,\n labelledBy,\n children,\n}: {\n readonly id?: string;\n readonly region: 'panel-body' | 'step-panel';\n readonly form: boolean;\n readonly labelledBy: string | undefined;\n readonly children: ReactNode;\n}): ReactElement {\n if (form)\n return (\n <fieldset\n {...(id === undefined ? {} : { id })}\n data-buro-region={region}\n {...(labelledBy === undefined ? {} : { 'aria-labelledby': labelledBy })}\n >\n {children}\n </fieldset>\n );\n return (\n <div {...(id === undefined ? {} : { id })} data-buro-region={region}>\n {children}\n </div>\n );\n}\n\n/**\n * A panel: the framework owns `open` (the plan's, toggled through the screen state), the\n * reveal (it calls the same `onToggle` the view is given), the error count and the body\n * element; the view draws the rest.\n */\nexport function PanelHost({\n node,\n region = 'panel-body',\n renderChildren,\n}: {\n readonly node: PlanNode;\n readonly region?: 'panel-body' | 'step-panel';\n readonly renderChildren: RenderChildren;\n}): ReactElement {\n const { compiled, controller, mode, form } = useScreenTree();\n const state = useScreenState();\n const text = useNodeText();\n const options = compiled.nodes[node.index]!.options;\n // A humanized slot's default (the key, humanized) captions a tab or a step; a standalone panel\n // draws a heading for it only when the bundle has an entry, never the humanized key itself.\n const title =\n options.title?.humanized === true\n ? text({ ...options.title, default: '' }) || undefined\n : text(options.title);\n const description = text(options.description);\n const collapsible = options.collapse !== undefined;\n // A collapsible panel's `open` is the plan's; the others are always drawn.\n const open = !collapsible || node.open !== false;\n const onToggle = useCallback(\n (next: boolean) => {\n if (collapsible) state?.setCollapsed(node.id, !next);\n },\n [collapsible, state, node.id],\n );\n useReveal(node.id, () => {\n if (collapsible && node.open === false) onToggle(true);\n });\n const errorCount = node.key === undefined ? 0 : controller.errorsIn(node.key);\n const bodyId = `panel-body:${node.id}`;\n const titleId = `panel-title:${node.id}`;\n const { view: View, id, builtin } = useNodeView(node, 'panel', region === 'step-panel');\n const t = useFrameT(id);\n const body =\n node.state === 'pending' ? (\n <PendingSkeleton />\n ) : open ? (\n <PanelBody\n id={bodyId}\n region={region}\n form={form}\n labelledBy={title === undefined ? undefined : titleId}\n >\n {renderChildren(node.children, node)}\n </PanelBody>\n ) : null;\n const props: PanelFrameViewProps & { stepPanel?: boolean } = {\n body,\n ...(title === undefined ? {} : { title }),\n ...(description === undefined ? {} : { description }),\n ...(options.tone === undefined ? {} : { tone: options.tone }),\n ...(options.icon === undefined ? {} : { icon: options.icon }),\n collapsible,\n open,\n onToggle,\n errorCount,\n mode,\n titleId,\n bodyId,\n info: nodeInfo(node, title ?? node.key ?? ''),\n nodeAttributes: nodeAttributes(node, node.kind, options.tone),\n t,\n ...(builtin && region === 'step-panel' ? { stepPanel: true } : {}),\n };\n return (\n <Suspense fallback={<PendingSkeleton />}>\n <View {...props} />\n </Suspense>\n );\n}\n\n/** The Radix value of a tab: its panel key, or its compiled id when it has none. */\nconst panelValue = (panel: PlanNode): string => panel.key ?? panel.id;\n\n/** A tab's reveal: selects its panel when it holds the first failing field. */\nfunction TabReveal({\n panel,\n select,\n}: {\n readonly panel: PlanNode;\n readonly select: (panel: PlanNode, reveal: boolean) => void;\n}): null {\n useReveal(panel.id, () => {\n if (panel.open !== true) select(panel, true);\n });\n return null;\n}\n\n/**\n * A tabs node: the framework owns which tab is active (the URL's or the screen state's), the\n * reveal, the error counts and demand (only the active tab's panel is rendered); the view draws\n * the strip.\n */\nexport function TabsHost({\n node,\n renderChildren,\n}: {\n readonly node: PlanNode;\n readonly renderChildren: RenderChildren;\n}): ReactElement {\n const { compiled, controller } = useScreenTree();\n const state = useScreenState();\n const text = useNodeText();\n const panels = node.children.filter((child) => child.state !== 'absent');\n // The panel the tabs open on when nothing says otherwise, and the one the URL omits: the declared\n // `default` if the user may see it, else the first permitted panel.\n const declared = compiled.nodes[node.index]!.options.default;\n const effectiveDefault =\n (declared === undefined ? undefined : panels.find((child) => child.key === declared)) ??\n panels[0];\n const open = panels.find((child) => child.open === true) ?? effectiveDefault;\n const urlSelect = useTabsUrlSelect();\n // A keyed tabs node in a routed record keeps its panel in the URL (decision 10); the\n // others, and every tabs node without a router, in the screen state.\n const select = (panel: PlanNode, reveal: boolean) => {\n if (urlSelect !== null && node.key !== undefined && panel.key !== undefined)\n urlSelect(node.key, panel.key, panel === effectiveDefault, reveal);\n else state?.openPanel(node.id, panelValue(panel));\n };\n const onSelect = (key: string) => {\n const panel = panels.find((candidate) => panelValue(candidate) === key);\n if (panel !== undefined) select(panel, false);\n };\n const titleOf = (panel: PlanNode) => text(compiled.nodes[panel.index]!.options.title) ?? panel.id;\n const tabs: FrameTab[] = panels.map((panel) => ({\n key: panelValue(panel),\n title: titleOf(panel),\n errorCount: panel.key === undefined ? 0 : controller.errorsIn(panel.key),\n panel:\n panels.length === 1 || panel.open === true ? (\n // biome-ignore lint/complexity/noUselessFragments: a view receives an element, not a node list\n <>{renderChildren(panel.children, panel)}</>\n ) : null,\n }));\n const { view: View, id } = useNodeView(node, 'tabs');\n const t = useFrameT(id);\n const props: TabsFrameViewProps = {\n tabs,\n active: open === undefined ? '' : panelValue(open),\n onSelect,\n info: nodeInfo(node, node.key ?? ''),\n nodeAttributes: nodeAttributes(node),\n t,\n };\n return (\n <>\n {panels.length > 1\n ? panels.map((panel) => <TabReveal key={panel.id} panel={panel} select={select} />)\n : null}\n <Suspense fallback={<PendingSkeleton />}>\n <View {...props} />\n </Suspense>\n </>\n );\n}\n\n/**\n * A steps node. In a create wizard (a create with a steps root, P1b+P1c decision 11) the\n * framework owns the current step, the \"Step i of n\" live region and the heading focus on a\n * step change (through `headingRef`); `next()` validates the step. Outside a wizard every step is\n * a panel, drawn whole.\n */\nexport function StepsHost({\n node,\n renderChildren,\n}: {\n readonly node: PlanNode;\n readonly renderChildren: RenderChildren;\n}): ReactElement {\n const { mode, controller } = useScreenTree();\n if (mode === 'create' && controller.steps !== null)\n return <WizardHost node={node} renderChildren={renderChildren} />;\n return <StackedStepsHost node={node} renderChildren={renderChildren} />;\n}\n\nfunction StackedStepsHost({\n node,\n renderChildren,\n}: {\n readonly node: PlanNode;\n readonly renderChildren: RenderChildren;\n}): ReactElement {\n const { compiled, controller } = useScreenTree();\n const text = useNodeText();\n const { view: View, id } = useNodeView(node, 'steps');\n const t = useFrameT(id);\n const panels = node.children.filter((child) => child.state !== 'absent');\n const steps: FrameStep[] = panels.map((panel) => {\n const options = compiled.nodes[panel.index]!.options;\n const title = text(options.title) ?? panel.id;\n const description = text(options.description);\n return {\n key: panel.key ?? panel.id,\n title,\n errorCount: panel.key === undefined ? 0 : controller.errorsIn(panel.key),\n state: 'reachable',\n panel: (\n <PanelHost\n key={`${panel.index}:${panel.id}`}\n node={panel}\n region=\"step-panel\"\n renderChildren={renderChildren}\n />\n ),\n ...(description === undefined ? {} : { description }),\n titleId: `panel-title:${panel.id}`,\n info: nodeInfo(panel, title),\n nodeAttributes: nodeAttributes(panel, 'panel', options.tone),\n };\n });\n const props: StepsFrameViewProps = {\n wizard: false,\n steps,\n current: steps[0]?.key ?? '',\n goTo: NOTHING,\n back: NOTHING,\n next: NOTHING,\n headingRef: NO_HEADING,\n info: nodeInfo(node, node.key ?? ''),\n nodeAttributes: nodeAttributes(node),\n t,\n };\n return (\n <Suspense fallback={<PendingSkeleton />}>\n <View {...props} />\n </Suspense>\n );\n}\n\nconst NOTHING = () => undefined;\nconst NO_HEADING = { current: null };\n\nfunction WizardHost({\n node,\n renderChildren,\n}: {\n readonly node: PlanNode;\n readonly renderChildren: RenderChildren;\n}): ReactElement {\n const { compiled, controller, form } = useScreenTree();\n const steps = controller.steps!;\n const ft = useOptionalT();\n const text = useNodeText();\n const { view: View, id, builtin } = useNodeView(node, 'steps');\n const t = useFrameT(id);\n const panels = node.children.filter((child) => child.state !== 'absent');\n const current = panels.find((child) => child.open === true) ?? panels[0];\n const index = current === undefined ? -1 : panels.indexOf(current);\n const idOf = (panel: PlanNode) => panel.key ?? panel.id;\n const titleOf = (panel: PlanNode) => text(compiled.nodes[panel.index]!.options.title) ?? panel.id;\n const headingRef = useRef<HTMLElement | null>(null);\n const shown = useRef<string | undefined>(undefined);\n const currentId = current === undefined ? undefined : idOf(current);\n // Focus moves to the step heading when the step changes (not on the first render).\n useEffect(() => {\n if (shown.current !== undefined && shown.current !== currentId) headingRef.current?.focus();\n shown.current = currentId;\n }, [currentId]);\n const next = useCallback(() => void steps.next(), [steps]);\n const frameSteps: FrameStep[] = panels.map((panel) => {\n const options = compiled.nodes[panel.index]!.options;\n const key = idOf(panel);\n const title = titleOf(panel);\n const description = text(options.description);\n const titleId = `panel-title:${panel.id}`;\n const isCurrent = panel === current;\n return {\n key,\n title,\n errorCount: panel.key === undefined ? 0 : controller.errorsIn(panel.key),\n state: isCurrent ? 'current' : steps.completed.includes(key) ? 'complete' : 'locked',\n panel: !isCurrent ? null : panel.state === 'pending' ? (\n <PendingSkeleton />\n ) : (\n <PanelBody region=\"step-panel\" form={form} labelledBy={titleId}>\n {renderChildren(panel.children, panel)}\n </PanelBody>\n ),\n ...(description === undefined ? {} : { description }),\n titleId,\n info: nodeInfo(panel, title),\n nodeAttributes: nodeAttributes(panel, 'panel', options.tone),\n };\n });\n if (current === undefined) return <div {...nodeAttributes(node)} />;\n const props: StepsFrameViewProps = {\n wizard: true,\n steps: frameSteps,\n current: idOf(current),\n goTo: steps.goTo,\n back: steps.back,\n next,\n headingRef,\n info: nodeInfo(node, node.key ?? ''),\n nodeAttributes: nodeAttributes(node),\n t,\n };\n const liveRegion = (\n <p role=\"status\" aria-live=\"polite\" className=\"sr-only\">\n {ft('steps.current', {\n params: { index: index + 1, count: panels.length },\n defaultValue: 'Step {{index}} of {{count}}',\n })}\n {`: ${titleOf(current)}`}\n </p>\n );\n // The built-in view draws the live region inside its root; a custom view gets it beside it.\n if (builtin) return <BuroStepsFrame {...props} liveRegion={liveRegion} />;\n return (\n <>\n {liveRegion}\n <Suspense fallback={<PendingSkeleton />}>\n <View {...props} />\n </Suspense>\n </>\n );\n}\n","'use client';\nimport type { PlanNode } from '@burojs/core';\nimport type { ReactElement, ReactNode } from 'react';\nimport { LoadError } from '../load-error/load-error-view.js';\nimport { PlaceNode } from '../blocks/place-node.js';\nimport { PanelHost, StepsHost, TabsHost } from '../frames/node-host.js';\nimport { FieldLeaf } from './field-leaf.js';\nimport { nodeAttributes, PendingSkeleton, useNodeText } from './node-parts.js';\nimport { useScreenTree } from './tree-context.js';\n\n/** A failed node: the reason and a Retry that refetches only its failed sources. */\nfunction FailedNode({ node }: { readonly node: PlanNode }): ReactElement {\n const { controller } = useScreenTree();\n // The first failed source's error; a node that failed on something with no source state (a\n // `meta:` outcome) has none, and normalizes to an unexpected failure with the generic sentence.\n let error: unknown;\n for (const name of node.failedOn) {\n const source = controller.sources[name];\n if (source?.status === 'failed') {\n error = source.error;\n break;\n }\n }\n return (\n <LoadError\n surface=\"tab\"\n error={error}\n retry={() => controller.retry(node.failedOn)}\n fallback={{ key: 'screen.failed', default: 'This section could not be loaded.' }}\n attributes={nodeAttributes(node)}\n />\n );\n}\n\n/** Whether every source a node failed on is its own field's `meta:<field>` outcome. */\nfunction failedOnlyOnMeta(node: PlanNode): boolean {\n return node.failedOn.length > 0 && node.failedOn.every((name) => name.startsWith('meta:'));\n}\n\n/** The children of a container, each through {@link ScreenNodeView}. */\nfunction renderChildren(nodes: readonly PlanNode[]): ReactNode {\n return nodes.map((child) => <ScreenNodeView key={`${child.index}:${child.id}`} node={child} />);\n}\n\n/** Whether a node draws anything: not absent, and not a field the tree hides. */\nfunction drawn(node: PlanNode, hiddenFields: ReadonlySet<string> | undefined): boolean {\n if (node.state === 'absent') return false;\n return !(node.kind === 'field' && node.field !== undefined && hiddenFields?.has(node.field));\n}\n\n/**\n * A section container's children: each run of consecutive field nodes inside one implicit\n * `data-buro-group=\"fields\"` stack, every other node as itself. The group exists only in the DOM\n * (never in the screen tree), so the styling contract can space blocks apart with\n * `--buro-section-gap` while fields stay at `--buro-node-gap`.\n *\n * The runs are cut from the static node list, never from what is drawn right now: a `when` reading\n * the form's values toggles a neighbour while the user types, and a field moved to another group\n * (or a group re-keyed) would remount its input mid-keystroke. A run with no field drawn emits\n * nothing, so it leaves no gap; an absent field inside a drawn run renders nothing in its place.\n */\nfunction SectionChildren({\n nodes,\n owner,\n}: {\n readonly nodes: readonly PlanNode[];\n readonly owner: PlanNode | undefined;\n}): ReactNode {\n const { compiled, hiddenFields } = useScreenTree();\n const text = useNodeText();\n // A keyed panel, tab or step with no child drawn shows its `empty` (phase 3 plan ruling 7), and\n // nothing when it has none: the slot is optional.\n if (owner !== undefined && !nodes.some((node) => drawn(node, hiddenFields))) {\n const empty = text(compiled.nodes[owner.index]?.options.empty);\n return empty === undefined || empty === '' ? null : (\n <p data-buro-region=\"empty\" className=\"text-sm text-muted-foreground\">\n {empty}\n </p>\n );\n }\n const out: ReactNode[] = [];\n let run: PlanNode[] = [];\n const flush = () => {\n if (run.some((node) => drawn(node, hiddenFields)))\n out.push(\n <div key={`group:${run[0]!.index}`} data-buro-node=\"stack\" data-buro-group=\"fields\">\n {renderChildren(run)}\n </div>,\n );\n run = [];\n };\n for (const node of nodes) {\n if (node.kind === 'field') {\n run.push(node);\n continue;\n }\n flush();\n out.push(<ScreenNodeView key={`${node.index}:${node.id}`} node={node} />);\n }\n flush();\n return out;\n}\n\n/**\n * The children of a section container (a slot's root, a panel, a tab, a step): fields grouped,\n * see {@link SectionChildren}. `owner` is the panel they belong to (absent at a slot's root): its\n * `empty` text stands in when none of them is drawn. Authored `row`, `grid` and `stack` lay\n * their children out themselves and use {@link renderChildren}.\n */\nexport function renderSection(nodes: readonly PlanNode[], owner?: PlanNode): ReactNode {\n return <SectionChildren nodes={nodes} owner={owner} />;\n}\n\nfunction Layout({ node }: { readonly node: PlanNode }): ReactElement {\n return <div {...nodeAttributes(node)}>{renderChildren(node.children)}</div>;\n}\n\n/** A field leaf, absent when the tree hides its field (a peek's filter). */\nfunction FieldNode({ node }: { readonly node: PlanNode }): ReactNode {\n const { hiddenFields } = useScreenTree();\n if (node.field !== undefined && hiddenFields?.has(node.field) === true) return null;\n return <FieldLeaf node={node} />;\n}\n\n/** One plan node: nothing when absent, its failed chrome when failed, else its kind's component. */\nexport function ScreenNodeView({ node }: { readonly node: PlanNode }): ReactNode {\n if (node.state === 'absent') return null;\n // A placement draws its own chrome, failed and pending included (spec 8.1).\n if (node.kind === 'place') return <PlaceNode node={node} />;\n // A field whose only failure is its own `meta` (a schema refused it, P7 3.3) is not a source to\n // retry: its leaf draws the labelled misconfigured control and says why in development.\n if (node.state === 'failed' && !(node.kind === 'field' && failedOnlyOnMeta(node)))\n return <FailedNode node={node} />;\n switch (node.kind) {\n case 'field':\n if (node.state === 'pending')\n return (\n <div {...nodeAttributes(node)}>\n <PendingSkeleton />\n </div>\n );\n return <FieldNode node={node} />;\n case 'panel':\n return <PanelHost node={node} renderChildren={renderSection} />;\n case 'tabs':\n return <TabsHost node={node} renderChildren={renderSection} />;\n case 'steps':\n return <StepsHost node={node} renderChildren={renderSection} />;\n case 'row':\n case 'grid':\n case 'stack':\n return <Layout node={node} />;\n default: {\n // Exhaustive: a node kind the dispatch does not know fails the typecheck here.\n const unknown: never = node.kind;\n return unknown;\n }\n }\n}\n","'use client';\nimport { type CompiledScreen, FORM_SLOT, type ScreenMode } from '@burojs/core';\nimport type { FormController, PageScreen } from '@burojs/react';\nimport { type ReactElement, type ReactNode, useMemo } from 'react';\nimport { renderSection } from './nodes.js';\nimport {\n type LeafIdScheme,\n type RenderFieldOverrides,\n ScreenTreeContext,\n type ScreenTreeValue,\n} from './tree-context.js';\n\nexport interface ScreenTreeProps {\n /**\n * Where the tree is drawn: `record` a record screen's slot (`slot`), `form-body` and\n * `page-body` the body. A record host wraps the tree in its own slot wrapper; for `form-body`\n * the tree renders the region element itself.\n */\n readonly region: 'record' | 'form-body' | 'page-body';\n /** On a record screen, the frame slot to draw (P6 3.3); `body` when omitted. */\n readonly slot?: string;\n /**\n * The resource's canonical name, or a resource-less form's\n * `i18nPrefix ?? 'form'`.\n */\n readonly resource: string;\n readonly mode: ScreenMode;\n /** The compiled screen the controller plans (`controller.screen`); nothing while `null`. */\n readonly compiled: CompiledScreen | null;\n /** The record or form controller that plans the screen; a page passes `page` instead. */\n readonly controller?: FormController;\n /**\n * A custom page's body (`usePageScreen`): its plan, Retry and placements. A page body has no\n * field leaves (refused when the page is parsed), so no field binding is ever asked of it.\n */\n readonly page?: PageScreen;\n /** Default `'record'`. */\n readonly leafIds?: LeafIdScheme;\n readonly renderField?: RenderFieldOverrides;\n /** A whole-form lock: every input renders disabled. */\n readonly disabled?: boolean;\n /** On the `form-body` region element. */\n readonly className?: string;\n /** Fields whose leaves render absent (a peek body's filter). */\n readonly hiddenFields?: ReadonlySet<string>;\n}\n\n/**\n * Draws one slot of a planned screen (P1b+P1c section 9): the slot's nodes in\n * a root stack, each node carrying the `data-buro-*` attributes the styling\n * contract keys off. Every node reads its static options from the compiled\n * screen by its plan index; nothing is compiled or planned here.\n */\nexport function ScreenTree({\n region,\n slot = FORM_SLOT,\n resource,\n mode,\n compiled,\n controller: own,\n page,\n leafIds = 'record',\n renderField,\n disabled,\n className,\n hiddenFields,\n}: ScreenTreeProps): ReactElement | null {\n const controller = useMemo(() => own ?? pageHost(page), [own, page]);\n const form =\n mode !== 'show' && (region === 'form-body' || (region === 'record' && slot === FORM_SLOT));\n const value = useMemo<ScreenTreeValue | null>(\n () =>\n compiled === null || controller === undefined\n ? null\n : {\n resource,\n mode,\n compiled,\n controller,\n region,\n form,\n leafIds,\n ...(renderField === undefined ? {} : { renderField }),\n ...(disabled === undefined ? {} : { disabled }),\n ...(hiddenFields === undefined ? {} : { hiddenFields }),\n },\n [\n resource,\n mode,\n compiled,\n controller,\n region,\n form,\n leafIds,\n renderField,\n disabled,\n hiddenFields,\n ],\n );\n const plan = controller?.plan ?? null;\n if (value === null || plan === null) return null;\n const roots = plan.slots[region === 'record' ? slot : FORM_SLOT] ?? [];\n if (roots.length === 0 && region !== 'form-body') return null;\n // A record's display slot: the stack is the slot's wrapper (`data-buro-slot`, no region, no\n // container type; P6-70). The body's wrapper is the record host's `record-body` element.\n const displaySlot = region === 'record' && slot !== FORM_SLOT;\n const stack = (\n <div data-buro-node=\"stack\" {...(displaySlot ? { 'data-buro-slot': slot } : {})}>\n {renderSection(roots)}\n </div>\n );\n return (\n <ScreenTreeContext.Provider value={value}>\n {region === 'form-body' ? (\n <div data-buro-region=\"form-body\" className={className}>\n {stack}\n </div>\n ) : (\n stack\n )}\n </ScreenTreeContext.Provider>\n );\n}\n\n/**\n * The tree context of a page's screen for what is drawn from its plan outside a slot's stack: the\n * route list's item block, which the rows draw one by one (P7-36), needs the screen its node was\n * planned in. Nothing is drawn here.\n */\nexport function ScreenTreeScope({\n resource,\n mode,\n compiled,\n page,\n children,\n}: {\n readonly resource: string;\n readonly mode: ScreenMode;\n readonly compiled: CompiledScreen;\n readonly page: PageScreen;\n readonly children: ReactNode;\n}): ReactElement {\n const controller = useMemo(() => pageHost(page), [page]);\n const value = useMemo<ScreenTreeValue>(\n () => ({\n resource,\n mode,\n compiled,\n controller: controller!,\n region: 'record',\n form: false,\n leafIds: 'record',\n }),\n [resource, mode, compiled, controller],\n );\n return <ScreenTreeContext.Provider value={value}>{children}</ScreenTreeContext.Provider>;\n}\n\n/**\n * The part of a controller the non-field nodes read, over a page's screen: its plan, Retry and\n * placements; a page has no field errors, steps or reveals.\n */\nfunction pageHost(page: PageScreen | undefined): FormController | undefined {\n if (page === undefined) return undefined;\n return {\n plan: page.plan,\n retry: page.retry,\n placement: page.placement,\n errorsIn: () => 0,\n steps: null,\n registerReveal: () => () => undefined,\n } as Partial<FormController> as FormController;\n}\n","'use client';\nimport type {\n DraftOption,\n Check,\n CheckOutcome,\n CheckSurface,\n FormBody,\n ResourceFieldMap,\n StandardSchemaV1,\n ValidationIssues,\n} from '@burojs/core';\nimport {\n ScreenStateProvider,\n resolveValidationMessage,\n useFormController,\n useI18nCaps,\n useChromeT,\n type CheckGateState,\n type FieldBinding,\n type FormValues,\n type ResolvedIssue,\n type UseFormControllerFormOptions,\n} from '@burojs/react';\nimport {\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport { CheckConfirmDialog } from '../checks/check-confirm-dialog.js';\nimport { Button } from '../primitives/button.js';\nimport { FormControlProvider, useFormControlOf } from '../resource/form-context.js';\nimport { ScreenTree } from '../screen/screen-tree.js';\n\n/**\n * A footer slot may need the controller's submit-gate to build its own submit\n * control — see {@link DeclarativeFormSlots.footer}.\n */\nexport interface DeclarativeFormFooterCtx {\n /**\n * `form.canSubmit` already ANDed with the whole-form `disabled` lock — a\n * footer never has to re-derive that combination itself.\n */\n readonly canSubmit: boolean;\n}\n\n/**\n * Slot overrides for the managed layout. `footer` replaces the default\n * submit-button row. The index signature keeps the shape open for future\n * per-section slots (design doc §4) without a breaking change to this\n * interface later.\n */\nexport interface DeclarativeFormSlots {\n /**\n * A plain `ReactNode` replaces the default footer outright, same as\n * before this widening (e.g. a footer with no submit button at all). The\n * function form exists for the common case a plain node cannot serve: a\n * CUSTOM footer (e.g. Cancel + Submit side by side) that still needs the\n * framework's own disabled-while-invalid gate — `slots` is built by the\n * CALLER before the form controller has run, so a plain node has no way\n * to read `form.canSubmit`. Called once per render with `{ canSubmit }`\n * (already ANDed with the whole-form `disabled` lock) instead of forcing\n * every such caller to either reimplement the gate or stand up a second,\n * parallel controller just to read it.\n */\n readonly footer?: ReactNode | ((ctx: DeclarativeFormFooterCtx) => ReactNode);\n readonly [slot: string]: ReactNode | ((ctx: DeclarativeFormFooterCtx) => ReactNode) | undefined;\n}\n\nexport interface DeclarativeFormProps<F extends ResourceFieldMap = ResourceFieldMap> {\n /** The same field-def map shape `defineResource`'s `f` builder produces. */\n readonly fields: F;\n /**\n * The form's tree (`(l) => [...]`, the same builder a resource's\n * `views.<mode>.body` uses); absent, every field in one column, in\n * declaration order. A field under a `when` that does not hold is inactive:\n * it is not drawn and not submitted.\n */\n readonly body?: FormBody<F>;\n /** The draft identity; `draft` without it is a development error. */\n readonly formId?: string;\n readonly draft?: DraftOption;\n /** Controlled values: presence (not truthiness) selects controlled mode. */\n readonly value?: FormValues;\n /** Uncontrolled seed. Ignored once `value` is supplied. */\n readonly defaults?: FormValues;\n readonly onChange?: (values: FormValues) => void;\n readonly schema?: StandardSchemaV1;\n /** Cross-field validation; may return warnings as well as errors. */\n readonly validate?: UseFormControllerFormOptions['validate'];\n /**\n * Conditional checks for this form, as a plain list (a resource-less form has\n * no `app.checkSource` entry); a confirmable warning asks through the\n * mounted `<CheckConfirmDialog>`.\n */\n readonly checks?: readonly Check[];\n /** The check surface; default `'create'`. */\n readonly surface?: CheckSurface;\n /** Receives the payload: the active declared fields only. */\n readonly onSubmit?: (values: FormValues) => unknown | Promise<unknown>;\n /**\n * Text slots and the doc address key as `resources.<i18nPrefix>.…`; the\n * leaf ids are `<i18nPrefix>:field:<name>:hint` / `:info`. Default `'form'`.\n */\n readonly i18nPrefix?: string;\n /**\n * Whole-form lock: every field renders disabled, OR-ed with that field's\n * own resolved `disabled`. Distinct from a read-only VIEW\n * (`<DeclarativeDisplay>`), which renders displays instead of inputs.\n */\n readonly disabled?: boolean;\n /**\n * Per-field render override — swap ONE field's node without abandoning\n * the managed leaf (label, message slot, hint): receives the binding and\n * the default input node, so an override can wrap rather than reimplement.\n */\n readonly renderField?: Record<\n string,\n (binding: FieldBinding, defaultNode: ReactNode) => ReactNode\n >;\n readonly slots?: DeclarativeFormSlots;\n /** The submit caption; defaults to the framework bundle's `actions.save` (\"Save\"). */\n readonly submitLabel?: string;\n /**\n * Class applied to the `<form>` element itself — e.g. `flex flex-col` for a\n * dialog taller than the viewport, so the body can scroll between a fixed\n * header and footer.\n */\n readonly className?: string;\n /**\n * Class applied to the fields region (`[data-buro-region=\"form-body\"]`), the\n * scroll region of a form too tall to fit (`flex-1 overflow-y-auto min-h-0`).\n */\n readonly bodyClassName?: string;\n}\n\n/**\n * Localize one resolved issue the same way across the field slots and the\n * form-level summary, through `resolveValidationMessage` (`@burojs/react`):\n * the per-field `resources.<i18nPrefix>.fields.<f>.validation.<code>` first,\n * then the app's shared `resources._.fields.<f>.validation.<code>` (the form's field key is a\n * `resources.<prefix>.fields.<f>` key, so the shared step applies to it too), then a semantic\n * key, the issue's own `default`, the common `validation.<code>`, and `errors.failed`. Resolved\n * at render, so a locale switch reaches the text.\n */\nfunction issueText(\n issue: ResolvedIssue,\n caps: Pick<ReturnType<typeof useI18nCaps>, 'has' | 't'>,\n i18nPrefix: string,\n): string {\n return resolveValidationMessage(\n {\n code: issue.code ?? '',\n message: issue.message,\n ...(issue.check === undefined ? {} : { check: issue.check }),\n },\n {\n has: caps.has,\n t: caps.t,\n ...(issue.field === '_form'\n ? {}\n : { fieldKey: `resources.${i18nPrefix}.fields.${issue.field}` }),\n },\n );\n}\n\nconst EMPTY_ISSUES: ValidationIssues = Object.freeze([]);\n\n/**\n * A minimal confirm gate driven by an EXPLICIT `CheckOutcome`, not a\n * `resource` string — `useCheckGate` (`@burojs/react`) re-derives its check\n * list via `app.checkSource.checks(resource)`, which has nothing to key off\n * for a resource-less declarative form whose checks arrive as a plain\n * `props.checks` array. The controller's submit already evaluates those\n * checks once; this hook only owns the DIALOG'S open/decide state, fed\n * through the controller's `onConfirmChecks` option — so checks are\n * evaluated exactly once per submit, not re-derived here.\n *\n * Renders through the SAME `<CheckConfirmDialog>` (Task 7) `<RecordScreen>`\n * uses, off a `CheckGateState`-shaped object built by hand. `blockers` is\n * always empty here: a `severity: 'error'` check already stops the submit\n * before `onConfirmChecks` is ever called (it renders inline instead), so\n * this gate only ever shows\n * `confirmable` issues, and `busy` stays `false` — unlike `useCheckGate`,\n * there is no async re-evaluation while the dialog is open, just a decision.\n */\nfunction useDeclarativeCheckGate(): {\n readonly state: CheckGateState;\n readonly confirmChecks: (outcome: CheckOutcome) => Promise<'proceed' | 'cancel'>;\n} {\n const [open, setOpen] = useState(false);\n const [confirmable, setConfirmable] = useState<ValidationIssues>(EMPTY_ISSUES);\n const decide = useRef<((decision: 'proceed' | 'cancel') => void) | null>(null);\n\n // Unmount mid-decision must resolve the pending promise rather than let it\n // dangle — same hazard `useCheckGate` itself guards against.\n useEffect(() => {\n return () => {\n decide.current?.('cancel');\n decide.current = null;\n };\n }, []);\n\n const close = useCallback((decision: 'proceed' | 'cancel') => {\n setOpen(false);\n setConfirmable(EMPTY_ISSUES);\n const resolve = decide.current;\n decide.current = null;\n resolve?.(decision);\n }, []);\n\n const confirmChecks = useCallback((outcome: CheckOutcome): Promise<'proceed' | 'cancel'> => {\n // Self-contained re-entrancy guard: a second `confirmChecks()` call while\n // one is still pending must not silently overwrite `decide.current` and\n // strand the FIRST caller's promise forever. Today the controller's own\n // submit latch makes a second call unreachable (a submit refuses to\n // re-enter while one is in flight), but\n // this hook has no business depending on another package's internal\n // guard to stay correct — resolve the superseded decision as 'cancel'\n // (same \"a broken/interrupted gate must not silently proceed\" contract\n // `useCheckGate`'s own `run()` uses) before starting the new one.\n decide.current?.('cancel');\n decide.current = null;\n setConfirmable(outcome.confirmable);\n setOpen(true);\n return new Promise<'proceed' | 'cancel'>((resolve) => {\n decide.current = resolve;\n });\n }, []);\n\n return {\n state: {\n open,\n busy: false,\n header: null,\n blockers: EMPTY_ISSUES,\n confirmable,\n proceed: () => close('proceed'),\n cancel: () => close('cancel'),\n },\n confirmChecks,\n };\n}\n\n/**\n * Batteries-included resource-less form (P1b+P1c decision 21) over\n * `useFormController` and the screen renderer: the form's `body` tree (or one\n * column of every field), each leaf with its label, input, one message slot\n * (error over warning) and hint; a form-level error / warning summary above;\n * the submit footer below. Uncontrolled by default (`defaults` seeds,\n * `onSubmit(payload)` delivers the active declared values); controlled\n * `value` / `onChange` remain available. Submit is disabled on\n * `!form.canSubmit` (errors only — warnings never block) or `disabled`.\n */\nexport function DeclarativeForm<F extends ResourceFieldMap = ResourceFieldMap>(\n props: DeclarativeFormProps<F>,\n): ReactElement {\n return (\n <ScreenStateProvider>\n <DeclarativeFormBody {...(props as DeclarativeFormProps)} />\n </ScreenStateProvider>\n );\n}\n\nfunction DeclarativeFormBody(props: DeclarativeFormProps): ReactElement {\n const gate = useDeclarativeCheckGate();\n const prefix = props.i18nPrefix ?? 'form';\n const form = useFormController({\n fields: props.fields,\n mode: 'create',\n onConfirmChecks: gate.confirmChecks,\n ...(props.body === undefined ? {} : { body: props.body }),\n ...(props.formId === undefined ? {} : { formId: props.formId }),\n ...(props.draft === undefined ? {} : { draft: props.draft }),\n ...(props.value === undefined ? {} : { value: props.value }),\n ...(props.defaults === undefined ? {} : { defaults: props.defaults }),\n ...(props.onChange === undefined ? {} : { onChange: props.onChange }),\n ...(props.i18nPrefix === undefined ? {} : { i18nPrefix: props.i18nPrefix }),\n ...(props.schema === undefined ? {} : { schema: props.schema }),\n ...(props.validate === undefined ? {} : { validate: props.validate }),\n ...(props.checks === undefined ? {} : { checks: props.checks }),\n ...(props.surface === undefined ? {} : { surface: props.surface }),\n ...(props.onSubmit === undefined ? {} : { onSubmit: props.onSubmit }),\n });\n const formControl = useFormControlOf(form);\n const chromeT = useChromeT();\n const caps = useI18nCaps();\n const disabled = props.disabled === true;\n const uid = useId();\n const leafIds = useMemo(() => ({ prefix, inputIds: uid }), [prefix, uid]);\n\n const formErrors = form.errors.filter((issue) => issue.field === '_form');\n // An error check that could not run (P1b+P1c decision 28): its \"could not\n // verify\" reason above, and Retry, which re-runs the check pass.\n const retryableChecks: string[] = [];\n for (const issue of form.checkOutcome?.blockers ?? []) {\n const checkId = issue.check?.id;\n if (issue.check?.cause === undefined || typeof checkId !== 'string') continue;\n if (!retryableChecks.includes(checkId)) retryableChecks.push(checkId);\n }\n const formWarnings = form.warnings.filter((issue) => issue.field === '_form');\n // Base testid for the mounted `<CheckConfirmDialog>`: declarative forms are\n // resource-less, so `i18nPrefix` is the stable per-form handle.\n const checksTestId = `${prefix}:checks`;\n\n return (\n <>\n <form onSubmit={form.handleSubmit()} noValidate className={props.className}>\n {formErrors.length > 0 && (\n <div\n role=\"alert\"\n className=\"mb-4 flex flex-col gap-1 rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive\"\n >\n {formErrors.map((issue, index) => (\n <p key={index}>{issueText(issue, caps, prefix)}</p>\n ))}\n </div>\n )}\n {retryableChecks.length > 0 && (\n <div className=\"mb-4 flex flex-wrap gap-2\">\n {retryableChecks.map((checkId) => (\n <Button\n key={checkId}\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n data-testid={`form-check-retry:${checkId}`}\n onClick={() => void form.revalidate()}\n >\n {chromeT('actions.retry', { defaultValue: 'Retry' })}\n </Button>\n ))}\n </div>\n )}\n {formWarnings.length > 0 && (\n <div\n role=\"status\"\n aria-live=\"polite\"\n className=\"mb-4 flex flex-col gap-1 rounded-md border border-warning/50 bg-warning/10 px-3 py-2 text-sm text-warning-emphasis\"\n >\n {formWarnings.map((issue, index) => (\n <p key={index}>{issueText(issue, caps, prefix)}</p>\n ))}\n </div>\n )}\n <FormControlProvider value={formControl}>\n <ScreenTree\n region=\"form-body\"\n resource={prefix}\n mode=\"create\"\n compiled={form.screen}\n controller={form}\n leafIds={leafIds}\n {...(props.renderField === undefined ? {} : { renderField: props.renderField })}\n disabled={disabled}\n {...(props.bodyClassName === undefined ? {} : { className: props.bodyClassName })}\n />\n </FormControlProvider>\n {props.slots?.footer === undefined ? (\n <div className=\"mt-4 flex justify-end\">\n <Button\n type=\"submit\"\n disabled={!form.canSubmit || disabled}\n // Without this, focusing out of the field a blur error just inserted moves the\n // submit button up, and the click that lands on the OLD position is swallowed.\n onMouseDown={(event) => event.preventDefault()}\n >\n {props.submitLabel ?? chromeT('actions.save', { defaultValue: 'Save' })}\n </Button>\n </div>\n ) : typeof props.slots.footer === 'function' ? (\n props.slots.footer({ canSubmit: form.canSubmit && !disabled })\n ) : (\n props.slots.footer\n )}\n </form>\n {/* Rendered as a SIBLING of the `<form>`, never inside a menu, so the dialog\n survives whatever closes the triggering control. */}\n <CheckConfirmDialog\n state={gate.state}\n testid={checksTestId}\n onAnchorFocus={(field) => {\n document.getElementById(`${uid}-${field}`)?.focus();\n }}\n />\n </>\n );\n}\n","import {\n type ExportFormat,\n type FieldOption,\n declaredText,\n fieldOptionText,\n type I18nCaps,\n type ResourceFieldMap,\n exportFormatFieldKey,\n exportFormatOptionKey,\n humanizeKey,\n resolveContentSlot,\n} from '@burojs/core';\n\n/**\n * A format's option fields with every label resolved for the active locale,\n * ready for `<DeclarativeForm>`. A format declares plain English defaults and\n * no keys; a translation lives in a `common` bundle under\n * {@link exportFormatFieldKey} and {@link exportFormatOptionKey}. The option form belongs to no resource, so the\n * resource-scoped field convention (`resources.<r>.fields.<f>.label`) cannot\n * reach the framework bundle — this is where these labels resolve. `caps`\n * changes with the locale; recompute per render (`useMemo` on `caps`).\n */\nexport function localizeFormatOptions(\n caps: I18nCaps,\n format: ExportFormat,\n): ResourceFieldMap | undefined {\n const fields = format.options;\n if (fields === undefined) return undefined;\n const out: Record<string, unknown> = {};\n for (const [name, field] of Object.entries(fields)) {\n const declared = field as {\n readonly texts?: unknown;\n readonly options?: readonly FieldOption[];\n };\n const label = resolveContentSlot(caps, [exportFormatFieldKey(format.id, name)], {\n default: declaredText('field', field, 'label'),\n humanize: () => humanizeKey(name),\n });\n const options = declared.options?.map((option) => ({\n value: String(option.value),\n label: resolveContentSlot(\n caps,\n [exportFormatOptionKey(format.id, name, String(option.value))],\n {\n default: fieldOptionText(field, String(option.value)),\n humanize: () => String(option.value),\n },\n ),\n }));\n // The resolved texts replace the declared ones in `texts` too: a reader asks `texts` first,\n // and the declared English default must not shadow the bundle's translation.\n const declaredTexts: Readonly<Record<string, unknown>> =\n typeof declared.texts === 'object' && declared.texts !== null\n ? (declared.texts as Readonly<Record<string, unknown>>)\n : {};\n const declaredOptions = (declaredTexts.options ?? {}) as Readonly<Record<string, unknown>>;\n const texts = {\n ...declaredTexts,\n label,\n ...(options === undefined\n ? {}\n : {\n options: Object.fromEntries(\n options.map(({ value, label: optionLabel }) => {\n const entry = declaredOptions[value];\n return [\n value,\n typeof entry === 'object' && entry !== null\n ? { ...entry, label: optionLabel }\n : optionLabel,\n ];\n }),\n ),\n }),\n };\n out[name] = { ...field, texts };\n }\n return out as ResourceFieldMap;\n}\n","'use client';\nimport {\n declaredText,\n dtoFields,\n exportFormatLabelKey,\n resolveContentSlot,\n type ExportFormat,\n type ExportRequest,\n type ExportRunState,\n type ExportTarget,\n type ResourceFieldMap,\n type ScopeSource,\n routeResourceKey,\n type ResourceNameOrRef,\n} from '@burojs/core';\nimport {\n DismissGuardScope,\n type ErrorTextCaps,\n type ExportRunEntry,\n useListAccess,\n useDismissGuard,\n resolveErrorText,\n useI18nCaps,\n useNavigationBlocker,\n useOptionalT,\n useResource,\n useResourceExport,\n useTestIds,\n} from '@burojs/react';\nimport * as React from 'react';\nimport { DeclarativeForm } from '../forms/declarative-form.js';\nimport { toast } from '../notification/toaster.js';\nimport { Button } from '../primitives/button.js';\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from '../primitives/dialog.js';\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '../primitives/select.js';\nimport { downloadArtifact } from './download.js';\nimport { localizeFormatOptions } from './format-option-labels.js';\nimport { useTrackDisplayedRun } from './run-watcher.js';\n\nexport interface ExportDialogProps<N extends string = string> {\n readonly open: boolean;\n readonly onOpenChange: (open: boolean) => void;\n readonly resource: ResourceNameOrRef<N>;\n readonly target: ExportTarget;\n /**\n * The list's currently visible columns — what \"as in table\" (the default) sends as `request.columns`.\n * Empty means \"unknown\": the dialog then sends the same set as \"All columns\" (the resource's list\n * fields, minus any a `column` rule hides). `request.columns` is never omitted.\n */\n readonly visibleColumns: readonly string[];\n /** Known row estimate, shown in the filter-scope title and handed to the exporter as a progress total hint. */\n readonly estimatedCount?: number;\n /** How the export reads the resource: the scope of the list it exports (default `'session'`). */\n readonly scope?: ScopeSource;\n}\n\ntype Mode = 'form' | 'progress' | 'confirm-close';\n\nconst EMPTY_VALUES: Record<string, unknown> = {};\n\n/** `FieldDeclaration.default` off every entry of a `ResourceFieldMap`, for seeding a format's options form each time the selected format changes. */\nfunction fieldDefaults(fields: ResourceFieldMap | undefined): Record<string, unknown> {\n if (!fields) return EMPTY_VALUES;\n const out: Record<string, unknown> = {};\n for (const [name, def] of Object.entries(fields)) {\n const value = (def as { default?: unknown } | undefined)?.default;\n if (value !== undefined) out[name] = value;\n }\n return out;\n}\n\nfunction hasOptions(\n format: ExportFormat | undefined,\n): format is ExportFormat & { options: ResourceFieldMap } {\n return format?.options !== undefined && Object.keys(format.options).length > 0;\n}\n\n/** An empty option: absent, `null` and `''` all mean \"not set\". */\nfunction isEmptyOption(value: unknown): boolean {\n return value === undefined || value === null || value === '';\n}\n\nfunction sameOption(a: unknown, b: unknown): boolean {\n if (Object.is(a, b)) return true;\n if (isEmptyOption(a) && isEmptyOption(b)) return true;\n if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null) return false;\n return JSON.stringify(a) === JSON.stringify(b);\n}\n\n/** True when any option value differs from the format's defaults (plan ruling 6). */\nexport function optionsDiffer(\n values: Readonly<Record<string, unknown>>,\n defaults: Readonly<Record<string, unknown>>,\n): boolean {\n const keys = new Set([...Object.keys(values), ...Object.keys(defaults)]);\n for (const key of keys) if (!sameOption(values[key], defaults[key])) return true;\n return false;\n}\n\n/**\n * Arms the unsaved-changes guard while the options differ from the format's defaults: in the\n * dialog's dismiss scope (Escape, an outside click and ✕ ask) and globally, like any form (a\n * route change and a reload ask too).\n */\nfunction ExportOptionsDirty({ dirty }: { readonly dirty: boolean }): null {\n useNavigationBlocker(dirty);\n return null;\n}\n\n/** Stable no-op snapshot getter for `useSyncExternalStore` before any run has started. */\nfunction getNoRunState(): ExportRunState | undefined {\n return undefined;\n}\n\n/**\n * Self-hosted export dialog — NOT presented through `useUIPresent`: an\n * unregistered `UIPresentRequest.component` registry key silently renders\n * `null`, so a framework-owned dialog would do nothing until every adopter\n * registered it (see `packages/react/src/ui/ui-presentations.tsx:74,138`).\n * The flow host draws the opposite line (it IS presented, as `buro:flow`, and\n * `shadcnPresentationHosts` registers it); this dialog stays self-hosted, built\n * on the local `<Dialog>` primitives, no registry involved.\n *\n * A `mode` state (`'form' | 'progress' | 'confirm-close'`) swaps content\n * inside ONE `<DialogContent>`/one Radix focus scope. A second, nested\n * Radix root for the close-while-running confirm was tried elsewhere in this\n * codebase and deadlocked the jsdom test runner (the old form-modal action's\n * menu-held dialog, deleted in P4) — this dialog\n * never repeats that shape.\n */\nexport function ExportDialog<const N extends string = string>({\n open,\n onOpenChange,\n resource: resourceInput,\n target,\n visibleColumns,\n estimatedCount,\n scope,\n}: ExportDialogProps<N>): React.ReactElement {\n const resource = routeResourceKey(resourceInput);\n const t = useOptionalT();\n const tid = useTestIds();\n const dialogTestId = tid.exportDialog(resource);\n // `{ load: open }` — this dialog is the ONE surface that actually needs the\n // exporter itself, so it is the one that invokes a deferred\n // (`ExporterLoader`) registration. The toolbar/bulk triggers call the same\n // hook with no options and answer `available` from the registration alone,\n // which is what keeps an app's exporter factories out of its initial JS.\n //\n // Keyed on `open`, not a literal `true`, for TWO reasons — both load-bearing:\n // - Both entry points keep this dialog mounted while it is closed (it is a\n // permanent sibling of their trigger; see the class comment). A constant\n // `true` would therefore ask for the exporter's chunk on every list page\n // that shows an export button, which is exactly the cost the deferred\n // registration exists to avoid.\n // - It makes a failed load RECOVERABLE. `useResourceExport`'s load effect\n // depends on this flag, so closing and reopening re-runs it and retries the\n // loader (the failed attempt is not cached). With a constant `true` the\n // effect's deps were all constant for the app's lifetime: one rejected load\n // left this dialog permanently unavailable, however many times the user\n // reopened it, while the changeset and the adopter guide both said\n // reopening retries.\n const { formats, start, exporter, available, error, loading } = useResourceExport(resource, {\n load: open,\n ...(scope === undefined ? {} : { scope }),\n });\n\n const [mode, setMode] = React.useState<Mode>('form');\n const [formatIdOverride, setFormatIdOverride] = React.useState<string | undefined>(undefined);\n const [columnsMode, setColumnsMode] = React.useState<'visible' | 'all'>('visible');\n const [formatValues, setFormatValues] = React.useState<Record<string, unknown>>(EMPTY_VALUES);\n const [runEntry, setRunEntry] = React.useState<ExportRunEntry | undefined>(undefined);\n\n // Tells `useExportRunWatcher()` (Task 8, fix round 1) exactly which run\n // THIS dialog is displaying right now — `undefined` whenever there is\n // none (no run started yet) or the dialog is closed, either of which\n // means the watcher owns the decision instead. Run-scoped, not\n // resource-scoped: a toolbar export and a bulk-bar export for the SAME\n // resource are two independent runs, and this dialog must only ever claim\n // credit for the one it is actually showing.\n useTrackDisplayedRun(open ? runEntry?.runId : undefined);\n\n // What \"All columns\" means: the resource's list fields in declaration order,\n // each gated by the same `kind: 'column'` view check `<ResourceList>` applies\n // to what it draws (`visibleColumnKeys`). `mode: 'list'` and no record, for\n // the same reason as there: a column spans every row.\n const def = useResource(resource);\n // The one list predicate (P5 spec 3.7): field view in any-record reach and `column` rules.\n const listAccess = useListAccess(resource);\n const accessPending = listAccess.status === 'pending';\n const allowedListColumns = React.useMemo<readonly string[]>(\n () =>\n def === undefined || accessPending\n ? []\n : dtoFields(def, 'list').filter((col) => listAccess.columnVisible(col)),\n [def, listAccess, accessPending],\n );\n // The table's visible columns, gated again by the same predicate: a prop a host built from a\n // stale or hand-made column set never widens what the user may export.\n const exportableVisible = React.useMemo<readonly string[]>(\n () => visibleColumns.filter((col) => !accessPending && listAccess.columnVisible(col)),\n [visibleColumns, listAccess, accessPending],\n );\n const requestColumns =\n columnsMode === 'visible' && visibleColumns.length > 0 ? exportableVisible : allowedListColumns;\n\n const selectedFormat = formats.find((f) => f.id === formatIdOverride) ?? formats[0];\n // A format's name is its `texts`; the flat `label` was removed. The type no longer allows it,\n // but an exporter's formats are adopter code at runtime: say so in development, once a format.\n const reportedLabels = React.useRef(new Set<string>());\n React.useEffect(() => {\n if (process.env.NODE_ENV === 'production') return;\n for (const format of formats) {\n const flat = Object.hasOwn(format, 'label')\n ? (format as { readonly label?: unknown }).label\n : undefined;\n if (flat === undefined || reportedLabels.current.has(format.id)) continue;\n reportedLabels.current.add(format.id);\n console.error(\n `[ExportDialog] export format '${format.id}' declares label, which was removed: write texts — the text the bundle holds at common.${exportFormatLabelKey(format.id)} (see docs/i18n-guide.md).`,\n );\n }\n }, [formats]);\n const caps = useI18nCaps();\n const localizedOptions = React.useMemo(\n () => (selectedFormat === undefined ? undefined : localizeFormatOptions(caps, selectedFormat)),\n [caps, selectedFormat],\n );\n\n // A controlled dialog Task 8 may keep mounted and reopen for a DIFFERENT\n // request (a fresh `target`/`estimatedCount` on the next click) — without\n // this, reopening after a finished run would show the PREVIOUS run's\n // progress/success/failure view instead of a fresh form. Resets exactly on\n // the false→true edge, never on the initial mount (whatever `open` starts\n // at already matches this ref, so the very first render never \"edges\").\n const wasOpenRef = React.useRef(open);\n React.useEffect(() => {\n if (open && !wasOpenRef.current) {\n setMode('form');\n setRunEntry(undefined);\n setFormatIdOverride(undefined);\n setColumnsMode('visible');\n }\n wasOpenRef.current = open;\n }, [open]);\n\n // Reset the format-options snapshot to the newly selected format's own\n // field defaults — `<DeclarativeForm>` below is remounted (`key`) on the\n // same change, so its OWN internal state already restarts; this keeps what\n // `handleStart` would submit in sync even if the user never touches a\n // field of the format they just switched to.\n // Keyed on the format ID deliberately, not on `selectedFormat.options`: a\n // format's option schema is a static declaration for a given id, so the narrow\n // dep cannot go stale — while depending on the `options` OBJECT would re-run\n // this on every render for any exporter whose `formats()` rebuilds its entries.\n // biome-ignore lint/correctness/useExhaustiveDependencies: see comment above\n React.useEffect(() => {\n setFormatValues(fieldDefaults(selectedFormat?.options));\n }, [selectedFormat?.id]);\n\n const runState = React.useSyncExternalStore(\n React.useCallback(\n (cb: () => void) => (runEntry ? runEntry.handle.subscribe(cb) : () => {}),\n [runEntry],\n ),\n React.useCallback(() => (runEntry ? runEntry.handle.getState() : undefined), [runEntry]),\n getNoRunState,\n );\n\n // `supportsSort` lives on the resolved `Exporter` (`@burojs/core`), not on\n // any individual `ExportFormat` — every format of one exporter shares the\n // same answer. `exporter` is genuinely absent (not falsy-but-present) when\n // nothing resolved, so `undefined === false` correctly keeps the warning\n // hidden rather than needing a separate `available` check here.\n const showSortWarning = target.kind === 'filter' && exporter?.supportsSort === false;\n\n const titleText =\n target.kind === 'ids'\n ? t('export.dialog.titleSelected', { count: target.ids.length })\n : estimatedCount === undefined\n ? t('export.dialog.titleFilterUnknownCount')\n : t('export.dialog.titleFilter', { count: estimatedCount });\n\n function handleStart(): void {\n if (!selectedFormat) return;\n const request: Omit<ExportRequest, 'resource'> = {\n target,\n format: hasOptions(selectedFormat)\n ? { id: selectedFormat.id, options: formatValues }\n : { id: selectedFormat.id },\n // ALWAYS explicit. With no `columns`, both stock exporters fall back to\n // every key of the first row — which includes fields a `column` rule\n // hides from this user and anything extra the provider selected, so one\n // click turned a deliberately hidden column into a file. \"All columns\"\n // and an EMPTY visible set (`<BulkActionToolbar>` defaults the prop to\n // `[]` for standalone callers that cannot know the visible set) both\n // send the resource's list fields as the table itself would gate them.\n columns: [...requestColumns],\n ...(estimatedCount === undefined ? {} : { estimatedCount }),\n };\n const entry = start(request);\n setRunEntry(entry);\n setMode('progress');\n }\n\n // The dialog is a dismiss scope (P3-33): a close asks while the options differ from\n // the format's defaults. The confirm-close flow below stays the one prompt while a run is\n // in progress (the options form is not mounted then, so the scope is clean).\n const guard = useDismissGuard(() => onOpenChange(false));\n const dirtyOptions =\n mode === 'form' &&\n hasOptions(selectedFormat) &&\n optionsDiffer(formatValues, fieldDefaults(selectedFormat.options));\n\n function handleOpenChange(next: boolean): void {\n if (next) return; // this dialog is only ever closed through this handler\n // Once the confirm view is up, EVERY dismiss path Radix funnels through\n // this same callback — Escape, an overlay click, and the chrome close\n // button all call `onOpenChange(false)` exactly like a first close\n // attempt does. Without this branch, a SECOND dismiss signal while\n // `mode === 'confirm-close'` fell through to the plain `onOpenChange(false)`\n // at the bottom of this function: no `handle.cancel()`, no toast, no\n // explicit choice — a silent, unannounced \"continue in background\" that\n // defeats the whole point of asking. Swallowing the signal (never calling\n // the prop) keeps the dialog visually open, because `open` is a prop WE\n // forward from the parent unchanged — Radix has nothing else to redraw.\n if (mode === 'confirm-close') return;\n if (mode === 'progress' && runState?.status === 'running') {\n if (runEntry?.handle.cancel) {\n setMode('confirm-close');\n return;\n }\n toast(t('export.continuesInBackground'));\n guard.dismiss();\n return;\n }\n guard.dismiss();\n }\n\n function handleStop(): void {\n setMode('progress');\n // `ExportHandle.cancel` is a public seam — any adopter exporter may\n // implement it, and a rejecting one used to become an unhandled promise\n // rejection (bare `void handle.cancel?.()`). Reported loudly rather than\n // swallowed, the same stance `handle.ts` takes for a throwing listener:\n // the run itself is unaffected (the exporter owns its own termination),\n // but a cancel endpoint that is failing is worth knowing about.\n runEntry?.handle.cancel?.().catch((thrown: unknown) => {\n console.error('[buro] ExportDialog: export cancel failed', thrown);\n });\n onOpenChange(false);\n }\n\n function handleContinue(): void {\n setMode('progress');\n onOpenChange(false);\n }\n\n return (\n <Dialog open={open} onOpenChange={handleOpenChange}>\n <DialogContent data-testid={dialogTestId}>\n <DismissGuardScope value={guard.scope}>\n <ExportOptionsDirty dirty={open && dirtyOptions} />\n {mode === 'confirm-close' ? (\n <>\n <DialogHeader>\n <DialogTitle>{t('export.dialog.confirmCloseTitle')}</DialogTitle>\n <DialogDescription>{t('export.dialog.confirmCloseMessage')}</DialogDescription>\n </DialogHeader>\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n data-testid={`${dialogTestId}:continue`}\n onClick={handleContinue}\n >\n {t('export.dialog.continue')}\n </Button>\n <Button\n type=\"button\"\n variant=\"destructive\"\n data-testid={`${dialogTestId}:stop`}\n onClick={handleStop}\n >\n {t('export.dialog.stop')}\n </Button>\n </DialogFooter>\n </>\n ) : mode === 'progress' ? (\n <>\n <DialogHeader>\n <DialogTitle>{titleText}</DialogTitle>\n <DialogDescription className=\"sr-only\">{titleText}</DialogDescription>\n </DialogHeader>\n <ExportProgressView state={runState} dialogTestId={dialogTestId} t={t} caps={caps} />\n </>\n ) : (\n <>\n <DialogHeader>\n <DialogTitle>{titleText}</DialogTitle>\n <DialogDescription className=\"sr-only\">{titleText}</DialogDescription>\n </DialogHeader>\n\n {!available ? (\n // Task 8 gates the TRIGGER on `available` before ever opening\n // this dialog, so this path is a defensive fallback for a\n // direct/programmatic mount — without it, an unavailable\n // resource showed an empty form (no format selector, no\n // fields) next to a Start button that was disabled for a\n // reason nobody explained.\n <p role=\"alert\" data-testid={`${dialogTestId}:unavailable`}>\n {error === undefined || error === null\n ? t('export.dialog.unavailable')\n : resolveErrorText(error, caps)}\n </p>\n ) : (\n <>\n {loading ? (\n // A deferred exporter registration is still loading, so\n // there are no `formats` to choose from yet — this stands in\n // for the selector rather than rendering an empty one (and\n // Start stays disabled below). There is no semantic HTML\n // element for a status live region, so `role=\"status\"` on a\n // <p> IS the correct ARIA construction — same call the sort\n // warning below makes.\n // biome-ignore lint/a11y/useSemanticElements: see comment above\n <p\n role=\"status\"\n data-testid={`${dialogTestId}:loading`}\n className=\"text-sm text-muted-foreground\"\n >\n {t('export.dialog.loading')}\n </p>\n ) : (\n formats.length > 1 && (\n <div className=\"flex flex-col gap-1.5\">\n <span className=\"text-sm font-medium\">{t('export.dialog.format')}</span>\n <Select\n value={selectedFormat?.id}\n onValueChange={(value) => setFormatIdOverride(value)}\n >\n <SelectTrigger data-testid={`${dialogTestId}:format`}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {formats.map((format) => (\n <SelectItem\n key={format.id}\n value={format.id}\n data-testid={`${dialogTestId}:format:option:${format.id}`}\n >\n {resolveContentSlot(caps, [exportFormatLabelKey(format.id)], {\n default: declaredText('export-format', format, 'label'),\n humanize: () => format.id,\n })}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n )\n )}\n\n {hasOptions(selectedFormat) && (\n <DeclarativeForm\n key={selectedFormat.id}\n fields={localizedOptions ?? selectedFormat.options}\n defaults={fieldDefaults(selectedFormat.options)}\n onChange={setFormatValues}\n i18nPrefix=\"export\"\n slots={{ footer: <React.Fragment /> }}\n />\n )}\n\n <div className=\"flex flex-col gap-1.5\">\n <span className=\"text-sm font-medium\">{t('export.dialog.columns')}</span>\n <div className=\"flex gap-2\">\n <Button\n type=\"button\"\n size=\"sm\"\n variant={columnsMode === 'visible' ? 'default' : 'outline'}\n aria-pressed={columnsMode === 'visible'}\n data-testid={`${dialogTestId}:columns-visible`}\n onClick={() => setColumnsMode('visible')}\n >\n {t('export.dialog.columnsVisible')}\n </Button>\n <Button\n type=\"button\"\n size=\"sm\"\n variant={columnsMode === 'all' ? 'default' : 'outline'}\n aria-pressed={columnsMode === 'all'}\n data-testid={`${dialogTestId}:columns-all`}\n onClick={() => setColumnsMode('all')}\n >\n {t('export.dialog.columnsAll')}\n </Button>\n </div>\n </div>\n\n {showSortWarning && (\n // There is no semantic HTML element for a status live region, so\n // `role=\"status\"` on a <p> IS the correct ARIA construction — the\n // same call data-table-faceted-filter.tsx makes for role=\"option\".\n // biome-ignore lint/a11y/useSemanticElements: see comment above\n <p\n role=\"status\"\n data-testid={`${dialogTestId}:sort-warning`}\n className=\"text-sm text-warning-emphasis\"\n >\n {t('export.dialog.sortWarning')}\n </p>\n )}\n\n <DialogFooter>\n <Button\n type=\"button\"\n // `loading` is stated explicitly even though an unloaded\n // exporter also has no `selectedFormat`: `start()` is\n // synchronous and THROWS while a deferred registration is\n // still loading, so the reason this control is disabled\n // should be readable at the call site rather than inferred\n // from an empty format list.\n disabled={loading || !selectedFormat || accessPending}\n data-testid={`${dialogTestId}:start`}\n onClick={handleStart}\n >\n {t('export.dialog.start')}\n </Button>\n </DialogFooter>\n </>\n )}\n </>\n )}\n </DismissGuardScope>\n </DialogContent>\n </Dialog>\n );\n}\n\nfunction ExportProgressView({\n state,\n dialogTestId,\n t,\n caps,\n}: {\n state: ExportRunState | undefined;\n dialogTestId: string;\n caps: ErrorTextCaps;\n t: (key: string, options?: { params?: Record<string, unknown> }) => string;\n}): React.ReactElement | null {\n if (state === undefined) return null;\n if (state.status === 'running') {\n const total = state.progress?.total;\n return (\n <p data-testid={`${dialogTestId}:progress`}>\n {total === undefined\n ? t('export.dialog.progressIndeterminate')\n : t('export.dialog.progress', { params: { done: state.progress?.done ?? 0, total } })}\n </p>\n );\n }\n if (state.status === 'succeeded') {\n return (\n <Button\n type=\"button\"\n data-testid={`${dialogTestId}:download`}\n onClick={() => downloadArtifact(state.artifact)}\n >\n {t('export.dialog.download')}\n </Button>\n );\n }\n if (state.status === 'failed') {\n // Framed with `export.dialog.failed` rather than rendering a bare\n // `DataError.message`: a message is a reference now and the developer's sentence lives in\n // `details`, which a user never reads. The text is the bundle's, framed by what failed. The key existed in both\n // bundles and was unused.\n return (\n <p role=\"alert\" data-testid={`${dialogTestId}:error`}>\n {`${t('export.dialog.failed')}: ${resolveErrorText(state.error, caps)}`}\n </p>\n );\n }\n if (state.status === 'canceled') {\n return <p data-testid={`${dialogTestId}:canceled`}>{t('export.dialog.canceled')}</p>;\n }\n // Exhaustiveness check: `ExportRunState` (`@burojs/core`) is a closed union\n // of exactly 4 statuses. A future 5th status would fail THIS assignment at\n // compile time — `state` would no longer be assignable to `never` — rather\n // than silently falling through to whatever a trailing catch-all used to\n // render (a `canceled` message, which is exactly wrong for an unmodeled\n // status).\n const exhaustive: never = state;\n return exhaustive;\n}\n","'use client';\nimport { BULK_EACH_LIMIT, type BulkProgress, compileFlow, type FlowResult } from '@burojs/core';\nimport { useApp, useFlowRowResolver, useChromeT, useOptionalT, useTestIds } from '@burojs/react';\nimport { type ReactElement, useMemo, useState } from 'react';\nimport { DisabledAction } from '../actions/action-button.js';\nimport { ActionInner } from '../actions/action-inner.js';\nimport { Button } from '../primitives/button.js';\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from '../primitives/dialog.js';\nimport { useFlowChrome } from './chrome.js';\nimport {\n FlowBoundary,\n loadBulkSummary,\n loadFailedText,\n preloadFlowRuntime,\n RuntimeBulkFlowRunner,\n useLoaded,\n} from './load-runtime.js';\nimport type { FlowBulkSummaryProps } from './bulk-summary.js';\n\n/** The summary, loaded on first use (plan ruling 8); a failed load says so, with Retry. */\nfunction BulkSummary(props: FlowBulkSummaryProps): ReactElement | null {\n const loaded = useLoaded(loadBulkSummary);\n const t = useOptionalT();\n const chromeT = useChromeT();\n const failed = (retry: () => void) => (\n <div role=\"alert\" className=\"flex items-center gap-2 text-sm\">\n <span>{loadFailedText(t)}</span>\n <Button type=\"button\" size=\"sm\" variant=\"outline\" onClick={retry}>\n {chromeT('actions.retry', { defaultValue: 'Retry' })}\n </Button>\n </div>\n );\n if (loaded.error !== undefined) return failed(loaded.retry);\n if (loaded.module === undefined) return null;\n const Summary = loaded.module.FlowBulkSummary;\n return (\n <FlowBoundary fallback={(_error, reset) => failed(reset)}>\n <Summary {...props} />\n </FlowBoundary>\n );\n}\n\nexport interface BulkFlowButtonProps {\n readonly resource: string;\n readonly actionName: string;\n /** The selected ids: the run's `selection` (`{ ids, count }`). */\n readonly ids: readonly string[];\n /** Replaces the selection: after a run, the ids that succeeded leave it (4.16). */\n readonly onSelectionChange?: (ids: string[]) => void;\n}\n\n/**\n * A bulk flow in the selection bar (P4 spec 4.16): over the selection `{ ids, count }`, at most\n * `BULK_EACH_LIMIT` ids (more renders the button refused, and nothing is read). Its state comes\n * from the flow's gate without a run; the click starts the run (loading the flow runtime when a\n * hover or a focus has not already): `confirm` and the fired warnings ask, the run re-reads the\n * rows in one read and writes each under its own key. Afterwards the ids that succeeded leave\n * the selection, the others stay, and anything but a full success shows the per-outcome summary.\n */\nexport function BulkFlowButton({\n resource,\n actionName,\n ids,\n onSelectionChange,\n}: BulkFlowButtonProps): ReactElement | null {\n const app = useApp();\n const tid = useTestIds();\n const t = useOptionalT();\n const control = useFlowRowResolver(resource)(actionName, undefined);\n const chrome = useFlowChrome(resource, actionName);\n const def = app.registry.get(resource);\n const compiled = useMemo(() => {\n try {\n return def === undefined ? undefined : compileFlow(def as never, actionName);\n } catch {\n return undefined;\n }\n }, [def, actionName]);\n const each = compiled?.each ?? false;\n const [running, setRunning] = useState(false);\n const [summary, setSummary] = useState<{\n readonly progress: BulkProgress;\n readonly total: number;\n } | null>(null);\n const testid = tid.bulkAction(resource, actionName);\n if (control.state === 'absent') return null;\n const variant = chrome.destructive ? 'destructive' : 'outline';\n const overLimit = each && ids.length > BULK_EACH_LIMIT;\n if (overLimit || control.state === 'disabled')\n return (\n <DisabledAction\n reason={\n overLimit\n ? t('flow.bulkLimit', {\n defaultValue: `Select at most ${BULK_EACH_LIMIT}.`,\n count: BULK_EACH_LIMIT,\n })\n : control.reason\n }\n label={chrome.label}\n icon={chrome.icon}\n testid={testid}\n size=\"sm\"\n variant={variant}\n resource={resource}\n actionName={actionName}\n surface=\"bulk\"\n />\n );\n const busy = control.state === 'undecided' || control.state === 'pending' || running;\n const finish = (result: FlowResult, progress: BulkProgress | undefined) => {\n setRunning(false);\n if (progress === undefined) return;\n if (result.outcome !== 'success') setSummary({ progress, total: ids.length });\n // The ids that succeeded leave the selection; the others stay selected (4.16).\n onSelectionChange?.(ids.filter((id) => !progress.success.includes(id)));\n };\n return (\n <>\n <Button\n type=\"button\"\n size=\"sm\"\n variant={variant}\n data-testid={testid}\n data-buro-flow-state={running ? 'running' : control.state}\n disabled={busy}\n aria-busy={busy ? 'true' : undefined}\n onPointerEnter={preloadFlowRuntime}\n onFocus={preloadFlowRuntime}\n onClick={() => {\n if (!busy) setRunning(true);\n }}\n >\n <ActionInner icon={chrome.icon} label={chrome.label} />\n </Button>\n {running ? (\n <RuntimeBulkFlowRunner\n resource={resource}\n actionName={actionName}\n ids={ids}\n onFinish={finish}\n />\n ) : null}\n <Dialog\n open={summary !== null}\n onOpenChange={(open) => {\n if (!open) setSummary(null);\n }}\n >\n <DialogContent data-testid={`${tid.bulkSummary(resource, actionName)}:dialog`}>\n <DialogHeader>\n <DialogTitle>{chrome.label}</DialogTitle>\n <DialogDescription className=\"sr-only\">{chrome.labelText}</DialogDescription>\n </DialogHeader>\n {summary === null ? null : (\n <BulkSummary\n resource={resource}\n actionName={actionName}\n label={chrome.labelText}\n total={summary.total}\n progress={summary.progress}\n texts={compiled?.flow.texts}\n />\n )}\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n data-testid={`${tid.bulkSummary(resource, actionName)}:close`}\n onClick={() => setSummary(null)}\n >\n {t('flow.close', { defaultValue: 'Close' })}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n </>\n );\n}\n","'use client';\nimport { routeResourceKey } from '@burojs/core';\nimport type { ResourceNameOrRef } from '@burojs/core';\nimport { isFlowAction } from '@burojs/core/internal';\nimport { useState } from 'react';\nimport { IconDownload, IconX } from '@tabler/icons-react';\nimport type { ActionFlow, ExportTarget, ScopeSource } from '@burojs/core';\nimport {\n useApp,\n useCapability,\n useOptionalDataRuntime,\n useChromeT,\n useOptionalT,\n useResourceExport,\n useTestIds,\n} from '@burojs/react';\nimport type { Table } from '@tanstack/react-table';\nimport { Button } from '../primitives/button.js';\nimport { cn } from '../lib/cn.js';\nimport { ExportDialog } from '../export/export-dialog.js';\nimport { BulkFlowButton } from '../flows/bulk-flow-button.js';\n\ntype BulkRecord = { id: string } & Record<string, unknown>;\n\n/**\n * Canonical order for the bar's declared actions — `order` when it is set,\n * declaration index otherwise, stable on ties.\n *\n * The identical weighting `planItemActions` gives item actions, deliberately\n * NOT that function: it also resolves SURFACES and a density, and a bulk\n * action has neither (`ActionSurfaces` is `{ row; show; edit; list }` — there\n * is no `bulk` surface, and this bar is the one place a bulk action renders).\n * Calling it here would mean inventing a surface name for a control that has\n * exactly one home.\n *\n * Until SP5 task 6 `order` was declared on bulk actions and read by\n * nothing: a probe declared `[{ name: 'second', order: 99 }, { name: 'first',\n * order: 1 }]` and the bar drew them in declaration order.\n */\nfunction orderBulkActions(actions: readonly ActionFlow[]): ActionFlow[] {\n return actions\n .map((action, index) => ({ action, weight: action.order ?? index, seq: index }))\n .sort((a, b) => a.weight - b.weight || a.seq - b.seq)\n .map(({ action }) => action);\n}\n\nexport interface BulkActionToolbarProps<\n TRecord extends BulkRecord = BulkRecord,\n N extends string = string,\n> {\n resource: ResourceNameOrRef<N>;\n /**\n * TanStack table instance from the surrounding `<ResourceList>`. Used only\n * as a FALLBACK, for standalone call sites that have no accumulated set of\n * their own: `getFilteredSelectedRowModel()` can only see the rows of the\n * current page, so it under-reports a selection built across pages.\n */\n table?: Table<TRecord>;\n /**\n * The selected records — the authoritative source when present. Includes\n * records for rows the user selected on pages they have since left.\n */\n selectedRecords?: TRecord[];\n /**\n * The selected ids. Defaults to the ids of `selectedRecords`; pass it\n * explicitly when the owner's id set can be wider than the records it\n * could resolve (see `ResourceListController.selection`).\n */\n selectedIds?: string[];\n /**\n * Called when the user clicks the \"Clear\" button. When `table` is\n * provided and this prop is omitted, the toolbar clears selection\n * itself via `table.resetRowSelection()`.\n */\n onClearSelection?: () => void;\n /**\n * Replaces the selection. A bulk flow calls it after its run: the ids that succeeded leave the\n * selection and the others stay (P4 spec 4.16). Without it, a run that succeeded for every id\n * clears the selection through `onClearSelection`.\n */\n onSelectionChange?: (ids: string[]) => void;\n className?: string;\n /**\n * The list's currently visible columns (Task 8) — forwarded to the\n * built-in bulk Export entry point's `<ExportDialog visibleColumns>` as\n * what \"as shown in the table\" (the dialog's default) sends as\n * `request.columns`. Optional: this toolbar is usable standalone, with no\n * `<ResourceListPage>`/list controller in reach — a caller that omits it\n * gets the dialog's \"All columns\" set for that default: the resource's list\n * fields, minus any a `column` rule hides.\n */\n visibleColumns?: readonly string[];\n /** How the built-in bulk Export reads the resource: the scope of the list the ids came from. */\n scope?: ScopeSource;\n /**\n * The bar's controls in place of the resource's bulk actions and the built-in Export (a link\n * panel's Detach). The count and Clear stay.\n */\n actions?: React.ReactNode;\n}\n\nexport function BulkActionToolbar<\n TRecord extends BulkRecord = BulkRecord,\n const N extends string = string,\n>({\n resource: resourceInput,\n table,\n selectedRecords,\n selectedIds,\n onClearSelection,\n onSelectionChange,\n className,\n visibleColumns,\n scope,\n actions,\n}: BulkActionToolbarProps<TRecord, N>): React.ReactElement | null {\n const resource = routeResourceKey(resourceInput);\n const app = useApp();\n const tid = useTestIds();\n const t = useOptionalT();\n const chromeT = useChromeT();\n const def = app.registry.get(resource);\n\n // Explicit selection wins: it is the whole accumulated set. The table only\n // knows the current page, so it is the fallback for standalone callers.\n const records: TRecord[] =\n selectedRecords ??\n (table ? table.getFilteredSelectedRowModel().rows.map((r) => r.original as TRecord) : []);\n const ids: string[] = selectedIds ?? records.map((record) => record.id);\n\n if (!def || (records.length === 0 && ids.length === 0)) return null;\n\n // Every bulk action is a flow (P4, F15): `order`, then declaration; each draws its own button.\n const bulkActions = orderBulkActions(\n ((def.actions.bulk ?? []) as readonly unknown[]).filter(isFlowAction) as ActionFlow[],\n );\n\n const handleClear = (): void => {\n if (onClearSelection) {\n onClearSelection();\n return;\n }\n table?.resetRowSelection();\n };\n\n return (\n <>\n {/*\n Floating command bar (#1). It used to sit INLINE above the table and\n shove the whole list down the moment a row was checked — jarring. It's\n now `fixed` to the bottom-centre of the viewport, so selecting rows never\n reflows the content. A matching spacer (below) extends the scroll height\n so the last rows can always be scrolled clear of the bar. Slide-up +\n fade on mount; a frosted, elevated pill on the theme's own tokens.\n */}\n <div className=\"pointer-events-none fixed inset-x-0 bottom-0 z-40 flex justify-center px-4 pb-4 sm:pb-6\">\n <div\n data-testid={tid.listBulkBar(resource)}\n className={cn(\n // `flex-wrap` + max-width: at 390px the bar would otherwise overflow\n // the viewport (measured 715px in a 356px container); wrapping keeps\n // every action reachable without a sideways scroll.\n 'pointer-events-auto flex max-w-[calc(100vw-2rem)] flex-wrap items-center gap-1.5 rounded-full border bg-background/95 p-1.5 pl-3 shadow-lg supports-[backdrop-filter]:bg-background/80 supports-[backdrop-filter]:backdrop-blur',\n 'animate-in fade-in-0 zoom-in-95 slide-in-from-bottom-3 duration-300 ease-out',\n className,\n )}\n >\n <span className=\"flex items-center gap-2 pr-1 text-sm font-medium\">\n {/* Narrow screens: a primary count chip stands in for the full\n sentence (which is hidden below `sm`), so the count is never\n lost. */}\n <span className=\"inline-flex h-6 min-w-6 items-center justify-center rounded-full bg-primary px-1.5 text-xs font-semibold tabular-nums text-primary-foreground sm:hidden\">\n {ids.length}\n </span>\n {/*\n The count is the WHOLE selection, which can exceed the number of\n checked boxes on screen: selection accumulates across pages. The\n chip (mobile) and this sentence (sm+) never show together, so the\n count is stated exactly once.\n */}\n <span className=\"hidden text-muted-foreground sm:inline\">\n {t('table.selectedCount', { count: ids.length })}\n </span>\n </span>\n <span className=\"mx-0.5 h-6 w-px bg-border\" aria-hidden=\"true\" />\n {actions !== undefined ? actions : null}\n {actions === undefined &&\n bulkActions.map((action) => (\n <BulkFlowButton\n key={action.name}\n resource={resource}\n actionName={action.name}\n ids={ids}\n onSelectionChange={(next) => {\n if (onSelectionChange !== undefined) onSelectionChange(next);\n else if (next.length === 0) handleClear();\n }}\n />\n ))}\n {/*\n Built-in Export entry point (Task 8) — NOT one of `def.actions\n .bulk`, so it renders unconditionally alongside them rather than\n through the per-action loop; its own gates\n (`useResourceExport().available` + the capability engine) decide\n whether it exists at all.\n */}\n {actions === undefined && (\n <BulkExportButton\n resource={resource}\n ids={ids}\n visibleColumns={visibleColumns ?? []}\n {...(scope === undefined ? {} : { scope })}\n />\n )}\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"ghost\"\n onClick={handleClear}\n className=\"h-8 gap-1.5 rounded-full px-2.5\"\n >\n <IconX className=\"size-4\" aria-hidden=\"true\" />\n <span className=\"hidden sm:inline\">\n {chromeT('actions.clearSelection', { defaultValue: 'Clear' })}\n </span>\n </Button>\n </div>\n </div>\n {/* Scroll-clearance spacer: only present while the bar is (its height +\n bottom gap ≈ the bar's footprint), so the bottom rows never hide\n behind the floating bar. Rendered in-flow at the end of the content. */}\n <div aria-hidden=\"true\" className=\"h-20 sm:h-24\" />\n </>\n );\n}\n\n/**\n * Built-in bulk Export entry point (Task 8) — the `selection.ids` analogue\n * of `<ExportButton>`'s filter-scope toolbar button. Own component (like\n * `BulkFlowButton`) so its hooks (`useResourceExport`, `useCapability`,\n * `useState`) keep a stable order regardless of how many declared bulk\n * actions render around it.\n *\n * Target is `{ kind: 'ids', ids }` — exactly `selection.ids`, never derived\n * from `records` (which may be shorter: a snapshot only exists for rows the\n * list still has a record for, per `ResourceListController.selection`'s own\n * doc). `ids` is threaded in as a prop rather than read from\n * `useResourceListContext()` — this toolbar is usable with NO\n * `<ResourceListProvider>` mounted at all (see `BulkActionToolbarProps`'s\n * own doc on `table`), and every existing test in this file renders it that\n * way; calling that hook here would throw for every one of them.\n *\n * `<ExportDialog>` is mounted as a SIBLING of the floating bar's buttons —\n * never nested inside a menu's content — matching `ActionOverflow`'s\n * flow runner, mounted beside its menu: two nested Radix\n * focus scopes make typing unreliable in a browser and deadlocked this\n * repo's jsdom runner. This toolbar renders plain `<Button>`s, not a\n * dropdown menu, so the failure mode does not apply today — but the dialog\n * still lives at this level (a sibling return, not inside anything that\n * could tear it down) so the invariant holds if a future menu-mode bulk bar\n * is ever built on top of this component.\n */\nfunction BulkExportButton({\n resource,\n ids,\n visibleColumns,\n scope,\n}: {\n resource: string;\n ids: string[];\n visibleColumns: readonly string[];\n scope?: ScopeSource;\n}): React.ReactElement | null {\n // See `ExportButton`'s identical guard (`export-button.tsx`) for why:\n // `useResourceExport` hard-requires a native data runtime, and this\n // toolbar is explicitly usable standalone (no `<ResourceListProvider>`,\n // sometimes no `dataRuntime` at all — several tests in this very file\n // render it that way). `useOptionalDataRuntime()` never throws, so it is\n // safe to call unconditionally here; `BulkExportButtonActive` calls the\n // hard hooks unconditionally because it only ever mounts once a runtime\n // is confirmed present.\n const hasDataRuntime = useOptionalDataRuntime() !== null;\n if (!hasDataRuntime) return null;\n return (\n <BulkExportButtonActive\n resource={resource}\n ids={ids}\n visibleColumns={visibleColumns}\n {...(scope === undefined ? {} : { scope })}\n />\n );\n}\n\nfunction BulkExportButtonActive({\n resource,\n ids,\n visibleColumns,\n scope,\n}: {\n resource: string;\n ids: string[];\n visibleColumns: readonly string[];\n scope?: ScopeSource;\n}): React.ReactElement | null {\n const tid = useTestIds();\n const t = useOptionalT();\n // No `{ load: true }`, plus hover/focus prefetch — identical reasoning to\n // `<ExportButton>`'s, documented there.\n const { available, prefetch } = useResourceExport(resource);\n const capability = useCapability('run', {\n resource,\n target: { kind: 'action', name: 'export' },\n mode: 'list',\n });\n const [open, setOpen] = useState(false);\n\n if (!available || !capability.allowed) return null;\n\n const target: ExportTarget = { kind: 'ids', ids };\n\n return (\n <>\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n data-testid={tid.exportBulkAction(resource)}\n onClick={() => setOpen(true)}\n onMouseEnter={prefetch}\n onFocus={prefetch}\n >\n <IconDownload className=\"size-4\" aria-hidden=\"true\" />\n {t('export.button.label')}\n </Button>\n <ExportDialog\n open={open}\n onOpenChange={setOpen}\n resource={resource}\n target={target}\n visibleColumns={visibleColumns}\n {...(scope === undefined ? {} : { scope })}\n />\n </>\n );\n}\n","'use client';\nimport { type ReactElement, useState } from 'react';\nimport { IconUnlink } from '@tabler/icons-react';\nimport { useOptionalT, useResourceListContext } from '@burojs/react';\nimport { BulkActionToolbar } from '../../actions/bulk-action-toolbar.js';\nimport { Button } from '../../primitives/button.js';\nimport { listPiece } from './piece.js';\nimport { useListSurface, usePieceMount } from './pieces-context.js';\n\n/** A link panel's bulk Detach: confirms (the panel's) and removes the selected rows' links. */\nfunction LinkDetachBulkButton(props: {\n readonly onDetach: (rows: readonly Readonly<Record<string, unknown>>[]) => Promise<unknown>;\n}): ReactElement {\n const { selection } = useResourceListContext();\n const { resource } = useListSurface();\n const t = useOptionalT();\n const [busy, setBusy] = useState(false);\n return (\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"ghost\"\n className=\"h-8 gap-1.5 rounded-full px-2.5 text-destructive\"\n disabled={busy}\n data-testid={`list-link-detach-bulk:${resource}`}\n onClick={() => {\n setBusy(true);\n void props.onDetach(selection.records).finally(() => setBusy(false));\n }}\n >\n <IconUnlink className=\"size-4\" aria-hidden=\"true\" />\n {t('field.link.detach', { defaultValue: 'Detach' })}\n </Button>\n );\n}\n\n/**\n * The floating bar of a selection. The surface mounts it BELOW the list frame, so a frame cannot\n * lose it; it must render at the END of the content flow so its in-flow spacer extends the scroll\n * height and the last rows clear the bar.\n */\nfunction ListBulkBarView() {\n usePieceMount('bulk-bar');\n const { selection, columns, scope } = useResourceListContext();\n const { resource, tableView, readOnly, linkEditing } = useListSurface();\n // A read-only list draws a bar only for a link panel's Detach, and then nothing else on it.\n const detach = readOnly ? linkEditing?.detach : undefined;\n if (!tableView || (readOnly && detach === undefined) || selection.ids.length === 0) return null;\n return (\n <BulkActionToolbar\n {...(detach === undefined\n ? {}\n : { actions: <LinkDetachBulkButton onDetach={detach.onDetach} /> })}\n resource={resource}\n selectedRecords={selection.records}\n selectedIds={selection.ids}\n onClearSelection={selection.clear}\n onSelectionChange={selection.set}\n visibleColumns={columns.visible}\n scope={scope}\n />\n );\n}\n\nexport const ListBulkBar: () => ReactElement | null = listPiece('ListBulkBar', ListBulkBarView);\n","'use client';\nimport type { ReactNode } from 'react';\nimport { useOptionalT } from '@burojs/react';\nimport type { Column, Table } from '@tanstack/react-table';\nimport { IconSettings2 } from '@tabler/icons-react';\nimport { Button } from '../primitives/button.js';\nimport { Checkbox } from '../primitives/checkbox.js';\nimport { Popover, PopoverContent, PopoverTrigger } from '../primitives/popover.js';\nimport { cn } from '../lib/cn.js';\n\n/**\n * Column visibility toggle for `<DataTable>`. Functional adaptation\n * of the canonical shadcn Tasks `data-table-view-options.tsx` using\n * existing Popover + Checkbox primitives. The shadcn version uses\n * DropdownMenu + DropdownMenuCheckboxItem; we mirror the\n * functionality without expanding our primitive surface (Popover\n * is what we already ship).\n *\n * The component lists every column for which `column.getCanHide()`\n * returns true and toggles visibility via `column.toggleVisibility()`.\n * Three features the original playground `ColumnsToggle` carried —\n * required-column locking (`data-required` attribute, disabled\n * checkbox), a \"Reset to defaults\" footer, and visual overrides for\n * trigger/menu — are all surfaced as optional props so the caller\n * keeps full control of look + behaviour.\n *\n * Testids: resource-agnostic, supplied by the caller via\n * `getTestId(role, columnId?)` callback. Roles: 'trigger', 'menu',\n * 'option' (with columnId), 'checkbox' (with columnId), 'reset'.\n */\nexport interface DataTableViewOptionsProps<TData> {\n table: Table<TData>;\n\n /**\n * Map a column to its visible label. Defaults to `column.id`.\n * The future ResourceList migration plugs in field labels (e.g.\n * `def.fields[col].label ?? humanizeKey(col)`).\n */\n getColumnLabel?: (column: Column<TData, unknown>) => string;\n\n /**\n * Mark a column as required (cannot be hidden). When true:\n * - the checkbox is disabled (and forced to checked)\n * - the option row carries `data-required=\"true\"` for\n * compatibility with the existing `column-toggle.spec.ts`.\n */\n isColumnRequired?: (column: Column<TData, unknown>) => boolean;\n\n /**\n * Resource-agnostic testid generator. Roles:\n * 'trigger' → the popover trigger button\n * 'menu' → the popover content container\n * 'option' → option row (columnId passed as second arg)\n * 'checkbox' → option checkbox input (columnId as second arg)\n * 'reset' → \"Reset to defaults\" footer button (only rendered\n * when `onReset` is provided)\n */\n getTestId?: (\n role: 'trigger' | 'menu' | 'option' | 'checkbox' | 'reset',\n columnId?: string,\n ) => string | undefined;\n\n /**\n * Optional reset callback. When provided, a footer button is\n * rendered at the bottom of the popover content. Caller controls\n * visibility by passing `undefined` when the table is already at\n * defaults — the typical pattern is `onReset={isAtDefaults ?\n * undefined : handler}`.\n */\n onReset?: () => void;\n\n /**\n * Extra footer actions (#17), rendered below the column list — e.g. «Reset\n * sizes» / «Restore defaults». Each is a full-width button. Shown\n * in addition to `onReset`.\n */\n footerActions?: Array<{ label: string; onClick: () => void; testid?: string }>;\n\n /** Label rendered inside the trigger button. Default: \"View\". */\n triggerLabel?: string;\n\n /**\n * Icon node rendered to the left of `triggerLabel`. Default:\n * `<Settings2 .../>`. Pass `null` to suppress the icon entirely\n * (the playground's \"Columns\" trigger uses no icon).\n */\n triggerIcon?: ReactNode;\n\n /**\n * className applied to the trigger Button. Default:\n * `'ml-auto hidden h-8 lg:flex'` (the canonical shadcn-tasks\n * trigger style, right-aligned, hidden on small viewports).\n * Pass an empty string to remove the default and let the Button\n * primitive's own classes drive layout.\n */\n triggerClassName?: string;\n\n /** Popover content alignment. Default: 'end'. */\n popoverAlign?: 'start' | 'center' | 'end';\n\n /** className applied to the popover content. Default: 'w-[180px] p-1'. */\n popoverContentClassName?: string;\n\n /**\n * Header rendered at the top of the popover content. Default:\n * \"Toggle columns\". Pass `null` to suppress the header (and its\n * divider).\n */\n menuTitle?: ReactNode;\n\n /** Label rendered inside the reset footer button. Defaults to `toolbar.restoreDefaults`. */\n resetLabel?: string;\n\n /**\n * Legacy alias for `triggerClassName`. Earlier callers used\n * `className` to override the trigger; we keep that behaviour for\n * backward compatibility — both compose via `cn`.\n */\n className?: string;\n\n /**\n * Render the trigger as a compact icon-only square button (no visible\n * label). `triggerLabel` becomes the `aria-label` + tooltip so the control\n * stays accessible. Pass `triggerIcon` WITHOUT a text margin in this mode.\n */\n iconOnly?: boolean;\n}\n\nconst DEFAULT_TRIGGER_ICON = <IconSettings2 className=\"mr-2 h-4 w-4\" aria-hidden=\"true\" />;\n\nexport function DataTableViewOptions<TData>({\n table,\n getColumnLabel,\n isColumnRequired,\n getTestId,\n onReset,\n footerActions,\n triggerLabel = 'View',\n triggerIcon = DEFAULT_TRIGGER_ICON,\n triggerClassName = 'ml-auto hidden h-8 lg:flex',\n popoverAlign = 'end',\n popoverContentClassName = 'w-[180px] p-1',\n menuTitle,\n resetLabel,\n className,\n iconOnly = false,\n}: DataTableViewOptionsProps<TData>): React.ReactElement {\n /*\n ⚠️ These defaulted to the English literals 'Toggle columns' and 'Reset to\n defaults'. This component is exported to adopters, so those strings were\n reachable — an app in another language that used `onReset` without also\n passing `resetLabel` got an English button. Defaults now come from the bundle;\n an explicitly-passed label still wins.\n */\n const t = useOptionalT();\n // `undefined` means \"not specified, use the default\"; an explicit `null`\n // means \"no header at all\" and is part of this component's contract, so\n // `??` would be wrong here.\n const menuTitleText =\n menuTitle === undefined ? t('toolbar.columns', { defaultValue: 'Toggle columns' }) : menuTitle;\n const resetLabelText =\n resetLabel ?? t('toolbar.restoreDefaults', { defaultValue: 'Reset to defaults' });\n const hideableColumns = table\n .getAllColumns()\n .filter((column) => typeof column.accessorFn !== 'undefined' && column.getCanHide());\n\n return (\n <Popover>\n <PopoverTrigger asChild>\n <Button\n type=\"button\"\n variant=\"outline\"\n size={iconOnly ? 'icon' : 'sm'}\n aria-label={iconOnly && typeof triggerLabel === 'string' ? triggerLabel : undefined}\n title={iconOnly && typeof triggerLabel === 'string' ? triggerLabel : undefined}\n data-testid={getTestId?.('trigger')}\n className={cn(iconOnly && 'h-8 w-8', triggerClassName, className)}\n >\n {triggerIcon}\n {!iconOnly && triggerLabel}\n </Button>\n </PopoverTrigger>\n <PopoverContent\n align={popoverAlign}\n className={popoverContentClassName}\n data-testid={getTestId?.('menu')}\n >\n {menuTitleText != null && (\n <>\n <div className=\"px-2 py-1.5 text-sm font-semibold\">{menuTitleText}</div>\n <div className=\"my-1 -mx-1 border-t\" />\n </>\n )}\n <div className=\"max-h-[300px] overflow-auto\">\n {hideableColumns.map((column) => {\n const label = getColumnLabel?.(column) ?? column.id;\n const required = isColumnRequired?.(column) ?? false;\n const checked = required ? true : column.getIsVisible();\n return (\n <label\n key={column.id}\n data-testid={getTestId?.('option', column.id)}\n data-required={required ? 'true' : 'false'}\n className={cn(\n 'flex items-center gap-2 px-2 py-1.5 rounded-sm text-sm cursor-pointer',\n required\n ? 'opacity-60 cursor-not-allowed'\n : 'hover:bg-accent hover:text-accent-foreground',\n )}\n >\n <Checkbox\n data-testid={getTestId?.('checkbox', column.id)}\n checked={checked}\n disabled={required}\n onCheckedChange={(value) => {\n if (required) return;\n column.toggleVisibility(!!value);\n }}\n />\n <span className=\"flex-1 truncate\">{label}</span>\n </label>\n );\n })}\n </div>\n {(onReset || (footerActions && footerActions.length > 0)) && (\n <div className=\"mt-2 space-y-0.5 border-t pt-2\">\n {onReset && (\n <button\n type=\"button\"\n onClick={onReset}\n data-testid={getTestId?.('reset')}\n className=\"w-full rounded-sm px-2 py-1 text-left text-sm text-muted-foreground hover:bg-accent hover:text-accent-foreground focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring\"\n >\n {resetLabelText}\n </button>\n )}\n {footerActions?.map((a) => (\n <button\n key={a.label}\n type=\"button\"\n onClick={a.onClick}\n data-testid={a.testid}\n className=\"w-full rounded-sm px-2 py-1 text-left text-sm text-muted-foreground hover:bg-accent hover:text-accent-foreground focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring\"\n >\n {a.label}\n </button>\n ))}\n </div>\n )}\n </PopoverContent>\n </Popover>\n );\n}\n","'use client';\nimport { routeResourceKey } from '@burojs/core';\nimport type { ResourceNameOrRef } from '@burojs/core';\nimport { useMemo } from 'react';\nimport { IconColumns3 } from '@tabler/icons-react';\nimport type { ColumnDef, VisibilityState } from '@tanstack/react-table';\nimport { getCoreRowModel, useReactTable } from '@tanstack/react-table';\nimport { resolveFieldLabel, type ResourceDef, declaredText } from '@burojs/core';\nimport { type RowRecord, useApp, useI18nCaps, useT } from '@burojs/react';\nimport { DataTableViewOptions } from '../data-table/data-table-view-options.js';\nimport { capsOf, columnTarget } from '../resource/column-target.js';\n\n/**\n * Storage-shape adapter around `<DataTableViewOptions>` (the canonical\n * shadcn-Tasks-style column visibility dropdown). The primitive\n * itself reads/writes TanStack's `VisibilityState` (`Record<columnId,\n * boolean>`); the playground persists visibility as `string[]` of\n * visible column ids in the URL at `?<resource>.cols=col1,col2,col3`\n * via `useResourceUrlState`'s `setVisibleColumns` setter (A3.1-A3.3).\n * This wrapper bridges those two shapes: it spins up a tiny\n * visibility-only `useReactTable`, derives the visibility map from\n * the parent's `visibleColumns`, and projects `onColumnVisibilityChange`\n * back into the `string[]` shape the parent owns.\n *\n * Stage-1 ColumnsToggle migration completed via this adapter — the\n * primitive's contracts (testid surface, `data-required=\"true\"`,\n * disabled-when-required checkbox, footer Reset, ARIA) are preserved\n * verbatim through the `getTestId` / `isColumnRequired` / `onReset`\n * callbacks.\n *\n * Reset semantics: `onChange(undefined)` reverts to defaults. The\n * parent maps `undefined → null` for `setVisibleColumns`, which drops\n * the `?<r>.cols=` URL param. The Reset button only renders when the\n * current `visibleColumns` differs from `defaultVisible` by\n * set-equality (since the merge always materialises in\n * `allAvailable` order, set-equality is sufficient).\n *\n * Visual overrides match the rest of the toolbar chrome: trigger\n * label \"Columns\" with no icon, popover `align=\"start\" w-64 p-2`\n * with no header.\n */\nexport function ColumnsToggle<const N extends string = string>({\n resource: resourceInput,\n def,\n allAvailable,\n required,\n visibleColumns,\n defaultVisible,\n onChange,\n onResetSizes,\n onRestoreDefaults,\n}: {\n resource: ResourceNameOrRef<N>;\n def: ResourceDef;\n allAvailable: string[];\n required: string[];\n visibleColumns: string[];\n defaultVisible: string[];\n onChange: (next: string[] | undefined) => void;\n onResetSizes?: () => void;\n onRestoreDefaults?: () => void;\n}) {\n const resource = routeResourceKey(resourceInput);\n const t = useT();\n const columnsCaps = useI18nCaps(resource);\n const app = useApp();\n const visibleSet = useMemo(() => new Set(visibleColumns), [visibleColumns]);\n const requiredSet = useMemo(() => new Set(required), [required]);\n const defaultSet = useMemo(() => new Set(defaultVisible), [defaultVisible]);\n\n // \"Differs from defaults\" means same elements (order is irrelevant —\n // the merge logic always keeps required first then optional in the\n // declared order). We compare set-equality.\n const isAtDefaults = useMemo(() => {\n if (visibleSet.size !== defaultSet.size) return false;\n for (const x of visibleSet) {\n if (!defaultSet.has(x)) return false;\n }\n return true;\n }, [visibleSet, defaultSet]);\n\n // ColumnDefs for the visibility-only TanStack table. `accessorKey`\n // is required so DataTableViewOptions' filter\n // (`typeof column.accessorFn !== 'undefined'`) accepts the column.\n const tableColumns = useMemo<ColumnDef<RowRecord>[]>(() => {\n return allAvailable.map((col) => ({\n id: col,\n accessorKey: col,\n enableHiding: true,\n }));\n }, [allAvailable]);\n\n // Project the parent's `string[]` into the TanStack VisibilityState\n // shape (`Record<columnId, boolean>`). Required columns are always\n // `true` here; non-required entries follow the parent's set.\n const visibilityState = useMemo<VisibilityState>(() => {\n const out: VisibilityState = {};\n for (const col of allAvailable) {\n out[col] = requiredSet.has(col) || visibleSet.has(col);\n }\n return out;\n }, [allAvailable, requiredSet, visibleSet]);\n\n const table = useReactTable<RowRecord>({\n data: COLUMNS_TOGGLE_EMPTY_DATA,\n columns: tableColumns,\n state: { columnVisibility: visibilityState },\n getCoreRowModel: getCoreRowModel(),\n onColumnVisibilityChange: (updater) => {\n const nextMap = typeof updater === 'function' ? updater(visibilityState) : updater;\n // Project the new visibility map back into the parent's\n // `string[]` shape, materialised in `allAvailable` order so the\n // table layout stays predictable across toggles. Required\n // columns are always included regardless of the map (the\n // primitive disables their checkbox; this is just defence in\n // depth in case TanStack ever emits a stale entry for them).\n const nextSet = new Set<string>();\n for (const col of allAvailable) {\n if (requiredSet.has(col) || nextMap[col] !== false) nextSet.add(col);\n }\n onChange(allAvailable.filter((c) => nextSet.has(c)));\n },\n });\n\n return (\n <DataTableViewOptions\n table={table}\n iconOnly\n triggerLabel={t('toolbar.columns')}\n triggerIcon={<IconColumns3 className=\"h-4 w-4\" aria-hidden=\"true\" />}\n triggerClassName=\"\"\n popoverAlign=\"end\"\n popoverContentClassName=\"w-64 p-2\"\n // Icon + title header — the trigger is icon-only, so the menu names itself\n // (consistent with the Saved-views popover).\n menuTitle={\n <span className=\"flex items-center gap-2\">\n <IconColumns3 className=\"h-4 w-4 text-muted-foreground\" aria-hidden=\"true\" />\n {t('toolbar.columns')}\n </span>\n }\n footerActions={[\n ...(onResetSizes\n ? [\n {\n label: t('toolbar.resetSizes'),\n onClick: onResetSizes,\n testid: `list-columns-reset-sizes:${resource}`,\n },\n ]\n : []),\n ...(onRestoreDefaults\n ? [\n {\n label: t('toolbar.restoreDefaults'),\n onClick: onRestoreDefaults,\n testid: `list-columns-restore-defaults:${resource}`,\n },\n ]\n : []),\n ]}\n getColumnLabel={(column) => {\n // A dotted column is labelled by the field it reads across its relations.\n const target = columnTarget(app.registry, resource, column.id);\n if (target !== undefined)\n return resolveFieldLabel(\n capsOf(columnsCaps, target.resource),\n target.name,\n declaredText('field', target.field, 'label'),\n );\n return resolveFieldLabel(\n columnsCaps,\n column.id,\n declaredText('field', def.fields?.[column.id], 'label'),\n );\n }}\n isColumnRequired={(column) => requiredSet.has(column.id)}\n getTestId={(role, columnId) => {\n switch (role) {\n case 'trigger':\n return `list-columns:${resource}`;\n case 'menu':\n return `list-columns-menu:${resource}`;\n case 'option':\n return `list-columns-option:${resource}:${columnId ?? ''}`;\n case 'checkbox':\n return `list-columns-checkbox:${resource}:${columnId ?? ''}`;\n default:\n return undefined;\n }\n }}\n />\n );\n}\n\n// Module-level constant so the `data` array reference stays stable\n// across renders — TanStack rebuilds row models when `data` identity\n// changes, and the visibility-only table never reads rows anyway.\nconst COLUMNS_TOGGLE_EMPTY_DATA: RowRecord[] = [];\n","'use client';\nimport type { ReactElement } from 'react';\nimport { useResourceListContext } from '@burojs/react';\nimport { ColumnsToggle } from '../columns-toggle.js';\nimport { listPiece } from './piece.js';\nimport { useListSurface, usePieceMount } from './pieces-context.js';\n\n/** The column picker; it renders nothing unless the list draws a table. */\nfunction ListColumnsView() {\n usePieceMount('columns');\n const { def, columns } = useResourceListContext();\n const { resource, tableView } = useListSurface();\n if (!def || !tableView) return null;\n return (\n <ColumnsToggle\n resource={resource}\n def={def}\n allAvailable={columns.all}\n required={columns.required}\n visibleColumns={columns.visible}\n defaultVisible={columns.defaultVisible}\n onChange={columns.setVisible}\n onResetSizes={() => columns.restoreDefaults('sizes')}\n // Sizes + pins + order (via the token) AND visibility + sort.\n onRestoreDefaults={() => columns.restoreDefaults()}\n />\n );\n}\n\nexport const ListColumns: () => ReactElement | null = listPiece('ListColumns', ListColumnsView);\n","'use client';\nimport { routeResourceKey } from '@burojs/core';\nimport type { ResourceNameOrRef } from '@burojs/core';\nimport { useAvailability, useEntryGate, useOptionalT } from '@burojs/react';\nimport { DisabledAction } from '../actions/action-button.js';\nimport { useLinkComponent } from '../layout/link-component.js';\nimport { Button, type ButtonProps } from '../primitives/button.js';\nimport { Icon } from '../primitives/icon.js';\n\nexport interface CreateButtonProps<N extends string = string> {\n /** Resource this creates. Required — the button gates itself. */\n resource: ResourceNameOrRef<N>;\n /** Target create route, e.g. `resourceCreateHref(def, resource)`. Ignored with `onOpen`. */\n href: string;\n /**\n * Opens the create somewhere other than a route — a resource without a create page opens its\n * `quick.create` (P3-19). The control is then a button, drawn when the entry gate answers\n * `open` (inert with its reason when `disabled`, absent otherwise, and while access loads).\n */\n onOpen?: () => void;\n /** `data-testid` for the button. */\n testid?: string;\n size?: ButtonProps['size'];\n variant?: ButtonProps['variant'];\n /** Override the label. Defaults to the localized `actions.create`. */\n label?: React.ReactNode;\n className?: string;\n}\n\n/**\n * The list-page \"create\" affordance.\n *\n * Lives in the library so its label resolves from the framework i18n bundle\n * (`actions.create`) rather than a hardcoded `+ Create` in each app's list\n * toolbar. Navigation goes through the installed `LinkComponent`, so SPA\n * routing is preserved. Falls back to English outside a `BuroProvider`.\n *\n * Gates itself against the availability gate (`useAvailability`): renders\n * nothing for `absent`/`hidden`, a focusable `aria-disabled` control with a\n * toast reason for `disabled`, and the normal link for `available`.\n */\nexport function CreateButton<const N extends string = string>({\n resource: resourceInput,\n href,\n testid,\n size = 'sm',\n variant,\n label,\n className,\n onOpen,\n}: CreateButtonProps<N>): React.ReactElement | null {\n const resource = routeResourceKey(resourceInput);\n const t = useOptionalT();\n const Link = useLinkComponent();\n const availability = useAvailability(resource, 'create');\n const gate = useEntryGate();\n const text = label ?? t('actions.create', { resource, defaultValue: 'Create' });\n\n if (onOpen !== undefined) {\n const answer = gate(resource, 'create');\n if (answer.state === 'disabled')\n return (\n <DisabledAction\n reason={availability.state === 'disabled' ? availability.reason : undefined}\n label={text}\n icon=\"Plus\"\n testid={testid}\n size={size}\n variant={variant}\n className={className}\n resource={resource}\n />\n );\n if (answer.state !== 'open') return null;\n return (\n <Button\n type=\"button\"\n size={size}\n variant={variant}\n data-testid={testid}\n className={className}\n onClick={onOpen}\n >\n <Icon name=\"Plus\" className=\"mr-1 h-4 w-4\" />\n {text}\n </Button>\n );\n }\n\n // `absent` and `hidden` render identically here — see the note on the\n // `Availability` type. Nothing about this button should depend on WHY.\n if (availability.state === 'absent' || availability.state === 'hidden') return null;\n\n if (availability.state === 'disabled') {\n /*\n `DisabledAction`, not a second implementation of it. It already owns the\n whole denied-affordance contract — reason → resolved via\n `resolveContentSlot` (bundle key or literal, never a `console.warn`) →\n the localized `availability.denied` fallback, `aria-disabled` instead of\n the native `disabled` attribute (a natively disabled element takes no\n focus and fires no events, so a keyboard or screen-reader user would get\n no explanation at all), the toast on click, and the `opacity-60` dimming.\n Forked here, this branch drifted: it had every behaviour EXCEPT the\n dimming, so the one denied affordance an adopter meets first was also the\n only one that looked fully live.\n */\n return (\n <DisabledAction\n reason={availability.reason}\n label={text}\n icon=\"Plus\"\n testid={testid}\n size={size}\n variant={variant}\n className={className}\n resource={resource}\n />\n );\n }\n\n return (\n /*\n ⚠️ `asChild`, so this is ONE <a> rather than a <button> nested inside one.\n Nested interactive content is invalid HTML, gives a keyboard user two tab\n stops for a single control, and makes a screen reader announce\n «Create» twice (`link \"Create\" › button \"Create\"`).\n */\n <Button asChild size={size} variant={variant} data-testid={testid} className={className}>\n <Link href={href}>\n <Icon name=\"Plus\" className=\"mr-1 h-4 w-4\" />\n {text}\n </Link>\n </Button>\n );\n}\n","'use client';\nimport type { ReactElement } from 'react';\nimport { useResourceListContext } from '@burojs/react';\nimport { CreateButton } from '../../resource/create-button.js';\nimport { listPiece } from './piece.js';\nimport { useListSurface, usePieceMount } from './pieces-context.js';\n\n/** The route list's primary action: create, as a page link or (without a create page) its quick form. */\nfunction ListCreateView() {\n usePieceMount('create');\n const { def, routing } = useResourceListContext();\n const { resource, route, openCreate } = useListSurface();\n if (!def || !route) return null;\n return (\n <CreateButton\n resource={resource}\n href={routing.createHref}\n testid={`list-create:${resource}`}\n {...(openCreate === undefined ? {} : { onOpen: openCreate })}\n />\n );\n}\n\nexport const ListCreate: () => ReactElement | null = listPiece('ListCreate', ListCreateView);\n","'use client';\nimport { routeResourceKey } from '@burojs/core';\nimport type { ResourceNameOrRef } from '@burojs/core';\nimport type { ExportTarget } from '@burojs/core';\nimport {\n useCapability,\n useOptionalDataRuntime,\n useOptionalT,\n useResourceExport,\n useResourceListContext,\n useTestIds,\n} from '@burojs/react';\nimport { IconDownload } from '@tabler/icons-react';\nimport * as React from 'react';\nimport { cn } from '../lib/cn.js';\nimport { Button } from '../primitives/button.js';\nimport { ExportDialog } from './export-dialog.js';\n\nexport interface ExportButtonProps<N extends string = string> {\n resource: ResourceNameOrRef<N>;\n className?: string;\n}\n\n/** One `providerQuery` warning per resource, not one per render — the same\n * dedup idiom `useResourceExport`'s own report sets use. */\nconst warnedProviderQueryResources = new Set<string>();\n\n/**\n * Toolbar entry point (Task 8) — mounted by `<ResourceListPage>` next to the\n * saved-views controls. Opens the self-hosted `<ExportDialog>` (Task 7 —\n * there is no `openExportDialog`; the caller drives `open` itself) with a\n * `filter`-kind target built from the LIVE list context, never from\n * `useResourceListContext` inside the dialog (Task 7's dialog is scope-blind\n * on purpose — see its own doc comment).\n *\n * Gated on TWO independent axes, both evaluated before any hook-order-unsafe\n * early return:\n * - `useResourceExport(resource).available` — whether an exporter resolves\n * at all (a resource `export: false` setting, or nothing configured).\n * Gated on `available`, never on truthiness of `exporter` — the key is\n * genuinely absent when unavailable (`useResourceExport`'s own contract).\n * - the capability engine, asked directly via `useCapability('run', {\n * target: { kind: 'action', name: 'export' } })` — the SAME axis\n * `resolveAvailability` resolves for every other action (capability\n * `'run'`, target `{ kind: 'action', name: <op> }`; see\n * `reference_capability_rule_shape` — the array-based deny trap). NOT\n * `useAvailability`/`useAvailabilityResolver`: those layer a static\n * \"is this a DECLARED operation\" existence check in front of the rule\n * engine (`resolveStaticAvailability`), and `'export'` is neither a\n * system operation nor a declared `actions.item/resource/bulk` entry —\n * every call would report `absent` (with a `console.error`) regardless\n * of any rule. `useResourceExport` already answers the existence\n * question; `useCapability` is asked ONLY about permission.\n */\nexport function ExportButton<const N extends string = string>({\n resource: resourceInput,\n className,\n}: ExportButtonProps<N>): React.ReactElement | null {\n const resource = routeResourceKey(resourceInput);\n // `useResourceExport` needs a native data runtime and throws without one\n // (`useDataRuntime`, not the optional variant — export genuinely cannot\n // function without one, the same stance `useAction` takes). Several\n // `<ResourceListPage>` tests mount it under \"compat mode\" (`<BuroProvider>`\n // with no `dataRuntime` prop — the established fixture for component-only\n // tests that never touch data),\n // where NOTHING in this package may call those hooks at all. Gating on\n // `useOptionalDataRuntime()` — which never throws — before rendering\n // {@link ExportButtonActive} keeps this component safe to mount\n // unconditionally in `<ResourceListPage>` regardless of which mode the\n // host is running in; `ExportButtonActive` then calls the hard hooks\n // unconditionally, because it only ever mounts once a runtime already\n // exists — no hook is ever conditionally called WITHIN one component.\n const hasDataRuntime = useOptionalDataRuntime() !== null;\n if (!hasDataRuntime) return null;\n return <ExportButtonActive resource={resource} className={className} />;\n}\n\nfunction ExportButtonActive({\n resource,\n className,\n}: {\n readonly resource: string;\n readonly className?: string;\n}): React.ReactElement | null {\n const list = useResourceListContext();\n // No `{ load: true }`: this trigger only needs to know whether an exporter is\n // REGISTERED, and asking for the instance here would fetch a deferred\n // exporter's chunk on every list page that shows the button. `prefetch` is\n // the deliberate exception — see `onMouseEnter`/`onFocus` below.\n const { available, prefetch } = useResourceExport(resource);\n const capability = useCapability('run', {\n resource,\n target: { kind: 'action', name: 'export' },\n // Matches the mode `useAvailabilityResolver` uses for list-surface\n // affordances (row actions, the create button) — a rule branching on\n // `ctx.mode` must see the same answer from every list-scoped gate.\n mode: 'list',\n });\n const tid = useTestIds();\n const t = useOptionalT();\n const [open, setOpen] = React.useState(false);\n\n const sent = list.query.sent;\n const target = React.useMemo<ExportTarget | null>(() => {\n // `null` while a selected option's read is pending, failed or unbound (T4 C17): the list\n // sends nothing, so there is nothing to export.\n if (sent === null) return null;\n // Exactly the query the list sent (T4 builder call C13): its composed filter (fixed filters,\n // option filters, pinned predicates, search, the builder group) and its sort as the provider\n // received it (`sort.by` applied, entries the provider cannot order by left out, the\n // tiebreaker appended). Recomposing it here from the filter state drifted twice: once it\n // carried the pinned slot alone, so a search, a builder group or a fixed filter was dropped\n // from the file (a scope leak on a `fixed`-narrowed list, and an `estimatedCount` describing\n // other rows); later it ordered by the column instead of its `sort.by`. The count\n // (`pagination.total`) describes these same rows.\n //\n // `providerQuery` (the level-2 raw provider blob, merged into the list's `meta`) is the ONE\n // input the production query has that this target cannot carry: `ExportTarget` has no\n // `meta`, and a raw provider blob is by definition uninterpretable to an exporter that\n // bypasses the provider. A `providerQuery`-narrowed list therefore exports WITHOUT that\n // narrowing. Rather than leave that silent, the effect below warns once — and the adopter\n // guide states it.\n const { filter, sort } = sent;\n return {\n kind: 'filter',\n ...(filter === undefined ? {} : { filter }),\n ...(sort.length > 0 ? { sort } : {}),\n };\n }, [sent]);\n // The last query the list sent: an open dialog keeps it while the list's options go unresolved,\n // rather than unmounting under the user (it can only have opened from a sent query).\n const lastTarget = React.useRef<ExportTarget | null>(target);\n if (target !== null) lastTarget.current = target;\n const dialogTarget = target ?? lastTarget.current;\n\n // Loud, deduped, and gated on the button actually being usable — an\n // export-less resource that uses `providerQuery` (the Temporal workflows\n // list, today's only consumer) must not warn about an export it can never\n // start. In an effect, not in the memo above, because the memo runs before\n // the gates are known.\n React.useEffect(() => {\n if (!available || !capability.allowed) return;\n if (list.providerQuery.value === undefined) return;\n if (warnedProviderQueryResources.has(resource)) return;\n warnedProviderQueryResources.add(resource);\n // One long template literal rather than a wrapped concatenation: biome's\n // `useTemplate` rejects the latter, and breaking it across source lines\n // inside the backticks would embed real newlines in the message.\n console.warn(\n `[buro] ExportButton('${resource}'): this list is narrowed by \\`providerQuery\\` (a raw provider blob), which an export target cannot carry — the exported file will NOT be narrowed by it. See docs/adopters/data-export.md.`,\n );\n }, [available, capability.allowed, list.providerQuery.value, resource]);\n\n // Both gates evaluated above, unconditionally, so hook order never\n // depends on either answer — only the RENDER branches on them.\n // A forbidden read lists nothing, so it exports nothing (the list, its count and its export\n // send the same predicates).\n if (!available || !capability.allowed || list.isForbidden) return null;\n // Nor is there anything to export while a selected option's read is unresolved (T4 C17,\n // `query.sent === null`): the button is not drawn, but a dialog already open stays mounted.\n if (target === null && !open) return null;\n // A dialog opens only from a sent query, so an open one always has a last target; never export\n // an unfiltered target in its place.\n if (dialogTarget === null) return null;\n\n return (\n <>\n {target === null ? null : (\n <Button\n type=\"button\"\n variant=\"outline\"\n // Icon-only, matching its immediate neighbour in the toolbar row — the\n // columns toggle renders through `<DataTableViewOptions iconOnly>`,\n // which is `size=\"icon\"` narrowed to `h-8 w-8` so it lines up with the\n // `sm` controls around it. The label survives as BOTH the accessible\n // name and the hover tooltip; dropping it from the DOM without\n // `aria-label` would leave the control announced only as \"button\".\n size=\"icon\"\n aria-label={t('export.button.label')}\n title={t('export.button.label')}\n className={cn('h-8 w-8', className)}\n data-testid={tid.exportButton(resource)}\n onClick={() => setOpen(true)}\n // Prefetch the exporter chunk on the first sign of intent, so a\n // deferred registration is usually already loaded by the time the\n // dialog OPENS (it renders a \"preparing\" state otherwise). Both\n // pointer AND keyboard paths, because focus is how a keyboard user\n // reaches this button. Fire-and-forget and idempotent — `prefetch()`\n // joins the one in-flight load and is a no-op once loaded, or when the\n // app registered a ready `Exporter` and there is nothing to fetch.\n // Unreachable for a resource with no export at all: this component\n // already returned `null` above in that case.\n onMouseEnter={prefetch}\n onFocus={prefetch}\n >\n <IconDownload className=\"size-4\" aria-hidden=\"true\" />\n </Button>\n )}\n {/* Mounted unconditionally — a closed dialog asks `useResourceExport` for\n nothing (it passes `{ load: open }`), so keeping it here costs no chunk\n fetch, and it is what lets a failed load be retried by simply\n reopening. */}\n <ExportDialog\n open={open}\n onOpenChange={setOpen}\n resource={resource}\n target={dialogTarget}\n visibleColumns={list.columns.visible}\n estimatedCount={list.pagination.total}\n scope={list.scope}\n />\n </>\n );\n}\n","'use client';\nimport type { ReactElement } from 'react';\nimport { useResourceListContext } from '@burojs/react';\nimport { ExportButton } from '../../export/export-button.js';\nimport { listPiece } from './piece.js';\nimport { useListSurface, usePieceMount } from './pieces-context.js';\n\n/**\n * The export trigger. It sits directly after the columns toggle: both are icon-only controls over\n * the SAME thing the page is showing, and the export dialog's default column scope is literally\n * the toggle's current selection.\n */\nfunction ListExportView() {\n usePieceMount('export');\n const { def } = useResourceListContext();\n const { resource, exportable } = useListSurface();\n if (!def || !exportable) return null;\n return <ExportButton resource={resource} />;\n}\n\nexport const ListExport: () => ReactElement | null = listPiece('ListExport', ListExportView);\n","'use client';\nimport { routeResourceKey } from '@burojs/core';\nimport type { ResourceNameOrRef } from '@burojs/core';\nimport { useEffect, useRef, useState } from 'react';\nimport { resolveContentSlot } from '@burojs/core';\nimport { useI18nCaps } from '@burojs/react';\nimport { Input } from '../primitives/input.js';\n\n/**\n * Debounced free-form search box. Keeps the typed text in LOCAL state so\n * keystrokes feel instant (only this component re-renders per key), and\n * commits to the URL-state setter (`onCommit`) after a short pause — so\n * a `router.replace` + `useList` refetch fires once per typing burst, not\n * once per character. Re-syncs from the external `value` when it changes\n * (deep-link / saved view / clear-all).\n */\nexport function ListSearchInput<const N extends string = string>({\n resource: resourceInput,\n value,\n onCommit,\n placeholder,\n}: {\n resource: ResourceNameOrRef<N>;\n value: string;\n onCommit: (next: string) => void;\n /**\n * Override the placeholder. The default is the kit's `list.search` (\"Search\"):\n * a plain word that promises nothing about HOW the query is matched and\n * names no field, because the framework cannot know what the search matches.\n */\n placeholder?: string;\n}) {\n const resource = routeResourceKey(resourceInput);\n const caps = useI18nCaps(resource);\n const [text, setText] = useState(value);\n const lastPushedRef = useRef(value);\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n // Adopt the external value ONLY when it changed from outside (clear-all,\n // saved view, deep link) — never when it's the echo of our own debounced\n // commit. Syncing on every external change would clobber characters the\n // user typed during the debounce window (they vanish, then reappear, and\n // the caret jumps).\n useEffect(() => {\n if (value !== lastPushedRef.current) {\n setText(value);\n lastPushedRef.current = value;\n }\n }, [value]);\n\n useEffect(\n () => () => {\n if (timerRef.current) clearTimeout(timerRef.current);\n },\n [],\n );\n\n return (\n <Input\n type=\"search\"\n placeholder={placeholder ?? resolveContentSlot(caps, ['list.search']) ?? 'Search'}\n value={text}\n data-testid={`list-search:${resource}`}\n // Fixed width once the row can hold search + funnel side-by-side (≥420px),\n // full-width only below that — where the RIGHT action group has already\n // wrapped to the line above, so the search fills the freed left line\n // instead of forcing the funnel onto its own row mid-band.\n className=\"h-8 w-full min-[420px]:w-72\"\n onChange={(e) => {\n const next = e.target.value;\n setText(next);\n if (timerRef.current) clearTimeout(timerRef.current);\n timerRef.current = setTimeout(() => {\n lastPushedRef.current = next;\n onCommit(next);\n }, 300);\n }}\n />\n );\n}\n","'use client';\nimport { type SearchDecl, resolveContentSlot } from '@burojs/core';\nimport { useChromeT, useI18nCaps, useResourceListContext } from '@burojs/react';\nimport { Button } from '../../primitives/button.js';\nimport { ListSearchInput } from '../list-search-input.js';\nimport { FilterBuilder } from './filter-builder.js';\n\n/**\n * The default `list.filters.<resource>` content — search box, option\n * pickers, pinned controls, the builder popover trigger, applied-filter badges and a\n * \"Clear filters\" action (shown while `filters.canReset`, which returns the list to its initial\n * state), left to right. Props-free: like every list slot, it\n * reads the live controller from `useResourceListContext()` rather than a\n * prop chain, which is the SAME contract a registered\n * `list.filters.<resource>` slot fulfils — an adopter that wants a\n * different layout composes `FilterBuilder` (or its own `FilterPanel` /\n * `FilterBadges` / `PinnedFilterControls` / `FilterValueControl`, all\n * exported) into its own region instead of forking this file.\n *\n * A THIN wrapper: everything that needs the list controller (the search\n * box, its placeholder, \"Clear filters\") stays here — that's the page's\n * concern, not the builder's — and everything else (the pinned controls,\n * the panel, the badges, and the `open`/`focusPath`/`externalRemoval`\n * wiring between them) is `<FilterBuilder>`'s job, which has no controller\n * dependency at all and so can also be mounted where there isn't one (the\n * relation picker's advanced-search dialog, SP3).\n *\n * `<ResourceListPage>` owns mounting: it renders `<FilterRegion>` only when\n * no `list.filters.<resource>` slot is registered, so this component itself\n * never has to know about the override ladder.\n */\nexport function FilterRegion({\n search,\n}: {\n /**\n * The search a placement declares (`related-list`'s `search` prop), `null` for none; the route\n * list omits it and reads the resource's `views.list.search`.\n */\n readonly search?: SearchDecl | null;\n} = {}): React.ReactElement {\n const { resource, def, filters, pagination } = useResourceListContext();\n const chromeT = useChromeT();\n\n const testIdBase = `list-filter:${resource}`;\n\n // The search BOX needs to know whether search is declared at all — declared per resource at\n // `views.list.search`. The controller reads the same declaration to compose the actual filter.\n // Its placeholder names no field. The resource's own page (no `search` prop) reads its\n // `list.searchPlaceholder`, else the kit's `list.search`; a placement (which passes `search`)\n // shows the plain `list.search` only: the slot belongs to the resource list page.\n const caps = useI18nCaps(resource);\n const placeholder =\n search === undefined\n ? (resolveContentSlot(caps, ['list.searchPlaceholder', 'list.search']) ?? 'Search')\n : undefined;\n const searchDecl = search === undefined ? def?.views?.list?.search : (search ?? undefined);\n\n return (\n <div className=\"flex flex-wrap items-center gap-2\">\n {searchDecl !== undefined && filters.searchEnabled && (\n <ListSearchInput\n resource={resource}\n {...(placeholder === undefined ? {} : { placeholder })}\n value={filters.search}\n onCommit={(v) => {\n // ⚠️ `filters.setSearch` is a pure pass-through — the page reset\n // has always lived at this call site, and without it a search\n // typed on page 3 keeps the user on page 3 while showing page-1\n // results.\n pagination.setPage(1);\n filters.setSearch(v);\n }}\n />\n )}\n <FilterBuilder\n group={filters.group}\n setGroup={filters.setGroup}\n available={filters.available}\n fixed={filters.fixed}\n presets={filters.presets}\n setPreset={filters.setPreset}\n pinnedFields={filters.pinnedFields}\n pinnedValue={filters.value}\n setPinnedValue={filters.set}\n setPage={pagination.setPage}\n testIdBase={testIdBase}\n />\n {filters.canReset && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n data-testid={`${testIdBase}:clear-all`}\n onClick={filters.reset}\n >\n {chromeT('filters.clearAll')}\n </Button>\n )}\n </div>\n );\n}\n","'use client';\nimport type { ReactElement } from 'react';\nimport { useResourceListContext } from '@burojs/react';\nimport { FilterRegion } from '../filter-builder/filter-region.js';\nimport { listPiece } from './piece.js';\nimport { useListSurface, usePieceMount } from './pieces-context.js';\n\n/**\n * The search box and the filter builder. `list.filters.<r>` replaces its CONTENTS, never the\n * group itself: the wrapper's `min-w-[21rem] flex-1` is the whole reason the right-hand group (and\n * not the search box) is what wraps on overflow, so the two-group geometry stays framework-owned\n * and a slot cannot break it. The test id switches with the content rather than lying:\n * `list-filters:*` names the standard region, `list-filters-slot:*` names an override.\n */\nfunction ListFiltersView() {\n usePieceMount('filters');\n const { def } = useResourceListContext();\n const { resource, route, searchDecl, FiltersSlot } = useListSurface();\n if (!def) return null;\n return (\n <div\n className=\"min-w-[21rem] flex-1\"\n data-testid={FiltersSlot ? `list-filters-slot:${resource}` : `list-filters:${resource}`}\n >\n {FiltersSlot ? (\n <FiltersSlot />\n ) : (\n <FilterRegion {...(route ? {} : { search: searchDecl ?? null })} />\n )}\n </div>\n );\n}\n\nexport const ListFilters: () => ReactElement | null = listPiece('ListFilters', ListFiltersView);\n","'use client';\nimport type { ReactElement } from 'react';\nimport { resolveActionDensity, resolveActionSurfaceMode } from '@burojs/core';\nimport {\n resourceFlowsOn,\n useFlowRowResolver,\n useOptionalT,\n useResourceListContext,\n useTestIds,\n} from '@burojs/react';\nimport { IconDots } from '@tabler/icons-react';\nimport { Fragment, useState } from 'react';\nimport { FlowActionButton, FlowMenuItem } from '../../flows/flow-action-button.js';\nimport { RuntimeFlowRunner, preloadFlowRuntime } from '../../flows/load-runtime.js';\nimport { Button } from '../../primitives/button.js';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuTrigger,\n} from '../../primitives/dropdown-menu.js';\nimport { listPiece } from './piece.js';\nimport { useListSurface, usePieceMount } from './pieces-context.js';\n\n/**\n * The resource-level flows (`toolbar.resource`) of the route list: one control per flow by its\n * `surfaces.list` — a labelled button (`regular`, and `auto`), an icon button (`compact`) or an\n * entry of one \"More actions\" menu (`menu`, the default) — and nothing for `false`. Each control\n * is decided by the flow's gate without a run and without a record: denied is absent, disabled is\n * inert with its reason, and a gate still deciding draws nothing, so no control (and no request)\n * appears before access is known. A `related-list` placement draws none of it.\n */\nfunction ListFlowsView() {\n usePieceMount('flows');\n const t = useOptionalT();\n const tid = useTestIds();\n const { def } = useResourceListContext();\n const { resource, route } = useListSurface();\n const resolve = useFlowRowResolver(resource);\n // A flow chosen from the menu runs here, outside the menu: the menu closes normally and the\n // run (its host, its confirm, its outcome) outlives it.\n const [flowFor, setFlowFor] = useState<string | null>(null);\n if (!def || !route) return null;\n const entries = resourceFlowsOn(def, 'list').flatMap((flow) => {\n const control = resolve(flow.name, undefined);\n if (control.state === 'absent' || control.state === 'undecided') return [];\n const mode = resolveActionSurfaceMode(flow.surfaces, 'list');\n return [{ flow, control, density: resolveActionDensity(mode, 'list') }];\n });\n const standalone = entries.filter((entry) => entry.density !== null);\n const menu = entries.filter((entry) => entry.density === null);\n if (entries.length === 0) return null;\n return (\n <>\n {standalone.map(({ flow, density }) => (\n <FlowActionButton\n key={flow.name}\n resource={resource}\n actionName={flow.name}\n scope=\"list\"\n // `density` is only null for the menu entries filtered out above.\n density={density ?? 'regular'}\n />\n ))}\n {menu.length > 0 && (\n <DropdownMenu\n modal={false}\n onOpenChange={(open) => {\n if (open) preloadFlowRuntime();\n }}\n >\n <DropdownMenuTrigger asChild>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"gap-1.5\"\n data-testid={tid.listFlowsMenu(resource)}\n aria-label={t('list.flowsMenu', { defaultValue: 'More actions' })}\n >\n <IconDots className=\"h-4 w-4\" aria-hidden=\"true\" />\n {t('list.flowsMenu', { defaultValue: 'More actions' })}\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {menu.map(({ flow, control }) => (\n <Fragment key={flow.name}>\n <FlowMenuItem\n resource={resource}\n actionName={flow.name}\n scope=\"list\"\n control={control}\n active={flowFor !== null}\n onRun={() => setFlowFor(flow.name)}\n />\n </Fragment>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n {flowFor !== null ? (\n <RuntimeFlowRunner\n resource={resource}\n actionName={flowFor}\n scope=\"list\"\n onClose={() => setFlowFor(null)}\n />\n ) : null}\n </>\n );\n}\n\nexport const ListFlows: () => ReactElement | null = listPiece('ListFlows', ListFlowsView);\n","'use client';\nimport type { ReactElement } from 'react';\nimport { useResourceListContext, useT } from '@burojs/react';\nimport { IconRefresh } from '@tabler/icons-react';\nimport { Button } from '../../primitives/button.js';\nimport { listPiece } from './piece.js';\nimport { useListSurface, usePieceMount } from './pieces-context.js';\n\n/**\n * The live-list pause toggle (`views.list.refetchInterval`). `live` is undefined for any resource\n * that declares no interval, and its absence is exactly what hides this control — a static list's\n * toolbar is unchanged. `aria-pressed` announces the state to assistive tech; the icon spins only\n * while polling is actually running.\n */\nfunction ListLiveView() {\n usePieceMount('live');\n const t = useT();\n const { def, live } = useResourceListContext();\n const { resource } = useListSurface();\n if (!def || !live) return null;\n return (\n <Button\n type=\"button\"\n variant={live.isPaused ? 'outline' : 'default'}\n size=\"sm\"\n aria-pressed={!live.isPaused}\n data-testid={`list-live:${resource}`}\n onClick={() => (live.isPaused ? live.resume() : live.pause())}\n >\n <IconRefresh className={live.isPaused ? undefined : 'animate-spin'} aria-hidden=\"true\" />\n {live.isPaused ? t('toolbar.liveOff') : t('toolbar.liveOn')}\n </Button>\n );\n}\n\nexport const ListLive: () => ReactElement | null = listPiece('ListLive', ListLiveView);\n","'use client';\nimport { useMemo, useState } from 'react';\nimport { IconBookmark, IconCopy, IconPencil, IconTrash } from '@tabler/icons-react';\nimport {\n declaredText,\n humanizeKey,\n resolveContentSlot,\n savedViewKey,\n type I18nCaps,\n type SavedViewDef,\n type UiSettingScope,\n type UiSettingsIssue,\n routeResourceKey,\n type ResourceNameOrRef,\n} from '@burojs/core';\nimport {\n LOCAL_USER_SCOPE_ID,\n useI18nCaps,\n useChromeT,\n useOptionalT,\n type SavedViewEntry,\n} from '@burojs/react';\nimport { Button } from '../primitives/button.js';\nimport { Popover, PopoverContent, PopoverTrigger } from '../primitives/popover.js';\nimport { cn } from '../lib/cn.js';\n\n/**\n * Saved-views dropdown for the list-page filter row.\n *\n * Renders as a popover (matching the existing `<DataTableViewOptions>`\n * pattern — `<Dropdown menu>` is not part of this package's primitive\n * surface, and the popover with role=\"menu\" carries the same UX +\n * keyboard semantics for our purposes).\n *\n * Sections (top to bottom), Task 9 — SCOPE-GROUPED, not hardcoded:\n * 1. An adapter-reported issues notice, when `issues` is non-empty —\n * rendered WITHOUT hiding any otherwise-valid group below it.\n * 2. Adopter-defined views (`adopterViews`, no scope, always read-only —\n * header rendered only when at least one OTHER section also exists,\n * otherwise the single section speaks for itself).\n * 3. One group per DISTINCT `entry.scope.id` found in `entries`, in the\n * order each scope first appears — header is the scope's OWN\n * `label`, verbatim, EXCEPT the framework's own local-user scope\n * (`LOCAL_USER_SCOPE_ID`), whose data-layer placeholder label is\n * swapped for a reactive i18n one (`toolbar.viewsMyScope`). Every\n * other (adopter-supplied) scope label is NEVER rewritten.\n * 4. \"Save current view…\" — hidden entirely when `canSaveCurrent` is\n * `false` (no writable scope, spec §5: \"empty `writeScopes` means the\n * current user cannot create … a value\").\n * 5. \"Manage views…\" — rendered only when at least one entry exists.\n *\n * Each entry row (never an adopter row — those carry no per-entry\n * permissions) offers inline Rename / Fork / Delete affordances, gated on\n * `entry.permissions.update` / `.fork` / `.remove` respectively — hidden,\n * not merely disabled, when the permission is absent (they are UI hints;\n * the adapter re-authorizes every mutation regardless, spec §4). Fork is\n * ADDITIONALLY gated on `canFork` (`writeScopes.length > 0`, spec §5):\n * forking always needs somewhere writable to land, so a fork-permitted\n * entry never renders a clickable-but-inert Fork button when there is no\n * write scope at all — the same \"hide, don't just disable\" rule\n * `canSaveCurrent` already applies to \"Save current view…\". An entry with\n * none of the (effectively available) three actions is additionally\n * marked read-only.\n *\n * The component is purely presentational — it owns no view state. The\n * caller (page integration) wires `onApply` to the URL-state replace\n * codepath, `onSaveCurrent`/`onRenameEntry`/`onForkEntry` to their own\n * dialogs, and `onDeleteEntry`/`onManage` to the delete flow / manage\n * dialog.\n */\nexport interface SavedViewsDropdownProps<N extends string = string> {\n /**\n * The resource the views belong to. Declared views (`adopterViews`) read their label from\n * `resources.<resource>.savedViews.<id>` in the bundle (that resource's own entry only, never\n * `resources._` or `common`); without it they render as declared.\n * User-saved `entries` are user data and always render as written.\n */\n resource?: ResourceNameOrRef<N>;\n /** Adopter-defined views from `def.views.list.savedViews`. Always read-only. */\n adopterViews: SavedViewDef[];\n /** Adapter-backed entries, WITH scope/permission metadata (Task 9). */\n entries: SavedViewEntry[];\n /** Adapter-reported issues for this collection (spec §13) — rendered, never hiding valid entries. */\n issues?: readonly UiSettingsIssue[];\n /** Click on a view item — apply its state. */\n onApply: (view: SavedViewDef) => void;\n /** Click on \"Save current view…\". Caller shows a label-prompt dialog. */\n onSaveCurrent: () => void;\n /** Whether saving is possible at all (`writeScopes.length > 0`, spec §5). Default `true`. */\n canSaveCurrent?: boolean;\n /** Click on \"Manage views…\". Caller shows a list dialog with delete/rename. */\n onManage: () => void;\n /** Click on an entry's Rename action. Shown only when `entry.permissions.update`. */\n onRenameEntry?: (entry: SavedViewEntry) => void;\n /** Click on an entry's Delete action. Shown only when `entry.permissions.remove`. */\n onDeleteEntry?: (entry: SavedViewEntry) => void;\n /** Click on an entry's Fork action. Shown only when `entry.permissions.fork` AND `canFork`. */\n onForkEntry?: (entry: SavedViewEntry) => void;\n /**\n * Whether forking is possible AT ALL (`writeScopes.length > 0`, spec §5) —\n * combined with each entry's own `permissions.fork`. Default `true`.\n * Mirrors `canSaveCurrent`: a fork-permitted entry with nowhere writable to\n * land must not render a clickable-but-inert Fork affordance (fork always\n * needs a writable scope regardless of the per-entry flag, spec §5's\n * \"copy into a writable scope\").\n */\n canFork?: boolean;\n /**\n * Optional testid generator. Roles:\n * 'trigger' → the popover trigger button\n * 'menu' → the popover content container\n * 'view-item' → a view row (viewId passed as second arg)\n * 'save-current' → the \"Save current view…\" action row\n * 'manage' → the \"Manage views…\" action row\n * 'separator' → between sections (no viewId)\n * 'section-header' → a group header (viewId is the section name: \"adopter\" or a scope id)\n * 'rename-entry' → an entry's inline Rename button (viewId passed)\n * 'delete-entry' → an entry's inline Delete button (viewId passed)\n * 'fork-entry' → an entry's inline Fork button (viewId passed)\n * 'issues-notice' → the adapter-issues banner (no viewId)\n */\n getTestId?: (\n role:\n | 'trigger'\n | 'menu'\n | 'view-item'\n | 'save-current'\n | 'manage'\n | 'separator'\n | 'section-header'\n | 'rename-entry'\n | 'delete-entry'\n | 'fork-entry'\n | 'issues-notice',\n viewId?: string,\n ) => string | undefined;\n /** Trigger label override. Default: \"Views\". */\n triggerLabel?: string;\n /**\n * Render the trigger as a compact icon-only square button (no visible label).\n * `triggerLabel` becomes the `aria-label` + tooltip. The bookmark icon (the\n * saved-views affordance) stays.\n */\n iconOnly?: boolean;\n /** className applied to the trigger button. */\n triggerClassName?: string;\n /** className applied to the popover content. */\n popoverContentClassName?: string;\n /** Popover content alignment. Default: 'start'. */\n popoverAlign?: 'start' | 'center' | 'end';\n}\n\nfunction ViewItem({\n view,\n caps,\n resource,\n onClick,\n testid,\n}: {\n view: SavedViewDef;\n caps: I18nCaps;\n resource?: string;\n onClick: () => void;\n testid?: string;\n}) {\n // The resource's own entry only, probed absolute: a relative `savedViews.<id>` would walk\n // `resources._` and `common` and let a shared entry replace this resource's declared label.\n const own = resource === undefined ? undefined : `resources.${resource}.${savedViewKey(view.id)}`;\n const declared = declaredText('saved-view', view, 'label');\n const label =\n own === undefined\n ? (declared ?? humanizeKey(view.id))\n : (resolveContentSlot(caps, [[`${own}.label`, own]], {\n default: declared,\n humanize: () => humanizeKey(view.id),\n }) as string);\n return (\n <button\n type=\"button\"\n onClick={onClick}\n data-testid={testid}\n className=\"w-full text-left rounded-sm px-2 py-1.5 text-sm hover:bg-accent hover:text-accent-foreground focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring\"\n >\n {label}\n </button>\n );\n}\n\n/** One adapter-backed entry row: click-to-apply plus permission-gated inline actions (Task 9). */\nfunction EntryRow({\n entry,\n onApply,\n onRename,\n onFork,\n onDelete,\n forkAvailable,\n applyTestId,\n renameTestId,\n forkTestId,\n deleteTestId,\n tr,\n}: {\n entry: SavedViewEntry;\n onApply: () => void;\n onRename?: () => void;\n onFork?: () => void;\n onDelete?: () => void;\n /** Whether ANY write scope exists at all — see `SavedViewsDropdownProps.canFork`. */\n forkAvailable: boolean;\n applyTestId?: string;\n renameTestId?: string;\n forkTestId?: string;\n deleteTestId?: string;\n tr: (key: string, fallback: string) => string;\n}) {\n const chromeT = useChromeT();\n const canRename = entry.permissions.update && onRename !== undefined;\n const canFork = forkAvailable && entry.permissions.fork && onFork !== undefined;\n const canDelete = entry.permissions.remove && onDelete !== undefined;\n // Effective, not raw: an entry whose only permission is `fork` but has\n // nowhere writable to land (`forkAvailable` false) offers NO action in\n // this UI, so it reads as read-only too — matching what the user can\n // actually see/click, not the adapter's raw permission bits.\n const readOnly = !canRename && !canFork && !canDelete;\n return (\n <div className=\"flex items-center gap-0.5 rounded-sm hover:bg-accent hover:text-accent-foreground\">\n <button\n type=\"button\"\n onClick={onApply}\n data-testid={applyTestId}\n className=\"min-w-0 flex-1 truncate rounded-sm px-2 py-1.5 text-left text-sm focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring\"\n >\n {entry.label}\n </button>\n {readOnly && (\n <span className=\"shrink-0 pr-1 text-[10px] uppercase tracking-wide text-muted-foreground\">\n {tr('toolbar.viewsReadOnly', 'Read-only')}\n </span>\n )}\n {canRename && (\n <button\n type=\"button\"\n onClick={onRename}\n aria-label={tr('toolbar.viewsRename', 'Rename')}\n title={tr('toolbar.viewsRename', 'Rename')}\n data-testid={renameTestId}\n className=\"shrink-0 rounded-sm p-1 text-muted-foreground hover:bg-accent hover:text-accent-foreground focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring\"\n >\n <IconPencil className=\"h-3.5 w-3.5\" aria-hidden=\"true\" />\n </button>\n )}\n {canFork && (\n <button\n type=\"button\"\n onClick={onFork}\n aria-label={tr('toolbar.viewsFork', 'Fork')}\n title={tr('toolbar.viewsFork', 'Fork')}\n data-testid={forkTestId}\n className=\"shrink-0 rounded-sm p-1 text-muted-foreground hover:bg-accent hover:text-accent-foreground focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring\"\n >\n <IconCopy className=\"h-3.5 w-3.5\" aria-hidden=\"true\" />\n </button>\n )}\n {canDelete && (\n <button\n type=\"button\"\n onClick={onDelete}\n aria-label={chromeT('actions.delete', { defaultValue: 'Delete' })}\n title={chromeT('actions.delete', { defaultValue: 'Delete' })}\n data-testid={deleteTestId}\n className=\"shrink-0 rounded-sm p-1 text-muted-foreground hover:bg-accent hover:text-accent-foreground focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring\"\n >\n <IconTrash className=\"h-3.5 w-3.5\" aria-hidden=\"true\" />\n </button>\n )}\n </div>\n );\n}\n\nfunction SectionHeader({ label, testid }: { label: string; testid?: string }) {\n return (\n <div\n data-testid={testid}\n className=\"px-2 py-1 text-xs font-semibold uppercase tracking-wide text-muted-foreground\"\n >\n {label}\n </div>\n );\n}\n\nfunction Separator({ testid }: { testid?: string }) {\n return <hr data-testid={testid} className=\"my-1 -mx-1 border-t\" />;\n}\n\ninterface ScopeGroup {\n scope: UiSettingScope;\n items: SavedViewEntry[];\n}\n\n/** Groups entries by `scope.id`, preserving the order each scope FIRST appears in `entries`. */\nfunction groupByScope(entries: SavedViewEntry[]): ScopeGroup[] {\n const order: string[] = [];\n const byId = new Map<string, ScopeGroup>();\n for (const entry of entries) {\n const existing = byId.get(entry.scope.id);\n if (existing) {\n existing.items.push(entry);\n } else {\n byId.set(entry.scope.id, { scope: entry.scope, items: [entry] });\n order.push(entry.scope.id);\n }\n }\n return order.map((id) => byId.get(id) as ScopeGroup);\n}\n\nexport function SavedViewsDropdown<const N extends string = string>({\n resource: resourceInput,\n adopterViews,\n entries,\n issues = [],\n onApply,\n onSaveCurrent,\n canSaveCurrent = true,\n onManage,\n onRenameEntry,\n onDeleteEntry,\n onForkEntry,\n canFork = true,\n getTestId,\n triggerLabel = 'Views',\n iconOnly = false,\n triggerClassName = 'h-9',\n popoverContentClassName = 'w-64 p-1',\n popoverAlign = 'start',\n}: SavedViewsDropdownProps<N>): React.ReactElement {\n const resource = resourceInput === undefined ? undefined : routeResourceKey(resourceInput);\n const t = useOptionalT();\n const caps = useI18nCaps(resource);\n const tr = (key: string, fallback: string) => t?.(key, { defaultValue: fallback }) ?? fallback;\n const [open, setOpen] = useState(false);\n const hasAdopter = adopterViews.length > 0;\n const hasEntries = entries.length > 0;\n const groups = useMemo(() => groupByScope(entries), [entries]);\n // A header only earns its keep when there is more than one section on\n // screen — a lone section is unambiguous without one (unchanged rule\n // from the pre-Task-9 \"Defaults\"/\"Yours\" behaviour, generalized from two\n // hardcoded sections to N scope groups).\n const showHeaders = (hasAdopter ? 1 : 0) + groups.length > 1;\n\n const scopeLabel = (scope: UiSettingScope): string =>\n scope.id === LOCAL_USER_SCOPE_ID ? tr('toolbar.viewsMyScope', 'Just me') : scope.label;\n\n // Wraps an item-click handler so the popover closes after the action.\n // Saved-view click is a single-shot navigation; leaving the popover\n // open would stack a stale state on top of the new URL.\n const closeAfter = (fn: () => void) => () => {\n fn();\n setOpen(false);\n };\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button\n type=\"button\"\n variant=\"outline\"\n size={iconOnly ? 'icon' : 'sm'}\n aria-label={iconOnly ? triggerLabel : undefined}\n title={iconOnly ? triggerLabel : undefined}\n data-testid={getTestId?.('trigger')}\n className={cn(iconOnly && 'h-8 w-8', triggerClassName)}\n >\n <IconBookmark className={cn('h-4 w-4', !iconOnly && 'mr-2')} aria-hidden=\"true\" />\n {!iconOnly && triggerLabel}\n </Button>\n </PopoverTrigger>\n <PopoverContent\n align={popoverAlign}\n className={popoverContentClassName}\n data-testid={getTestId?.('menu')}\n >\n {/* Title header — the trigger is icon-only, so the menu names itself. */}\n <div className=\"flex items-center gap-2 border-b px-2 pb-2 pt-1 text-sm font-semibold\">\n <IconBookmark className=\"h-4 w-4 text-muted-foreground\" aria-hidden=\"true\" />\n {triggerLabel}\n </div>\n {issues.length > 0 && (\n <div\n data-testid={getTestId?.('issues-notice')}\n className=\"mx-1 mt-1 rounded-sm bg-warning/15 px-2 py-1 text-xs text-warning-emphasis\"\n >\n {tr('toolbar.viewsIssuesNotice', 'Some views could not be loaded.')}\n </div>\n )}\n {hasAdopter && (\n <>\n {showHeaders && (\n <SectionHeader\n label={tr('toolbar.viewsDefaults', 'Defaults')}\n testid={getTestId?.('section-header', 'adopter')}\n />\n )}\n <div className=\"max-h-[200px] overflow-auto\">\n {adopterViews.map((v) => (\n <ViewItem\n key={v.id}\n view={v}\n caps={caps}\n resource={resource}\n testid={getTestId?.('view-item', v.id)}\n onClick={closeAfter(() => onApply(v))}\n />\n ))}\n </div>\n </>\n )}\n {hasAdopter && groups.length > 0 && <Separator testid={getTestId?.('separator')} />}\n {groups.map((group, index) => (\n <div key={group.scope.id}>\n {index > 0 && <Separator testid={getTestId?.('separator')} />}\n {showHeaders && (\n <SectionHeader\n label={scopeLabel(group.scope)}\n testid={getTestId?.('section-header', group.scope.id)}\n />\n )}\n <div className=\"max-h-[200px] overflow-auto\">\n {group.items.map((entry) => (\n <EntryRow\n key={entry.id}\n entry={entry}\n tr={tr}\n onApply={closeAfter(() => onApply(entry))}\n onRename={onRenameEntry ? closeAfter(() => onRenameEntry(entry)) : undefined}\n onFork={onForkEntry ? closeAfter(() => onForkEntry(entry)) : undefined}\n onDelete={onDeleteEntry ? closeAfter(() => onDeleteEntry(entry)) : undefined}\n forkAvailable={canFork}\n applyTestId={getTestId?.('view-item', entry.id)}\n renameTestId={getTestId?.('rename-entry', entry.id)}\n forkTestId={getTestId?.('fork-entry', entry.id)}\n deleteTestId={getTestId?.('delete-entry', entry.id)}\n />\n ))}\n </div>\n </div>\n ))}\n {(hasAdopter || hasEntries) && <Separator testid={getTestId?.('separator')} />}\n {canSaveCurrent && (\n <button\n type=\"button\"\n onClick={closeAfter(onSaveCurrent)}\n data-testid={getTestId?.('save-current')}\n className=\"w-full text-left rounded-sm px-2 py-1.5 text-sm hover:bg-accent hover:text-accent-foreground focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring\"\n >\n {tr('toolbar.viewsSaveCurrent', 'Save current view…')}\n </button>\n )}\n {hasEntries && (\n <button\n type=\"button\"\n onClick={closeAfter(onManage)}\n data-testid={getTestId?.('manage')}\n className=\"w-full text-left rounded-sm px-2 py-1.5 text-sm hover:bg-accent hover:text-accent-foreground focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring\"\n >\n {tr('toolbar.viewsManage', 'Manage views…')}\n </button>\n )}\n </PopoverContent>\n </Popover>\n );\n}\n","'use client';\nimport type { ReactElement } from 'react';\nimport { useResourceListContext, useT } from '@burojs/react';\nimport { SavedViewsDropdown } from '../../saved-views/saved-views-dropdown.js';\nimport { listPiece } from './piece.js';\nimport { useListSurface, usePieceMount } from './pieces-context.js';\n\n/** The saved-views menu of the route list; a `related-list` placement has none. */\nfunction ListSavedViewsView() {\n usePieceMount('saved-views');\n const t = useT();\n const { def, savedViews } = useResourceListContext();\n const { resource, route, savedViewsUi } = useListSurface();\n if (!def || !route) return null;\n return (\n <SavedViewsDropdown\n resource={resource}\n adopterViews={savedViews.adopter}\n entries={savedViews.entries}\n issues={savedViews.issues}\n onApply={savedViews.apply}\n onSaveCurrent={savedViewsUi.onSaveCurrent}\n canSaveCurrent={savedViewsUi.canSaveCurrent}\n onManage={savedViewsUi.onManage}\n onRenameEntry={savedViewsUi.onRenameEntry}\n onForkEntry={savedViewsUi.onForkEntry}\n canFork={savedViewsUi.canFork}\n onDeleteEntry={savedViewsUi.onDeleteEntry}\n iconOnly\n popoverAlign=\"end\"\n triggerLabel={t('toolbar.views')}\n triggerClassName=\"\"\n getTestId={(role, viewId) => {\n switch (role) {\n case 'trigger':\n return `list-saved-views:${resource}`;\n case 'menu':\n return `list-saved-views-menu:${resource}`;\n case 'view-item':\n return `list-saved-view:${resource}:${viewId ?? ''}`;\n case 'save-current':\n return `list-saved-view-save:${resource}`;\n case 'manage':\n return `list-saved-view-manage:${resource}`;\n case 'section-header':\n return `list-saved-view-section:${resource}:${viewId ?? ''}`;\n case 'rename-entry':\n return `list-saved-view-rename:${resource}:${viewId ?? ''}`;\n case 'fork-entry':\n return `list-saved-view-fork:${resource}:${viewId ?? ''}`;\n case 'delete-entry':\n return `list-saved-view-delete:${resource}:${viewId ?? ''}`;\n case 'issues-notice':\n return `list-saved-view-issues:${resource}`;\n default:\n return undefined;\n }\n }}\n />\n );\n}\n\nexport const ListSavedViews: () => ReactElement | null = listPiece(\n 'ListSavedViews',\n ListSavedViewsView,\n);\n","'use client';\nimport { useFramePiece, useResourceListContext } from '@burojs/react';\nimport type { ReactElement } from 'react';\nimport { ListColumns } from './list-columns.js';\nimport { ListCreate } from './list-create.js';\nimport { ListExport } from './list-export.js';\nimport { ListFilters } from './list-filters.js';\nimport { ListFlows } from './list-flows.js';\nimport { ListLive } from './list-live.js';\nimport { ListSavedViews } from './list-saved-views.js';\n\n/**\n * The toolbar: the filter region on the left, a group of controls pinned right. Two flex groups in\n * one row that wraps ONLY when it cannot fit — on overflow `flex-wrap-reverse` drops the right\n * group onto a line above the filters, each half keeping its own alignment. The left group's\n * min-width is what forces the right group (not the search) to be the thing that wraps.\n */\nfunction ListControlsView() {\n const { def } = useResourceListContext();\n if (!def) return null;\n return (\n <div className=\"flex flex-wrap-reverse items-end justify-end gap-2\">\n <ListFilters />\n <div className=\"flex shrink-0 items-center gap-2\">\n <ListFlows />\n <ListLive />\n <ListSavedViews />\n <ListColumns />\n <ListExport />\n <ListCreate />\n </div>\n </div>\n );\n}\n\n/**\n * The toolbar as a frame places it (`<ListControls/>`): under `checkFrame` it draws the pieces it\n * is made of, so a frame that also places one of them is counted twice.\n */\nexport function ListControls(): ReactElement | null {\n const check = useFramePiece('ListControls');\n if (check?.stub === true)\n return (\n <>\n <span data-check-piece=\"ListControls\" />\n <ListFilters />\n <ListFlows />\n <ListLive />\n <ListSavedViews />\n <ListColumns />\n <ListExport />\n <ListCreate />\n </>\n );\n return <ListControlsView />;\n}\n","'use client';\nimport type { ListFrameViewProps } from '@burojs/react';\nimport type { ReactElement } from 'react';\nimport { ListBody, ListControls } from '../list-kit/pieces/index.js';\n\n/**\n * `buro:list`: the `header` slot above the toolbar and the rows. The page header, the export\n * watcher, the saved-view dialogs and the bulk bar belong to the surface, not to the frame, so a\n * frame that arranges the pieces differently cannot lose them (P7-34).\n */\nexport function BuroListFrame({ slots }: ListFrameViewProps): ReactElement {\n return (\n <>\n {slots.header ?? null}\n <ListControls />\n <ListBody />\n </>\n );\n}\n","'use client';\nimport type { PageFrameViewProps } from '@burojs/react';\nimport type { ReactElement } from 'react';\n\n/**\n * `buro:page`: the `body` slot, nothing more. The page's `<h1>` and its access gate belong to the\n * page host, and `NavChrome` to the layout around the page, so a frame that arranges the slots\n * differently cannot lose them.\n */\nexport function BuroPageFrame({ slots }: PageFrameViewProps): ReactElement {\n return <>{slots.body}</>;\n}\n","'use client';\nimport type { PeekFrameViewProps } from '@burojs/react';\nimport type { ReactElement } from 'react';\n\n/** `buro:peek`: the `body` slot as it is. */\nexport function BuroPeekFrame({ slots }: PeekFrameViewProps): ReactElement {\n return <>{slots.body ?? null}</>;\n}\n","'use client';\nimport type { Applied, ValidationIssues } from '@burojs/core';\nimport { createContext, type ReactNode, type RefObject, useContext } from 'react';\n\n/** What the built-in frame pieces read besides the public record frame: `<RecordScreen>`'s props. */\nexport interface FrameChrome {\n readonly onCancel?: () => void;\n readonly submitLabel?: string;\n readonly extraActions?: ReactNode;\n /** The `<form>` the body renders in edit and create; `FormActions` submits it. */\n readonly formId: string;\n /** The last failed write, shown above the form actions until the next submit. */\n readonly submitError: unknown;\n /** The last failed write's settled `applied` (the controller's): what its sentence says. */\n readonly submitApplied?: Applied;\n /**\n * The last failed write's issues (spec 4.14), in the answer's order, until the next submit. The\n * alert shows, after the request-level text, the ones no drawn field takes (request-level, or on\n * a field the live plan does not hold active), routed at render.\n */\n readonly serverIssues?: ValidationIssues;\n /** Runs the controller's submit, then `onSuccess` or the failure banner. */\n submit(): Promise<void>;\n /** A typed create with an accepted type: back to the type offer. */\n readonly changeType?: () => void;\n /**\n * Show and edit of a typed resource whose record names no declared type: the\n * value (`null` when the record has none). Show adds a notice; edit refuses.\n */\n readonly unsupportedType?: string | null;\n /**\n * The screen is a quick entry's: its host draws the record title as the overlay's heading\n * (spec 4.1), so the frame's `<RecordTitle/>` renders nothing.\n */\n readonly hostTitle?: true;\n /** The screen's root element (the frame's runtime checks look for an `h1` inside it). */\n readonly root?: RefObject<HTMLElement | null>;\n}\n\nexport const FrameChromeContext = createContext<FrameChrome | null>(null);\n\n/** The frame's chrome; a piece outside `<RecordScreen>` has thrown before it reads this. */\nexport function useFrameChrome(): FrameChrome {\n const chrome = useContext(FrameChromeContext);\n if (chrome === null)\n throw new Error('[burojs] useRecordFrame() must be called inside <RecordScreen>');\n return chrome;\n}\n\n/** The frame's chrome, or `null` outside `<RecordScreen>` (a view rendered alone, `checkFrame`). */\nexport function useOptionalFrameChrome(): FrameChrome | null {\n return useContext(FrameChromeContext);\n}\n","'use client';\nimport {\n type CheckIssueMeta,\n type Applied,\n type DataErrorKind,\n type CompiledScreen,\n type MessageReference,\n declaredText,\n resolveFieldLabel,\n resolveResourceLabel,\n routeServerIssues,\n type ScreenPlan,\n type ValidationIssue,\n} from '@burojs/core';\nimport {\n type ErrorTextCaps,\n policyRecordOf,\n RECORD_KIND_KEYS,\n recordKeyOf,\n kindErrorText,\n specificErrorText,\n resolveValidationMessage,\n useApp,\n useI18nCaps,\n useChromeT,\n useOptionalT,\n useRecordFrame,\n useRecordTitle,\n useRouteNavigate,\n useFramePiece,\n useScreenState,\n useTestIds,\n} from '@burojs/react';\nimport { IconAlertCircle, IconAlertTriangle, IconCopy, IconLoader2 } from '@tabler/icons-react';\nimport { type ReactElement, useMemo } from 'react';\nimport { ActionOverflow } from '../actions/action-overflow.js';\nimport { listTarget, recordReturnTarget } from '../layout/record-targets.js';\nimport { resolveResourceTitle } from '../resource/resource-title.js';\nimport {\n friendlyStringsFrom,\n isNetworkFailure,\n technicalTexts,\n toFriendlyError,\n} from '../lib/friendly-error.js';\nimport { Button } from '../primitives/button.js';\nimport { useFrameChrome } from './frame-context.js';\n\n/** The record's id as the frame knows it: the `recordId`, else the record's key for its resource. */\nfunction useFrameId(): string | undefined {\n const { resource, recordId, record } = useRecordFrame();\n const def = useApp().registry.get(resource);\n if (recordId !== undefined) return recordId;\n const id = recordKeyOf(def, record);\n return typeof id === 'string' || typeof id === 'number' ? String(id) : undefined;\n}\n\n/**\n * The record's title: its `recordTitle` / display field (show, edit), or\n * \"Create <label>\" in create. Inside `<RecordScreen>` only; no props.\n */\nfunction RecordTitleView(): ReactElement | null {\n const { resource, mode, record } = useRecordFrame();\n const id = useFrameId();\n const app = useApp();\n const caps = useI18nCaps(resource);\n const t = useOptionalT();\n const title = useRecordTitle(resource, mode === 'create' ? undefined : id, record);\n // A quick entry's host draws the title as its heading: drawn and announced once (spec 4.1).\n if (useFrameChrome().hostTitle === true) return null;\n const text =\n mode === 'create'\n ? resolveResourceTitle(caps, t, resource, 'createTitle', {\n label: resolveResourceLabel(caps, resource, 'single', app.registry.get(resource)),\n })\n : title;\n if (text === '') return null;\n return <h2 className=\"min-w-0 break-words text-xl font-semibold tracking-tight\">{text}</h2>;\n}\n\n/**\n * The record's item actions: the resolved `<ActionOverflow>` of the mode's\n * surface, then `<RecordScreen extraActions>`. Nothing in create or before\n * the record is read.\n */\nfunction RecordActionsView(): ReactElement | null {\n const { resource, mode, record, controller } = useRecordFrame();\n const { extraActions } = useFrameChrome();\n const id = useFrameId();\n const holder = useScreenState()?.inline;\n if (mode === 'create' || record === undefined || id === undefined) return null;\n // Item actions are policy (P5 decision 12): their gates and the flows they start read the row\n // as read, not the projected one (P4 4.24 C2) — what they render projects on its own.\n const row = { ...policyRecordOf(controller, record), id } as { id: string } & Record<\n string,\n unknown\n >;\n // A flow this screen presents inline has no button of its own here (P6 3.12): this screen\n // instance only, a screen without the placement draws it.\n holder?.declare(inlineFlowNames(controller.screen, controller.plan));\n return (\n <div className=\"flex flex-wrap items-center gap-2\">\n <ActionOverflow\n resource={resource}\n record={row}\n surface={mode}\n // Drawn on the record's screen: an action's `when` reads the screen's sources, its `with`\n // sources included (T4 D9 part 4); `record` stays the row as read (unprojected), and the\n // action's own scope, user and route fill only what the screen lacks.\n sources={controller.sources}\n {...(holder === undefined ? {} : { hideFlows: (name: string) => holder.suppressed(name) })}\n />\n {mode === 'show' ? extraActions : null}\n </div>\n );\n}\n\n/** Copies the record's id to the clipboard. Nothing without an id (create). */\nfunction CopyIdView(): ReactElement | null {\n const id = useFrameId();\n const t = useOptionalT();\n if (id === undefined) return null;\n const label = t('record.copyId', { defaultValue: 'Copy ID' });\n return (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n aria-label={label}\n title={label}\n onClick={() => void navigator.clipboard?.writeText(id)}\n className=\"h-7 gap-1 px-2 font-mono text-xs text-muted-foreground\"\n >\n <IconCopy className=\"h-3.5 w-3.5\" aria-hidden=\"true\" />\n <span>{id}</span>\n </Button>\n );\n}\n\n/**\n * Submit and Cancel (edit, create): Submit runs the controller's submit and\n * then `onSuccess`; Cancel calls `onCancel`, else navigates back through the\n * navigation guard. Above them, the form-level messages and a failed write.\n * Nothing in show.\n */\nfunction FormActionsView(): ReactElement | null {\n const { resource, mode, controller } = useRecordFrame();\n const chrome = useFrameChrome();\n const app = useApp();\n const navigate = useRouteNavigate();\n const t = useOptionalT();\n const chromeT = useChromeT();\n const caps = useI18nCaps();\n const labelCaps = useI18nCaps(resource);\n const tid = useTestIds();\n const id = useFrameId();\n // The failed write's issues no drawn field takes, against the live plan (spec 4.6 rule 5).\n const failedIssues = chrome.serverIssues;\n const livePlan = controller.plan;\n const alertIssues = useMemo(\n () =>\n failedIssues === undefined || failedIssues.length === 0\n ? NO_ALERT_ISSUES\n : routeServerIssues(\n { issues: failedIssues },\n (segment) => segment,\n // `_form` is the form's own. While the plan is unknown, the controller holds the\n // field issues and the form-level list above shows the ones no leaf can take.\n (field) =>\n field !== '_form' && (livePlan === null || livePlan.fields[field] === 'active'),\n ).form,\n [failedIssues, livePlan],\n );\n const fieldDefs = (\n app.registry.get(resource) as\n | { readonly fields?: Readonly<Record<string, unknown>> }\n | undefined\n )?.fields;\n if (mode === 'show') return null;\n const busy = controller.isSubmitting;\n const cancel = () => {\n if (chrome.onCancel !== undefined) chrome.onCancel();\n else\n navigate(\n mode === 'edit' && id !== undefined\n ? recordReturnTarget(app.registry, resource, id)\n : listTarget(resource),\n );\n };\n // Record-level: an issue with no field, or anchored to a field no leaf renders (it would\n // otherwise show nowhere). One message per banner, a validator's before a check's: a\n // check's record-level message never clobbers the form's own.\n const plan = controller.plan;\n // A field the mode does not draw (`inactive`: hidden by the tree or its `in`) has no leaf either.\n const undrawn = (field: string) =>\n plan === null || plan.fields[field] === undefined || plan.fields[field] === 'inactive';\n const recordLevel = (issue: (typeof controller.errors)[number]) =>\n issue.field === '_form' || undrawn(issue.field);\n // A blocking check anchored to a field no leaf draws never reaches `errors` (it is shown once\n // its field is touched, and nobody can touch it): it still blocks, so its message shows here\n // (P3 Known finding 16).\n const undrawnBlockers = (controller.checkOutcome?.blockers ?? []).flatMap((issue) => {\n const field = typeof issue.path?.[0] === 'string' ? issue.path[0] : '_form';\n if (field !== '_form' && !undrawn(field)) return [];\n if (controller.errors.some((own) => own.code === issue.code && own.field === field)) return [];\n return [{ ...issue, field }];\n });\n const formErrors = firstPreferred([\n ...controller.errors.filter(recordLevel),\n ...(undrawnBlockers as unknown as typeof controller.errors),\n ]);\n const formWarnings = firstPreferred(controller.warnings.filter(recordLevel));\n const text = (issue: (typeof formErrors)[number]) =>\n resolveValidationMessage(\n {\n code: issue.code ?? '',\n message: issue.message,\n ...(issue.check === undefined ? {} : { check: issue.check }),\n },\n { has: caps.has, t: caps.t },\n );\n // An error check that could not run: Retry re-runs the check pass (decision 28).\n const retryable: string[] = [];\n for (const issue of controller.checkOutcome?.blockers ?? []) {\n const checkId = issue.check?.id;\n if (issue.check?.cause === undefined || typeof checkId !== 'string') continue;\n if (!retryable.includes(checkId)) retryable.push(checkId);\n }\n const failure =\n chrome.submitError === undefined\n ? undefined\n : failureText(chrome.submitError, chrome.submitApplied, t, caps);\n // The failed write's issues no drawn field took (spec 4.14), error first: one naming a declared\n // field leads with that field's label, both resolved here so a language switch re-renders them.\n const serverIssues = bySeverity(alertIssues).map((issue) => {\n const head = issue.path[0];\n const name = typeof head === 'string' ? head : undefined;\n const declared = name === undefined ? undefined : fieldDefs?.[name];\n const message = resolveValidationMessage(\n {\n code: issue.code,\n message: issue.message,\n ...(issue.check === undefined ? {} : { check: issue.check }),\n },\n {\n has: caps.has,\n t: caps.t,\n ...(declared === undefined ? {} : { fieldKey: `resources.${resource}.fields.${name}` }),\n },\n );\n const label =\n declared === undefined || name === undefined\n ? undefined\n : resolveFieldLabel(labelCaps, name, declaredText('field', declared, 'label'));\n return { label, message, severity: issue.severity };\n });\n // A create wizard submits from its last step; before it, the steps rail's Next moves on.\n const steps = controller.steps;\n const midSteps =\n steps !== null &&\n steps.ids.length > 1 &&\n steps.current !== undefined &&\n steps.current !== steps.ids[steps.ids.length - 1];\n return (\n <div className=\"flex flex-col gap-3\">\n {failure === undefined && formErrors.length === 0 && serverIssues.length === 0 ? null : (\n <div\n role=\"alert\"\n className=\"flex items-start gap-2 rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive\"\n >\n <IconAlertCircle className=\"mt-0.5 h-4 w-4 shrink-0\" aria-hidden=\"true\" />\n <div className=\"leading-snug\">\n {failure === undefined ? null : <p className=\"font-medium\">{failure}</p>}\n {serverIssues.map((issue, index) => (\n <p\n // biome-ignore lint/suspicious/noArrayIndexKey: one failed write's fixed list\n key={index}\n data-testid={`form-server-issue:${resource}:${mode}:${index}`}\n data-buro-severity={issue.severity}\n className={issue.severity === 'error' ? undefined : 'text-warning-emphasis'}\n >\n {issue.label === undefined ? null : (\n <span className=\"font-medium\">{issue.label}: </span>\n )}\n {issue.message}\n </p>\n ))}\n {formErrors.map((issue) => (\n <p key={issueKey(issue)}>{text(issue)}</p>\n ))}\n </div>\n {failure !== undefined && steps !== null ? (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"ml-auto\"\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => void chrome.submit()}\n >\n {chromeT('actions.retry', { defaultValue: 'Retry' })}\n </Button>\n ) : null}\n </div>\n )}\n {retryable.length === 0 ? null : (\n <div className=\"flex flex-wrap gap-2\">\n {retryable.map((checkId) => (\n <Button\n key={checkId}\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n data-testid={`form-check-retry:${checkId}`}\n onClick={() => void controller.revalidate()}\n >\n {chromeT('actions.retry', { defaultValue: 'Retry' })}\n </Button>\n ))}\n </div>\n )}\n {formWarnings.length === 0 ? null : (\n <div\n role=\"status\"\n aria-live=\"polite\"\n className=\"flex items-start gap-2 rounded-md border border-warning/50 bg-warning/10 px-3 py-2 text-sm text-warning-emphasis\"\n data-testid={`form-warning:${resource}:${mode}`}\n >\n <IconAlertTriangle className=\"mt-0.5 h-4 w-4 shrink-0\" aria-hidden=\"true\" />\n <div className=\"leading-snug\">\n {formWarnings.map((issue) => (\n <p key={issueKey(issue)}>{text(issue)}</p>\n ))}\n </div>\n </div>\n )}\n {/* The `actions.*` chrome keys are read unscoped (`resources._`, then `common`): under the\n record screen's resource, `resources.<r>.actions.cancel` is the `cancel` flow's entry,\n and its string shorthand would label this button. */}\n <div className=\"flex justify-end gap-2 border-t pt-4\">\n {controller.isValidating ? (\n <span\n className=\"mr-auto inline-flex items-center gap-2 text-sm text-muted-foreground\"\n data-testid={tid.formValidating(resource, mode)}\n aria-live=\"polite\"\n >\n <IconLoader2 className=\"h-3.5 w-3.5 animate-spin\" aria-hidden=\"true\" />\n <span>{chromeT('actions.validating', { defaultValue: 'Validating…' })}</span>\n </span>\n ) : null}\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={cancel}\n // A button taking focus on mousedown blurs the field, whose validation shifts the\n // layout, and the click lands nowhere: keep the focus where it is.\n onMouseDown={(event) => event.preventDefault()}\n data-testid={tid.formCancel(resource, mode)}\n >\n {chromeT('actions.cancel', { defaultValue: 'Cancel' })}\n </Button>\n {midSteps ? null : (\n <Button\n type=\"submit\"\n form={chrome.formId}\n disabled={busy || controller.failure !== null}\n aria-busy={busy}\n onMouseDown={(event) => event.preventDefault()}\n onClick={(event) => {\n event.preventDefault();\n void chrome.submit();\n }}\n data-testid={tid.formSubmit(resource, mode)}\n className=\"min-w-24\"\n >\n {busy ? <IconLoader2 className=\"mr-2 h-4 w-4 animate-spin\" aria-hidden=\"true\" /> : null}\n {busy\n ? mode === 'edit'\n ? chromeT('actions.saving', { defaultValue: 'Saving…' })\n : chromeT('actions.creating', { defaultValue: 'Creating…' })\n : (chrome.submitLabel ??\n (mode === 'edit'\n ? chromeT('actions.save', { defaultValue: 'Save' })\n : chromeT('actions.create', { defaultValue: 'Create' })))}\n </Button>\n )}\n </div>\n </div>\n );\n}\n\nconst NO_ALERT_ISSUES: readonly ValidationIssue[] = Object.freeze([]);\n\nconst SEVERITY_RANK: Readonly<Record<string, number>> = { error: 0, warning: 1, info: 2 };\n\n/** Issues ordered error, then warning, then info (spec 4.6); stable within a severity. */\nfunction bySeverity(issues: readonly ValidationIssue[]): readonly ValidationIssue[] {\n return [...issues].sort(\n (a, b) => (SEVERITY_RANK[a.severity] ?? 3) - (SEVERITY_RANK[b.severity] ?? 3),\n );\n}\n\n/** The banner's one issue: the first that no check raised, else the first. */\nfunction firstPreferred<T extends { readonly check?: CheckIssueMeta }>(\n issues: readonly T[],\n): readonly T[] {\n const own = issues.find((issue) => issue.check?.id === undefined);\n const first = own ?? issues[0];\n return first === undefined ? [] : [first];\n}\n\n/** A form-level issue's identity in a list: its code, message key and check. */\nfunction issueKey(issue: {\n readonly code?: string;\n readonly message: { readonly key: string };\n readonly check?: { readonly id: string };\n}): string {\n return JSON.stringify([issue.code ?? '', issue.message.key, issue.check?.id ?? null]);\n}\n\n/**\n * A failed write as the user reads it: a friendly title, never a provider's raw message.\n * `settled` is the controller's settled `applied` for the attempt (spec 4.8), so the sentence and\n * the kept key agree; without one, the error's own `applied` is read.\n */\nfunction failureText(\n error: unknown,\n settled: Applied | undefined,\n t: ReturnType<typeof useOptionalT>,\n caps: ErrorTextCaps,\n): string {\n const texts = technicalTexts(error).filter((text) => text.length <= 1024);\n const strings = friendlyStringsFrom(t);\n // The first technical text the friendly path recognises, else the first one (not replaced).\n const friendly =\n texts.map((text) => toFriendlyError(text, undefined, strings)).find((f) => f.replaced) ??\n toFriendlyError(texts[0], undefined, strings);\n // A write that may have taken effect says so (spec 4.9). When the network itself failed, in\n // `details` or behind a provider's own sentence in `cause`, the offline sentence leads it. No\n // other lead is added: a generic \"Please try again.\" before \"Check the record\" contradicts it.\n const applied = settled ?? ownDataProperty(error, 'applied');\n if (applied === 'partial' || applied === 'unknown') {\n const key = applied === 'partial' ? 'errors.partlyApplied' : 'errors.mayHaveBeenApplied';\n const sentence = caps.has(key)\n ? caps.t(key)\n : applied === 'partial'\n ? 'Part of this may have been saved. Check the record before trying again.'\n : 'It may have been saved. Check the record before trying again.';\n const lead = texts.some(isNetworkFailure) ? strings.offline : '';\n return lead === '' ? sentence : `${lead} ${sentence}`;\n }\n const code = ownDataProperty(error, 'code');\n const kind = ownDataProperty(error, 'kind');\n // A kind with a sentence of its own (spec 4.15: every kind but `transport`, which covers an\n // unexpected failure) is read from that sentence: an HTTP trace or a fetch failure among its\n // technical texts does not replace it. The friendly sentence is for a failure with no kind text\n // to read, so a trace there still says what went wrong in plain language.\n const hasOwnSentence =\n typeof code === 'string' &&\n typeof kind === 'string' &&\n kind !== 'transport' &&\n Object.hasOwn(RECORD_KIND_KEYS, kind);\n const message = ownDataProperty(error, 'message');\n // The code's own text comes first (spec 4.15): the friendly sentence of a trace is only the\n // fallback when the lookup finds no text for the code.\n if (friendly.replaced && !hasOwnSentence) {\n const own =\n typeof code === 'string'\n ? specificErrorText({ code, ...(isMessageReference(message) ? { message } : {}) }, caps, {\n record: true,\n })\n : undefined;\n return own ?? friendly.title;\n }\n // Step 6 of spec 4.15 is the record form's generic failure sentence, never `errors.failed`\n // (\"Validation failed\"), which is an issue's fallback and wrong for a failure of any other kind.\n if (typeof code !== 'string') return strings.title;\n const reference = { code, ...(isMessageReference(message) ? { message } : {}) };\n return (\n specificErrorText(reference, caps, { record: true }) ??\n (typeof kind === 'string'\n ? kindErrorText(kind as DataErrorKind, caps, { record: true })\n : undefined) ??\n strings.title\n );\n}\n\n/** A provider error's own data property, never a getter. */\nfunction ownDataProperty(error: unknown, name: string): unknown {\n if (error === null || typeof error !== 'object') return undefined;\n try {\n const descriptor = Object.getOwnPropertyDescriptor(error, name);\n return descriptor !== undefined && 'value' in descriptor ? descriptor.value : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction isMessageReference(value: unknown): value is MessageReference {\n return (\n value !== null &&\n typeof value === 'object' &&\n typeof (value as { readonly key?: unknown }).key === 'string'\n );\n}\n\n/**\n * The names of the flows a compiled screen places inline (`buro:inline-flow`) and actually draws:\n * a placement the plan dropped (its own `when`, `requires` or `in`) leaves the flow's button.\n */\nfunction inlineFlowNames(screen: CompiledScreen | null, plan: ScreenPlan | null): string[] {\n if (screen === null) return [];\n const names: string[] = [];\n for (const node of screen.nodes) {\n const block = node.placement?.block;\n const flow = node.placement?.props.flow;\n if (block?.namespace !== 'buro' || block.id !== 'inline-flow' || typeof flow !== 'string')\n continue;\n const planned = plan === null || node.key === undefined ? undefined : plan.byKey[node.key];\n if (plan !== null && (planned === undefined || planned.state === 'absent')) continue;\n names.push(flow);\n }\n return names;\n}\n\n/** A piece as a frame places it: recorded while mounted, a marker under `checkFrame`. */\nfunction piece(\n name: 'RecordTitle' | 'RecordActions' | 'CopyId' | 'FormActions',\n View: () => ReactElement | null,\n) {\n function Piece(): ReactElement | null {\n const check = useFramePiece(name);\n if (check?.stub === true) return <span data-check-piece={name} />;\n return <View />;\n }\n Piece.displayName = name;\n return Piece;\n}\n\n/**\n * The record's title: its `recordTitle` / display field (show, edit), or\n * \"Create <label>\" in create. Inside `<RecordScreen>` only; no props.\n */\nexport const RecordTitle: () => ReactElement | null = piece('RecordTitle', RecordTitleView);\n\n/**\n * The record's item actions: the resolved `<ActionOverflow>` of the mode's\n * surface, then `<RecordScreen extraActions>`. Nothing in create or before\n * the record is read.\n */\nexport const RecordActions: () => ReactElement | null = piece('RecordActions', RecordActionsView);\n\n/** Copies the record's id to the clipboard. Nothing without an id (create). */\nexport const CopyId: () => ReactElement | null = piece('CopyId', CopyIdView);\n\n/**\n * Submit and Cancel (edit, create): Submit runs the controller's submit and\n * then `onSuccess`; Cancel calls `onCancel`, else navigates back through the\n * navigation guard. Above them, the form-level messages and a failed write.\n * Nothing in show.\n */\nexport const FormActions: () => ReactElement | null = piece('FormActions', FormActionsView);\n","'use client';\nimport { type RecordFrameViewProps, useOptionalT, useTestIds } from '@burojs/react';\nimport { createContext, type ReactElement, useContext } from 'react';\nimport { Button } from '../primitives/button.js';\nimport { useOptionalFrameChrome } from '../record/frame-context.js';\nimport { CopyId, FormActions, RecordActions, RecordTitle } from '../record/frame-pieces.js';\n\n/**\n * The undeclared-type notice: a record whose discriminator value no type declares (or that has\n * none) reads as the base with this notice, and nothing can be written for it (P1b+P1c\n * decision 64). The strings are the framework's `create.unsupportedType` /\n * `create.unsupportedTypeHint`.\n */\nexport function UndeclaredTypeNotice({\n resource,\n typeValue,\n className,\n}: {\n readonly resource: string;\n readonly typeValue: string | null;\n readonly className?: string;\n}): ReactElement {\n const t = useOptionalT();\n const tid = useTestIds();\n return (\n <div\n data-testid={tid.unsupportedDocumentType(resource)}\n data-type-value={typeValue ?? ''}\n role=\"status\"\n className={className ?? 'rounded-md border border-dashed p-8 text-center'}\n >\n <h2 className=\"text-base font-semibold tracking-tight\">\n {t('create.unsupportedType', { defaultValue: 'Unsupported type' })}\n </h2>\n <p className=\"mx-auto max-w-sm text-sm text-muted-foreground\">\n {t('create.unsupportedTypeHint', {\n params: { type: typeValue ?? '' },\n defaultValue: 'The type “{{type}}” is not registered for this resource.',\n })}\n </p>\n </div>\n );\n}\n\n/**\n * Whether the framework already drew the type chrome above a custom frame (P6-70): the built-in\n * view's notice and Change type then render nothing (a lazily-failed custom view falls back to\n * the built-in view under the same flag).\n */\nexport const TypeChromeDrawnContext = createContext(false);\n\n/** The undeclared-type notice in a frame's header row (the framework's, P6-70). */\nexport function HeaderTypeNotice({ resource }: { readonly resource: string }): ReactElement | null {\n const chrome = useOptionalFrameChrome();\n const drawn = useContext(TypeChromeDrawnContext);\n if (drawn || chrome?.unsupportedType === undefined) return null;\n return (\n <UndeclaredTypeNotice\n resource={resource}\n typeValue={chrome.unsupportedType}\n className=\"rounded-md border border-dashed px-3 py-2 text-sm\"\n />\n );\n}\n\n/** A typed create's \"Change type\" (the framework's, P6-70). */\nexport function ChangeTypeButton(): ReactElement | null {\n const chrome = useOptionalFrameChrome();\n const drawn = useContext(TypeChromeDrawnContext);\n const t = useOptionalT();\n if (drawn || chrome?.changeType === undefined) return null;\n return (\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={chrome.changeType}>\n {t('create.typeOffer.change', { defaultValue: 'Change type' })}\n </Button>\n );\n}\n\n/**\n * `buro:record`: the header region (the undeclared-type notice, the title row, then the `header`\n * slot), the `body` slot, the form actions.\n */\nexport function BuroRecordFrame({ slots, screen }: RecordFrameViewProps): ReactElement {\n return (\n <>\n <div data-buro-region=\"record-header\" className=\"flex flex-col gap-3\">\n <HeaderTypeNotice resource={screen.resource} />\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <div className=\"flex min-w-0 items-baseline gap-2\">\n <RecordTitle />\n <CopyId />\n </div>\n <RecordActions />\n <ChangeTypeButton />\n </div>\n {slots.header ?? null}\n </div>\n {slots.body}\n <FormActions />\n </>\n );\n}\n","import { builtinFrames } from '@burojs/core';\nimport { type FrameImplementation, implementFrame } from '@burojs/react';\nimport { BuroPanelFrame, BuroStepsFrame, BuroTabsFrame } from './builtin-nodes.js';\nimport { BuroListFrame } from './builtin-list.js';\nimport { BuroPageFrame } from './builtin-page.js';\nimport { BuroPeekFrame } from './builtin-peek.js';\nimport { BuroRecordFrame } from './builtin-record.js';\n\n/** The ids of the seven built-in frames. */\nexport type BuiltinFrameId =\n | 'buro:record'\n | 'buro:peek'\n | 'buro:list'\n | 'buro:page'\n | 'buro:panel'\n | 'buro:tabs'\n | 'buro:steps';\n\n/**\n * The seven built-in frames' views, the kit's own (P6-8): the renderer looks a `buro:` id up here\n * and any other in the app's `<BuroProvider frameImplementations>`.\n */\nexport const shadcnFrameViews: Readonly<\n // biome-ignore lint/suspicious/noExplicitAny: the views of five frame kinds\n Record<BuiltinFrameId, FrameImplementation<any>>\n> = Object.freeze({\n 'buro:record': implementFrame(builtinFrames.record, { component: BuroRecordFrame }),\n 'buro:peek': implementFrame(builtinFrames.peek, { component: BuroPeekFrame }),\n 'buro:list': implementFrame(builtinFrames.list, { component: BuroListFrame }),\n 'buro:page': implementFrame(builtinFrames.page, { component: BuroPageFrame }),\n 'buro:panel': implementFrame(builtinFrames.panel, { component: BuroPanelFrame }),\n 'buro:tabs': implementFrame(builtinFrames.tabs, { component: BuroTabsFrame }),\n 'buro:steps': implementFrame(builtinFrames.steps, { component: BuroStepsFrame }),\n});\n","'use client';\nimport { type EntityRef, type FrameKind, formatEntityRef } from '@burojs/core';\nimport type { FrameImplementation, FrameImplementationCatalog } from '@burojs/react';\nimport {\n type ComponentType,\n type ReactNode,\n createElement,\n Fragment,\n lazy,\n useEffect,\n useRef,\n} from 'react';\nimport { BuroPanelFrame, BuroStepsFrame, BuroTabsFrame } from './builtin-nodes.js';\nimport { BuroListFrame } from './builtin-list.js';\nimport { BuroPageFrame } from './builtin-page.js';\nimport { BuroPeekFrame } from './builtin-peek.js';\nimport { BuroRecordFrame } from './builtin-record.js';\nimport { type BuiltinFrameId, shadcnFrameViews } from './builtin.js';\n\n// biome-ignore lint/suspicious/noExplicitAny: a frame view of any kind\ntype View = ComponentType<any>;\n\n/** A resolved frame view; `fallback` when the frame has no view and the built-in draws it. */\nexport interface ResolvedFrameView {\n readonly view: View;\n readonly fallback?: 'not-implemented';\n}\n\nconst BUILTIN_BY_KIND: Readonly<Record<FrameKind, View>> = {\n record: BuroRecordFrame,\n peek: BuroPeekFrame,\n list: BuroListFrame,\n page: BuroPageFrame,\n panel: BuroPanelFrame,\n tabs: BuroTabsFrame,\n steps: BuroStepsFrame,\n};\n\n/** Logs `frame.not-implemented` once per mounted instance (a screen or a node), in development. */\nfunction useNotImplemented(id: string): void {\n const told = useRef(false);\n useEffect(() => {\n if (told.current || process.env.NODE_ENV === 'production') return;\n told.current = true;\n console.error(\n `[burojs] frame.not-implemented: ${id} has no view; register implementFrame(<the ${id} frame>, { component }) in <BuroProvider frameImplementations>. The built-in frame draws it.`,\n );\n }, [id]);\n}\n\nconst notImplementedViews = new Map<string, View>();\n\n/**\n * The built-in view of `kind` standing in for the frame `id` (P6-10): one development error per\n * instance; a record frame's extra slots render in declaration order above `body`, so nothing\n * the frame would have shown is hidden.\n */\nfunction notImplementedView(kind: FrameKind, id: string): View {\n const key = `${kind}\\u0000${id}`;\n let view = notImplementedViews.get(key);\n if (view !== undefined) return view;\n const builtin = BUILTIN_BY_KIND[kind];\n view =\n kind === 'record' || kind === 'page'\n ? function RecordFrameNotImplemented(props: {\n readonly slots: Readonly<Record<string, ReactNode>>;\n }) {\n useNotImplemented(id);\n const extras = Object.entries(props.slots)\n .filter(([name]) => name !== 'header' && name !== 'body')\n .map(([, element]) => element);\n return createElement(builtin, {\n ...props,\n slots: {\n ...props.slots,\n body: createElement(Fragment, null, ...extras, props.slots.body),\n },\n });\n }\n : function FrameNotImplemented(props: object) {\n useNotImplemented(id);\n return createElement(builtin, props);\n };\n notImplementedViews.set(key, view);\n return view;\n}\n\nconst lazyViews = new WeakMap<FrameImplementation, View>();\n\n/** A `load` entry's view behind `React.lazy`, one per entry; a rejecting load is not-implemented. */\nfunction lazyView(entry: FrameImplementation, kind: FrameKind): View {\n let view = lazyViews.get(entry);\n if (view === undefined) {\n const load = entry.load!;\n view = lazy(async () => {\n try {\n const module = await load();\n return { default: module.default as View };\n } catch {\n return { default: notImplementedView(kind, entry.id) };\n }\n });\n lazyViews.set(entry, view);\n }\n return view;\n}\n\n/**\n * The view of a frame: a `buro:` id from the kit's own table, any other from the app's\n * catalogue (`component`, or `load` behind `React.lazy`); a frame with no view is drawn by the\n * built-in of its kind with `fallback: 'not-implemented'` (spec 3.2). Never reads a prop or an\n * attribute: only the frame reference the compiled screen holds.\n */\nexport function resolveFrameView(\n ref: EntityRef,\n catalog: FrameImplementationCatalog,\n kind: FrameKind,\n): ResolvedFrameView {\n const id = formatEntityRef(ref);\n if (ref.namespace === 'buro') {\n const builtin = Object.hasOwn(shadcnFrameViews, id)\n ? shadcnFrameViews[id as BuiltinFrameId]\n : undefined;\n if (builtin !== undefined && builtin.for === kind) return { view: builtin.component as View };\n return { view: notImplementedView(kind, id), fallback: 'not-implemented' };\n }\n const entry = Object.hasOwn(catalog, id) ? catalog[id] : undefined;\n if (entry === undefined || entry.for !== kind)\n return { view: notImplementedView(kind, id), fallback: 'not-implemented' };\n if (entry.component !== undefined) return { view: entry.component as View };\n return { view: lazyView(entry, kind) };\n}\n\n/** Whether a resolved view is the kit's built-in record view (it draws the type chrome itself). */\nexport function isBuiltinRecordView(resolved: ResolvedFrameView): boolean {\n return resolved.view === BuroRecordFrame || resolved.fallback === 'not-implemented';\n}\n","'use client';\nimport {\n type EntityRef,\n type CompiledScreen,\n compiledScreenFor,\n formatEntityRef,\n isScreenFailure,\n} from '@burojs/core';\nimport {\n ActionRouteContext,\n RouteSourceContext,\n type ListFrameViewProps,\n useApp,\n useApplicationSnapshot,\n useFrameImplementations,\n useFrameT,\n useOptionalDataRuntime,\n usePageScreen,\n useResourceListContext,\n useTestIds,\n} from '@burojs/react';\nimport {\n type ReactElement,\n Suspense,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { itemHandle } from '../blocks/related-item.js';\nimport { resolveFrameView } from '../frames/resolve.js';\nimport { ScreenTree, ScreenTreeScope } from '../screen/screen-tree.js';\nimport {\n ForceTableView,\n ListBody,\n ListControls,\n ListItemContext,\n type ListPieceName,\n useListPieceCounts,\n} from './pieces/index.js';\n\n/** The pieces a frame places at most once each; `bulk-bar` is the surface's own. */\nconst ONCE: readonly ListPieceName[] = [\n 'filters',\n 'flows',\n 'live',\n 'saved-views',\n 'columns',\n 'export',\n 'create',\n 'body',\n 'bulk-bar',\n];\n\n/**\n * Reports, once the frame view has mounted, a frame that places `ListBody` zero or two times\n * (development: `list.body-missing`, `list.piece-twice`) and asks the host for the built-in body\n * when there is none, so a list never vanishes. It mounts in the view's own Suspense boundary\n * and after it, so a lazy view is counted when it has loaded, not before.\n */\nfunction MountCheck(props: {\n readonly frameId: string;\n readonly onBodyMissing: (missing: boolean) => void;\n}): null {\n const { frameId, onBodyMissing } = props;\n const counts = useListPieceCounts();\n const told = useRef(new Set<string>());\n // Every commit: a frame may place its pieces after a state change, and the counts are final\n // only after the pieces' own effects, which run before this one.\n useEffect(() => {\n const seen = counts();\n const body = seen.get('body') ?? 0;\n onBodyMissing(body === 0);\n if (process.env.NODE_ENV === 'production') return;\n const tell = (code: string, message: string) => {\n if (told.current.has(code)) return;\n told.current.add(code);\n console.error(`[burojs] ${code}: ${message}`);\n };\n if (body === 0)\n tell(\n 'list.body-missing',\n `${frameId} renders no <ListBody/>; the built-in body is drawn below the frame. Place <ListBody/> where the rows go.`,\n );\n for (const name of ONCE)\n if ((seen.get(name) ?? 0) > 1)\n tell(\n 'list.piece-twice',\n `${frameId} renders the ${name} piece more than once; place each piece once.`,\n );\n });\n return null;\n}\n\n/** The compiled list screen of a resource: its failure marker is a development error. */\nfunction useCompiledListScreen(resource: string): CompiledScreen | null {\n const app = useApp();\n const snapshot = useApplicationSnapshot();\n const ref = (app.registry.get(resource) as { readonly ref?: EntityRef } | undefined)?.ref;\n const compiled = useMemo(\n () => (ref === undefined ? undefined : compiledScreenFor(snapshot, ref, 'show', 'list')),\n [snapshot, ref],\n );\n const failure = compiled !== undefined && isScreenFailure(compiled) ? compiled : null;\n useEffect(() => {\n if (failure === null || process.env.NODE_ENV === 'production') return;\n console.error(\n `[burojs] The list of \"${resource}\" cannot render its frame: ${failure.code} at ${failure.path.join('.')}: ${failure.message}. The built-in frame draws it.`,\n );\n }, [failure, resource]);\n return compiled === undefined || isScreenFailure(compiled) ? null : compiled;\n}\n\n/** The compiled screen's frame slots: the item (P7-36) is planned beside them and is no slot. */\nfunction frameSlotNames(compiled: CompiledScreen): readonly string[] {\n return Object.keys(compiled.slots).filter((name) => name !== 'item');\n}\n\n/**\n * The built-in arrangement, with no slot: what a list that cannot draw its frame falls back to.\n * It has no screen-tree scope, which cards and a timeline need to read their rows, so it draws\n * the table whatever `views.list.initial.view` says.\n */\nfunction Arrangement(): ReactElement {\n return (\n <ForceTableView>\n <ListControls />\n <ListBody />\n </ForceTableView>\n );\n}\n\n/**\n * The frame view of a compiled list screen, given its slots' elements: resolved from the frame\n * reference (a `buro:` id from the kit's own table, any other from the app's catalogue), with the\n * mount check beside it. A view without `<ListBody/>` gets the built-in body below it.\n */\nfunction FrameView(props: {\n readonly resource: string;\n readonly compiled: CompiledScreen;\n readonly slots: Readonly<Record<string, ReactElement | null>>;\n}): ReactElement {\n const { resource, compiled, slots } = props;\n const catalog = useFrameImplementations();\n const [bodyMissing, setBodyMissing] = useState(false);\n const id = formatEntityRef(compiled.frame);\n const resolved = useMemo(\n () => resolveFrameView(compiled.frame, catalog, 'list'),\n [compiled.frame, catalog],\n );\n const t = useFrameT(id);\n const View = resolved.view;\n const viewProps: ListFrameViewProps = {\n slots: slots as ListFrameViewProps['slots'],\n resource,\n t,\n };\n return (\n <>\n <Suspense fallback={null}>\n <View {...viewProps} />\n <MountCheck frameId={id} onBodyMissing={setBodyMissing} />\n </Suspense>\n {bodyMissing ? <ListBody /> : null}\n </>\n );\n}\n\n/** A list whose slots hold nodes: planned as a page's (the sources a list reads are user and scope). */\nfunction PlannedFrame(props: {\n readonly resource: string;\n readonly compiled: CompiledScreen;\n}): ReactElement {\n const { resource, compiled } = props;\n const page = usePageScreen(compiled);\n const tid = useTestIds();\n const slots: Record<string, ReactElement | null> = {};\n for (const name of frameSlotNames(compiled)) {\n const roots = page.plan.slots[name] ?? [];\n slots[name] = roots.every((node) => node.state === 'absent') ? null : (\n <div key={name} data-testid={tid.listSlot(resource, name)}>\n <ScreenTree\n region=\"record\"\n slot={name}\n resource={resource}\n mode=\"show\"\n compiled={compiled}\n page={page}\n />\n </div>\n );\n }\n const { PlacementScope } = page;\n // The route around the list (the route list has none of its own, spec 4.5): the reset below\n // hides it from the blocks it places, but the list's own actions read it (read-scope 7c.6).\n const claimedRoute = useContext(RouteSourceContext);\n // The item block of a cards or timeline list is planned with the screen, beside the slots.\n const itemNode = page.plan.slots.item?.[0];\n const item = useMemo(\n () => (itemNode === undefined ? undefined : itemHandle(itemNode)),\n [itemNode],\n );\n return (\n <RouteSourceContext.Provider value={null}>\n <ActionRouteContext.Provider value={claimedRoute}>\n <PlacementScope>\n <ScreenTreeScope resource={resource} mode=\"show\" compiled={compiled} page={page}>\n <ListItemContext.Provider value={item}>\n <FrameView resource={resource} compiled={compiled} slots={slots} />\n </ListItemContext.Provider>\n </ScreenTreeScope>\n </PlacementScope>\n </ActionRouteContext.Provider>\n </RouteSourceContext.Provider>\n );\n}\n\n/**\n * The route list's frame (P7-34): the effective frame of `views.list` (its own, the app's default,\n * `buro:list`) and its slots, each inside the framework's wrapper. The pieces the view places read\n * the controller the surface owns; the page header, the export watcher, the saved-view dialogs and\n * the bulk bar are drawn outside this host, so no frame can drop or fork them. A screen that\n * cannot compile draws the built-in arrangement with no slot (fail closed); a list whose slots\n * hold no node plans nothing, and one that does needs a data runtime to read its placements.\n */\nexport function ListFrameHost({ resource }: { readonly resource: string }): ReactElement {\n const compiled = useCompiledListScreen(resource);\n const hasDataRuntime = useOptionalDataRuntime() !== null;\n const { def } = useResourceListContext();\n // Cards and a timeline draw their rows from the screen's tree context, even with no node of\n // their own to plan (P7-36).\n const rowsView = def?.views?.list?.initial?.view ?? 'table';\n if (compiled === null) return <Arrangement />;\n if (compiled.nodes.length === 0 && rowsView === 'table') {\n const empty: Record<string, ReactElement | null> = {};\n for (const name of frameSlotNames(compiled)) empty[name] = null;\n return <FrameView resource={resource} compiled={compiled} slots={empty} />;\n }\n if (!hasDataRuntime) return <Arrangement />;\n return <PlannedFrame resource={resource} compiled={compiled} />;\n}\n","'use client';\nimport { lazy, Suspense, useEffect, useMemo, useRef, useState, type ReactNode } from 'react';\nimport { IconLink, IconLoader2, IconPlus } from '@tabler/icons-react';\nimport {\n type CountPolicy,\n type FixedFilterInput,\n type RelatedListInitial,\n type ScopeSource,\n type SearchDecl,\n enumNamespaceOf,\n resolveEnumLabel,\n resolveFieldOptionLabel,\n resolveResourceLabel,\n hasRecordPage,\n resourceShowHref,\n fieldOptionText,\n resolveSurfaceUi,\n type ColumnEntry,\n columnName,\n} from '@burojs/core';\nimport {\n LOCAL_USER_SCOPE_ID,\n policyRowsOf,\n ResourceListProvider,\n useApp,\n useAvailability,\n useAvailabilityResolver,\n useEntryGate,\n useQuick,\n useQuickOpener,\n useComponent,\n useI18nCaps,\n useOptionalDataRuntime,\n useChromeT,\n useOptionalT,\n useResourceList,\n useT,\n useTestIds,\n type ListState,\n type SavedViewEntry,\n} from '@burojs/react';\nimport type { ResourceListPageProps } from './resource-list-page.js';\nimport { enumBindingKey } from '@burojs/core/internal';\nimport { EnumBadge } from '../enum/enum-badge.js';\nimport { useExportRunWatcher } from '../export/run-watcher.js';\nimport { cn } from '../lib/cn.js';\nimport { toast } from '../notification/toaster.js';\nimport { Badge } from '../primitives/badge.js';\nimport { Button } from '../primitives/button.js';\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from '../primitives/dialog.js';\nimport { Input } from '../primitives/input.js';\nimport { PageHeader } from '../resource/page-header.js';\nimport { useDeepLinkOpen } from '../quick/use-deep-link.js';\nimport type { ItemHandle } from '../blocks/related-item.js';\nimport { RelatedCardsSkeleton, RelatedTimelineSkeleton } from '../blocks/related-skeletons.js';\nimport { canonicalResourceName, useListSlot } from './list-slots.js';\nimport { ListFrameHost } from './list-frame-host.js';\nimport {\n ListBody,\n ListBulkBar,\n ListControls,\n ListPiecesProvider,\n type ListSurfaceValue,\n} from './pieces/index.js';\nimport type { ResourceListProps } from '../resource/resource-list.js';\n\n/**\n * Whether a list column's field names its own display implementation: `ui.display` or\n * `ui.column.display`, an id or the object form's `use`. `{ overflow }` alone names none.\n */\nfunction declaresDisplay(field: { readonly ui?: unknown } | undefined) {\n return field !== undefined && resolveSurfaceUi(field, 'column').use !== undefined;\n}\n\n// The cards and timeline views load when a placement asks for one (P6 ruling 15).\n/**\n * A placement that declares no `initial.filters` selects nothing, never its target's (T4 Q4,\n * builder call C3). One frozen object, a stable memo key.\n */\nconst NO_INITIAL_FILTERS: Readonly<Record<string, never>> = Object.freeze({});\n\nconst RelatedCards = lazy(async () => ({\n default: (await import('../blocks/related-list-cards.js')).RelatedCards,\n}));\nconst RelatedTimeline = lazy(async () => ({\n default: (await import('../blocks/related-list-timeline.js')).RelatedTimeline,\n}));\n\n/**\n * Props of {@link ResourceListSurface}: the route list's (`variant: 'route'`, from\n * {@link ResourceListPageProps}) or a `related-list` placement's (`variant: 'placement'`, from its\n * props).\n */\nexport interface ResourceListSurfaceProps {\n /** Registry name of the resource to list (it MUST be registered). */\n readonly resource: string;\n readonly variant: 'route' | 'placement';\n /** Where the list keeps its state; the route list passes none (`?<resource>.`). */\n readonly state?: ListState;\n /** Locked filters (a placement's `where`); the route list has none. */\n readonly fixedFilters?: readonly FixedFilterInput[];\n /**\n * A placement's own initial state (T4 D9): `sort` and `pageSize` it omits follow the target's\n * `views.list.initial`; `filters` it omits is none, never the target's (owner, Q4). The route\n * list passes none and follows its resource's `views.list.initial`.\n */\n readonly initial?: RelatedListInitial;\n /** A placement's own search field (a box only when set); the route list uses `views.list.search`. */\n readonly search?: string;\n /** A placement's columns (names or entries, REF-117 §4.9); else the target's `views.list.columns`. */\n readonly columns?: readonly ColumnEntry[];\n /**\n * What a row opens: its `quick.show` (`quick`, a placement's default), its show page (`page`)\n * or nothing (`none`). The route list opens the page, or `quick.show` for a resource without\n * one (`views.show.page: false`).\n */\n readonly open?: 'page' | 'none' | 'quick';\n /** A placement's heading. */\n readonly title?: string;\n /**\n * A placement's `empty` text: drawn in place of the list's empty panel when it has no rows and\n * no filter of the user's narrows it (the table, the cards and the timeline alike).\n */\n readonly empty?: string;\n /**\n * Where a placement's reads take their scope values from; the route list passes none and keeps\n * the session's scope.\n */\n readonly scope?: ScopeSource;\n /**\n * How a placement draws its rows: the table (the default), cards or a timeline over the same\n * controller. The column menu, resize, selection and the bulk bar are the table's only.\n */\n readonly view?: 'table' | 'cards' | 'timeline';\n /** The planned item block of a cards or timeline placement (else the default item). */\n readonly item?: ItemHandle;\n /** The placement's key: its cards' and entries' test ids. */\n readonly placementKey?: string;\n /** A placement's \"+ Create\" (its `quick.create`, seeded by the caller); absent: none drawn. */\n readonly onCreate?: () => void;\n /** A placement's count policy, in place of the listed resource's `views.list.count`. */\n readonly count?: CountPolicy;\n /**\n * The record a row opens is another resource's (`resource`), keyed by the row's `field`: a\n * link panel lists junction rows and opens their targets. `open` then says `page` or `none`.\n */\n readonly rowTarget?: { readonly resource: string; readonly field: string };\n /**\n * No row actions, no selection and no bulk bar: a row can only be opened — except for a link\n * panel's {@link ResourceListSurfaceProps.linkEditing}.\n */\n readonly readOnly?: true;\n /**\n * A link panel's writes. `attach` draws Attach in the header. With `readOnly`, `detach` enables\n * selection; the bulk bar then draws only Detach and the row-actions column only Detach (no\n * create, no export, no item actions).\n */\n readonly linkEditing?: {\n /** `busy`: an Attach write is running; the button is drawn disabled, with a spinner. */\n readonly attach?: { readonly onAttach: () => void; readonly busy?: boolean };\n /** Resolves to the row keys (a list row's `id`) of the rows that left; they leave the selection. */\n readonly detach?: {\n readonly onDetach: (\n rows: readonly Readonly<Record<string, unknown>>[],\n ) => Promise<readonly string[]>;\n };\n };\n /**\n * `false`: no export control. A link panel shows target columns over junction rows, and an\n * export would ask (and write) the junction's fields and permissions, not the shown target's.\n */\n readonly exportable?: false;\n /**\n * Where the table keeps the user's column layout (REF-117 §4.10, C18): the list id of the\n * `buro/table-layout` UI setting. The route list passes `'route'`, a placement\n * `<owner resource>/<placement key path>`. A list rendered by hand passes its own stable id to\n * keep the layout across mounts; without one, the layout lasts for the mount.\n */\n readonly layoutId?: string;\n /** Route only: see {@link ResourceListPageProps.meta}. */\n readonly meta?: Record<string, unknown>;\n /** Route only: see {@link ResourceListPageProps.renderCell}. */\n readonly renderCell?: ResourceListPageProps['renderCell'];\n /** Route only: see {@link ResourceListPageProps.emptyState}. */\n readonly emptyState?: ReactNode;\n}\n\n/**\n * The one list body (spec 8.4, decision 63): the route list page and every `related-list`\n * placement render it. The route variant is today's list page, moved here unchanged — header,\n * filter region, saved views and their dialogs, the columns toggle, export, create, the table,\n * the bulk bar, and the `list.filters.<r>` / `list.body.<r>` / `list.cell.<r>` slots. The\n * placement variant drops the page header, the saved views and the `filters` / `body` slots\n * (decisions 61, 62); `list.cell.<r>` applies in both. See `ResourceListPage` for the override\n * ladder.\n */\n\n/** The discriminator field's own label for `value` (its `options`), or the value itself. */\nfunction discriminatorOptionLabel(field: unknown, value: string): string {\n const text = fieldOptionText(field, value);\n if (text !== undefined) return text;\n const declared = field as\n | {\n readonly options?: readonly { readonly value?: unknown; readonly label?: unknown }[];\n readonly meta?: { readonly options?: unknown };\n }\n | undefined;\n const options = Array.isArray(declared?.options)\n ? declared.options\n : Array.isArray(declared?.meta?.options)\n ? (declared.meta.options as readonly { readonly value?: unknown; readonly label?: unknown }[])\n : [];\n const label = options.find((option) => option?.value === value)?.label;\n return typeof label === 'string' ? label : value;\n}\n\n/** The resource's declared `views.list.initial.sort` (T4 D1), when it declares one. */\nfunction declaredInitialSort(def: unknown): readonly { readonly field: string }[] | undefined {\n return (\n def as\n | {\n readonly views?: {\n readonly list?: {\n readonly initial?: { readonly sort?: readonly { readonly field: string }[] };\n };\n };\n }\n | undefined\n )?.views?.list?.initial?.sort;\n}\n\n/** The route list's declared `views.list.initial.view` (T4 D1), when the resource declares one. */\nfunction declaredRouteView(def: unknown): 'table' | 'cards' | 'timeline' | undefined {\n return (\n def as\n | {\n readonly views?: {\n readonly list?: {\n readonly initial?: { readonly view?: 'table' | 'cards' | 'timeline' };\n };\n };\n }\n | undefined\n )?.views?.list?.initial?.view;\n}\n\nexport function ResourceListSurface({\n resource,\n variant,\n state,\n fixedFilters,\n initial,\n search: searchField,\n columns: columnEntries,\n open,\n title,\n empty,\n scope,\n view,\n item,\n placementKey,\n onCreate,\n count: countPolicy,\n rowTarget,\n readOnly,\n linkEditing,\n exportable,\n layoutId,\n meta,\n renderCell,\n emptyState,\n}: ResourceListSurfaceProps) {\n const route = variant === 'route';\n const t = useT();\n // A string that must read without the framework bundle (a host without `en` mounted).\n const optionalT = useOptionalT();\n const chromeT = useChromeT();\n const tid = useTestIds();\n const listCaps = useI18nCaps(resource);\n\n /**\n * The three override seams. Resolved unconditionally (Rules of Hooks) and\n * `undefined` for every resource that registers nothing — the level-0\n * path, which is byte-identical to the pre-B3.2 render (and, for\n * `CellSlot`, the pre-Task-5 render).\n *\n * `useListSlot` is overloaded on `region`: the `'cell'` call resolves to\n * {@link ListCellRenderer} — a 3-arg function — while `'filters'`/`'body'`\n * still resolve to {@link ListSlot}, a no-props component. No cast is\n * needed here; the hook's own signature carries the distinction.\n */\n const RouteFiltersSlot = useListSlot('filters', resource);\n // `list.body.<r>` was retired (P7-37): a component still registered there is told, not rendered.\n const RemovedBodySlot = useComponent<unknown>(`list.body.${canonicalResourceName(resource)}`);\n const CellSlot = useListSlot('cell', resource);\n // The route list only (decision 62): a placement renders the standard region.\n const FiltersSlot = route ? RouteFiltersSlot : undefined;\n const removedBody = route && RemovedBodySlot !== undefined;\n const bodyRemovedTold = useRef(false);\n useEffect(() => {\n if (!removedBody || bodyRemovedTold.current || process.env.NODE_ENV === 'production') return;\n bodyRemovedTold.current = true;\n console.error(\n `[burojs] list.body-removed: list.body.${canonicalResourceName(resource)} is no longer rendered; a whole-body override is a list frame (views.list.frame).`,\n );\n }, [removedBody, resource]);\n const searchDecl = useMemo<SearchDecl | undefined>(\n () => (searchField === undefined ? undefined : { fields: [searchField] }),\n [searchField],\n );\n\n /**\n * The list controller (`@burojs/react`). Owns everything that is not\n * rendering: URL-state sync, the column math, filter composition, the\n * `useList` call, row identity, selection, saved views and hrefs.\n *\n * ⚠️ No `onReset` here (Task 7). That seam existed ONLY to cross into the\n * old chip toolbar's app-owned `visibleIds` — its ephemeral \"which\n * filters are showing as chips\" set, which `filters.reset`/\n * `savedViews.apply` had to reach from outside (that toolbar and its hook\n * are gone — SP2 Task 8). The\n * filter-builder region (`FilterRegion`) has no equivalent state: its\n * badges render straight off the APPLIED `filters.group`/`filters.value`\n * and its panel draft reseeds from `filters.group` on every open (see\n * `FilterPanel`'s doc), so there is nothing left for a reset seam to\n * clear. `onReset` stays optional on `useResourceList` for any other\n * caller that still needs it.\n */\n // The route list's call is `{ meta }` exactly, no `state` key: its URL namespace stays the\n // resource's registry key.\n const appRegistry = useApp().registry;\n // Cards and timeline draw the same rows from the same controller (P6 3.13); the route list\n // draws them too when its `views.list.initial.view` says so (P7-36, T4 D1), else it is the table.\n // Read before the controller is mounted: a timeline list always sorts by `initial.sort` (C24).\n const effectiveView: 'table' | 'cards' | 'timeline' = route\n ? (declaredRouteView(appRegistry.get(resource)) ?? 'table')\n : (view ?? 'table');\n const timeline = effectiveView === 'timeline';\n // A placement's initial, each key over the target's; its filters are its own or none (Q4).\n const initialKey = JSON.stringify(initial ?? null);\n // biome-ignore lint/correctness/useExhaustiveDependencies: keyed by the initial's value\n const placementInitial = useMemo(\n () => (route ? undefined : { ...initial, filters: initial?.filters ?? NO_INITIAL_FILTERS }),\n [route, initialKey],\n );\n // A timeline's axis is the first entry of its effective initial sort (T4 D9).\n const timelineAxis = (placementInitial?.sort ??\n declaredInitialSort(appRegistry.get(resource)))?.[0]?.field;\n // A card or timeline item draws the placement's columns by name (§4.9: a card reads `ui.card`).\n const columnNames = useMemo(() => columnEntries?.map(columnName), [columnEntries]);\n const list = useResourceList(\n resource,\n route\n ? { meta, ...(timeline ? { timeline } : {}) }\n : {\n ...(timeline ? { timeline } : {}),\n ...(state === undefined ? {} : { state }),\n ...(fixedFilters === undefined ? {} : { fixedFilters }),\n ...(placementInitial === undefined ? {} : { initial: placementInitial }),\n ...(searchDecl === undefined ? {} : { search: searchDecl }),\n ...(columnEntries === undefined ? {} : { columns: columnEntries }),\n ...(scope === undefined ? {} : { scope }),\n ...(countPolicy === undefined ? {} : { countPolicy }),\n },\n );\n // Both sides added a destructured member: `live` (l2-lists SP0's polling\n // seam) and `cursor` (cursor pagination on main). They are independent —\n // keep both.\n const {\n def,\n query,\n pagination,\n cursor,\n count,\n filters,\n sorting,\n columns,\n selection,\n savedViews,\n routing,\n live,\n droppedPredicates,\n } = list;\n // The table keeps the rows as read: selection, the quick opener and item-action gates are\n // policy, and its cells project each row on their own (`viewRow`).\n const rows = policyRowsOf(list, list.rows);\n\n // A link panel's Detach: the rows that left leave the selection, the others stay selected.\n // The selection is read when the write answers, not when it started.\n const selectionRef = useRef(selection);\n selectionRef.current = selection;\n const onDetach = linkEditing?.detach?.onDetach;\n const surfaceLinkEditing = useMemo(\n () =>\n onDetach === undefined\n ? undefined\n : {\n detach: {\n onDetach: async (detached: readonly Readonly<Record<string, unknown>>[]) => {\n const left = await onDetach(detached);\n if (left.length > 0) {\n const gone = new Set(left);\n const current = selectionRef.current;\n if (current.ids.some((id) => gone.has(id)))\n current.set(current.ids.filter((id) => !gone.has(id)));\n }\n return left;\n },\n },\n },\n [onDetach],\n );\n const onAttach = linkEditing?.attach?.onAttach;\n const attachBusy = linkEditing?.attach?.busy === true;\n\n /**\n * `useExportRunWatcher()`/`useResourceExport()` (and everything\n * `<ExportButton>` needs) hard-require a native data runtime and throw\n * without one — the same stance `useAction` takes, and the reason\n * `<ExportButton>` gates itself on `useOptionalDataRuntime()` internally\n * (see that file). This page, though, is also mounted in \"compat mode\"\n * (`<BuroProvider>` with no `dataRuntime` — every assembly/slot test in\n * this package's suite does this), where NOTHING may call those hooks.\n * `useOptionalDataRuntime()` itself never throws, so checking it here —\n * once, as an ordinary unconditional hook call — decides whether the\n * watcher may be mounted at all, without ever conditionally calling a\n * HARD hook from inside one component's own body.\n */\n const hasDataRuntime = useOptionalDataRuntime() !== null;\n\n /** Task 9 — scope's own label, except the framework's local scope (reactive i18n swap). */\n const scopeLabel = (scope: { id: string; label: string }): string =>\n scope.id === LOCAL_USER_SCOPE_ID ? t('toolbar.viewsMyScope') : scope.label;\n\n // The empty-state \"+ Create\" is drawn by <ResourceList>, which takes an href\n // rather than a resource — so the gate is applied here, at the only place\n // that knows both.\n //\n // ⚠️ `disabled` collapses to hidden here, unlike the toolbar's\n // `<CreateButton>`, which draws it inert and explains itself. That is the\n // LINK rule from the spec, not an oversight: `<ResourceList>`'s contract for\n // this slot is an href, so the only thing it can render is a link, and a link\n // cannot carry a toast. The toolbar button above still says why.\n const createAvailable = useAvailability(resource, 'create').state === 'available';\n // A resource without a create page (`views.show.page: false`) creates in its `quick.create`\n // (spec 4.7); the empty state's link has nowhere to go and is not drawn.\n const quick = useQuick();\n const createPage = def === undefined || hasRecordPage(def, 'create');\n const openCreate = createPage ? undefined : () => void quick.create(resource);\n\n // What a row opens (spec 4.5): a placement opens `quick.show` unless told otherwise; the route\n // list opens the page, or `quick.show` when the resource has none. A quick row asks the entry\n // gate with the row: `open` opens the overlay (the first cell keeps the page anchor when there\n // is a page); undecided draws no link and takes no click; anything else falls back to the page\n // when there is one (`routing.rowHref` is `''` otherwise).\n const gate = useEntryGate();\n const openQuick = useQuickOpener();\n const effectiveOpen =\n open ??\n (route ? (def !== undefined && !hasRecordPage(def, 'show') ? 'quick' : 'page') : 'quick');\n // A row whose record is another resource's never opens its own row's quick entry.\n const quickRows = effectiveOpen === 'quick' && rowTarget === undefined;\n // The route list of a resource without a page reads `?<resource>.open=<id>` (spec 4.8).\n useDeepLinkOpen(resource, resource, route && quickRows);\n const rowQuick = useMemo(\n () =>\n quickRows\n ? (row: { readonly id: string } & Record<string, unknown>) =>\n gate(resource, 'show', row).state === 'open'\n ? () => void openQuick(resource, String(row.id), { row })\n : null\n : undefined,\n [quickRows, gate, openQuick, resource],\n );\n // A row whose record is another resource's (`rowTarget`) links to that record's show page when\n // it has one and the user may see it; the row's own resource is never linked then.\n const registry = useApp().registry;\n const targetName = rowTarget?.resource;\n const targetField = rowTarget?.field;\n const targetGate = useAvailabilityResolver(targetName ?? resource);\n const targetHref = useMemo(() => {\n if (targetName === undefined || targetField === undefined) return undefined;\n const targetDef = registry.get(targetName);\n const delegate = targetDef?.routesTo?.show;\n const showDef = delegate === undefined ? targetDef : registry.get(delegate as never);\n const showPage =\n targetDef !== undefined && showDef !== undefined && hasRecordPage(showDef, 'show');\n return (row: { readonly id: string } & Record<string, unknown>): string | undefined => {\n const key = row[targetField];\n if (!showPage || key === null || key === undefined || key === '') return undefined;\n // Asked without the row: the junction row is not the target's record. The target's page\n // enforces its own record-level rule when it opens.\n if (targetGate('show').state !== 'available') return undefined;\n return resourceShowHref(registry, targetDef, targetName, String(key));\n };\n }, [registry, targetName, targetField, targetGate]);\n const rowHref = useMemo(\n () =>\n effectiveOpen === 'none'\n ? undefined\n : targetHref !== undefined\n ? targetHref\n : quickRows\n ? (row: { readonly id: string } & Record<string, unknown>) =>\n gate(resource, 'show', row).state === 'undecided' ? undefined : routing.rowHref(row)\n : routing.rowHref,\n [effectiveOpen, targetHref, quickRows, gate, resource, routing.rowHref],\n );\n\n const tableView = effectiveView === 'table';\n const rowsViewFor = useMemo(\n () =>\n tableView\n ? undefined\n : (planned: ItemHandle | undefined) => ({\n skeleton:\n effectiveView === 'cards' ? <RelatedCardsSkeleton /> : <RelatedTimelineSkeleton />,\n render: (rows: readonly (typeof list.rows)[number][]) => {\n const common = {\n resource,\n placementKey: placementKey ?? resource,\n rows,\n // A placement's item is its own prop; the route list's is its frame's plan.\n item: route ? planned : item,\n // The route list draws the columns it would show as a table.\n columns: route ? columns.visible : columnNames,\n rowQuick,\n rowHref,\n ...(empty === undefined ? {} : { empty }),\n };\n return (\n <Suspense\n fallback={\n effectiveView === 'cards' ? (\n <RelatedCardsSkeleton />\n ) : (\n <RelatedTimelineSkeleton />\n )\n }\n >\n {effectiveView === 'cards' ? (\n <RelatedCards {...common} />\n ) : (\n <RelatedTimeline {...common} axis={timelineAxis} />\n )}\n </Suspense>\n );\n },\n }),\n [\n tableView,\n effectiveView,\n route,\n resource,\n placementKey,\n item,\n columns.visible,\n columnNames,\n rowQuick,\n rowHref,\n empty,\n timelineAxis,\n ],\n );\n\n // Render-time so the H1 flips live on a language switch (was reading the\n // frozen `def.label`, which is baked at app-construction time).\n const pageTitle = resolveResourceLabel(listCaps, resource, 'plural', def);\n\n /**\n * Saved-view dialogs (A4.1-A4.3, extended Task 9) are page-local UI so\n * the primitive stays presentational: the save-prompt is a single-input\n * shadcn Dialog (plus a scope picker when more than one write scope\n * exists), the manage dialog lists entries with per-row delete, and\n * separate rename/fork dialogs cover the dropdown's inline actions. The\n * controller supplies the entries themselves plus `apply` / `saveCurrent`\n * / `renameUser` / `deleteUser` / `forkView` — all mutations `await`ed\n * here; every dialog stays OPEN and surfaces a toast on a rejected/\n * conflict result, closing only on success (Task 9).\n */\n const [saveOpen, setSaveOpen] = useState(false);\n const [saveLabel, setSaveLabel] = useState('');\n const [saveScopeId, setSaveScopeId] = useState<string | undefined>(undefined);\n const [manageOpen, setManageOpen] = useState(false);\n const [renameOpen, setRenameOpen] = useState(false);\n const [renameTarget, setRenameTarget] = useState<SavedViewEntry | null>(null);\n const [renameLabel, setRenameLabel] = useState('');\n const [forkOpen, setForkOpen] = useState(false);\n const [forkTarget, setForkTarget] = useState<SavedViewEntry | null>(null);\n const [forkScopeId, setForkScopeId] = useState<string | undefined>(undefined);\n\n const canSaveCurrent = savedViews.writeScopes.length > 0;\n // Fork always needs somewhere writable to land (spec §5's \"copy into a\n // writable scope\"), regardless of any one entry's own `permissions.fork`\n // — mirrors `canSaveCurrent` so a fork-permitted entry with zero write\n // scopes never renders a clickable-but-inert affordance (fix: a bare\n // `entry.permissions.fork` gate let that happen).\n const canFork = savedViews.writeScopes.length > 0;\n\n const handleSaveCurrent = () => {\n setSaveLabel('');\n setSaveScopeId(savedViews.writeScopes[0]?.id);\n setSaveOpen(true);\n };\n\n const handleSaveConfirm = async () => {\n const label = saveLabel.trim();\n if (label.length === 0) return;\n try {\n // The controller snapshots the live URL state itself; it rejects on\n // a failed store mutation (Task 8 — the settings store backing\n // saved views is async), so the toast wiring stays here. A single\n // write scope saves directly (`scopeId` omitted, spec §5); more than\n // one requires the picker's explicit answer to \"for whom?\" (Task 9).\n await savedViews.saveCurrent(\n label,\n savedViews.writeScopes.length > 1 ? saveScopeId : undefined,\n );\n setSaveOpen(false);\n toast.success(t('toolbar.viewsSaved', { params: { label } }));\n } catch {\n // Dialog stays open — the user can retry or cancel.\n toast.error(t('toolbar.viewsSaveFailed'));\n }\n };\n\n const handleManage = () => {\n setManageOpen(true);\n };\n\n /**\n * Delete a user view (Task 8 — `savedViews.deleteUser` is async now).\n * Fired fire-and-forget from either the manage dialog's row button or the\n * dropdown's inline delete action; a failed mutation surfaces the same\n * generic error toast `handleSaveConfirm` uses rather than leaving an\n * unhandled rejection.\n */\n const handleDeleteUserView = (id: string) => {\n void savedViews.deleteUser(id).catch(() => {\n toast.error(t('toolbar.viewsDeleteFailed'));\n });\n };\n\n /** Opens the rename dialog for one entry (Task 9), prefilled with its current label. */\n const handleRenameEntry = (entry: SavedViewEntry) => {\n setRenameTarget(entry);\n setRenameLabel(entry.label);\n setRenameOpen(true);\n };\n\n const handleRenameConfirm = async () => {\n if (renameTarget === null) return;\n const label = renameLabel.trim();\n if (label.length === 0) return;\n try {\n await savedViews.renameUser(renameTarget.id, label);\n setRenameOpen(false);\n setRenameTarget(null);\n } catch {\n // Dialog stays open — the user can retry or cancel.\n toast.error(t('toolbar.viewsRenameFailed'));\n }\n };\n\n /**\n * Fork an entry (Task 9, spec §5). One write scope forks directly, no\n * prompt; more than one opens the SAME shape of \"for whom?\" question the\n * save flow uses. Zero write scopes should never reach here — the\n * dropdown gates Fork's visibility on `canFork` (`writeScopes.length >\n * 0`) in addition to `entry.permissions.fork`, so there is normally no\n * button to click. The `scopeId === undefined` branch below is\n * defense-in-depth only (a caller wiring the dropdown without `canFork`,\n * or a future regression re-introducing the old bare-permission gate)\n * — it surfaces a toast rather than silently doing nothing.\n */\n const handleForkEntry = (entry: SavedViewEntry) => {\n if (savedViews.writeScopes.length > 1) {\n setForkTarget(entry);\n setForkScopeId(savedViews.writeScopes[0]?.id);\n setForkOpen(true);\n return;\n }\n const scopeId = savedViews.writeScopes[0]?.id;\n if (scopeId === undefined) {\n toast.error(t('toolbar.viewsForkFailed'));\n return;\n }\n void savedViews.forkView(entry.id, scopeId).catch(() => {\n toast.error(t('toolbar.viewsForkFailed'));\n });\n };\n\n const handleForkConfirm = async () => {\n if (forkTarget === null || forkScopeId === undefined) return;\n try {\n await savedViews.forkView(forkTarget.id, forkScopeId);\n setForkOpen(false);\n setForkTarget(null);\n } catch {\n // Dialog stays open — the user can retry or cancel.\n toast.error(t('toolbar.viewsForkFailed'));\n }\n };\n\n // The cell ladder (route and placement alike): a typed resource's discriminator badge, the\n // app's own cell (prop or slot), then an enum badge; anything else is the field's display.\n /**\n * Whether a column names its display implementation at any layer: its resolved column\n * presentation (the list entry over the field's layers), else — while the controller has not\n * resolved it (`columns.ui` is `{}` while access is pending) — the field's own layers.\n */\n const columnNamesDisplay = (col: string, field: { readonly ui?: unknown } | undefined) => {\n const resolved = list.columns.ui[col];\n return resolved === undefined ? declaresDisplay(field) : resolved.display.use !== undefined;\n };\n\n const renderCellLadder: NonNullable<ResourceListProps['renderCell']> = (col, value, row) => {\n // A typed resource's discriminator column renders the value's label as a badge:\n // a value a type declares is `list-cell-type:<r>:<v>`, labelled from the\n // discriminator's enum namespace (its `meta.enumNamespace`) or, without one, from the\n // field's own option slot (`fields.<by>.options.<value>`), the field's option label as\n // the inline default either way; any other value (an undeclared type, an empty one)\n // is the unknown badge.\n if (def?.types && col === def.types.by) {\n const raw = typeof value === 'string' ? value : '';\n const declared = raw !== '' && def.types.items.some((item) => item.name === raw);\n if (!declared) {\n return (\n <Badge variant=\"outline\" data-testid={`list-cell-template-unknown:${resource}`}>\n {t('list.templateUnknown')}\n </Badge>\n );\n }\n const fieldDef = def.fields[col];\n const inline = discriminatorOptionLabel(fieldDef, raw);\n const namespace = enumNamespaceOf(fieldDef as never);\n const label =\n namespace === undefined\n ? resolveFieldOptionLabel(listCaps, col, raw, inline)\n : resolveEnumLabel(listCaps, namespace, raw, inline);\n return (\n <Badge variant=\"secondary\" data-testid={`list-cell-type:${resource}:${raw}`}>\n {label}\n </Badge>\n );\n }\n // The app's own cell, next: the explicit prop wins over a registered `list.cell.<resource>`\n // slot (level 1) — a host that mounted this page and passed its own `renderCell` knows more\n // than the registry does. Either one declared for a column is the adopter's word on it, so it\n // is asked BEFORE the enum badge below; returning `undefined` passes the column on.\n const custom = (renderCell ?? CellSlot)?.(col, value, row);\n if (custom !== undefined) return custom;\n // Enum-aware rendering: any field declaring `enum: '<name>'` in its opts gets the framework's\n // <EnumBadge> with the registered color/label (plain text when the enum is missing from the\n // registry — the badge's own fail-soft policy). A field that declares its own display\n // (`ui.display`), or whose column entry does (`{ field, display }`, REF-117 §4.9), is not an\n // enum badge: `undefined` hands it to `<ResourceList>`'s field display, which resolves that\n // display.\n const fieldDef = def?.fields[col] as\n | { opts?: { enum?: unknown }; ui?: { enum?: unknown; display?: unknown } }\n | undefined;\n // The binding as a key: a lowered entity ref keeps its namespace (`audit:severity`).\n const enumName = enumBindingKey(fieldDef?.opts?.enum ?? fieldDef?.ui?.enum);\n if (enumName && typeof value === 'string' && !columnNamesDisplay(col, fieldDef)) {\n return <EnumBadge enumName={enumName} value={value} />;\n }\n return undefined;\n };\n\n const surface: ListSurfaceValue = {\n resource,\n route,\n tableView,\n searchDecl,\n FiltersSlot,\n savedViewsUi: {\n canSaveCurrent,\n canFork,\n onSaveCurrent: handleSaveCurrent,\n onManage: handleManage,\n onRenameEntry: handleRenameEntry,\n onForkEntry: handleForkEntry,\n onDeleteEntry: (entry) => handleDeleteUserView(entry.id),\n },\n openCreate,\n createAvailable,\n createPage,\n rowProps: {\n rowHref,\n ...(rowQuick === undefined ? {} : { rowQuick, rowLinkKey: gate }),\n },\n rowsViewFor,\n // A placement's own `empty` replaces the panel, unless the user's filter or an out-of-range\n // page is why there are no rows (the panel then says so and offers the way back), or a cursor\n // list has a next page: an empty page there is not an empty list, and the panel keeps its\n // \"Load more\" (a supplied `emptyState` skips both).\n emptyState:\n empty !== undefined &&\n !list.filters.isFiltered &&\n list.pagination.page <= 1 &&\n (list.cursor === null || list.cursor.next === null) ? (\n <p data-buro-region=\"empty\" className=\"text-sm text-muted-foreground\">\n {empty}\n </p>\n ) : (\n emptyState\n ),\n renderCell: renderCellLadder,\n readOnly: readOnly === true,\n exportable: exportable !== false,\n ...(layoutId === undefined ? {} : { layoutId }),\n ...(surfaceLinkEditing === undefined ? {} : { linkEditing: surfaceLinkEditing }),\n };\n\n return (\n <ResourceListProvider value={list}>\n <ListPiecesProvider value={surface}>\n <div className=\"space-y-4\">\n {route ? (\n <PageHeader resource={resource} mode=\"list\" title={pageTitle} />\n ) : title === undefined && onCreate === undefined && onAttach === undefined ? null : (\n <div className=\"flex items-center justify-between gap-2\">\n {title === undefined ? <span /> : <h3 className=\"text-sm font-semibold\">{title}</h3>}\n {onAttach === undefined ? null : (\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n data-testid={`list-link-attach:${resource}`}\n onClick={onAttach}\n disabled={attachBusy}\n aria-busy={attachBusy}\n >\n {attachBusy ? (\n <IconLoader2 className=\"mr-1 h-4 w-4 animate-spin\" aria-hidden=\"true\" />\n ) : (\n <IconLink className=\"mr-1 h-4 w-4\" aria-hidden=\"true\" />\n )}\n {optionalT('field.link.attach', { defaultValue: 'Attach' })}\n </Button>\n )}\n {onCreate === undefined ? null : (\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n data-testid={`list-create:${resource}`}\n onClick={onCreate}\n >\n <IconPlus className=\"mr-1 h-4 w-4\" aria-hidden=\"true\" />\n {optionalT('actions.create', { resource, defaultValue: 'Create' })}\n </Button>\n )}\n </div>\n )}\n {hasDataRuntime && <ExportRunWatcherMount />}\n\n {droppedPredicates > 0 && (\n // Predicates on fields the user may not view were left out (P5 spec 3.7): no field\n // name, no value.\n <p\n role=\"status\"\n className=\"text-[13px] leading-snug text-muted-foreground\"\n data-testid={tid.listPredicatesDropped(resource)}\n >\n {t('list.predicatesDropped')}\n </p>\n )}\n {route ? (\n <ListFrameHost resource={resource} />\n ) : (\n <>\n <ListControls />\n <ListBody />\n </>\n )}\n {route && (\n <>\n {/* Save-current-view prompt dialog. When more than one write scope\n is available, an inline scope picker asks \"for whom?\" (Task 9,\n spec §5) — a single scope saves directly, no prompt. */}\n <Dialog open={saveOpen} onOpenChange={setSaveOpen}>\n <DialogContent\n data-testid={`list-saved-view-save-dialog:${resource}`}\n className=\"max-w-sm\"\n >\n <DialogHeader>\n <DialogTitle>{t('toolbar.viewsSaveTitle')}</DialogTitle>\n <DialogDescription>{t('toolbar.viewsSaveDescription')}</DialogDescription>\n </DialogHeader>\n <Input\n autoFocus\n value={saveLabel}\n onChange={(e) => setSaveLabel(e.target.value)}\n placeholder={t('toolbar.viewsSavePlaceholder')}\n data-testid={`list-saved-view-save-input:${resource}`}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && saveLabel.trim().length > 0) {\n handleSaveConfirm();\n }\n }}\n />\n {savedViews.writeScopes.length > 1 && (\n <div\n className=\"space-y-1\"\n data-testid={`list-saved-view-scope-picker:${resource}`}\n >\n <div className=\"text-xs font-medium text-muted-foreground\">\n {t('toolbar.viewsScopeDialogTitle')}\n </div>\n {savedViews.writeScopes.map((scope) => (\n <button\n key={scope.id}\n type=\"button\"\n onClick={() => setSaveScopeId(scope.id)}\n aria-pressed={saveScopeId === scope.id}\n data-testid={`list-saved-view-scope-option:${resource}:${scope.id}`}\n className={cn(\n 'w-full rounded-sm border px-2 py-1.5 text-left text-sm',\n saveScopeId === scope.id\n ? 'border-primary bg-accent text-accent-foreground'\n : 'border-input hover:bg-accent hover:text-accent-foreground',\n )}\n >\n {scopeLabel(scope)}\n </button>\n ))}\n </div>\n )}\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => setSaveOpen(false)}\n data-testid={`list-saved-view-save-cancel:${resource}`}\n >\n {chromeT('actions.cancel')}\n </Button>\n <Button\n type=\"button\"\n onClick={handleSaveConfirm}\n disabled={saveLabel.trim().length === 0}\n data-testid={`list-saved-view-save-confirm:${resource}`}\n >\n {chromeT('actions.save')}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n {/* Manage-views dialog: list entries (Task 9 — scope badge per row)\n with a delete button gated on `entry.permissions.remove`. */}\n <Dialog open={manageOpen} onOpenChange={setManageOpen}>\n <DialogContent\n data-testid={`list-saved-view-manage-dialog:${resource}`}\n className=\"max-w-md\"\n >\n <DialogHeader>\n <DialogTitle>{t('toolbar.viewsManageTitle')}</DialogTitle>\n <DialogDescription>{t('toolbar.viewsManageDescription')}</DialogDescription>\n </DialogHeader>\n {savedViews.entries.length === 0 ? (\n <p className=\"text-sm text-muted-foreground\">{t('toolbar.viewsManageEmpty')}</p>\n ) : (\n <ul className=\"space-y-1\">\n {savedViews.entries.map((entry) => (\n <li\n key={entry.id}\n className=\"flex items-center justify-between gap-2 rounded-sm px-2 py-1.5 hover:bg-accent hover:text-accent-foreground\"\n data-testid={`list-saved-view-manage-row:${resource}:${entry.id}`}\n >\n <span className=\"flex min-w-0 items-center gap-2 text-sm\">\n <span className=\"truncate\">{entry.label}</span>\n <Badge variant=\"outline\" className=\"shrink-0\">\n {scopeLabel(entry.scope)}\n </Badge>\n </span>\n {entry.permissions.remove ? (\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n onClick={() => handleDeleteUserView(entry.id)}\n data-testid={`list-saved-view-manage-delete:${resource}:${entry.id}`}\n >\n {chromeT('actions.delete')}\n </Button>\n ) : (\n <span className=\"shrink-0 text-xs text-muted-foreground\">\n {t('toolbar.viewsReadOnly')}\n </span>\n )}\n </li>\n ))}\n </ul>\n )}\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => setManageOpen(false)}\n data-testid={`list-saved-view-manage-close:${resource}`}\n >\n {chromeT('actions.close')}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n {/* Rename dialog (Task 9) — opened from the dropdown's inline\n Rename action; prefilled with the entry's current label. */}\n <Dialog\n open={renameOpen}\n onOpenChange={(next) => {\n setRenameOpen(next);\n if (!next) setRenameTarget(null);\n }}\n >\n <DialogContent\n data-testid={`list-saved-view-rename-dialog:${resource}`}\n className=\"max-w-sm\"\n >\n <DialogHeader>\n <DialogTitle>{t('toolbar.viewsRenameTitle')}</DialogTitle>\n <DialogDescription>{t('toolbar.viewsRenameDescription')}</DialogDescription>\n </DialogHeader>\n <Input\n autoFocus\n value={renameLabel}\n onChange={(e) => setRenameLabel(e.target.value)}\n data-testid={`list-saved-view-rename-input:${resource}`}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && renameLabel.trim().length > 0) {\n handleRenameConfirm();\n }\n }}\n />\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => {\n setRenameOpen(false);\n setRenameTarget(null);\n }}\n data-testid={`list-saved-view-rename-cancel:${resource}`}\n >\n {chromeT('actions.cancel')}\n </Button>\n <Button\n type=\"button\"\n onClick={handleRenameConfirm}\n disabled={renameLabel.trim().length === 0}\n data-testid={`list-saved-view-rename-confirm:${resource}`}\n >\n {chromeT('actions.save')}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n {/* Fork \"for whom?\" dialog (Task 9, spec §5) — only reached when\n more than one write scope exists; a single scope forks directly\n with no prompt (see `handleForkEntry`). */}\n <Dialog\n open={forkOpen}\n onOpenChange={(next) => {\n setForkOpen(next);\n if (!next) setForkTarget(null);\n }}\n >\n <DialogContent\n data-testid={`list-saved-view-fork-dialog:${resource}`}\n className=\"max-w-sm\"\n >\n <DialogHeader>\n <DialogTitle>{t('toolbar.viewsScopeDialogTitle')}</DialogTitle>\n <DialogDescription>\n {t('toolbar.viewsScopeDialogDescription')}\n </DialogDescription>\n </DialogHeader>\n <div className=\"space-y-1\">\n {savedViews.writeScopes.map((scope) => (\n <button\n key={scope.id}\n type=\"button\"\n onClick={() => setForkScopeId(scope.id)}\n aria-pressed={forkScopeId === scope.id}\n data-testid={`list-saved-view-fork-scope-option:${resource}:${scope.id}`}\n className={cn(\n 'w-full rounded-sm border px-2 py-1.5 text-left text-sm',\n forkScopeId === scope.id\n ? 'border-primary bg-accent text-accent-foreground'\n : 'border-input hover:bg-accent hover:text-accent-foreground',\n )}\n >\n {scopeLabel(scope)}\n </button>\n ))}\n </div>\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => {\n setForkOpen(false);\n setForkTarget(null);\n }}\n data-testid={`list-saved-view-fork-cancel:${resource}`}\n >\n {chromeT('actions.cancel')}\n </Button>\n <Button\n type=\"button\"\n onClick={handleForkConfirm}\n disabled={forkScopeId === undefined}\n data-testid={`list-saved-view-fork-confirm:${resource}`}\n >\n {t('toolbar.viewsFork')}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n </>\n )}\n <ListBulkBar />\n </div>\n </ListPiecesProvider>\n </ResourceListProvider>\n );\n}\n\n/**\n * Renders nothing — exists solely so `useExportRunWatcher()` (a HARD hook;\n * see `run-watcher.ts`) is only ever called from a component that is itself\n * only mounted once `<ResourceListSurface>` has already confirmed (via\n * `useOptionalDataRuntime()`, which never throws) that a native data\n * runtime exists. This is what lets `<ResourceListPage>` mount the watcher\n * unconditionally on that ONE checked condition without ever conditionally\n * calling a hook from inside a single component's own body — this\n * component's own hook call sequence never varies across its lifetime,\n * because it only ever exists under a confirmed runtime.\n */\nfunction ExportRunWatcherMount(): null {\n useExportRunWatcher();\n return null;\n}\n","'use client';\n\nimport {\n type FixedFilterInput,\n type RecordScopeFrame,\n type RelationCandidate,\n type ResourceHandle,\n type ResourceRefInput,\n resourceKey,\n type ScopeSource,\n type EntityRef,\n type ResourceHandleOf,\n type ResourceRefArg,\n} from '@burojs/core';\nimport {\n type QuickSettledRow,\n RecordScopeChain,\n useApp,\n useDataRuntime,\n useOptionalRecordFrame,\n useRecordScopeFrames,\n} from '@burojs/react';\nimport * as React from 'react';\nimport { useCandidateSelection } from './candidates-gate.js';\nimport { LazyRelationPickerDialog } from './lazy-relation-picker-dialog.js';\nimport type { SelectCreate } from './relation-create.js';\nimport { useRelationSelect } from './relation-select.js';\n\n// biome-ignore lint/suspicious/noExplicitAny: any resource handle\ntype AnyResourceHandle = ResourceHandle<any, any, any, any>;\n\ntype FieldNamesOf<R> =\n // biome-ignore lint/suspicious/noExplicitAny: matches any record, name and id field\n R extends ResourceHandle<any, infer F, any, any>\n ? keyof F & string\n : R extends string\n ? FieldNamesOf<ResourceHandleOf<R>>\n : string;\n\nexport type UseRelationPickerOptions<\n R extends AnyResourceHandle | string | EntityRef,\n TSelect extends FieldNamesOf<R>,\n> =\n /**\n * The target: its handle, its name (checked against the registered resources, and typing\n * `select` by the registered fields) or its entity ref.\n */\n (\n | { readonly to: ResourceRefArg<R>; readonly field?: never }\n /** A relation field of the surrounding record (`useOptionalRecordFrame()`): `to`, `by` and `candidates` come from its declaration. */\n | { readonly field: string; readonly to?: never }\n ) & {\n readonly multiple?: boolean;\n /** The row fields the promise hands back (plus the key), projected as of selection. Absent: the row as read. */\n readonly select?: readonly TSelect[];\n /** Declared-candidates grammar; refs resolve against the surrounding record's sources (`controller.sources`), literals only outside one. */\n readonly candidates?: readonly RelationCandidate[];\n readonly fixedFilters?: readonly FixedFilterInput[];\n /** The target field the keys hold; default: the field's `by`, else the target's id field. */\n readonly valueField?: string;\n /** Offers \"+ Create\" (the target's quick create) seeded with `seeds`; a created record settles as selected. */\n readonly create?: { readonly seeds?: Readonly<Record<string, unknown>> };\n /** Default 'context'. */\n readonly scope?: ScopeSource;\n /** Rows of each shown page whose key is in the resolved set are drawn checked and disabled. */\n readonly disabledKeys?: (\n keys: readonly (string | number)[],\n signal: AbortSignal,\n ) => Promise<ReadonlySet<string>>;\n /** With `disabledKeys`: the dialog footer's note for a page's disabled rows, given their count. */\n readonly disabledLabel?: (count: number) => React.ReactNode;\n };\n\nexport type RelationPickerRow<TSelect extends string> = { readonly [K in TSelect]?: unknown } & {\n readonly id?: unknown;\n};\n\nexport type RelationPickerCancelReason =\n | 'dismissed'\n | 'aborted'\n | 'superseded'\n | 'unmounted'\n | 'session-changed'\n | 'not-mounted'\n | 'unavailable';\n\n/**\n * How an `open()` settled. `selected.rows` are the rows chosen during this open, each projected\n * to `select` plus `id` and the value field (`valueField`, else the field's `by`, else the id\n * field), so a row can be joined to its key. No row is re-read: a key passed in through\n * `open({ selected })` and left unchanged comes back in `keys` without a row, and so does a\n * created record whose quick create handed back no row.\n */\nexport type RelationPickerResult<TRow> =\n | {\n readonly kind: 'selected';\n readonly keys: readonly (string | number)[];\n readonly rows: readonly TRow[];\n }\n | { readonly kind: 'cancelled'; readonly reason: RelationPickerCancelReason };\n\nexport interface RelationPickerOpenOptions {\n readonly signal?: AbortSignal;\n /**\n * Multiple mode: the keys already chosen. Those left unchanged are returned in `keys` but have\n * no row in `rows` (they are not re-read).\n */\n readonly selected?: readonly (string | number)[];\n}\n\nexport interface RelationPickerHandle<TRow> {\n open(opts?: RelationPickerOpenOptions): Promise<RelationPickerResult<TRow>>;\n /** Render it once, anywhere in the caller's tree. Always an element; it draws nothing while closed. */\n readonly element: React.ReactElement;\n}\n\ntype Row = Record<string, unknown>;\ntype Key = string | number;\n\n/** The open picker: what `element` draws. */\ninterface Active {\n readonly id: number;\n readonly frames: readonly RecordScopeFrame[];\n readonly selected: readonly Key[];\n}\n\n/** The open promise: settled exactly once. */\ninterface Pending {\n readonly id: number;\n readonly sessionKey: string;\n readonly scopeKey: string;\n readonly resolve: (result: RelationPickerResult<Row>) => void;\n readonly detach: () => void;\n}\n\nconst noop = (): void => undefined;\n\nfunction safeKey(input: unknown): string | undefined {\n if (input === undefined || input === null) return undefined;\n try {\n return resourceKey(input as ResourceRefInput);\n } catch {\n return undefined;\n }\n}\n\n/**\n * What an open picker's list belongs to: the session, its partition and, with `defineScope`, the\n * selection (a selection change re-keys the list without changing the partition).\n */\nfunction sessionIdentity(runtime: ReturnType<typeof useDataRuntime>): {\n readonly sessionKey: string;\n readonly scopeKey: string;\n} {\n const state = runtime.dataSession.getState();\n const snapshot = state.status === 'ready' ? state.snapshot : state.target;\n const selection = snapshot.scope?.selection;\n const partition = selection === undefined ? snapshot.scopeKey : [snapshot.scopeKey, selection];\n let scopeKey: string;\n try {\n scopeKey = JSON.stringify(partition) ?? '';\n } catch {\n scopeKey = String(snapshot.scopeKey);\n }\n return { sessionKey: snapshot.sessionKey, scopeKey };\n}\n\n/** Registers `element` as mounted while it is rendered. */\nfunction PickerHost(props: {\n readonly register: () => () => void;\n readonly children: React.ReactNode;\n}): React.ReactElement {\n const { register } = props;\n React.useEffect(() => register(), [register]);\n return <>{props.children}</>;\n}\n\n/**\n * A relation picker as a promise: `open()` shows the target's \"Advanced search\" dialog and settles\n * with the chosen keys and rows, or with why nothing was chosen. It never rejects.\n *\n * const picker = useRelationPicker({ to: merchants, select: ['name'] });\n * …\n * const result = await picker.open();\n * if (result.kind === 'selected') setMerchant(result.keys[0]);\n * …\n * return <>{…}{picker.element}</>;\n *\n * `open()` snapshots the record scope around the caller and the data session: the list reads with\n * the scope as it was at the call, and a session or scope change while open cancels. Candidate\n * filters, by contrast, resolve live: when they stop resolving while open (a ref they read is\n * cleared), the picker closes and settles `unavailable` rather than list rows without them. Render\n * `element` once, anywhere in the caller's tree; an `open()` while it is not rendered settles\n * `not-mounted`.\n */\nexport function useRelationPicker<\n R extends AnyResourceHandle | string | EntityRef,\n TSelect extends FieldNamesOf<R> = FieldNamesOf<R>,\n>(options: UseRelationPickerOptions<R, TSelect>): RelationPickerHandle<RelationPickerRow<TSelect>> {\n const app = useApp();\n const runtime = useDataRuntime();\n const frame = useOptionalRecordFrame();\n const frames = useRecordScopeFrames();\n const multiple = options.multiple === true;\n\n // The target, `by` and candidates: from the record field's declaration, or from the options.\n const fieldName = options.field;\n let to: string | undefined;\n let declaredBy: string | undefined;\n let declaredCandidates: readonly RelationCandidate[] | undefined;\n if (fieldName !== undefined) {\n const owner =\n frame === null\n ? undefined\n : (app.registry.get(frame.resource)?.fields as Record<string, unknown> | undefined);\n const meta = (owner?.[fieldName] as { readonly meta?: Record<string, unknown> } | undefined)\n ?.meta;\n to = safeKey(meta?.to);\n declaredBy = typeof meta?.by === 'string' ? meta.by : undefined;\n declaredCandidates = Array.isArray(meta?.candidates)\n ? (meta.candidates as readonly RelationCandidate[])\n : undefined;\n } else {\n to = safeKey(options.to);\n }\n const target = to ?? '';\n const by = options.valueField ?? declaredBy;\n const scope = options.scope ?? 'context';\n\n const selection = useCandidateSelection({\n to,\n candidates: options.candidates ?? declaredCandidates,\n sources: frame?.controller.sources,\n resource: frame?.resource ?? '',\n fieldName: fieldName ?? target,\n fixedFilters: options.fixedFilters,\n });\n const held = selection.gate !== undefined;\n\n const pendingRef = React.useRef<Pending | null>(null);\n const [active, setActive] = React.useState<Active | null>(null);\n const activeRef = React.useRef<Active | null>(null);\n activeRef.current = active;\n // Multiple mode: the rows of the keys chosen during this open, by key.\n const rowsRef = React.useRef(new Map<string, Row>());\n // The row the last create handed back, remembered from its quick create.\n const createdRowRef = React.useRef<Row | undefined>(undefined);\n const alive = React.useRef(true);\n const mounts = React.useRef(0);\n const sequence = React.useRef(0);\n // What the callbacks read at call time; refreshed every render, below.\n const latest = React.useRef({\n multiple,\n select: options.select as readonly string[] | undefined,\n idField: 'id',\n valueField: 'id',\n available: false,\n frames,\n });\n\n const project = React.useCallback((row: Row): Row => {\n const select = latest.current.select;\n if (select === undefined) return { ...row };\n const out: Row = {};\n // The target's id field keys the row; a genuine `id` of a target keyed by another column never.\n const key = row[latest.current.idField] !== undefined ? row[latest.current.idField] : row.id;\n if (key !== undefined) out.id = key;\n // The value field always comes back, so a row can be joined to its key.\n const { valueField } = latest.current;\n if (Object.hasOwn(row, valueField)) out[valueField] = row[valueField];\n for (const name of select) if (Object.hasOwn(row, name)) out[name] = row[name];\n return out;\n }, []);\n\n const settle = React.useCallback((result: RelationPickerResult<Row>) => {\n const pending = pendingRef.current;\n if (pending === null) return;\n pendingRef.current = null;\n pending.detach();\n if (alive.current) setActive(null);\n pending.resolve(result);\n }, []);\n\n const toggle = React.useCallback((key: Key, row: Row | undefined) => {\n setActive((current) => {\n if (current === null) return current;\n const has = current.selected.some((k) => String(k) === String(key));\n if (has) rowsRef.current.delete(String(key));\n else if (row !== undefined) rowsRef.current.set(String(key), row);\n const selected = has\n ? current.selected.filter((k) => String(k) !== String(key))\n : [...current.selected, key];\n const next = { ...current, selected };\n activeRef.current = next;\n return next;\n });\n }, []);\n\n const onValue = React.useCallback(\n (value: Key) => {\n const row = createdRowRef.current;\n createdRowRef.current = undefined;\n if (latest.current.multiple) {\n const current = activeRef.current;\n if (current !== null && !current.selected.some((k) => String(k) === String(value)))\n toggle(value, row);\n return;\n }\n settle({\n kind: 'selected',\n keys: [value],\n rows: row === undefined ? [] : [project(row)],\n });\n },\n [project, settle, toggle],\n );\n\n const wiring = useRelationSelect({\n to: target,\n by,\n fixedFilters: selection.fixedFilters,\n scope,\n ...(fieldName === undefined ? {} : { scopeField: fieldName }),\n held,\n onValue,\n });\n\n latest.current = {\n multiple,\n select: options.select as readonly string[] | undefined,\n idField: wiring.idField,\n valueField: wiring.valueField,\n available: to !== undefined && wiring.targetDef !== undefined && !held,\n frames,\n };\n\n // A created record's row is remembered from its quick create, so it settles with its row.\n const { create: shared } = wiring;\n const create = React.useMemo<SelectCreate>(\n () => ({\n ...shared,\n start: (openCreate) =>\n shared.start(() => {\n const opened = openCreate();\n void opened.then((row: QuickSettledRow) => {\n createdRowRef.current = row === null ? undefined : { ...row };\n }, noop);\n return opened;\n }),\n }),\n [shared],\n );\n\n // A session or scope change while open cancels: the list would no longer be the one opened.\n React.useEffect(\n () =>\n runtime.dataSession.subscribe(() => {\n const pending = pendingRef.current;\n if (pending === null) return;\n const now = sessionIdentity(runtime);\n if (now.sessionKey !== pending.sessionKey || now.scopeKey !== pending.scopeKey)\n settle({ kind: 'cancelled', reason: 'session-changed' });\n }),\n [runtime, settle],\n );\n\n React.useEffect(() => {\n alive.current = true;\n return () => {\n alive.current = false;\n settle({ kind: 'cancelled', reason: 'unmounted' });\n };\n }, [settle]);\n\n // The candidates stopped resolving while open: settle rather than keep a list without them.\n React.useEffect(() => {\n if (held) settle({ kind: 'cancelled', reason: 'unavailable' });\n }, [held, settle]);\n\n const register = React.useCallback(() => {\n mounts.current += 1;\n return () => {\n mounts.current -= 1;\n if (mounts.current === 0) settle({ kind: 'cancelled', reason: 'unmounted' });\n };\n }, [settle]);\n\n const open = React.useCallback(\n (opts: RelationPickerOpenOptions = {}): Promise<RelationPickerResult<Row>> =>\n new Promise((resolve) => {\n settle({ kind: 'cancelled', reason: 'superseded' });\n if (mounts.current === 0) {\n if (process.env.NODE_ENV !== 'production') {\n // eslint-disable-next-line no-console\n console.error(\n '[burojs] useRelationPicker: open() was called but its element is not rendered — render `handle.element` once in your tree.',\n );\n }\n resolve({ kind: 'cancelled', reason: 'not-mounted' });\n return;\n }\n const { signal } = opts;\n if (signal?.aborted === true) {\n resolve({ kind: 'cancelled', reason: 'aborted' });\n return;\n }\n if (!latest.current.available) {\n resolve({ kind: 'cancelled', reason: 'unavailable' });\n return;\n }\n sequence.current += 1;\n const id = sequence.current;\n const onAbort = () => {\n if (pendingRef.current?.id === id) settle({ kind: 'cancelled', reason: 'aborted' });\n };\n signal?.addEventListener('abort', onAbort, { once: true });\n pendingRef.current = {\n id,\n ...sessionIdentity(runtime),\n resolve,\n detach: () => signal?.removeEventListener('abort', onAbort),\n };\n rowsRef.current = new Map();\n createdRowRef.current = undefined;\n const next: Active = { id, frames: latest.current.frames, selected: opts.selected ?? [] };\n activeRef.current = next;\n setActive(next);\n }),\n [runtime, settle],\n );\n\n const onSelectRow = React.useCallback(\n (row: Row) => {\n const field = wiring.valueField;\n const value = field === 'id' ? row.id : row[field];\n if (typeof value !== 'string' && typeof value !== 'number') return;\n settle({ kind: 'selected', keys: [value], rows: [project(row)] });\n },\n [wiring.valueField, settle, project],\n );\n\n const onDone = React.useCallback(() => {\n const keys = activeRef.current?.selected ?? [];\n const rows = keys.flatMap((key) => {\n const row = rowsRef.current.get(String(key));\n return row === undefined ? [] : [project(row)];\n });\n settle({ kind: 'selected', keys, rows });\n }, [settle, project]);\n\n const onOpenChange = React.useCallback(\n (next: boolean) => {\n if (!next) settle({ kind: 'cancelled', reason: 'dismissed' });\n },\n [settle],\n );\n\n const element = (\n <PickerHost register={register}>\n {/* No dialog while the candidates are not ready: it would list rows without their filters. */}\n {active === null || held ? null : (\n <RecordScopeChain key={active.id} frames={active.frames}>\n <LazyRelationPickerDialog\n to={target}\n open\n onOpenChange={onOpenChange}\n onSelect={noop}\n onSelectRow={onSelectRow}\n valueField={wiring.valueField}\n {...(selection.fixedFilters === undefined\n ? {}\n : { fixedFilters: selection.fixedFilters })}\n scope={scope}\n {...(fieldName === undefined ? {} : { scopeField: fieldName })}\n {...(options.create === undefined\n ? {}\n : {\n create,\n ...(options.create.seeds === undefined\n ? {}\n : { createSeeds: options.create.seeds }),\n })}\n fieldName={fieldName ?? target}\n {...(options.disabledKeys === undefined ? {} : { disabledKeys: options.disabledKeys })}\n {...(options.disabledLabel === undefined\n ? {}\n : { disabledLabel: options.disabledLabel })}\n {...(multiple\n ? {\n multiple: true,\n selected: active.selected,\n onToggle: (value: Key, row: Row) => toggle(value, row),\n onDone,\n }\n : {})}\n />\n {wiring.reader}\n </RecordScopeChain>\n )}\n </PickerHost>\n );\n\n return { open, element } as unknown as RelationPickerHandle<RelationPickerRow<TSelect>>;\n}\n","'use client';\nimport {\n type LinkWriteReport,\n resolveErrorText,\n useChromeT,\n useI18nCaps,\n useOptionalT,\n} from '@burojs/react';\nimport type { ReactElement } from 'react';\nimport { Button } from '../primitives/button.js';\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from '../primitives/dialog.js';\n\n/**\n * What an Attach or Detach that did not write every link reports: each failed link by its title\n * (`titles`, by the report's id; the id itself when it has none) with the text its error resolves to.\n * `testid` names the dialog; each failed link is `<testid>:item:<id>`.\n */\nexport function LinkWriteSummary(props: {\n readonly report: LinkWriteReport;\n readonly titles: Readonly<Record<string, string>>;\n readonly onClose: () => void;\n readonly testid?: string;\n}): ReactElement {\n const { report, titles, onClose } = props;\n const testid = props.testid ?? 'link-write-summary';\n const t = useOptionalT();\n const caps = useI18nCaps();\n const chromeT = useChromeT();\n const heading = t('field.link.partial', { defaultValue: 'Some links were not changed' });\n return (\n <Dialog\n open\n onOpenChange={(open) => {\n if (!open) onClose();\n }}\n >\n <DialogContent data-testid={testid} className=\"flex max-h-[85vh] flex-col overflow-hidden\">\n <DialogHeader>\n <DialogTitle>{heading}</DialogTitle>\n <DialogDescription className=\"sr-only\">{heading}</DialogDescription>\n </DialogHeader>\n <ul className=\"flex min-h-0 flex-1 flex-col gap-2 overflow-y-auto overscroll-contain\">\n {report.failed.map(({ id, error }) => (\n <li key={id} data-testid={`${testid}:item:${id}`} className=\"text-sm\">\n <span className=\"font-medium\">{titles[id] ?? id}</span>\n <span className=\"text-destructive\">{`: ${resolveErrorText(error, caps)}`}</span>\n </li>\n ))}\n </ul>\n <DialogFooter>\n <Button type=\"button\" onClick={onClose} data-testid={`${testid}:close`}>\n {chromeT('actions.close', { defaultValue: 'Close' })}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}\n","'use client';\nimport {\n type FixedFilterInput,\n type LinkActions,\n type ScopeSource,\n type ValidationIssues,\n reverseLinkOf,\n} from '@burojs/core';\nimport {\n type CheckGateState,\n type LinkWriteReport,\n linkCapabilitiesOf,\n useApp,\n useDataRuntime,\n useLinkRights,\n useLinkWriter,\n useLinkedKeys,\n useOptionalT,\n} from '@burojs/react';\nimport { type ReactElement, useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { CheckConfirmDialog } from '../checks/check-confirm-dialog.js';\nimport { useRelationPicker } from '../fields/use-relation-picker.js';\nimport type { ResourceListSurfaceProps } from '../list-kit/resource-list-surface.js';\nimport { toast } from '../notification/toaster.js';\nimport { LinkWriteSummary } from './link-write-summary.js';\n\ntype Rec = Readonly<Record<string, unknown>>;\n\nconst NO_ISSUES: ValidationIssues = Object.freeze([]);\n\n/** What a link panel's writes need to know of its link. */\nexport interface LinkPanelWritesOptions {\n /** The owner's and the junction's and the target's canonical names. */\n readonly owner: string;\n readonly junction: string;\n readonly target: string;\n /** The link field of the owner. */\n readonly link: string;\n readonly targetKey: string;\n /** The target field the junction's targetKey holds (its relation's `by`, else the target's id). */\n readonly valueField: string;\n /** The junction's id field: a row's id in the panel and in a Detach report. */\n readonly junctionIdField: string;\n /** The target's display field: a link's title. */\n readonly displayField: string;\n /** The link field's declared picker read scope, else `'context'`. */\n readonly scope: ScopeSource;\n /** The owner record, holding the owner key. */\n readonly record: Rec;\n /** The value the junction's sourceKey holds for this owner. */\n readonly ownerKey: unknown;\n /** The placement's `linkActions`. */\n readonly placement: LinkActions | undefined;\n}\n\ninterface PendingDetach {\n readonly rows: readonly Rec[];\n /** Resolves with the row keys of the rows that left. */\n readonly resolve: (left: readonly string[]) => void;\n}\n\n/**\n * A link panel's Attach and Detach, drawn where the link rights allow them (the panel surface,\n * the owner field's edit right, the junction's operations and rules, the placement's\n * `linkActions`; never the owner's own `edit` operation).\n *\n * Attach opens the target's picker (multi-select, in the link field's declared scope). Targets\n * the record already links under this link are hidden by the reverse link's `hasNone` when the\n * target declares one and its provider reads links and can express it; otherwise the picker\n * asks the junction which of each page's targets are linked and draws them checked and disabled.\n * Detach confirms, then removes the junction rows (a row whose target is gone or hidden is\n * removed by its junction row all the same). A write that wrote every link toasts; otherwise a\n * summary lists the failed links by title with their messages. The panel re-reads through the\n * write's own invalidation.\n */\nexport function useLinkPanelWrites(options: LinkPanelWritesOptions): {\n readonly linkEditing: ResourceListSurfaceProps['linkEditing'];\n readonly element: ReactElement;\n} {\n const {\n owner,\n junction,\n target,\n link,\n targetKey,\n valueField,\n junctionIdField,\n displayField,\n scope,\n record,\n ownerKey,\n placement,\n } = options;\n const app = useApp();\n const runtime = useDataRuntime();\n const t = useOptionalT();\n const rights = useLinkRights(owner, link, {\n surface: 'panel',\n record,\n ...(placement === undefined ? {} : { placement }),\n });\n const writer = useLinkWriter(owner, link);\n const linkedKeys = useLinkedKeys(owner, link);\n\n // Already-linked targets are hidden when the target reads the link back and its provider can\n // filter on it by `hasNone`. The capability record is read at render, it is not reactive, so the\n // decision is frozen while the picker is open: an open picker never switches its mode.\n const reverse = useMemo(\n () =>\n reverseLinkOf(\n (name) => app.registry.get(name)?.fields as Readonly<Record<string, unknown>> | undefined,\n owner,\n link,\n ),\n [app.registry, owner, link],\n );\n let liveHides = false;\n if (reverse !== undefined) {\n try {\n const { providerId } = runtime.app.resolveDataBinding(target);\n liveHides =\n runtime.providers.resolve(providerId).provider.readRelations?.links === true &&\n linkCapabilitiesOf(runtime, providerId)?.links?.filter.none !== false;\n } catch {\n liveHides = false;\n }\n }\n const liveHidesRef = useRef(liveHides);\n liveHidesRef.current = liveHides;\n const [frozenHides, setFrozenHides] = useState<boolean | null>(null);\n const hides = frozenHides ?? liveHides;\n const ownerKeyId = JSON.stringify(ownerKey ?? null);\n // biome-ignore lint/correctness/useExhaustiveDependencies: keyed by the owner key's value\n const hidden = useMemo<readonly FixedFilterInput[] | undefined>(\n () =>\n hides && reverse !== undefined\n ? [{ field: reverse, op: 'hasNone', value: [ownerKey] } as FixedFilterInput]\n : undefined,\n [hides, reverse, ownerKeyId],\n );\n const disabledKeys = useCallback(\n (keys: readonly (string | number)[], signal: AbortSignal) => linkedKeys(record, keys, signal),\n [linkedKeys, record],\n );\n const disabledLabel = useCallback(\n (count: number) =>\n t('field.link.alreadyLinked', { count, defaultValue: `${count} already linked` }),\n [t],\n );\n const picker = useRelationPicker({\n to: target,\n multiple: true,\n valueField,\n scope,\n ...(hidden === undefined ? { disabledKeys, disabledLabel } : { fixedFilters: hidden }),\n });\n\n const openPicker = picker.open;\n\n const [summary, setSummary] = useState<{\n readonly report: LinkWriteReport;\n readonly titles: Readonly<Record<string, string>>;\n } | null>(null);\n\n const finish = useCallback(\n (\n report: LinkWriteReport,\n titles: Readonly<Record<string, string>>,\n done: 'attached' | 'detached',\n ) => {\n if (report.outcome !== 'success') {\n setSummary({ report, titles });\n return;\n }\n const count = report.succeeded.length;\n if (count === 0) return;\n toast.success(\n t(`field.link.${done}`, {\n count,\n defaultValue: `${count} ${count === 1 ? 'link' : 'links'} ${done}`,\n }),\n );\n },\n [t],\n );\n\n // One Attach at a time: the ref guards re-entry, the state draws the button busy while the\n // write runs.\n const attaching = useRef(false);\n const [attachWriting, setAttachWriting] = useState(false);\n const onAttach = useCallback(() => {\n if (attaching.current) return;\n attaching.current = true;\n void (async () => {\n try {\n setFrozenHides(liveHidesRef.current);\n let result: Awaited<ReturnType<typeof openPicker>>;\n try {\n result = await openPicker();\n } finally {\n setFrozenHides(null);\n }\n if (result.kind !== 'selected' || result.keys.length === 0) return;\n const titles: Record<string, string> = {};\n for (const row of result.rows as readonly Rec[]) {\n const key = valueField === 'id' ? row.id : row[valueField];\n const title = row[displayField];\n if (key !== undefined && key !== null && title !== undefined && title !== null)\n titles[String(key)] = String(title);\n }\n setAttachWriting(true);\n try {\n finish(await writer.attach(result.keys, record), titles, 'attached');\n } finally {\n setAttachWriting(false);\n }\n } finally {\n attaching.current = false;\n }\n })();\n }, [displayField, finish, openPicker, record, valueField, writer]);\n\n // Detach confirms first; the promise the surface awaits resolves with the rows that left.\n const pending = useRef<PendingDetach | null>(null);\n const [confirming, setConfirming] = useState<number | null>(null);\n // The ref guards re-entry (a second proceed before the re-render); the state draws it.\n const detaching = useRef(false);\n const [busy, setBusy] = useState(false);\n const onDetach = useCallback(\n (rows: readonly Rec[]) =>\n new Promise<readonly string[]>((resolve) => {\n pending.current?.resolve([]);\n pending.current = { rows, resolve };\n setConfirming(rows.length);\n }),\n [],\n );\n useEffect(\n () => () => {\n pending.current?.resolve([]);\n pending.current = null;\n },\n [],\n );\n const cancel = useCallback(() => {\n if (detaching.current) return;\n pending.current?.resolve([]);\n pending.current = null;\n setConfirming(null);\n }, []);\n const proceed = useCallback(() => {\n const current = pending.current;\n if (current === null || detaching.current) return;\n detaching.current = true;\n setBusy(true);\n void (async () => {\n try {\n const titles: Record<string, string> = {};\n for (const row of current.rows) {\n const id = row[junctionIdField];\n if (id === undefined || id === null) continue;\n // The target's title when the row read it, else its key: a gone target has no title.\n const title = row[`${targetKey}.${displayField}`] ?? row[targetKey];\n if (title !== undefined && title !== null) titles[String(id)] = String(title);\n }\n const report = await writer.detach(current.rows, record);\n pending.current = null;\n setConfirming(null);\n finish(report, titles, 'detached');\n // The report names junction ids; the surface selects rows by their row key (`id` of a\n // list row, which a declared `rowId` makes differ from the junction id).\n const left = new Set(report.succeeded);\n current.resolve(\n current.rows\n .filter((row) => {\n const id = row[junctionIdField];\n return id !== undefined && id !== null && left.has(String(id));\n })\n .map((row) => String(row.id)),\n );\n } finally {\n detaching.current = false;\n setBusy(false);\n }\n })();\n }, [displayField, finish, junctionIdField, record, targetKey, writer]);\n\n const detachLabel = t('field.link.detach', { defaultValue: 'Detach' });\n const count = confirming ?? 0;\n const gate: CheckGateState = {\n resource: junction,\n open: confirming !== null,\n busy,\n header: t('field.link.confirmDetach', {\n count,\n defaultValue: `Detach ${count} ${count === 1 ? 'link' : 'links'}? The linked records themselves are not deleted.`,\n }),\n blockers: NO_ISSUES,\n confirmable: NO_ISSUES,\n proceed,\n cancel,\n };\n\n const attachAllowed = rights.attach.allowed;\n const detachAllowed = rights.detach.allowed;\n const linkEditing = useMemo<ResourceListSurfaceProps['linkEditing']>(\n () =>\n !attachAllowed && !detachAllowed\n ? undefined\n : {\n ...(attachAllowed ? { attach: { onAttach, busy: attachWriting } } : {}),\n ...(detachAllowed ? { detach: { onDetach } } : {}),\n },\n [attachAllowed, attachWriting, detachAllowed, onAttach, onDetach],\n );\n\n const element = (\n <>\n {picker.element}\n <CheckConfirmDialog\n state={gate}\n testid={`link-detach-confirm:${junction}`}\n title={detachLabel}\n proceedLabel={detachLabel}\n tone=\"destructive\"\n />\n {summary === null ? null : (\n <LinkWriteSummary\n report={summary.report}\n titles={summary.titles}\n onClose={() => setSummary(null)}\n testid={`link-write-summary:${junction}`}\n />\n )}\n </>\n );\n return { linkEditing, element };\n}\n","import { declaredField, fieldSensitivity } from '@burojs/core';\nimport type { CapabilityResolver } from '@burojs/react';\n\n/** What `peekFields` reads of a resource definition. */\nexport interface PeekFieldSource {\n readonly displayField?: string;\n readonly fields: Readonly<Record<string, unknown>>;\n readonly types?: {\n readonly items: readonly { readonly fields: readonly { readonly name: string }[] }[];\n };\n}\n\n/**\n * A field's definition by name: a base field, else a type's own field (Known finding 2: a field a\n * type declares lives in `types.items[].fields`, never in the base map).\n */\nexport function peekFieldDefinition(def: PeekFieldSource, name: string): unknown {\n return declaredField(def, name);\n}\n\n/**\n * Whether a peek may show `name` (P3-38, P6-66): the field is declared, not `sensitive`, and\n * not hidden from this viewer by the target's `column` rule — \"nothing a page would hide may\n * surface on hover\". The default body and a declared peek body both apply it. The third\n * condition is P5's field view in record reach (spec 3.6.5): `fieldVisible` is true only for a\n * `visible` field, so a hidden, restricted or still undecided field is not allowed.\n */\nexport function peekLeafAllowed(\n def: PeekFieldSource,\n name: string,\n capabilityFor: CapabilityResolver,\n fieldVisible: (name: string) => boolean,\n): boolean {\n const field = peekFieldDefinition(def, name);\n if (field === undefined || fieldSensitivity(field) !== undefined) return false;\n if (capabilityFor('view', { kind: 'column', name }).allowed === false) return false;\n return fieldVisible(name);\n}\n\n/**\n * The row a declared peek body is planned over: the id field and every field\n * {@link peekLeafAllowed} admits keep their values; every other field reads `null` — its leaf\n * renders absent, and a block prop reading it reads `null` (spec 3.9). With `drawn`, the row is\n * narrowed to the fields the body draws (P5 spec 3.6.5, for a peek frame's `record` prop): every\n * field outside it reads `null`, whatever the filter allows.\n */\nexport function peekRow(\n def: PeekFieldSource,\n row: Readonly<Record<string, unknown>>,\n idField: string,\n capabilityFor: CapabilityResolver,\n fieldVisible: (name: string) => boolean,\n drawn?: ReadonlySet<string>,\n): Readonly<Record<string, unknown>> {\n const out: Record<string, unknown> = {};\n for (const [name, value] of Object.entries(row))\n out[name] =\n name === idField ||\n ((drawn === undefined || drawn.has(name)) &&\n peekLeafAllowed(def, name, capabilityFor, fieldVisible))\n ? value\n : null;\n return Object.freeze(out);\n}\n\n/**\n * The peek's `record` (the row a declared body is planned over and a peek frame's `record` starts\n * from): {@link peekRow} over the target's definition, and the id field alone when the target has\n * no registry definition — without a definition nothing can be filtered, so nothing but the id\n * leaves (fail closed).\n */\nexport function peekRecord(\n def: PeekFieldSource | undefined,\n row: Readonly<Record<string, unknown>>,\n idField: string,\n capabilityFor: CapabilityResolver,\n fieldVisible: (name: string) => boolean,\n): Readonly<Record<string, unknown>> {\n if (def === undefined) return Object.freeze({ [idField]: row[idField] });\n return peekRow(def, row, idField, capabilityFor, fieldVisible);\n}\n","'use client';\nimport {\n type CountPolicy,\n type EntityRef,\n type FixedFilterInput,\n type DtoSource,\n type LinkDeclaration,\n type ScopeSource,\n dtoFields,\n fieldSensitivity,\n isRelationField,\n linkOf,\n normalizeEntityRef,\n resourceKey,\n whereEntryToFilter,\n type ColumnEntry,\n} from '@burojs/core';\nimport { hasNullRef, whereToFilter } from '@burojs/core/internal';\nimport {\n linkCapabilitiesOf,\n resolveColumnField,\n useApp,\n useOptionalDataRuntime,\n useOptionalRecordFrame,\n} from '@burojs/react';\nimport { type ReactElement, useMemo } from 'react';\nimport {\n ResourceListSurface,\n type ResourceListSurfaceProps,\n} from '../list-kit/resource-list-surface.js';\nimport { useLinkPanelWrites } from './link-attach.js';\nimport { type PeekFieldSource, peekFieldDefinition } from '../quick/peek-filter.js';\nimport { useIsRouteScreen } from '../record/route-screen-context.js';\nimport { placementLayoutId, usePlacementFrame } from './placement-frame.js';\nimport { UnboundRelatedList, placementScope } from './related-list-unbound.js';\nimport type { RelatedListViewProps } from './related-list-view.js';\n\ntype Rec = Readonly<Record<string, unknown>>;\n\nconst isRecord = (value: unknown): value is Rec =>\n value !== null && typeof value === 'object' && !Array.isArray(value);\n\nconst isResourceHandle = (value: unknown): value is { readonly ref: EntityRef } =>\n isRecord(value) && value.kind === 'resource';\n\n/** `ref` (a name, an entity ref or a resource handle) as a registry key; a bare name means `default` (REF-95 §4.3). */\nfunction qualify(ref: unknown): string | undefined {\n try {\n return resourceKey(normalizeEntityRef((isResourceHandle(ref) ? ref.ref : ref) as EntityRef));\n } catch {\n return undefined;\n }\n}\n\n/** The link field `link` of `owner` (a base field or a type's), or undefined when it is none. */\nfunction linkField(\n registry: { get(name: string): unknown },\n owner: string | undefined,\n link: string,\n): { readonly field: Rec; readonly declaration: LinkDeclaration } | undefined {\n if (owner === undefined) return undefined;\n const def = registry.get(owner) as PeekFieldSource | undefined;\n const field = def === undefined ? undefined : peekFieldDefinition(def, link);\n if (!isRecord(field)) return undefined;\n const declaration = linkOf(field);\n return declaration === undefined ? undefined : { field, declaration };\n}\n\n/**\n * The registry name of the target of the link field `link` of `owner` (the resource whose screen\n * holds the placement; the field is a base field or a type's), resolved against the owner's\n * namespace; undefined without an owner or when `link` is no link field of it.\n */\nexport function linkTarget(\n registry: { get(name: string): unknown },\n owner: string | undefined,\n link: string,\n): string | undefined {\n const found = linkField(registry, owner, link);\n if (found === undefined || owner === undefined) return undefined;\n return qualify((found.field.meta as Rec | undefined)?.to);\n}\n\nfunction idFieldOf(def: unknown): string {\n const declared = isRecord(def) && isRecord(def.data) ? def.data.idField : undefined;\n return typeof declared === 'string' && declared.length > 0 ? declared : 'id';\n}\n\n/** The field a relation keys its target by (`meta.by`), when it is not the target's id. */\nfunction byOf(field: unknown): string | undefined {\n const by = isRecord(field) && isRecord(field.meta) ? field.meta.by : undefined;\n return typeof by === 'string' && by.length > 0 ? by : undefined;\n}\n\n/** The most relations of the target a panel's dotted column may cross (one more reaches it). */\nconst MAX_TARGET_HOPS = 2;\n\n/**\n * The target's list columns a dotted column can end at: its `views.list.columns`, else the fields\n * a list row of it holds. A relation or a link (a hop needs a field after it), a sensitive or\n * undeclared field, and a path across more relations than a panel reads are left out silently:\n * the target's list columns are its own page's, and drawing fewer of them is no error of the panel.\n */\nfunction targetColumns(\n registry: Parameters<typeof resolveColumnField>[0],\n target: string,\n def: unknown,\n): readonly string[] {\n if (!isRecord(def) || !isRecord(def.fields)) return [];\n const source = def as unknown as DtoSource & PeekFieldSource;\n const views = isRecord(def.views) ? def.views : undefined;\n const list = views !== undefined && isRecord(views.list) ? views.list : undefined;\n // A column entry (REF-117 §4.9) is named by its `field`; the panel draws the target's names.\n const declared =\n list !== undefined && Array.isArray(list.columns)\n ? list.columns.flatMap((entry: unknown): string[] => {\n const name = isRecord(entry) ? entry.field : entry;\n return typeof name === 'string' ? [name] : [];\n })\n : dtoFields(source, 'list');\n return declared.filter((name) => {\n // A dotted column of the target: declared to-one hops to a declared, non-relation,\n // non-sensitive field, within the panel's hop budget.\n if (name.includes('.'))\n return (\n name.split('.').length - 1 <= MAX_TARGET_HOPS &&\n resolveColumnField(registry, target, name) !== undefined\n );\n const field = peekFieldDefinition(source, name);\n return isRecord(field) && !isRelationField(field) && fieldSensitivity(field) === undefined;\n });\n}\n\n/** What the panel reads: the junction, its keys, and how a row reaches its target. */\ninterface PanelStorage {\n readonly junction: string;\n readonly target: string;\n readonly sourceKey: string;\n readonly targetKey: string;\n /** The owner's field the junction's `sourceKey` holds (its relation's `by`, else the id). */\n readonly ownerField: string;\n /** The junction's `targetKey` relation keys the target by a non-id field: no row opens. */\n readonly targetKeyedBy: boolean;\n /** The target field the junction's `targetKey` holds (its relation's `by`, else the id). */\n readonly targetValueField: string;\n readonly junctionIdField: string;\n readonly where: LinkDeclaration['where'];\n readonly targetDef: unknown;\n /** The link field's declared picker read scope (`meta.scope`). */\n readonly pickerScope: ScopeSource | undefined;\n}\n\n/**\n * A link panel (`relatedList({ link })`): the record's links of one link field, shown as target\n * rows and read as junction rows. Target `columns` (else the target's list columns) are read\n * through the junction's `targetKey` hop as dotted columns, `linkColumns` are the junction's own;\n * the owner key, the link's `through.where` and the placement's `where` (on target fields,\n * through the hop) are locked filters, so paging and the count count links. No create, no item\n * actions, no export: Attach and Detach are its only writes, drawn as the link rights allow\n * (`useLinkPanelWrites`). The count is the placement's, else off when the junction's provider\n * declares `count: false` in its link capability record. A row opens the target record's page,\n * or nothing when `open` is `'none'` or the junction keys the target by a non-id field.\n */\nexport function LinkPanel(props: {\n readonly link: string;\n readonly owner: string;\n readonly own: RelatedListViewProps;\n /** The placement's own empty text (`BlockViewProps.empty`). */\n readonly empty?: string;\n}): ReactElement {\n const { link, owner, own, empty } = props;\n const app = useApp();\n const frame = usePlacementFrame();\n const routeScreen = useIsRouteScreen();\n const record = useOptionalRecordFrame()?.record;\n const runtime = useOptionalDataRuntime();\n\n const storage = useMemo<PanelStorage | undefined>(() => {\n const found = linkField(app.registry, owner, link);\n if (found === undefined) return undefined;\n const { declaration } = found;\n const junction = qualify(declaration.junction);\n const target = qualify((found.field.meta as Rec | undefined)?.to);\n if (junction === undefined || target === undefined) return undefined;\n const junctionDef = app.registry.get(junction);\n if (junctionDef === undefined) return undefined;\n const junctionFields = junctionDef.fields as Rec;\n const targetDef = app.registry.get(target);\n const targetBy = byOf(junctionFields[declaration.targetKey]);\n const declaredScope = (found.field.meta as Rec | undefined)?.scope;\n return {\n junction,\n target,\n sourceKey: declaration.sourceKey,\n targetKey: declaration.targetKey,\n ownerField: byOf(junctionFields[declaration.sourceKey]) ?? idFieldOf(app.registry.get(owner)),\n targetKeyedBy: targetBy !== undefined,\n targetValueField: targetBy ?? idFieldOf(targetDef),\n junctionIdField: idFieldOf(junctionDef),\n where: declaration.where,\n targetDef,\n pickerScope:\n declaredScope === 'context' || declaredScope === 'session' || declaredScope === 'none'\n ? declaredScope\n : undefined,\n };\n }, [app.registry, owner, link]);\n\n const ownerKey = storage === undefined ? undefined : record?.[storage.ownerField];\n const whereKey = JSON.stringify(own.where ?? []);\n // biome-ignore lint/correctness/useExhaustiveDependencies: keyed by the where's value, not its identity\n const fixedFilters = useMemo<readonly FixedFilterInput[] | undefined>(() => {\n if (storage === undefined || ownerKey === null || ownerKey === undefined) return undefined;\n const { sourceKey, targetKey } = storage;\n const placed = whereToFilter(own.where ?? [], (field) => `${targetKey}.${field}`);\n return [\n whereEntryToFilter(sourceKey, 'eq', ownerKey),\n ...storage.where.map((entry) => whereEntryToFilter(entry.field, entry.op, entry.value)),\n ...(placed === undefined ? [] : [placed as FixedFilterInput]),\n ];\n }, [storage, ownerKey, whereKey]);\n\n const columnsKey = JSON.stringify([own.columns ?? null, own.linkColumns ?? null]);\n // biome-ignore lint/correctness/useExhaustiveDependencies: keyed by the columns' value\n const columns = useMemo<readonly ColumnEntry[] | undefined>(() => {\n if (storage === undefined) return undefined;\n const shown = own.columns ?? targetColumns(app.registry, storage.target, storage.targetDef);\n // A target column is read across the junction's targetKey hop; an entry keeps its keys.\n const across = (entry: ColumnEntry): ColumnEntry =>\n typeof entry === 'string'\n ? `${storage.targetKey}.${entry}`\n : { ...entry, field: `${storage.targetKey}.${entry.field}` };\n return [...shown.map(across), ...(own.linkColumns ?? [])];\n }, [storage, columnsKey, app.registry]);\n\n const rowTarget = useMemo(\n () =>\n storage === undefined || storage.targetKeyedBy\n ? undefined\n : { resource: storage.target, field: storage.targetKey },\n [storage],\n );\n\n // A record not read yet (or a create screen), a link the registry cannot resolve, or a `where`\n // value that resolved to nothing binds no links: nothing is read.\n const unbound = fixedFilters === undefined || (own.where !== undefined && hasNullRef(own.where));\n if (storage === undefined || unbound)\n return (\n <UnboundRelatedList\n resource={storage?.target ?? ''}\n title={own.title}\n {...(empty === undefined ? {} : { empty })}\n />\n );\n\n // URL state on the top level of a route screen only, as for any placement.\n const state =\n frame?.state === 'url' && routeScreen && !frame.nested\n ? { url: frame.key }\n : ('memory' as const);\n // The placement's count, else off when the junction's provider declares it cannot count links.\n let providerCounts: boolean | undefined;\n if (runtime !== null) {\n try {\n providerCounts = linkCapabilitiesOf(\n runtime,\n runtime.app.resolveDataBinding(storage.junction).providerId,\n )?.links?.count;\n } catch {\n providerCounts = undefined;\n }\n }\n const count: CountPolicy | undefined =\n own.count === false\n ? 'off'\n : (own.count ?? (providerCounts === false ? ('off' as const) : undefined));\n // The link panel's own layout, beside the junction resource it lists (C18).\n const layoutId = frame === null ? undefined : placementLayoutId({ owner, key: frame.key });\n const surface: ResourceListSurfaceProps = {\n resource: storage.junction,\n variant: 'placement',\n state,\n fixedFilters,\n // A link panel's initial takes pageSize only (T4 D9): its rows are the junction's.\n ...(own.initial?.pageSize === undefined ? {} : { initial: { pageSize: own.initial.pageSize } }),\n ...(own.search === undefined ? {} : { search: `${storage.targetKey}.${own.search}` }),\n ...(columns === undefined ? {} : { columns }),\n open: rowTarget === undefined || own.open === 'none' ? 'none' : 'page',\n ...(rowTarget === undefined ? {} : { rowTarget }),\n ...(frame === null ? {} : { placementKey: frame.key }),\n ...(layoutId === undefined ? {} : { layoutId }),\n ...(own.title === undefined ? {} : { title: own.title }),\n ...(empty === undefined ? {} : { empty }),\n scope: placementScope(own.scope, owner),\n ...(count === undefined ? {} : { count }),\n readOnly: true,\n exportable: false,\n };\n // Writes need the data runtime; without one (a host rendering without it) the panel only reads.\n if (runtime === null || record === undefined) return <ResourceListSurface {...surface} />;\n return (\n <WritableLinkPanel\n surface={surface}\n owner={owner}\n link={link}\n storage={storage}\n record={record}\n ownerKey={ownerKey}\n placement={own.linkActions}\n />\n );\n}\n\n/** A link panel whose Attach and Detach are drawn as the link rights allow. */\nfunction WritableLinkPanel(props: {\n readonly surface: ResourceListSurfaceProps;\n readonly owner: string;\n readonly link: string;\n readonly storage: PanelStorage;\n readonly record: Rec;\n readonly ownerKey: unknown;\n readonly placement: RelatedListViewProps['linkActions'];\n}): ReactElement {\n const { surface, owner, link, storage, record, ownerKey, placement } = props;\n const displayField =\n isRecord(storage.targetDef) && typeof storage.targetDef.displayField === 'string'\n ? storage.targetDef.displayField\n : storage.targetValueField;\n const { linkEditing, element } = useLinkPanelWrites({\n owner,\n junction: storage.junction,\n target: storage.target,\n link,\n targetKey: storage.targetKey,\n valueField: storage.targetValueField,\n junctionIdField: storage.junctionIdField,\n displayField,\n scope: storage.pickerScope ?? 'context',\n record,\n ownerKey,\n placement,\n });\n return (\n <>\n <ResourceListSurface {...surface} {...(linkEditing === undefined ? {} : { linkEditing })} />\n {element}\n </>\n );\n}\n","import type { ReactNode } from 'react';\nimport { createContext, useContext } from 'react';\nimport type { ResourceListPageProps } from '../list-kit/resource-list-page.js';\n\n/**\n * What `ResourceListPage` hands the `related-list` view: its route-only props. Its presence is\n * what selects the route variant (decision 63). Internal.\n */\nexport interface RouteListValue {\n readonly meta?: Record<string, unknown>;\n readonly renderCell?: ResourceListPageProps['renderCell'];\n readonly emptyState?: ReactNode;\n}\n\nexport const RouteListContext = createContext<RouteListValue | null>(null);\n\nexport function useRouteList(): RouteListValue | null {\n return useContext(RouteListContext);\n}\n","'use client';\nimport {\n type AppContext,\n type CountPolicy,\n type EntityRef,\n type FixedFilterInput,\n type LinkActions,\n type RelatedListCreate,\n type RelatedListInitial,\n type RelatedListWhereEntry,\n type ScopeSource,\n grantedPlacementKeys,\n resourceKey,\n type ColumnEntry,\n} from '@burojs/core';\nimport { actionWhenHolds, hasNullRef, whereToFilter } from '@burojs/core/internal';\nimport {\n type BlockViewProps,\n useApp,\n useCtx,\n useEntryGate,\n useQuick,\n useQuickEntry,\n} from '@burojs/react';\nimport { useDeepLinkOpen } from '../quick/use-deep-link.js';\nimport { type PortableWhereEntry, placementSeeds } from './placement-seeds.js';\nimport { type ReactElement, useEffect, useMemo, useRef } from 'react';\nimport { ResourceListSurface } from '../list-kit/resource-list-surface.js';\nimport { useIsRouteScreen } from '../record/route-screen-context.js';\nimport { LinkPanel, linkTarget } from './link-panel.js';\nimport { placementLayoutId, usePlacementFrame } from './placement-frame.js';\nimport { isItemHandle } from './related-item.js';\nimport { RelatedCardsSkeleton, RelatedTimelineSkeleton } from './related-skeletons.js';\nimport { UnboundRelatedList, placementScope } from './related-list-unbound.js';\nimport { useRouteList } from './route-list-context.js';\n\n/** The props of `buro:related-list` as its view receives them (each schema's output). */\nexport interface RelatedListViewProps {\n /** Absent on a link list: its resource is the link field's target. */\n readonly resource?: EntityRef;\n /** A link field of the record's resource: the list shows that record's links. */\n readonly link?: string;\n readonly where?: readonly RelatedListWhereEntry[];\n /** Column names or entries (REF-117 §4.9). */\n readonly columns?: readonly ColumnEntry[];\n /**\n * The placement's own initial state (T4 D9): `sort` and `pageSize` it omits follow the target's\n * `views.list.initial`; `filters` is never the target's. A link panel's takes `pageSize` only.\n */\n readonly initial?: RelatedListInitial;\n readonly search?: string;\n readonly open?: 'page' | 'none' | 'quick';\n readonly title?: string;\n /** Absent: a card tab reads `'none'`, a list on a page keeps the session's scope. */\n readonly scope?: ScopeSource;\n readonly view?: 'table' | 'cards' | 'timeline';\n /** The planned item node, drawn once per row; absent on the route list and without `item`. */\n readonly item?: unknown;\n /** A link list's junction columns, after its target columns. */\n readonly linkColumns?: readonly ColumnEntry[];\n /** When the list reads its total, in place of the listed resource's; `false` is `'off'`. */\n readonly count?: CountPolicy | false;\n /** A link list's attach and detach controls: none (`false`) or one switched off each. */\n readonly linkActions?: LinkActions;\n /** \"+ Create\": `false` removes it, `{ when }` (parsed, refs unresolved) narrows it (T4 D9). */\n readonly create?: RelatedListCreate;\n}\n\n/**\n * The built-in `buro:related-list` view (spec 8.4): the route list when `ResourceListPage` renders\n * it, a placement otherwise. A placement's `where` is a locked filter (user and URL filters\n * conjoin it, never replace it), its state lives in memory, or in the URL under its key when\n * the node says `state: 'url'` at the top level of a route screen (a record route or a page); a\n * `where` value that resolved to null lists nothing and sends no request.\n */\nexport function RelatedListView({ props, empty }: BlockViewProps<unknown>): ReactElement {\n const own = props as unknown as RelatedListViewProps;\n const route = useRouteList();\n const frame = usePlacementFrame();\n const app = useApp();\n // Derived before any hook that reads it: a link list has no `resource` prop, its resource is\n // the link's target ('' when the link names no link field of the record's resource).\n const linked = own.link !== undefined;\n const resource = linked\n ? (linkTarget(app.registry, frame?.owner, own.link as string) ?? '')\n : resourceKey(own.resource as EntityRef);\n const whereKey = JSON.stringify(own.where ?? []);\n // biome-ignore lint/correctness/useExhaustiveDependencies: keyed by the where's value, not its identity\n const fixedFilters = useMemo<readonly FixedFilterInput[] | undefined>(\n () =>\n own.where === undefined || own.where.length === 0\n ? undefined\n : [whereToFilter(own.where) as FixedFilterInput],\n [whereKey],\n );\n const columnsKey = JSON.stringify(own.columns ?? null);\n // biome-ignore lint/correctness/useExhaustiveDependencies: keyed by the columns' value\n const columns = useMemo(() => own.columns, [columnsKey]);\n const routeScreen = useIsRouteScreen();\n // Inside a quick entry an inherited `state: 'url'` is expected to fall back (spec 4.13 item 4).\n const inQuick = useQuickEntry() !== null;\n useMemoryNotice(frame, routeScreen || inQuick, route !== null);\n const permissions = useCtx((c: AppContext) => c.permissions);\n const gate = useEntryGate();\n const quick = useQuick();\n // A placement's \"+ Create\" (spec 4.5, P3-18): only a top-level placement on a record screen\n // whose key no granted layer placed or changed (plan rulings 1 and 21; an unknown marker is\n // untrusted), and only when the target's quick create passes the entry gate. It opens\n // `quick.create` — a new overlay, above the sheet when inside one — seeded from the trusted\n // `where` values only.\n const ownerDef = frame?.owner === undefined ? undefined : app.registry.get(frame.owner);\n const granted = ownerDef === undefined ? 'unknown' : grantedPlacementKeys(ownerDef);\n const trusted =\n frame !== null && !frame.nested && granted !== 'unknown' && !granted.has(frame.key);\n // `create` (T4 D9 part 4) only narrows: `false` removes \"+ Create\", `{ when }` shows it only\n // while the condition holds over the screen's sources; undecided (a source pending or failed)\n // hides it, while the list itself never waits on them (C40, C46).\n const createOpen =\n route === null &&\n !linked &&\n trusted &&\n gate(resource, 'create').state === 'open' &&\n own.create !== false &&\n (own.create === undefined || actionWhenHolds(own.create, frame?.sources ?? {}));\n const onCreate =\n createOpen && frame !== null\n ? () =>\n void quick.create(resource, {\n defaults: placementSeeds(\n (frame.where ?? []) as readonly PortableWhereEntry[],\n own.where ?? [],\n frame.closure ?? {},\n ),\n })\n : undefined;\n // The deep link `?<key>.open=<id>` (spec 4.8): a drawn top-level placement on a route screen\n // whose rows open quick entries consumes it.\n useDeepLinkOpen(\n frame?.key ?? null,\n resource,\n route === null &&\n !linked &&\n frame !== null &&\n !frame.nested &&\n routeScreen &&\n (own.open ?? 'quick') === 'quick',\n );\n // A `where` value that resolved to nothing (a null relation key) binds no rows: the list is\n // empty and no list, count or export request goes out — never `field eq null`, whose meaning\n // is the backend's (spec Review Focus 2).\n const unbound = own.where !== undefined && hasNullRef(own.where);\n // A link list's rows are the record's links, read through the junction: never a list of every\n // target row, so it is no placement over `resource`.\n if (linked)\n return frame?.owner === undefined ? (\n <UnboundRelatedList\n resource={resource}\n title={own.title}\n {...(empty === undefined ? {} : { empty })}\n />\n ) : (\n <LinkPanel\n link={own.link as string}\n owner={frame.owner}\n own={own}\n {...(empty === undefined ? {} : { empty })}\n />\n );\n if (route !== null)\n return (\n <ResourceListSurface\n resource={resource}\n variant=\"route\"\n layoutId=\"route\"\n {...(route.meta === undefined ? {} : { meta: route.meta })}\n {...(route.renderCell === undefined ? {} : { renderCell: route.renderCell })}\n {...(route.emptyState === undefined ? {} : { emptyState: route.emptyState })}\n />\n );\n // Cards and timeline are new hosts of the list: while the permission map loads they draw\n // their skeleton and read nothing (P6 3.14 item 9).\n if (own.view !== undefined && own.view !== 'table' && permissions?.status === 'loading')\n return (\n <div role=\"status\" aria-busy=\"true\" data-testid={`list-undecided:${resource}`}>\n {own.view === 'cards' ? <RelatedCardsSkeleton /> : <RelatedTimelineSkeleton />}\n </div>\n );\n if (unbound)\n return (\n <UnboundRelatedList\n resource={resource}\n title={own.title}\n {...(empty === undefined ? {} : { empty })}\n />\n );\n // URL state is honoured on the top level of a route screen only (spec 8.4, P2 4.7); anywhere\n // else the state is local, so two screens on one page never share `?<key>.` parameters, and a\n // nested placement's derived key never becomes part of a shared link.\n const state =\n frame?.state === 'url' && routeScreen && !frame.nested\n ? { url: frame.key }\n : ('memory' as const);\n // A tab of a record's card lists what belongs to the record, whatever the session's scope; a\n // list on a custom page has no record around it and keeps the session (spec 4, table).\n const scope: ScopeSource = placementScope(own.scope, frame?.owner);\n // The placement's count policy replaces the target's `views.list.count`; `false` reads none.\n const count: CountPolicy | undefined = own.count === false ? 'off' : own.count;\n const layoutId = placementLayoutId(frame);\n return (\n <ResourceListSurface\n resource={resource}\n variant=\"placement\"\n state={state}\n {...(fixedFilters === undefined ? {} : { fixedFilters })}\n /* The surface keys its controller's initial by value: a fresh object here is fine. */\n {...(own.initial === undefined ? {} : { initial: own.initial })}\n {...(own.search === undefined ? {} : { search: own.search })}\n {...(columns === undefined ? {} : { columns })}\n open={own.open ?? 'quick'}\n {...(own.view === undefined ? {} : { view: own.view })}\n {...(isItemHandle(own.item) ? { item: own.item } : {})}\n {...(frame === null ? {} : { placementKey: frame.key })}\n {...(layoutId === undefined ? {} : { layoutId })}\n {...(own.title === undefined ? {} : { title: own.title })}\n {...(empty === undefined ? {} : { empty })}\n scope={scope}\n {...(count === undefined ? {} : { count })}\n {...(onCreate === undefined ? {} : { onCreate })}\n />\n );\n}\n\n/**\n * In development, one `console.warn` per key per mount when a placement asks for `state: 'url'`\n * and keeps its state in memory instead: the checker cannot see where a host renders a screen\n * (P2 4.7), and it warns `list.url-state-nested` only where it can see the nesting.\n */\nfunction useMemoryNotice(\n frame: ReturnType<typeof usePlacementFrame>,\n routeScreen: boolean,\n routeList: boolean,\n): void {\n const warned = useRef<string | null>(null);\n const why =\n routeList || frame === null || frame.state !== 'url'\n ? undefined\n : frame.nested\n ? 'it is nested in a block'\n : routeScreen\n ? undefined\n : 'this screen is not a route screen';\n const key = frame?.key;\n useEffect(() => {\n if (why === undefined || key === undefined || process.env.NODE_ENV === 'production') return;\n if (warned.current === key) return;\n warned.current = key;\n console.warn(`[burojs] The list \"${key}\" keeps its state in memory: ${why}.`);\n }, [key, why]);\n}\n","'use client';\nimport {\n type EntityRef,\n dtoFields,\n fieldSensitivity,\n projectDto,\n resolveFieldLabel,\n resourceKey,\n declaredText,\n} from '@burojs/core';\nimport {\n type BlockViewProps,\n useApp,\n useCapabilityResolver,\n useFieldAccess,\n useI18nCaps,\n useOne,\n useOptionalT,\n useProjectedRecord,\n} from '@burojs/react';\nimport { type ReactElement, useMemo } from 'react';\nimport { ActionOverflow } from '../actions/action-overflow.js';\nimport { FieldValueFrame } from '../fields/field-value-frame.js';\nimport { ResolvedFieldDisplay } from '../fields/resolved-field.js';\nimport { toDisplayText } from '../fields/display-value.js';\nimport { Skeleton } from '../primitives/skeleton.js';\nimport { FIELD_LABEL_SHOW } from '../screen/field-leaf.js';\n\n/** The props of `buro:related-record` as its view receives them (each schema's output). */\ninterface RelatedRecordViewProps {\n readonly resource: EntityRef;\n readonly record: unknown;\n readonly title?: string;\n readonly fields?: readonly string[];\n readonly toolbar?: 'item' | 'none';\n readonly missing?: string;\n}\n\n/**\n * A field's definition by name: a base field, else a type's own field (the record DTO is the union\n * over types), so its sensitivity, label and display are read for a typed target too.\n */\nfunction fieldDefinition(\n def: {\n readonly fields: Readonly<Record<string, unknown>>;\n readonly types?: {\n readonly items: readonly { readonly fields: readonly { readonly name: string }[] }[];\n };\n },\n name: string,\n): unknown {\n if (Object.hasOwn(def.fields, name)) return def.fields[name];\n for (const type of def.types?.items ?? [])\n for (const field of type.fields ?? []) if (field.name === name) return field;\n return undefined;\n}\n\n/** A record id as a ref resolves it: `null` for none. */\nfunction recordId(value: unknown): string | null {\n if (typeof value === 'string') return value === '' ? null : value;\n if (typeof value === 'number' && Number.isFinite(value)) return String(value);\n return null;\n}\n\nfunction Missing({ text }: { readonly text: string | undefined }): ReactElement {\n const t = useOptionalT();\n return (\n <p className=\"text-sm text-muted-foreground\">\n {text ?? t('table.empty', { defaultValue: 'No records' })}\n </p>\n );\n}\n\n/**\n * The built-in `buro:related-record` view (spec 8.4): one record of another resource in a panel.\n * It reads the target with the target's record DTO projection and renders each of `fields`\n * (default: the record DTO's fields, sensitive ones left out) with the field's display under its\n * label, minus the fields the target's `column` rules deny; the record is the DTO (decision 41),\n * so an undeclared column never renders. `toolbar: 'item'` shows the target's item actions under\n * its own rules; a null `record` renders `missing` and reads nothing.\n */\nexport function RelatedRecordView({ props, empty }: BlockViewProps<unknown>): ReactElement {\n const own = props as unknown as RelatedRecordViewProps;\n const app = useApp();\n const resource = resourceKey(own.resource);\n const def = app.registry.get(resource);\n const id = recordId(own.record);\n const caps = useI18nCaps(resource);\n const capabilityFor = useCapabilityResolver(resource, undefined, 'show');\n const projection = useMemo(\n () => (def === undefined ? undefined : dtoFields(def, 'record')),\n [def],\n );\n const query = useOne(resource, {\n id: id ?? '',\n enabled: id !== null,\n ...(projection === undefined ? {} : { projection }),\n });\n // The target's rows are read with the record DTO, then decided in record reach over the row as\n // read (P5 spec 3.6): a field the viewer may not see never reaches a label, a value or a title.\n const result = query.data as { readonly data?: unknown } | undefined;\n const raw = result?.data;\n const dtoRow = useMemo(\n () =>\n raw !== null && typeof raw === 'object' && projection !== undefined\n ? projectDto(raw as Readonly<Record<string, unknown>>, projection)\n : undefined,\n [raw, projection],\n );\n const access = useFieldAccess(resource, 'record', dtoRow);\n const projected = useProjectedRecord(resource, dtoRow, {\n placeholder: query.isPlaceholderData === true,\n });\n const fieldsKey = JSON.stringify(own.fields ?? null);\n // biome-ignore lint/correctness/useExhaustiveDependencies: keyed by the fields' value\n const shown = useMemo(() => {\n if (def === undefined || projection === undefined) return [];\n const declared = new Set(projection);\n const wanted =\n own.fields ??\n projection.filter((name) => fieldSensitivity(fieldDefinition(def, name)) === undefined);\n // Only declared fields of the DTO, and only those the target's column rules let this viewer see.\n return wanted.filter(\n (name) =>\n declared.has(name) &&\n capabilityFor('view', { kind: 'column', name }).allowed &&\n access[name]?.view === 'visible',\n );\n }, [def, projection, fieldsKey, capabilityFor, access]);\n if (id === null) return <Missing text={own.missing ?? empty} />;\n if (result === undefined) {\n if (query.error != null) return <Missing text={own.missing ?? empty} />;\n return <Skeleton data-buro-skeleton=\"\" className=\"h-9 w-full\" />;\n }\n if (dtoRow === undefined) return <Missing text={own.missing ?? empty} />;\n if (projected.status === 'pending' || projected.value === null)\n return <Skeleton data-buro-skeleton=\"\" className=\"h-9 w-full\" />;\n const row = projected.value;\n return (\n <div className=\"flex flex-col gap-2\">\n {own.title === undefined && own.toolbar !== 'item' ? null : (\n <div className=\"flex items-center gap-2\">\n {own.title === undefined ? null : <h3 className=\"text-sm font-semibold\">{own.title}</h3>}\n {own.toolbar === 'item' ? (\n <ActionOverflow\n resource={resource}\n record={{ ...dtoRow, id } as { id: string } & Record<string, unknown>}\n surface=\"show\"\n />\n ) : null}\n </div>\n )}\n <dl className=\"grid gap-2 sm:grid-cols-2\">\n {shown.map((name) => {\n const field = fieldDefinition(def!, name) as { readonly label?: string } | undefined;\n const value = row[name];\n return (\n <div key={name} className=\"flex min-w-0 flex-col gap-0.5\">\n <dt className={FIELD_LABEL_SHOW}>\n {resolveFieldLabel(caps, name, declaredText('field', field, 'label'))}\n </dt>\n <dd className=\"min-w-0 break-words text-sm\">\n <FieldValueFrame field={{ ...(field ?? {}), name }} value={value} surface=\"display\">\n <ResolvedFieldDisplay\n resource={own.resource}\n name={name}\n field={field as never}\n value={value}\n record={row}\n fallback={toDisplayText(value).text}\n />\n </FieldValueFrame>\n </dd>\n </div>\n );\n })}\n </dl>\n </div>\n );\n}\n","import { facts, inlineFlow, relatedList, relatedRecord } from '@burojs/core';\nimport type {\n BlockImplementation,\n BlockImplementationCatalog,\n BlockViewProps,\n} from '@burojs/react';\nimport type { ComponentType } from 'react';\nimport { FactsView } from './facts-view.js';\nimport { InlineFlowView } from '../flows/inline-flow-view.js';\nimport { RelatedListView } from './related-list-view.js';\nimport { RelatedRecordView } from './related-record-view.js';\n\n/**\n * A built-in entry whose `definition` (the block handle) is built on first read: the handles are\n * built on first use (spec decision 20), so importing the catalogue builds none.\n */\nfunction builtinEntry(\n id: string,\n component: ComponentType<BlockViewProps<unknown>>,\n definition: () => unknown,\n): BlockImplementation<unknown> {\n const [namespace, name] = id.split(':') as [string, string];\n const entry = { id, block: Object.freeze({ namespace, id: name }), component };\n Object.defineProperty(entry, 'definition', { enumerable: true, get: definition });\n return Object.freeze(entry) as BlockImplementation<unknown>;\n}\n\nfunction builtinCatalog(): BlockImplementationCatalog {\n return Object.freeze({\n 'buro:related-list': builtinEntry('buro:related-list', RelatedListView, () =>\n relatedList(undefined as never),\n ),\n 'buro:related-record': builtinEntry('buro:related-record', RelatedRecordView, () =>\n relatedRecord(undefined as never),\n ),\n 'buro:inline-flow': builtinEntry('buro:inline-flow', InlineFlowView, () => inlineFlow),\n 'buro:facts': builtinEntry('buro:facts', FactsView, () => facts),\n });\n}\n\n/**\n * The built-in block views (`buro:*`), keyed by block id. The renderer composes them first and\n * the app's `blockImplementations` over them: an app entry with a built-in id replaces that view\n * (with a development notice); a built-in cannot be dropped.\n */\nexport const shadcnBlockImplementations: BlockImplementationCatalog =\n /* @__PURE__ */ builtinCatalog();\n","'use client';\nimport { type DataError, formatEntityRef, normalizeDataError, type PlanNode } from '@burojs/core';\nimport {\n type BlockImplementation,\n type BlockViewProps,\n type PlacementView,\n useOptionalRecordFrame,\n useChromeT,\n useOptionalT,\n usePlacement,\n} from '@burojs/react';\nimport {\n Component,\n type ComponentType,\n type ErrorInfo,\n lazy,\n type ReactElement,\n type ReactNode,\n Suspense,\n useEffect,\n useMemo,\n} from 'react';\nimport { LoadError } from '../load-error/load-error-view.js';\nimport { Button } from '../primitives/button.js';\nimport { Skeleton } from '../primitives/skeleton.js';\nimport { useScreenTree } from '../screen/tree-context.js';\nimport { shadcnBlockImplementations } from './builtins.js';\nimport { PlacementFrameContext } from './placement-frame.js';\nimport { itemHandle } from './related-item.js';\nimport { RouteListContext } from './route-list-context.js';\n\n// biome-ignore lint/suspicious/noExplicitAny: a view of any block\ntype AnyImplementation = BlockImplementation<any>;\ntype View = ComponentType<BlockViewProps<unknown>>;\n\n/** The lazy view of a `load` entry, one per entry object. */\nconst lazyViews = new WeakMap<AnyImplementation, View>();\n/** Built-in ids an app entry replaced, warned once per process. */\nconst replacedWarned = new Set<string>();\n/** Placements reported as `block.not-implemented`, once per location. */\nconst notImplementedReported = new Set<string>();\n\n/** A catalogue entry's view: its component, or its `load` behind `React.lazy` (one per entry). Internal. */\nexport function viewOf(implementation: AnyImplementation): View {\n if (implementation.component !== undefined) return implementation.component as View;\n let view = lazyViews.get(implementation);\n if (view === undefined) {\n const load = implementation.load!;\n view = lazy(async () => {\n const module = await load();\n return { default: module.default as View };\n });\n lazyViews.set(implementation, view);\n }\n return view;\n}\n\n/** The app's entry over the built-in one; a replaced built-in is said once, in development. Internal. */\nexport function selectImplementation(id: string, app: AnyImplementation | undefined) {\n const builtin = Object.hasOwn(shadcnBlockImplementations, id)\n ? shadcnBlockImplementations[id]\n : undefined;\n if (app !== undefined && builtin !== undefined && !replacedWarned.has(id)) {\n replacedWarned.add(id);\n if (process.env.NODE_ENV !== 'production')\n console.warn(\n `[burojs] blockImplementations: the app's ${id} replaces the built-in ${id} view.`,\n );\n }\n return app ?? builtin;\n}\n\ninterface ChromeProps {\n readonly node: PlanNode;\n readonly size: string;\n readonly state?: 'pending' | 'failed';\n readonly children?: ReactNode;\n}\n\n/** The place node's box: the styling contract's attributes (section 9). */\nfunction Chrome({ node, size, state, children }: ChromeProps): ReactElement {\n return (\n <div\n data-buro-node=\"place\"\n {...(node.key === undefined ? {} : { 'data-buro-key': node.key })}\n data-buro-size={size}\n {...(state === undefined ? {} : { 'data-buro-state': state })}\n className=\"min-w-0\"\n >\n {children}\n </div>\n );\n}\n\nfunction isAuthError(error: unknown): error is DataError {\n return normalizeDataError(error).kind === 'auth';\n}\n\n/** @internal The messages `block.<message>` is keyed by, with their English defaults. */\nexport const PLACE_NODE_MESSAGES = {\n failed: 'This section could not be loaded.',\n sessionExpired: 'Your session has expired. Sign in again to continue.',\n notImplemented: 'This section is not available.',\n} as const;\n\n/** A placement that failed: its reason, and Retry when a refetch can help. */\nfunction FailedPlacement({\n node,\n size,\n message,\n retry,\n error,\n}: {\n readonly node: PlanNode;\n readonly size: string;\n readonly message: 'failed' | 'sessionExpired' | 'notImplemented';\n readonly retry?: () => void;\n readonly error?: unknown;\n}): ReactElement {\n const t = useOptionalT();\n const chromeT = useChromeT();\n const fallback = { key: `block.${message}`, default: PLACE_NODE_MESSAGES[message] };\n return (\n <Chrome node={node} size={size} state=\"failed\">\n {message === 'notImplemented' ? (\n // Nothing failed to load: the app has no view for the block, so there is no error to show.\n <div\n role=\"alert\"\n className=\"flex flex-wrap items-center gap-2 rounded-md border border-dashed px-3 py-2 text-sm text-muted-foreground\"\n >\n <span>{t(fallback.key, { defaultValue: fallback.default })}</span>\n {retry === undefined ? null : (\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={retry}>\n {chromeT('actions.retry', { defaultValue: 'Retry' })}\n </Button>\n )}\n </div>\n ) : (\n <LoadError\n surface=\"block\"\n error={error}\n {...(retry === undefined ? {} : { retry })}\n fallback={fallback}\n />\n )}\n </Chrome>\n );\n}\n\nfunction PendingPlacement({ node, size }: { readonly node: PlanNode; readonly size: string }) {\n return (\n <Chrome node={node} size={size} state=\"pending\">\n <Skeleton data-buro-skeleton=\"\" className=\"h-9 w-full\" />\n </Chrome>\n );\n}\n\ninterface BoundaryProps {\n readonly node: PlanNode;\n readonly size: string;\n readonly retryable: boolean;\n readonly onRetry: () => void;\n readonly children: ReactNode;\n}\n\n/**\n * One error boundary per place node: a view that throws while rendering shows the failed\n * chrome in its own box; the frame and the sibling nodes keep rendering.\n */\nclass PlacementBoundary extends Component<BoundaryProps, { readonly failed: boolean }> {\n override state = { failed: false };\n\n static getDerivedStateFromError(): { readonly failed: boolean } {\n return { failed: true };\n }\n\n override componentDidCatch(error: unknown, info: ErrorInfo): void {\n if (process.env.NODE_ENV !== 'production')\n console.error(\n `[burojs] The view of the placement ${this.props.node.key ?? this.props.node.id} threw while rendering.`,\n error,\n info.componentStack,\n );\n }\n\n override render(): ReactNode {\n if (!this.state.failed) return this.props.children;\n const { node, size, retryable, onRetry } = this.props;\n return (\n <FailedPlacement\n node={node}\n size={size}\n message=\"failed\"\n {...(retryable\n ? {\n retry: () => {\n this.setState({ failed: false });\n onRetry();\n },\n }\n : {})}\n />\n );\n }\n}\n\n/** The view props with each `block()` prop as its nested placement, rendered. */\nfunction useViewProps(node: PlanNode, placement: PlacementView): BlockViewProps<unknown> {\n const { compiled } = useScreenTree();\n const viewProps = placement.viewProps!;\n if (node.children.length === 0) return viewProps;\n const props: Record<string, unknown> = { ...(viewProps.props as Record<string, unknown>) };\n const lists = new Map<string, ReactElement[]>();\n for (const child of node.children) {\n const host = compiled.nodes[child.index]?.placement?.host;\n if (host === undefined) continue;\n // The item of a related list is drawn once per row by the list, not here (P6 3.13).\n if (host.itemOf === host.key && host.prop === 'item') {\n props.item = itemHandle(child);\n continue;\n }\n const element = <PlaceNode key={`${child.index}:${child.id}`} node={child} />;\n if (host.index === undefined) props[host.prop] = element;\n else {\n const list = lists.get(host.prop) ?? [];\n list[host.index] = element;\n lists.set(host.prop, list);\n }\n }\n for (const [name, list] of lists) props[name] = list.filter((entry) => entry !== undefined);\n return { ...viewProps, props: props as BlockViewProps<unknown>['props'] };\n}\n\nfunction ReadyPlacement({\n node,\n size,\n placement,\n implementation,\n}: {\n readonly node: PlanNode;\n readonly size: string;\n readonly placement: PlacementView;\n readonly implementation: AnyImplementation;\n}): ReactElement {\n const { compiled, controller } = useScreenTree();\n const View = viewOf(implementation);\n const viewProps = useViewProps(node, placement);\n const placementNode = compiled.nodes[node.index]?.placement;\n const hasData = placementNode?.hasData === true;\n const placementState = placementNode?.state;\n const nested = placementNode?.host !== undefined;\n const declaredWhere = placementNode?.props.where;\n const owner = useOptionalRecordFrame()?.resource;\n const frame = useMemo(\n () => ({\n key: node.key ?? node.id,\n ...(placementState === undefined ? {} : { state: placementState }),\n nested,\n ...(Array.isArray(declaredWhere) ? { where: declaredWhere as readonly unknown[] } : {}),\n closure: compiled.sourceClosure,\n ...(owner === undefined ? {} : { owner }),\n sources: controller.sources,\n }),\n [\n node.key,\n node.id,\n placementState,\n nested,\n declaredWhere,\n compiled.sourceClosure,\n owner,\n controller.sources,\n ],\n );\n return (\n <PlacementBoundary\n node={node}\n size={size}\n retryable={hasData}\n onRetry={() => {\n if (node.key !== undefined) controller.retry([`block:${node.key}`]);\n }}\n >\n <Suspense fallback={<PendingPlacement node={node} size={size} />}>\n <Chrome node={node} size={size}>\n {/* A placement is never the route list, even inside one (a screen in a list cell). */}\n <RouteListContext.Provider value={null}>\n <PlacementFrameContext.Provider value={frame}>\n <View {...viewProps} />\n </PlacementFrameContext.Provider>\n </RouteListContext.Provider>\n </Chrome>\n </Suspense>\n </PlacementBoundary>\n );\n}\n\n/** Reports a placement whose block has no view, once per location (criteria 58, 75). */\nfunction useNotImplemented(node: PlanNode, id: string, missing: boolean): void {\n const { compiled } = useScreenTree();\n const path = compiled.nodes[node.index]?.path ?? [];\n const location = `${path.join('.')} (${node.key ?? node.id})`;\n useEffect(() => {\n if (!missing || process.env.NODE_ENV === 'production') return;\n if (notImplementedReported.has(location + id)) return;\n notImplementedReported.add(location + id);\n console.error(\n `[burojs] block.not-implemented: ${location} places ${id}, which has no view. Add implementBlock(${id}, { load }) to <BuroProvider blockImplementations>.`,\n );\n }, [missing, location, id]);\n}\n\n/**\n * A `place` node (spec 8.1, section 9): the framework chrome around a block view — pending,\n * failed with Retry when a refetch can help, an expired session — and the view itself, the\n * app's over the built-in one, inside its own error boundary.\n */\nexport function PlaceNode({ node }: { readonly node: PlanNode }): ReactElement | null {\n const { compiled, controller } = useScreenTree();\n const placement = usePlacement(node.key ?? '', controller);\n const size = compiled.nodes[node.index]?.options.size ?? 'full';\n const id = formatEntityRef(placement.block);\n const implementation =\n placement.state === 'ready' ? selectImplementation(id, placement.appImplementation) : undefined;\n useNotImplemented(node, id, placement.state === 'ready' && implementation === undefined);\n if (placement.state === 'absent') return null;\n if (placement.state === 'pending') return <PendingPlacement node={node} size={size} />;\n if (placement.state === 'failed')\n return (\n <FailedPlacement\n node={node}\n size={size}\n message={isAuthError(placement.error) ? 'sessionExpired' : 'failed'}\n error={placement.error}\n {...(placement.retry === undefined ? {} : { retry: placement.retry })}\n />\n );\n if (implementation === undefined)\n return <FailedPlacement node={node} size={size} message=\"notImplemented\" />;\n return (\n <ReadyPlacement node={node} size={size} placement={placement} implementation={implementation} />\n );\n}\n"],"mappings":"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"}
|