gridsmith-ui 0.26.0 → 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. package/CHANGELOG.md +969 -0
  2. package/README.md +21 -5
  3. package/dist/charts.d.ts +2 -2
  4. package/dist/charts.js +58 -43
  5. package/dist/charts.js.map +1 -1
  6. package/dist/chat.js +4 -3
  7. package/dist/chat.js.map +1 -1
  8. package/dist/{chunk-CYN5O567.js → chunk-2CKSSWYG.js} +9 -5
  9. package/dist/chunk-2CKSSWYG.js.map +1 -0
  10. package/dist/chunk-3BRQRKDO.js +1 -0
  11. package/dist/chunk-3BRQRKDO.js.map +1 -1
  12. package/dist/{chunk-RWKCAKN3.js → chunk-5TUVX4B2.js} +6 -5
  13. package/dist/chunk-5TUVX4B2.js.map +1 -0
  14. package/dist/{chunk-X2HEV7FB.js → chunk-64TXZ4L7.js} +23 -33
  15. package/dist/chunk-64TXZ4L7.js.map +1 -0
  16. package/dist/chunk-7Q46JXSK.js +1 -0
  17. package/dist/chunk-7Q46JXSK.js.map +1 -1
  18. package/dist/chunk-CRQ6KCRD.js +1 -0
  19. package/dist/chunk-CRQ6KCRD.js.map +1 -1
  20. package/dist/{chunk-ZYVXV4WC.js → chunk-EKBWWA6P.js} +53 -6
  21. package/dist/chunk-EKBWWA6P.js.map +1 -0
  22. package/dist/chunk-HP7WUZPK.js +1 -0
  23. package/dist/chunk-HP7WUZPK.js.map +1 -1
  24. package/dist/{chunk-MYIJNVTK.js → chunk-IXR4UEF4.js} +5 -4
  25. package/dist/chunk-IXR4UEF4.js.map +1 -0
  26. package/dist/chunk-M2QRNBDQ.js +1 -0
  27. package/dist/chunk-M2QRNBDQ.js.map +1 -1
  28. package/dist/chunk-MD2EFMES.js +1 -0
  29. package/dist/chunk-MD2EFMES.js.map +1 -1
  30. package/dist/chunk-NRHIYS5W.js +1 -0
  31. package/dist/chunk-NRHIYS5W.js.map +1 -1
  32. package/dist/chunk-OTCEJN64.js +1 -0
  33. package/dist/chunk-OTCEJN64.js.map +1 -1
  34. package/dist/chunk-OYNUU346.js +78 -0
  35. package/dist/chunk-OYNUU346.js.map +1 -0
  36. package/dist/{chunk-EX64MN2U.js → chunk-PO65I3MQ.js} +4 -3
  37. package/dist/chunk-PO65I3MQ.js.map +1 -0
  38. package/dist/chunk-QM4SJKWV.js +1 -0
  39. package/dist/chunk-QM4SJKWV.js.map +1 -1
  40. package/dist/{chunk-KWLNEH53.js → chunk-R5NFCEZ3.js} +10 -7
  41. package/dist/chunk-R5NFCEZ3.js.map +1 -0
  42. package/dist/chunk-SFY2KMHG.js +1 -0
  43. package/dist/chunk-SFY2KMHG.js.map +1 -1
  44. package/dist/{chunk-HXVXJUGV.js → chunk-TJEV7YAY.js} +38 -10
  45. package/dist/chunk-TJEV7YAY.js.map +1 -0
  46. package/dist/chunk-WH2FUFAC.js +1 -0
  47. package/dist/chunk-WH2FUFAC.js.map +1 -1
  48. package/dist/chunk-XVB55M3N.js +1 -0
  49. package/dist/chunk-XVB55M3N.js.map +1 -1
  50. package/dist/chunk-ZI3OQDET.js +1 -0
  51. package/dist/chunk-ZI3OQDET.js.map +1 -1
  52. package/dist/data-grid.d.ts +1 -1
  53. package/dist/data-grid.js +5 -3
  54. package/dist/data-grid.js.map +1 -1
  55. package/dist/editor-mentions.js +2 -1
  56. package/dist/editor-mentions.js.map +1 -1
  57. package/dist/editor.js +3 -2
  58. package/dist/editor.js.map +1 -1
  59. package/dist/{feather-VFWLAILO.js → feather-FNBQ74RR.js} +10 -17
  60. package/dist/feather-FNBQ74RR.js.map +1 -0
  61. package/dist/{heroicons-H3Z7DFCF.js → heroicons-DODCSYWD.js} +9 -8
  62. package/dist/heroicons-DODCSYWD.js.map +1 -0
  63. package/dist/icons.d.ts +31 -4
  64. package/dist/icons.js +2 -1
  65. package/dist/icons.js.map +1 -1
  66. package/dist/index.d.ts +418 -65
  67. package/dist/index.js +1893 -838
  68. package/dist/index.js.map +1 -1
  69. package/dist/kanban.js +3 -2
  70. package/dist/kanban.js.map +1 -1
  71. package/dist/{lucide-MR32KM4G.js → lucide-ZWE3EPGP.js} +9 -8
  72. package/dist/lucide-ZWE3EPGP.js.map +1 -0
  73. package/dist/{phosphor-ABQQL5N5.js → phosphor-DIHPA4AJ.js} +9 -8
  74. package/dist/phosphor-DIHPA4AJ.js.map +1 -0
  75. package/dist/resizable.js +7 -5
  76. package/dist/resizable.js.map +1 -1
  77. package/dist/roots.css +25 -7
  78. package/dist/{tabler-ANUSY4D2.js → tabler-D3VYTSGI.js} +9 -8
  79. package/dist/tabler-D3VYTSGI.js.map +1 -0
  80. package/dist/tokens.css +11 -8
  81. package/dist/{use-pagination-BnKOnBdz.d.ts → use-pagination-BxcRlNQG.d.ts} +6 -0
  82. package/dist/utils.d.ts +275 -1
  83. package/dist/utils.js +875 -1
  84. package/dist/utils.js.map +1 -1
  85. package/dist/virtualized.d.ts +1 -1
  86. package/dist/virtualized.js +5 -3
  87. package/dist/virtualized.js.map +1 -1
  88. package/dist-static/tokens.css +11 -8
  89. package/package.json +5 -3
  90. package/dist/chunk-CYN5O567.js.map +0 -1
  91. package/dist/chunk-EX64MN2U.js.map +0 -1
  92. package/dist/chunk-HXVXJUGV.js.map +0 -1
  93. package/dist/chunk-KWLNEH53.js.map +0 -1
  94. package/dist/chunk-MYIJNVTK.js.map +0 -1
  95. package/dist/chunk-RWKCAKN3.js.map +0 -1
  96. package/dist/chunk-X2HEV7FB.js.map +0 -1
  97. package/dist/chunk-ZYVXV4WC.js.map +0 -1
  98. package/dist/feather-VFWLAILO.js.map +0 -1
  99. package/dist/heroicons-H3Z7DFCF.js.map +0 -1
  100. package/dist/lucide-MR32KM4G.js.map +0 -1
  101. package/dist/phosphor-ABQQL5N5.js.map +0 -1
  102. package/dist/tabler-ANUSY4D2.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../showcase/src/components/DataGrid.tsx"],"names":[],"mappings":"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","file":"data-grid.js","sourcesContent":["import { useState, useCallback, useEffect, useLayoutEffect, useMemo, useRef, type ReactNode, type KeyboardEvent as ReactKeyboardEvent } from \"react\";\nimport { useShellPreferences } from \"../lib/preferences\";\nimport {\n useReactTable,\n getCoreRowModel,\n getSortedRowModel,\n flexRender,\n type CellContext,\n type ColumnDef,\n type Header,\n type SortingState,\n} from \"@tanstack/react-table\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"../lib/icons\";\nimport { Tooltip } from \"./Tooltip\";\nimport { Input } from \"./Input\";\nimport { Pagination } from \"./Pagination\";\nimport { useTextOverflow } from \"../lib/use-text-overflow\";\nimport { useBreakpoint, type BreakpointKey } from \"../lib/use-breakpoint\";\nimport { inferColumnKinds, type ColumnKind } from \"../lib/table-utils\";\nimport { CardValue } from \"../lib/card-cell\";\nimport { TableCardCtx, RowsCtx, useFramesItself } from \"../lib/surface-context\";\nimport { FormChangeCtx } from \"../lib/form-context\";\nimport { useGridKeyboard } from \"../lib/focus\";\nimport { usePagination, pagerPart, useWholeListCheck, type Pager } from \"../lib/use-pagination\";\nimport { CARDS_BELOW, useCardsSwitch } from \"../lib/use-cards-switch\";\n\n/** Column meta for opt-in truncation. Set on ColumnDef.meta. */\nexport interface DataGridColumnMeta {\n /** true = single-line, or { lines: N } for multi-line clamp. */\n truncate?: boolean | { lines: number };\n /** CSS max-width for the column. */\n maxWidth?: string;\n /** CSS width for the column — sibling grids that share a column set line up when their columns carry the same widths (round 14). */\n width?: string;\n /** CSS min-width for the column. */\n minWidth?: string;\n /** Explicit column kind. When omitted the DataGrid infers it from data values. */\n kind?: ColumnKind;\n /** Horizontal alignment of the header and the cells; a block element (a Checkbox, a Button) is laid out with flex so it follows too (round 14). Default: numbers right, everything else left. */\n align?: \"left\" | \"center\" | \"right\";\n /** In an editable grid, whether this column's cells edit (default true); false for a column that shows (a status, actions). */\n editable?: boolean;\n /**\n * In an editable grid, the value onCellEdit gets from the text typed (default the text itself): a number column's\n * `(text) => Number(text)`, so a salary stays a number (the review of 30 September).\n */\n parse?: (text: string) => unknown;\n}\n\nfunction TruncCell({ children, lines }: { children: ReactNode; lines: number }) {\n const { ref, isTruncated } = useTextOverflow({ lines });\n const clampClass = lines === 1 ? \"truncate\" : `line-clamp-${lines}`;\n const cell = <span ref={ref} className={cn(clampClass, \"block\")}>{children}</span>;\n if (!isTruncated) return cell;\n return <Tooltip content={children}>{cell}</Tooltip>;\n}\n\nexport interface DataGridProps<T> {\n data: T[];\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- public API: columns may carry any value type\n columns: ColumnDef<T, any>[];\n /**\n * Rows a page, over the project's (dataDisplay.itemsPerPage), for a grid the user asked to page differently. Leave it\n * out: the grid pages as the project says, with the project's control (Sprint 25.13 A5; it was 10).\n */\n pageSize?: number;\n /**\n * Cells edit in place, as the APG's grid (Sprint 25.13 A5): the grid is one Tab stop and the arrow keys move between\n * cells; Enter or F2 (or a double-click) opens a cell's editor, Enter or leaving it saves and Escape cancels, and a\n * brief tick, announced as \"Saved\", shows the save. A grid saves as you go, so it never marks a form around it.\n */\n editable?: boolean;\n /**\n * A saved edit: the row's index in `data`, the column's id and the new value (the text typed, or the column's\n * `meta.parse` of it). Called only when the value changed. Return a promise to have the tick and \"Saved\" wait for it:\n * a rejection is announced as \"Not saved\", and the page says why and keeps the old value.\n */\n onCellEdit?: (rowIndex: number, columnId: string, value: unknown) => void | Promise<unknown>;\n /** The screen width below which the grid shows cards: the project's responsive.tableToCardsBreakpoint, else \"md\". */\n mobileBreakpoint?: BreakpointKey;\n /**\n * The grid's own width below which it shows cards when it doesn't fit, in px (Sprint 25.13 A35): about a phone's; 0\n * never switches by width. An editable grid never shows cards: it stays the APG's grid, scrolling sideways.\n */\n cardsBelow?: number;\n /**\n * The list's pager (Sprint 25.13 A3), from `usePagination(data)` over the same rows: pass it when the page also shows\n * the count (TableToolbar). Without it the grid pages itself the same way.\n */\n pager?: Pager<unknown>;\n /** The grid's name for assistive tech. */\n \"aria-label\"?: string;\n className?: string;\n}\n\n/** A cell of an editable grid: its row among those drawn (-1 for the header) and its column. */\ninterface CellAt { r: number; c: number }\nconst cellKey = (p: CellAt) => (p.r < 0 ? `h:${p.c}` : `${p.r}:${p.c}`);\n/** A cell by its row's id (null for the header), which a sort or a save that re-sorts never moves to another row. */\ninterface CellId { row: string | null; c: number }\n/** How long the saved tick shows, in ms (A5). */\nconst SAVED_TICK_MS = 1500;\n\nexport function DataGrid<T>({\n data,\n columns,\n pageSize,\n editable = false,\n onCellEdit,\n mobileBreakpoint: mobileBreakpointProp,\n cardsBelow = CARDS_BELOW,\n pager: pagerProp,\n \"aria-label\": ariaLabel,\n className,\n}: DataGridProps<T>) {\n // Sprint 25.14 A44: a grid draws its own frame, so a SplitView's list pane draws none around it\n useFramesItself();\n // Sprint 25.6 (B9): responsive.tableToCardsBreakpoint reaches the table through the shell; a prop wins; md outside any shell.\n const preferences = useShellPreferences();\n const mobileBreakpoint: BreakpointKey = mobileBreakpointProp ?? preferences.tableToCardsBreakpoint ?? \"md\";\n const narrowScreen = useBreakpoint(mobileBreakpoint);\n // A35: cards only on a narrow screen or where the grid's own width is a phone's. An editable grid stays the APG's grid\n // at every width, scrolling sideways: its cards have no editor (the review of 30 September: in a default Drawer, whose\n // body is 359 px, the grid went to cards and could no longer be edited).\n const { cards: isMobile, rootRef } = useCardsSwitch(editable ? false : narrowScreen, editable ? 0 : cardsBelow);\n const [sorting, setSorting] = useState<SortingState>([]);\n const [editing, setEditing] = useState<(CellId & { value: string; was: string }) | null>(null);\n\n /* ── Column kind inference ─────────────────────────────────────────── */\n const columnKeys = useMemo(() => columns.map((c) => c.id ?? (\"accessorKey\" in c ? String(c.accessorKey) : \"\")).filter(Boolean), [columns]);\n const inferredKinds = useMemo(\n () => inferColumnKinds(data as Record<string, unknown>[], columnKeys),\n [data, columnKeys],\n );\n const kindOf = useCallback(\n (colId: string, meta: DataGridColumnMeta | undefined) => meta?.kind ?? inferredKinds.get(colId),\n [inferredKinds],\n );\n\n // TanStack Table returns functions the React Compiler cannot memoise; the\n // compiler would skip this component, which is fine — the project does not\n // use it. The note is informational, not a defect.\n // eslint-disable-next-line react-hooks/incompatible-library -- TanStack Table is not compiler-compatible\n const table = useReactTable({\n data,\n columns,\n state: { sorting },\n onSortingChange: (updater) => { setSorting(updater); pagerProp?.setPage(1); },\n getCoreRowModel: getCoreRowModel(),\n getSortedRowModel: getSortedRowModel(),\n });\n\n // ── A5 / A3: the project's page size and list style, through the pager, over every row sorted ──\n const sortedRows = table.getRowModel().rows;\n const ownPager = usePagination(sortedRows, { pageSize, resetOn: sorting });\n const pager = pagerProp ?? ownPager;\n useWholeListCheck(\"DataGrid\", data.length, pagerProp);\n const rows = pagerPart(sortedRows, pager);\n const leafColumns = table.getVisibleLeafColumns();\n const headerText = (id: string) => {\n const header = leafColumns.find((c) => c.id === id)?.columnDef.header;\n return typeof header === \"string\" ? header : id;\n };\n\n // ── A5: the grid's keyboard (the APG's grid), when editable ──\n // The Tab stop, the editor and the saved tick are kept by the row's id, so a sort, or a save that re-sorts the rows,\n // keeps each on its row (the review of 30 September: the tick and the Tab stop went to the row now in the old place).\n const gridRef = useRef<HTMLTableElement>(null);\n const [activeId, setActiveId] = useState<CellId>({ row: null, c: 0 });\n const lastRow = rows.length - 1;\n const rowAt = (id: string | null) => (id === null ? -1 : rows.findIndex((row) => row.id === id));\n const idAt = (p: CellAt): CellId => ({ row: p.r < 0 ? null : rows[p.r]?.id ?? null, c: p.c });\n const current: CellAt = { r: Math.min(rowAt(activeId.row), lastRow), c: Math.min(activeId.c, Math.max(0, leafColumns.length - 1)) };\n const setActive = (p: CellAt) => setActiveId(idAt(p));\n const move = (p: CellAt, e: ReactKeyboardEvent): CellAt | null => {\n // Alt with an arrow is the browser's (Back, Forward), and Ctrl or ⌘ with one too; Ctrl or ⌘ with Home or End goes to\n // the grid's first or last cell (the APG's grid)\n if (e.altKey) return null;\n const toCorner = e.ctrlKey || e.metaKey;\n switch (e.key) {\n case \"ArrowRight\": return !toCorner && p.c < leafColumns.length - 1 ? { ...p, c: p.c + 1 } : null;\n case \"ArrowLeft\": return !toCorner && p.c > 0 ? { ...p, c: p.c - 1 } : null;\n case \"ArrowDown\": return !toCorner && p.r < lastRow ? { ...p, r: p.r + 1 } : null;\n case \"ArrowUp\": return !toCorner && p.r > -1 ? { ...p, r: p.r - 1 } : null;\n case \"Home\": return toCorner ? { r: -1, c: 0 } : { ...p, c: 0 };\n case \"End\": return toCorner ? { r: lastRow, c: leafColumns.length - 1 } : { ...p, c: leafColumns.length - 1 };\n default: return null;\n }\n };\n // an edit ends once: Enter saves and unmounts the editor, whose blur must not save it again\n const ended = useRef(false);\n const startEdit = (p: CellAt) => {\n const row = rows[p.r];\n const column = leafColumns[p.c];\n if (!row || !column || (column.columnDef.meta as DataGridColumnMeta | undefined)?.editable === false) return;\n ended.current = false;\n setActive(p);\n const text = String(row.getValue(column.id) ?? \"\");\n setEditing({ row: row.id, c: p.c, value: text, was: text });\n };\n const grid = useGridKeyboard<CellAt>({\n container: gridRef,\n active: current,\n setActive,\n keyOf: cellKey,\n move,\n onActivate: (p, e) => {\n if (p.r < 0) { if (leafColumns[p.c]?.getCanSort()) leafColumns[p.c].toggleSorting(); }\n else if (e.key === \"Enter\") startEdit(p);\n },\n modifierKeys: true,\n });\n const onGridKeyDown = (e: ReactKeyboardEvent) => {\n // F2 opens the cell's editor too (the APG's grid)\n if (e.key === \"F2\" && !editing && current.r >= 0 && e.target instanceof HTMLElement && e.target.getAttribute(\"data-grid-key\") === cellKey(current)) {\n e.preventDefault();\n startEdit(current);\n return;\n }\n grid.onKeyDown(e);\n };\n // the Tab stop follows focus, however it got there: a click, a screen reader's command, a double-click (the hook's\n // contract; the review of 30 September: a clicked cell took no Enter, and ArrowDown went from the header)\n const onGridFocus = (e: React.FocusEvent) => {\n const key = e.target instanceof HTMLElement ? e.target.getAttribute(\"data-grid-key\") : null;\n if (!key) return;\n const [r, c] = key.startsWith(\"h:\") ? [-1, Number(key.slice(2))] : key.split(\":\").map(Number);\n if (Number.isFinite(r) && Number.isFinite(c) && cellKey(current) !== key) setActive({ r, c });\n };\n\n // ── A5: the save, its tick and its announcement ──\n const [saved, setSaved] = useState<{ row: string; c: number; n: number; ok: boolean } | null>(null);\n useEffect(() => {\n if (!saved) return;\n const t = setTimeout(() => setSaved((s) => (s && s.n === saved.n ? null : s)), SAVED_TICK_MS);\n return () => clearTimeout(t);\n }, [saved]);\n const heard = useRef(0);\n // after Enter or Escape focus comes back to the cell, on its row wherever a save that re-sorts puts it: its page first\n const refocus = useRef<CellId | null>(null);\n useLayoutEffect(() => {\n const want = refocus.current;\n if (!want) return;\n const r = rowAt(want.row);\n if (r < 0) {\n const all = sortedRows.findIndex((row) => row.id === want.row);\n if (all >= 0 && pager.style === \"pagination\") { const page = Math.floor(all / pager.pageSize) + 1; if (page !== pager.page) { pager.setPage(page); return; } }\n refocus.current = null;\n return;\n }\n refocus.current = null;\n grid.focus({ r, c: want.c });\n });\n const finishEdit = (commit: boolean, focusBack: boolean) => {\n if (!editing || ended.current) return;\n ended.current = true;\n const r = rowAt(editing.row);\n const row = rows[r];\n const column = leafColumns[editing.c];\n const cell = { row: editing.row, c: editing.c };\n setEditing(null);\n // leaving the editor (a click elsewhere, Tab) saves and lets focus go where it went (the review of 30 September:\n // it pulled focus back, and the next keys were lost)\n if (focusBack) { setActiveId(cell); refocus.current = cell; }\n // a save that changes nothing isn't one\n if (!commit || !row || !column || editing.value === editing.was) return;\n const meta = column.columnDef.meta as DataGridColumnMeta | undefined;\n const done = (ok: boolean) => { heard.current += 1; setSaved({ ...cell, row: editing.row!, n: heard.current, ok }); };\n const result = onCellEdit?.(row.index, column.id, meta?.parse ? meta.parse(editing.value) : editing.value);\n if (result && typeof (result as Promise<unknown>).then === \"function\") (result as Promise<unknown>).then(() => done(true), () => done(false));\n else done(true);\n };\n\n // A3: the grid and its control are one element, as in 0.21, which takes the className: in a grid or a flex row they\n // stay one item (the review of 30 September: the control became an item of its own beside the grid)\n const control = data.length > 0 ? <Pagination {...pager.props} /> : null;\n const setRoot = (node: HTMLDivElement | null) => { rootRef.current = node; };\n const withControl = (list: ReactNode) => <div ref={setRoot} data-gs-paged=\"\" className={cn(\"flex flex-col min-w-0\", className)}>{list}{control}</div>;\n\n if (isMobile) {\n return withControl(\n <div data-ds-list=\"\" className=\"space-y-ds-3\">\n <TableCardCtx value={true}><RowsCtx value={true}>\n <div className=\"flex flex-col gap-ds-3\">\n {rows.map((row) => (\n <div\n key={row.id}\n className={cn(\n \"border-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]\",\n \"rounded-[var(--ds-radius-md)] bg-[var(--ds-bg-surface)]\",\n \"p-ds-4 space-y-ds-3\",\n )}\n >\n {row.getVisibleCells().map((cell) => (\n <div key={cell.id} className=\"flex justify-between gap-ds-2 text-sm\">\n <span className=\"shrink-0 text-[var(--ds-text-secondary)] font-medium text-xs uppercase tracking-wider\">\n {typeof cell.column.columnDef.header === \"string\"\n ? cell.column.columnDef.header\n : cell.column.id}\n </span>\n <CardValue value={flexRender(cell.column.columnDef.cell, cell.getContext())} />\n </div>\n ))}\n </div>\n ))}\n </div>\n </RowsCtx></TableCardCtx>\n </div>\n );\n }\n\n const sortIcons = (sorted: false | \"asc\" | \"desc\") => (\n <span className=\"inline-flex flex-col -space-y-ds-1.5\" aria-hidden=\"true\">\n <Icon name=\"chevron-up\" size={10} className={sorted === \"asc\" ? \"text-[var(--ds-accent-primary)]\" : \"opacity-30\"} />\n <Icon name=\"chevron-down\" size={10} className={sorted === \"desc\" ? \"text-[var(--ds-accent-primary)]\" : \"opacity-30\"} />\n </span>\n );\n const headerCell = (header: Header<T, unknown>, c: number) => {\n const canSort = header.column.getCanSort();\n const sorted = header.column.getIsSorted();\n const meta = header.column.columnDef.meta as DataGridColumnMeta | undefined;\n const headerKind = kindOf(header.column.id, meta);\n const headerAlign = meta?.align ?? (headerKind === \"number\" ? \"right\" : \"left\");\n const shrink = (headerKind === \"number\" || headerKind === \"date\") && !meta?.maxWidth;\n const at = { r: -1, c };\n const label = flexRender(header.column.columnDef.header, header.getContext());\n // A47: a sortable header holds a button: a Tab stop in a read-only grid, a cell the arrows reach in an editable one\n const inside = canSort ? (\n <button\n type=\"button\"\n onClick={header.column.getToggleSortingHandler()}\n {...(editable ? { \"data-grid-key\": cellKey(at), tabIndex: grid.tabIndexOf(at) } : {})}\n className={cn(\n \"inline-flex items-center gap-ds-1 uppercase tracking-wider cursor-pointer select-none [font:inherit] text-inherit\",\n \"hover:text-[var(--ds-text-primary)] rounded-[var(--ds-radius-sm)] focus-visible:outline-none focus-visible:shadow-[var(--ds-shadow-focus)]\",\n )}\n >\n {label}\n {sortIcons(sorted)}\n </button>\n ) : label;\n return (\n <th\n key={header.id}\n role={editable ? \"columnheader\" : undefined}\n aria-sort={sorted === \"asc\" ? \"ascending\" : sorted === \"desc\" ? \"descending\" : undefined}\n {...(editable && !canSort ? { \"data-grid-key\": cellKey(at), tabIndex: grid.tabIndexOf(at) } : {})}\n className={cn(\n \"px-ds-4 py-ds-3 text-xs font-[var(--ds-weight-heading)] uppercase tracking-wider\",\n headerAlign === \"right\" ? \"text-right\" : headerAlign === \"center\" ? \"text-center\" : \"text-left\",\n shrink && \"w-px whitespace-nowrap\",\n \"text-[var(--ds-text-secondary)] outline-none focus-visible:shadow-[inset_var(--ds-shadow-focus)]\",\n )}\n style={meta?.maxWidth || meta?.width || meta?.minWidth ? { maxWidth: meta?.maxWidth, width: meta?.width, minWidth: meta?.minWidth } : undefined}\n >\n <span className={cn(\"flex items-center gap-ds-1\", headerAlign === \"right\" && \"justify-end\", headerAlign === \"center\" && \"justify-center\")}>\n {inside}\n </span>\n </th>\n );\n };\n\n return withControl(\n <div data-ds-list=\"\" className=\"min-w-0\">\n <div\n // the scroll area the width switch reads (A35), as the Table's\n data-table-scroll=\"\"\n className={cn(\n \"relative w-full overflow-auto rounded-[var(--ds-radius-md)]\",\n \"border-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]\",\n \"shadow-[var(--ds-shadow-card)]\",\n \"bg-[var(--ds-bg-surface)]\",\n )}\n >\n <table\n ref={gridRef}\n role={editable ? \"grid\" : undefined}\n aria-label={ariaLabel}\n onKeyDown={editable ? onGridKeyDown : undefined}\n onFocus={editable ? onGridFocus : undefined}\n className=\"w-full text-sm\"\n >\n <thead className=\"bg-[var(--ds-bg-muted)]\">\n {table.getHeaderGroups().map((hg) => (\n <tr key={hg.id} role={editable ? \"row\" : undefined} className=\"border-b-[length:var(--ds-divider-width)] border-[var(--ds-border-subtle)]\">\n {hg.headers.map((header, c) => headerCell(header, c))}\n </tr>\n ))}\n </thead>\n <tbody><RowsCtx value={true}>\n {rows.map((row, r) => (\n <tr\n key={row.id}\n role={editable ? \"row\" : undefined}\n className={cn(\n \"border-b-[length:var(--ds-divider-width)] border-[var(--ds-border-subtle)] last:border-b-0\",\n \"hover:bg-[var(--ds-bg-muted)] transition-colors\",\n )}\n >\n {row.getVisibleCells().map((cell, c) => {\n const meta = cell.column.columnDef.meta as DataGridColumnMeta | undefined;\n const truncLines = meta?.truncate === true ? 1 : meta?.truncate ? meta.truncate.lines : 0;\n const kind = kindOf(cell.column.id, meta);\n const rendered = flexRender(cell.column.columnDef.cell, cell.getContext() as CellContext<T, unknown>);\n const at = { r, c };\n const isEditing = editable && editing?.row === row.id && editing.c === c;\n\n const shrink = (kind === \"number\" || kind === \"date\") && !meta?.maxWidth;\n let inner: ReactNode;\n if (isEditing) {\n // the library's Input, named for its column; Enter or leaving it saves, Escape cancels. A grid saves as\n // you go, so its editor never marks a form around it; the cells' own controls still do (the review\n // of 30 September: the whole grid opted out, and a Drawer closed on a changed checkbox unasked)\n inner = (\n <FormChangeCtx value={null}>\n <Input\n size=\"sm\"\n autoFocus\n aria-label={headerText(cell.column.id)}\n // the value opens selected: typing replaces it, an arrow key keeps it\n onFocus={(e) => e.currentTarget.select()}\n value={editing.value}\n onChange={(e) => setEditing({ ...editing, value: e.target.value })}\n onBlur={() => finishEdit(true, false)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") { e.preventDefault(); finishEdit(true, true); }\n else if (e.key === \"Escape\") { e.preventDefault(); e.stopPropagation(); finishEdit(false, true); }\n }}\n />\n </FormChangeCtx>\n );\n } else if (truncLines > 0) {\n inner = <TruncCell lines={truncLines}>{rendered}</TruncCell>;\n } else if (kind === \"email\") {\n inner = (\n <span className=\"max-w-[40ch] truncate inline-block align-bottom\" title={typeof cell.getValue() === \"string\" ? cell.getValue() as string : undefined}>\n {rendered}\n </span>\n );\n } else {\n inner = rendered;\n }\n // Round 14 (50.2): a centred or right-aligned column lays a block element out with flex — text-align moves inline content only.\n const align = meta?.align ?? (kind === \"number\" ? \"right\" : \"left\");\n const value = cell.getValue();\n if (!isEditing && align !== \"left\" && typeof value !== \"string\" && typeof value !== \"number\" && value !== null && value !== undefined) {\n inner = <div className={cn(\"flex items-center\", align === \"center\" ? \"justify-center\" : \"justify-end\")}>{inner}</div>;\n }\n const tick = editable && saved?.ok && saved.row === row.id && saved.c === c\n ? <Icon name=\"check\" size={14} className=\"ml-ds-1 inline-block align-middle text-[var(--ds-status-success)]\" />\n : null;\n\n return (\n <td\n key={cell.id}\n // a double-click in the open editor selects a word, and never reopens it over what was typed\n {...(editable ? { role: \"gridcell\", \"data-grid-key\": cellKey(at), tabIndex: grid.tabIndexOf(at), onDoubleClick: () => { if (!isEditing) startEdit(at); } } : {})}\n className={cn(\n \"px-ds-4 py-ds-3 text-[var(--ds-text-primary)]\",\n align === \"right\" && \"text-right\",\n align === \"center\" && \"text-center\",\n shrink && \"w-px whitespace-nowrap\",\n editable && \"outline-none focus-visible:shadow-[inset_var(--ds-shadow-focus)]\",\n )}\n style={meta?.maxWidth || meta?.width || meta?.minWidth ? { maxWidth: meta?.maxWidth, width: meta?.width, minWidth: meta?.minWidth } : undefined}\n >\n {inner}\n {tick}\n </td>\n );\n })}\n </tr>\n ))}\n </RowsCtx></tbody>\n </table>\n </div>\n {/* A5: a save is heard, politely (WCAG 4.1.3); each one is a new line, so two saves are heard twice */}\n {editable && <div role=\"status\" className=\"sr-only\"><span key={saved?.n ?? 0}>{saved ? (saved.ok ? \"Saved\" : \"Not saved\") : \"\"}</span></div>}\n </div>\n );\n}\n"]}
1
+ {"version":3,"sources":["../../../showcase/src/components/DataGrid.tsx"],"names":[],"mappings":"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","file":"data-grid.js","sourcesContent":["import { useState, useCallback, useEffect, useLayoutEffect, useMemo, useRef, type ReactNode, type KeyboardEvent as ReactKeyboardEvent } from \"react\";\nimport { useShellPreferences } from \"../lib/preferences\";\nimport {\n useReactTable,\n getCoreRowModel,\n getSortedRowModel,\n flexRender,\n type CellContext,\n type ColumnDef,\n type Header,\n type SortingState,\n} from \"@tanstack/react-table\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"../lib/icons\";\nimport { Tooltip } from \"./Tooltip\";\nimport { Input } from \"./Input\";\nimport { Pagination } from \"./Pagination\";\nimport { useTextOverflow } from \"../lib/use-text-overflow\";\nimport { useBreakpoint, type BreakpointKey } from \"../lib/use-breakpoint\";\nimport { inferColumnKinds, type ColumnKind } from \"../lib/table-utils\";\nimport { CardValue } from \"../lib/card-cell\";\nimport { TableCardCtx, RowsCtx, useFramesItself } from \"../lib/surface-context\";\nimport { FormChangeCtx } from \"../lib/form-context\";\nimport { useGridKeyboard } from \"../lib/focus\";\nimport { usePagination, pagerPart, useWholeListCheck, type Pager } from \"../lib/use-pagination\";\nimport { CARDS_BELOW, useCardsSwitch } from \"../lib/use-cards-switch\";\n\n/** Column meta for opt-in truncation. Set on ColumnDef.meta. */\nexport interface DataGridColumnMeta {\n /** true = single-line, or { lines: N } for multi-line clamp. */\n truncate?: boolean | { lines: number };\n /** CSS max-width for the column. */\n maxWidth?: string;\n /** CSS width for the column — sibling grids that share a column set line up when their columns carry the same widths (round 14). */\n width?: string;\n /** CSS min-width for the column. */\n minWidth?: string;\n /** Explicit column kind. When omitted the DataGrid infers it from data values. */\n kind?: ColumnKind;\n /** Horizontal alignment of the header and the cells; a block element (a Checkbox, a Button) is laid out with flex so it follows too (round 14). Default: numbers right, everything else left. */\n align?: \"left\" | \"center\" | \"right\";\n /** In an editable grid, whether this column's cells edit (default true); false for a column that shows (a status, actions). */\n editable?: boolean;\n /**\n * In an editable grid, the value onCellEdit gets from the text typed (default the text itself): a number column's\n * `(text) => Number(text)`, so a salary stays a number (the review of 30 September).\n */\n parse?: (text: string) => unknown;\n}\n\nfunction TruncCell({ children, lines }: { children: ReactNode; lines: number }) {\n const { ref, isTruncated } = useTextOverflow({ lines });\n const clampClass = lines === 1 ? \"truncate\" : `line-clamp-${lines}`;\n const cell = <span ref={ref} className={cn(clampClass, \"block\")}>{children}</span>;\n if (!isTruncated) return cell;\n return <Tooltip content={children}>{cell}</Tooltip>;\n}\n\nexport interface DataGridProps<T> {\n data: T[];\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- public API: columns may carry any value type\n columns: ColumnDef<T, any>[];\n /**\n * Rows a page, over the project's (dataDisplay.itemsPerPage), for a grid the user asked to page differently. Leave it\n * out: the grid pages as the project says, with the project's control (Sprint 25.13 A5; it was 10).\n */\n pageSize?: number;\n /**\n * Cells edit in place, as the APG's grid (Sprint 25.13 A5): the grid is one Tab stop and the arrow keys move between\n * cells; Enter or F2 (or a double-click) opens a cell's editor, Enter or leaving it saves and Escape cancels, and a\n * brief tick, announced as \"Saved\", shows the save. A grid saves as you go, so it never marks a form around it.\n */\n editable?: boolean;\n /**\n * A saved edit: the row's index in `data`, the column's id and the new value (the text typed, or the column's\n * `meta.parse` of it). Called only when the value changed. Return a promise to have the tick and \"Saved\" wait for it:\n * a rejection is announced as \"Not saved\", and the page says why and keeps the old value.\n */\n onCellEdit?: (rowIndex: number, columnId: string, value: unknown) => void | Promise<unknown>;\n /** The screen width below which the grid shows cards: the project's responsive.tableToCardsBreakpoint, else \"md\". */\n mobileBreakpoint?: BreakpointKey;\n /**\n * The grid's own width below which it shows cards when it doesn't fit, in px (Sprint 25.13 A35): about a phone's; 0\n * never switches by width. An editable grid never shows cards: it stays the APG's grid, scrolling sideways.\n */\n cardsBelow?: number;\n /**\n * The list's pager (Sprint 25.13 A3), from `usePagination(data)` over the same rows: pass it when the page also shows\n * the count (TableToolbar). Without it the grid pages itself the same way.\n */\n pager?: Pager<unknown>;\n /** The grid's name for assistive tech. */\n \"aria-label\"?: string;\n className?: string;\n}\n\n/** A cell of an editable grid: its row among those drawn (-1 for the header) and its column. */\ninterface CellAt { r: number; c: number }\nconst cellKey = (p: CellAt) => (p.r < 0 ? `h:${p.c}` : `${p.r}:${p.c}`);\n/** A cell by its row's id (null for the header), which a sort or a save that re-sorts never moves to another row. */\ninterface CellId { row: string | null; c: number }\n/** How long the saved tick shows, in ms (A5). */\nconst SAVED_TICK_MS = 1500;\n\nexport function DataGrid<T>({\n data,\n columns,\n pageSize,\n editable = false,\n onCellEdit,\n mobileBreakpoint: mobileBreakpointProp,\n cardsBelow = CARDS_BELOW,\n pager: pagerProp,\n \"aria-label\": ariaLabel,\n className,\n}: DataGridProps<T>) {\n // Sprint 25.14 A44: a grid draws its own frame, so a SplitView's list pane draws none around it\n useFramesItself();\n // Sprint 25.6 (B9): responsive.tableToCardsBreakpoint reaches the table through the shell; a prop wins; md outside any shell.\n const preferences = useShellPreferences();\n const mobileBreakpoint: BreakpointKey = mobileBreakpointProp ?? preferences.tableToCardsBreakpoint ?? \"md\";\n const narrowScreen = useBreakpoint(mobileBreakpoint);\n // A35: cards only on a narrow screen or where the grid's own width is a phone's. An editable grid stays the APG's grid\n // at every width, scrolling sideways: its cards have no editor (the review of 30 September: in a default Drawer, whose\n // body is 359 px, the grid went to cards and could no longer be edited).\n const { cards: isMobile, rootRef } = useCardsSwitch(editable ? false : narrowScreen, editable ? 0 : cardsBelow);\n const [sorting, setSorting] = useState<SortingState>([]);\n const [editing, setEditing] = useState<(CellId & { value: string; was: string }) | null>(null);\n\n /* ── Column kind inference ─────────────────────────────────────────── */\n const columnKeys = useMemo(() => columns.map((c) => c.id ?? (\"accessorKey\" in c ? String(c.accessorKey) : \"\")).filter(Boolean), [columns]);\n const inferredKinds = useMemo(\n () => inferColumnKinds(data as Record<string, unknown>[], columnKeys),\n [data, columnKeys],\n );\n const kindOf = useCallback(\n (colId: string, meta: DataGridColumnMeta | undefined) => meta?.kind ?? inferredKinds.get(colId),\n [inferredKinds],\n );\n\n // TanStack Table returns functions the React Compiler cannot memoise; the\n // compiler would skip this component, which is fine — the project does not\n // use it. The note is informational, not a defect.\n // eslint-disable-next-line react-hooks/incompatible-library -- TanStack Table is not compiler-compatible\n const table = useReactTable({\n data,\n columns,\n state: { sorting },\n onSortingChange: (updater) => { setSorting(updater); pagerProp?.setPage(1); },\n getCoreRowModel: getCoreRowModel(),\n getSortedRowModel: getSortedRowModel(),\n });\n\n // ── A5 / A3: the project's page size and list style, through the pager, over every row sorted ──\n const sortedRows = table.getRowModel().rows;\n const ownPager = usePagination(sortedRows, { pageSize, resetOn: sorting });\n const pager = pagerProp ?? ownPager;\n useWholeListCheck(\"DataGrid\", data.length, pagerProp);\n const rows = pagerPart(sortedRows, pager);\n const leafColumns = table.getVisibleLeafColumns();\n const headerText = (id: string) => {\n const header = leafColumns.find((c) => c.id === id)?.columnDef.header;\n return typeof header === \"string\" ? header : id;\n };\n\n // ── A5: the grid's keyboard (the APG's grid), when editable ──\n // The Tab stop, the editor and the saved tick are kept by the row's id, so a sort, or a save that re-sorts the rows,\n // keeps each on its row (the review of 30 September: the tick and the Tab stop went to the row now in the old place).\n const gridRef = useRef<HTMLTableElement>(null);\n const [activeId, setActiveId] = useState<CellId>({ row: null, c: 0 });\n const lastRow = rows.length - 1;\n const rowAt = (id: string | null) => (id === null ? -1 : rows.findIndex((row) => row.id === id));\n const idAt = (p: CellAt): CellId => ({ row: p.r < 0 ? null : rows[p.r]?.id ?? null, c: p.c });\n const current: CellAt = { r: Math.min(rowAt(activeId.row), lastRow), c: Math.min(activeId.c, Math.max(0, leafColumns.length - 1)) };\n const setActive = (p: CellAt) => setActiveId(idAt(p));\n const move = (p: CellAt, e: ReactKeyboardEvent): CellAt | null => {\n // Alt with an arrow is the browser's (Back, Forward), and Ctrl or ⌘ with one too; Ctrl or ⌘ with Home or End goes to\n // the grid's first or last cell (the APG's grid)\n if (e.altKey) return null;\n const toCorner = e.ctrlKey || e.metaKey;\n switch (e.key) {\n case \"ArrowRight\": return !toCorner && p.c < leafColumns.length - 1 ? { ...p, c: p.c + 1 } : null;\n case \"ArrowLeft\": return !toCorner && p.c > 0 ? { ...p, c: p.c - 1 } : null;\n case \"ArrowDown\": return !toCorner && p.r < lastRow ? { ...p, r: p.r + 1 } : null;\n case \"ArrowUp\": return !toCorner && p.r > -1 ? { ...p, r: p.r - 1 } : null;\n case \"Home\": return toCorner ? { r: -1, c: 0 } : { ...p, c: 0 };\n case \"End\": return toCorner ? { r: lastRow, c: leafColumns.length - 1 } : { ...p, c: leafColumns.length - 1 };\n default: return null;\n }\n };\n // an edit ends once: Enter saves and unmounts the editor, whose blur must not save it again\n const ended = useRef(false);\n const startEdit = (p: CellAt) => {\n const row = rows[p.r];\n const column = leafColumns[p.c];\n if (!row || !column || (column.columnDef.meta as DataGridColumnMeta | undefined)?.editable === false) return;\n ended.current = false;\n setActive(p);\n const text = String(row.getValue(column.id) ?? \"\");\n setEditing({ row: row.id, c: p.c, value: text, was: text });\n };\n const grid = useGridKeyboard<CellAt>({\n container: gridRef,\n active: current,\n setActive,\n keyOf: cellKey,\n move,\n onActivate: (p, e) => {\n if (p.r < 0) { if (leafColumns[p.c]?.getCanSort()) leafColumns[p.c].toggleSorting(); }\n else if (e.key === \"Enter\") startEdit(p);\n },\n modifierKeys: true,\n });\n const onGridKeyDown = (e: ReactKeyboardEvent) => {\n // F2 opens the cell's editor too (the APG's grid)\n if (e.key === \"F2\" && !editing && current.r >= 0 && e.target instanceof HTMLElement && e.target.getAttribute(\"data-grid-key\") === cellKey(current)) {\n e.preventDefault();\n startEdit(current);\n return;\n }\n grid.onKeyDown(e);\n };\n // the Tab stop follows focus, however it got there: a click, a screen reader's command, a double-click (the hook's\n // contract; the review of 30 September: a clicked cell took no Enter, and ArrowDown went from the header)\n const onGridFocus = (e: React.FocusEvent) => {\n const key = e.target instanceof HTMLElement ? e.target.getAttribute(\"data-grid-key\") : null;\n if (!key) return;\n const [r, c] = key.startsWith(\"h:\") ? [-1, Number(key.slice(2))] : key.split(\":\").map(Number);\n if (Number.isFinite(r) && Number.isFinite(c) && cellKey(current) !== key) setActive({ r, c });\n };\n\n // ── A5: the save, its tick and its announcement ──\n const [saved, setSaved] = useState<{ row: string; c: number; n: number; ok: boolean } | null>(null);\n useEffect(() => {\n if (!saved) return;\n const t = setTimeout(() => setSaved((s) => (s && s.n === saved.n ? null : s)), SAVED_TICK_MS);\n return () => clearTimeout(t);\n }, [saved]);\n const heard = useRef(0);\n // after Enter or Escape focus comes back to the cell, on its row wherever a save that re-sorts puts it: its page first\n const refocus = useRef<CellId | null>(null);\n useLayoutEffect(() => {\n const want = refocus.current;\n if (!want) return;\n const r = rowAt(want.row);\n if (r < 0) {\n const all = sortedRows.findIndex((row) => row.id === want.row);\n if (all >= 0 && pager.style === \"pagination\") { const page = Math.floor(all / pager.pageSize) + 1; if (page !== pager.page) { pager.setPage(page); return; } }\n refocus.current = null;\n return;\n }\n refocus.current = null;\n grid.focus({ r, c: want.c });\n });\n const finishEdit = (commit: boolean, focusBack: boolean) => {\n if (!editing || ended.current) return;\n ended.current = true;\n const r = rowAt(editing.row);\n const row = rows[r];\n const column = leafColumns[editing.c];\n const cell = { row: editing.row, c: editing.c };\n setEditing(null);\n // leaving the editor (a click elsewhere, Tab) saves and lets focus go where it went (the review of 30 September:\n // it pulled focus back, and the next keys were lost)\n if (focusBack) { setActiveId(cell); refocus.current = cell; }\n // a save that changes nothing isn't one\n if (!commit || !row || !column || editing.value === editing.was) return;\n const meta = column.columnDef.meta as DataGridColumnMeta | undefined;\n const done = (ok: boolean) => { heard.current += 1; setSaved({ ...cell, row: editing.row!, n: heard.current, ok }); };\n const result = onCellEdit?.(row.index, column.id, meta?.parse ? meta.parse(editing.value) : editing.value);\n if (result && typeof (result as Promise<unknown>).then === \"function\") (result as Promise<unknown>).then(() => done(true), () => done(false));\n else done(true);\n };\n\n // A3: the grid and its control are one element, as in 0.21, which takes the className: in a grid or a flex row they\n // stay one item (the review of 30 September: the control became an item of its own beside the grid)\n const control = data.length > 0 ? <Pagination {...pager.props} /> : null;\n const setRoot = (node: HTMLDivElement | null) => { rootRef.current = node; };\n const withControl = (list: ReactNode) => <div ref={setRoot} data-gs-paged=\"\" className={cn(\"flex flex-col min-w-0\", className)}>{list}{control}</div>;\n\n if (isMobile) {\n return withControl(\n <div data-ds-list=\"\" className=\"space-y-ds-3\">\n <TableCardCtx value={true}><RowsCtx value={true}>\n <div className=\"flex flex-col gap-ds-3\">\n {rows.map((row) => (\n <div\n key={row.id}\n className={cn(\n \"border-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]\",\n \"rounded-[var(--ds-radius-md)] bg-[var(--ds-bg-surface)]\",\n \"p-ds-4 space-y-ds-3\",\n )}\n >\n {row.getVisibleCells().map((cell) => (\n <div key={cell.id} className=\"flex justify-between gap-ds-2 text-sm\">\n <span className=\"shrink-0 text-[var(--ds-text-secondary)] font-medium text-xs uppercase tracking-wider\">\n {typeof cell.column.columnDef.header === \"string\"\n ? cell.column.columnDef.header\n : cell.column.id}\n </span>\n <CardValue value={flexRender(cell.column.columnDef.cell, cell.getContext())} />\n </div>\n ))}\n </div>\n ))}\n </div>\n </RowsCtx></TableCardCtx>\n </div>\n );\n }\n\n const sortIcons = (sorted: false | \"asc\" | \"desc\") => (\n <span className=\"inline-flex flex-col -space-y-ds-1.5\" aria-hidden=\"true\">\n <Icon name=\"chevron-up\" size={10} className={sorted === \"asc\" ? \"text-[var(--ds-accent-primary)]\" : \"opacity-30\"} />\n <Icon name=\"chevron-down\" size={10} className={sorted === \"desc\" ? \"text-[var(--ds-accent-primary)]\" : \"opacity-30\"} />\n </span>\n );\n const headerCell = (header: Header<T, unknown>, c: number) => {\n const canSort = header.column.getCanSort();\n const sorted = header.column.getIsSorted();\n const meta = header.column.columnDef.meta as DataGridColumnMeta | undefined;\n const headerKind = kindOf(header.column.id, meta);\n const headerAlign = meta?.align ?? (headerKind === \"number\" ? \"right\" : \"left\");\n const shrink = (headerKind === \"number\" || headerKind === \"date\") && !meta?.maxWidth;\n const at = { r: -1, c };\n const label = flexRender(header.column.columnDef.header, header.getContext());\n // A47: a sortable header holds a button: a Tab stop in a read-only grid, a cell the arrows reach in an editable one\n const inside = canSort ? (\n <button\n type=\"button\"\n onClick={header.column.getToggleSortingHandler()}\n {...(editable ? { \"data-grid-key\": cellKey(at), tabIndex: grid.tabIndexOf(at) } : {})}\n className={cn(\n \"inline-flex items-center gap-ds-1 uppercase tracking-wider cursor-pointer select-none [font:inherit] text-inherit\",\n \"hover:text-[var(--ds-text-primary)] rounded-[var(--ds-radius-sm)] focus-visible:outline-none focus-visible:shadow-[var(--ds-shadow-focus)]\",\n )}\n >\n {label}\n {sortIcons(sorted)}\n </button>\n ) : label;\n return (\n <th\n key={header.id}\n role={editable ? \"columnheader\" : undefined}\n aria-sort={sorted === \"asc\" ? \"ascending\" : sorted === \"desc\" ? \"descending\" : undefined}\n {...(editable && !canSort ? { \"data-grid-key\": cellKey(at), tabIndex: grid.tabIndexOf(at) } : {})}\n className={cn(\n \"px-ds-4 py-ds-3 text-xs font-[var(--ds-weight-heading)] uppercase tracking-wider\",\n headerAlign === \"right\" ? \"text-right\" : headerAlign === \"center\" ? \"text-center\" : \"text-left\",\n shrink && \"w-px whitespace-nowrap\",\n \"text-[var(--ds-text-secondary)] outline-none focus-visible:shadow-[inset_var(--ds-shadow-focus)]\",\n )}\n style={meta?.maxWidth || meta?.width || meta?.minWidth ? { maxWidth: meta?.maxWidth, width: meta?.width, minWidth: meta?.minWidth } : undefined}\n >\n <span className={cn(\"flex items-center gap-ds-1\", headerAlign === \"right\" && \"justify-end\", headerAlign === \"center\" && \"justify-center\")}>\n {inside}\n </span>\n </th>\n );\n };\n\n return withControl(\n <div data-ds-list=\"\" className=\"min-w-0\">\n <div\n // the scroll area the width switch reads (A35), as the Table's\n data-table-scroll=\"\"\n className={cn(\n \"relative w-full overflow-auto rounded-[var(--ds-radius-md)]\",\n \"border-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]\",\n \"shadow-[var(--ds-shadow-card)]\",\n \"bg-[var(--ds-bg-surface)]\",\n )}\n >\n <table\n ref={gridRef}\n role={editable ? \"grid\" : undefined}\n aria-label={ariaLabel}\n onKeyDown={editable ? onGridKeyDown : undefined}\n onFocus={editable ? onGridFocus : undefined}\n className=\"w-full text-sm\"\n >\n <thead className=\"bg-[var(--ds-bg-muted)]\">\n {table.getHeaderGroups().map((hg) => (\n <tr key={hg.id} role={editable ? \"row\" : undefined} className=\"border-b-[length:var(--ds-divider-width)] border-[var(--ds-border-subtle)]\">\n {hg.headers.map((header, c) => headerCell(header, c))}\n </tr>\n ))}\n </thead>\n <tbody><RowsCtx value={true}>\n {rows.map((row, r) => (\n <tr\n key={row.id}\n role={editable ? \"row\" : undefined}\n className={cn(\n \"border-b-[length:var(--ds-divider-width)] border-[var(--ds-border-subtle)] last:border-b-0\",\n \"hover:bg-[var(--ds-bg-muted)] transition-colors\",\n )}\n >\n {row.getVisibleCells().map((cell, c) => {\n const meta = cell.column.columnDef.meta as DataGridColumnMeta | undefined;\n const truncLines = meta?.truncate === true ? 1 : meta?.truncate ? meta.truncate.lines : 0;\n const kind = kindOf(cell.column.id, meta);\n const rendered = flexRender(cell.column.columnDef.cell, cell.getContext() as CellContext<T, unknown>);\n const at = { r, c };\n const isEditing = editable && editing?.row === row.id && editing.c === c;\n\n const shrink = (kind === \"number\" || kind === \"date\") && !meta?.maxWidth;\n let inner: ReactNode;\n if (isEditing) {\n // the library's Input, named for its column; Enter or leaving it saves, Escape cancels. A grid saves as\n // you go, so its editor never marks a form around it; the cells' own controls still do (the review\n // of 30 September: the whole grid opted out, and a Drawer closed on a changed checkbox unasked)\n inner = (\n <FormChangeCtx value={null}>\n <Input\n size=\"sm\"\n autoFocus\n aria-label={headerText(cell.column.id)}\n // the value opens selected: typing replaces it, an arrow key keeps it\n onFocus={(e) => e.currentTarget.select()}\n value={editing.value}\n onChange={(e) => setEditing({ ...editing, value: e.target.value })}\n onBlur={() => finishEdit(true, false)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") { e.preventDefault(); finishEdit(true, true); }\n else if (e.key === \"Escape\") { e.preventDefault(); e.stopPropagation(); finishEdit(false, true); }\n }}\n />\n </FormChangeCtx>\n );\n } else if (truncLines > 0) {\n inner = <TruncCell lines={truncLines}>{rendered}</TruncCell>;\n } else if (kind === \"email\") {\n inner = (\n <span className=\"max-w-[40ch] truncate inline-block align-bottom\" title={typeof cell.getValue() === \"string\" ? cell.getValue() as string : undefined}>\n {rendered}\n </span>\n );\n } else {\n inner = rendered;\n }\n // Round 14 (50.2): a centred or right-aligned column lays a block element out with flex — text-align moves inline content only.\n const align = meta?.align ?? (kind === \"number\" ? \"right\" : \"left\");\n const value = cell.getValue();\n if (!isEditing && align !== \"left\" && typeof value !== \"string\" && typeof value !== \"number\" && value !== null && value !== undefined) {\n inner = <div className={cn(\"flex items-center\", align === \"center\" ? \"justify-center\" : \"justify-end\")}>{inner}</div>;\n }\n const tick = editable && saved?.ok && saved.row === row.id && saved.c === c\n ? <Icon name=\"check\" size={14} className=\"ml-ds-1 inline-block align-middle text-[var(--ds-status-success)]\" />\n : null;\n\n return (\n <td\n key={cell.id}\n // a double-click in the open editor selects a word, and never reopens it over what was typed\n {...(editable ? { role: \"gridcell\", \"data-grid-key\": cellKey(at), tabIndex: grid.tabIndexOf(at), onDoubleClick: () => { if (!isEditing) startEdit(at); } } : {})}\n className={cn(\n \"px-ds-4 py-ds-3 text-[var(--ds-text-primary)]\",\n align === \"right\" && \"text-right\",\n align === \"center\" && \"text-center\",\n shrink && \"w-px whitespace-nowrap\",\n editable && \"outline-none focus-visible:shadow-[inset_var(--ds-shadow-focus)]\",\n )}\n style={meta?.maxWidth || meta?.width || meta?.minWidth ? { maxWidth: meta?.maxWidth, width: meta?.width, minWidth: meta?.minWidth } : undefined}\n >\n {inner}\n {tick}\n </td>\n );\n })}\n </tr>\n ))}\n </RowsCtx></tbody>\n </table>\n </div>\n {/* A5: a save is heard, politely (WCAG 4.1.3); each one is a new line, so two saves are heard twice */}\n {editable && <div role=\"status\" className=\"sr-only\"><span key={saved?.n ?? 0}>{saved ? (saved.ok ? \"Saved\" : \"Not saved\") : \"\"}</span></div>}\n </div>\n );\n}\n"]}
@@ -1,4 +1,5 @@
1
- import { matchMentions, shownMentions, mentionOptionId, MentionList } from './chunk-RWKCAKN3.js';
1
+ "use client";
2
+ import { matchMentions, shownMentions, mentionOptionId, MentionList } from './chunk-5TUVX4B2.js';
2
3
  import { useOverlayLayer } from './chunk-ZI3OQDET.js';
3
4
  import './chunk-HP7WUZPK.js';
4
5
  import { useLatest } from './chunk-WH2FUFAC.js';
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../showcase/src/lib/use-mentions.tsx"],"names":[],"mappings":";;;;;;;;;;;AA8BA,IAAM,MAAA,GAAoB,EAAE,IAAA,EAAM,KAAA,EAAO,QAAQ,KAAA,EAAO,KAAA,EAAO,EAAC,EAAG,IAAA,EAAM,CAAA,EAAG,WAAA,EAAa,CAAA,EAAG,OAAO,IAAA,EAAK;AAExG,SAAS,YAAY,OAAA,EAAoB;AACvC,EAAA,IAAI,KAAA,GAAQ,OAAA;AACZ,EAAA,MAAM,SAAA,uBAAgB,GAAA,EAAgB;AACtC,EAAA,OAAO;AAAA,IACL,KAAK,MAAM,KAAA;AAAA,IACX,IAAI,KAAA,EAA2B;AAC7B,MAAA,KAAA,GAAQ,EAAE,GAAG,KAAA,EAAO,GAAG,KAAA,EAAM;AAC7B,MAAA,KAAA,MAAW,QAAA,IAAY,WAAW,QAAA,EAAS;AAAA,IAC7C,CAAA;AAAA,IACA,UAAU,QAAA,EAAsB;AAC9B,MAAA,SAAA,CAAU,IAAI,QAAQ,CAAA;AACtB,MAAA,OAAO,MAAM;AAAE,QAAA,SAAA,CAAU,OAAO,QAAQ,CAAA;AAAA,MAAG,CAAA;AAAA,IAC7C;AAAA,GACF;AACF;AAEA,SAAS,eAAe,OAAA,EAAgE;AACtF,EAAA,MAAM,KAAA,GAAQ,YAAY,MAAM,CAAA;AAChC,EAAA,MAAM,SAAA,GAAY,IAAI,SAAA,CAAU,oBAAoB,CAAA;AACpD,EAAA,IAAI,IAAA,GAAmD,IAAA;AACvD,EAAA,IAAI,MAAA,GAAwC,IAAA;AAE5C,EAAA,IAAI,KAAA,GAAuB,IAAA;AAC3B,EAAA,IAAI,MAAA,GAAqC,IAAA;AACzC,EAAA,MAAM,QAAQ,MAAM;AAAE,IAAA,MAAM,CAAA,GAAI,MAAM,GAAA,EAAI;AAAG,IAAA,OAAO,EAAE,IAAA,IAAQ,CAAC,EAAE,MAAA,IAAU,CAAA,CAAE,MAAM,MAAA,GAAS,CAAA;AAAA,EAAG,CAAA;AAI/F,EAAA,MAAM,KAAA,GAAQ,CAAC,KAAA,KAA8C;AAC3D,IAAA,IAAA,GAAO,CAAC,IAAA,KAAS,KAAA,CAAM,OAAA,CAAQ,EAAE,EAAA,EAAI,IAAA,CAAK,EAAA,EAAI,KAAA,EAAO,IAAA,CAAK,KAAA,EAAO,CAAA;AACjE,IAAA,MAAA,GAAS,MAAM,UAAA,IAAc,IAAA;AAC7B,IAAA,KAAA,CAAM,GAAA,CAAI,EAAE,IAAA,EAAM,IAAA,EAAM,QAAQ,KAAA,EAAO,KAAA,EAAO,KAAA,CAAM,MAAA,EAAkB,CAAA;AAAA,EACxE,CAAA;AAGA,EAAA,MAAM,QAAA,GAAW,CAAC,KAAA,KAA8C;AAC9D,IAAA,IAAI,KAAA,CAAM,KAAA,KAAU,KAAA,IAAS,MAAA,KAAW,IAAA,EAAM;AAC9C,IAAA,KAAA,CAAM,KAAK,CAAA;AACX,IAAA,KAAA,CAAM,GAAA,CAAI,EAAE,GAAG,aAAA,CAAc,MAAM,CAAA,EAAG,WAAA,EAAa,GAAG,CAAA;AAAA,EACxD,CAAA;AAKA,EAAA,MAAM,MAAA,GAAS,IAAI,MAAA,CAAO;AAAA,IACxB,KAAA,EAAO;AAAA,MACL,aAAA,CAAc,MAAM,KAAA,EAAO;AACzB,QAAA,IAAA,CAAK,MAAM,GAAA,KAAQ,QAAA,IAAY,KAAA,CAAM,GAAA,KAAQ,UAAU,CAAC,KAAA,EAAM,IAAK,SAAA,CAAU,SAAS,IAAA,CAAK,KAAK,GAAG,MAAA,EAAQ,cAAA,CAAe,MAAM,SAAS,CAAA;AACzI,QAAA,OAAO,KAAA;AAAA,MACT;AAAA;AACF,GACD,CAAA;AAED,EAAA,MAAM,SAAA,GAAY,QAAQ,MAAA,CAAO;AAAA,IAC/B,qBAAA,GAAwB;AACtB,MAAA,OAAO,CAAC,MAAA,EAAQ,GAAI,KAAK,MAAA,IAAS,IAAK,EAAG,CAAA;AAAA,IAC5C;AAAA,GACD,EAAE,SAAA,CAAU;AAAA;AAAA,IAEX,0BAAA,EAA4B,IAAA;AAAA,IAC5B,cAAA,EAAgB,EAAE,KAAA,EAAO,aAAA,EAAc;AAAA,IACvC,UAAA,EAAY;AAAA,MACV,SAAA;AAAA,MACA,KAAA,EAAO,OAAO,EAAE,KAAA,EAAM,KAAM;AAC1B,QAAA,KAAA,GAAQ,KAAA;AACR,QAAA,MAAA,GAAS,IAAA;AACT,QAAA,MAAM,IAAI,OAAA,CAAQ,OAAA;AAClB,QAAA,IAAI,KAAA;AACJ,QAAA,IAAI;AACF,UAAA,KAAA,GAAQ,CAAA,CAAE,MAAA,GAAS,MAAM,CAAA,CAAE,MAAA,CAAO,KAAK,CAAA,GAAI,aAAA,CAAc,CAAA,CAAE,MAAA,IAAU,EAAC,EAAG,KAAK,CAAA;AAAA,QAChF,CAAA,CAAA,MAAQ;AACN,UAAA,KAAA,GAAQ,EAAC;AAAA,QACX;AACA,QAAA,IAAI,KAAA,KAAU,OAAO,MAAA,GAAS,KAAA;AAC9B,QAAA,OAAO,KAAA;AAAA,MACT,CAAA;AAAA,MACA,QAAQ,OAAO;AAAA,QACb,aAAA,EAAe,KAAA;AAAA,QACf,cAAA,EAAgB,KAAA;AAAA,QAChB,OAAA,EAAS,QAAA;AAAA,QACT,QAAA,EAAU,QAAA;AAAA,QACV,QAAQ,MAAM;AACZ,UAAA,IAAA,GAAO,IAAA;AACP,UAAA,KAAA,GAAQ,IAAA;AACR,UAAA,MAAA,GAAS,IAAA;AACT,UAAA,KAAA,CAAM,IAAI,MAAM,CAAA;AAAA,QAClB,CAAA;AAAA;AAAA;AAAA,QAGA,SAAA,EAAW,CAAC,EAAE,KAAA,EAAM,KAAM;AACxB,UAAA,IAAI,CAAC,KAAA,EAAM,EAAG,OAAO,KAAA;AACrB,UAAA,MAAM,EAAE,KAAA,EAAO,WAAA,EAAY,GAAI,MAAM,GAAA,EAAI;AACzC,UAAA,IAAI,KAAA,CAAM,GAAA,KAAQ,WAAA,EAAa,KAAA,CAAM,GAAA,CAAI,EAAE,WAAA,EAAA,CAAc,WAAA,GAAc,CAAA,IAAK,KAAA,CAAM,MAAA,EAAQ,CAAA;AAAA,eAAA,IACjF,KAAA,CAAM,GAAA,KAAQ,SAAA,EAAW,KAAA,CAAM,GAAA,CAAI,EAAE,WAAA,EAAA,CAAc,WAAA,GAAc,CAAA,GAAI,KAAA,CAAM,MAAA,IAAU,KAAA,CAAM,QAAQ,CAAA;AAAA,eAAA,IACnG,KAAA,CAAM,GAAA,KAAQ,OAAA,IAAY,KAAA,CAAM,GAAA,KAAQ,KAAA,IAAS,CAAC,KAAA,CAAM,QAAA,EAAW,IAAA,GAAO,KAAA,CAAM,WAAW,CAAC,CAAA;AAAA,eAChG,OAAO,MAAM,GAAA,KAAQ,QAAA;AAC1B,UAAA,OAAO,IAAA;AAAA,QACT;AAAA,OACF;AAAA;AACF,GACD,CAAA;AAED,EAAA,SAAS,IAAA,CAAK,EAAE,MAAA,EAAO,EAAuB;AAC5C,IAAA,MAAM,QAAQ,oBAAA,CAAqB,KAAA,CAAM,WAAW,KAAA,CAAM,GAAA,EAAK,MAAM,GAAG,CAAA;AACxE,IAAA,MAAM,KAAK,KAAA,EAAM;AACjB,IAAA,MAAM,OAAA,GAAU,OAAuB,IAAI,CAAA;AAC3C,IAAA,MAAM,OAAA,GAAU,KAAA,CAAM,IAAA,IAAQ,CAAC,KAAA,CAAM,MAAA,IAAU,KAAA,CAAM,KAAA,CAAM,MAAA,GAAS,CAAA,IAAK,KAAA,CAAM,KAAA,KAAU,MAAA;AAEzF,IAAA,eAAA,CAAgB,OAAO,CAAA;AAGvB,IAAA,SAAA,CAAU,MAAM;AACd,MAAA,IAAI,CAAC,OAAA,EAAS;AACd,MAAA,MAAM,GAAA,GAAM,OAAO,IAAA,CAAK,GAAA;AACxB,MAAA,GAAA,CAAI,YAAA,CAAa,iBAAiB,EAAE,CAAA;AACpC,MAAA,GAAA,CAAI,aAAa,uBAAA,EAAyB,eAAA,CAAgB,EAAA,EAAI,KAAA,CAAM,WAAW,CAAC,CAAA;AAChF,MAAA,OAAO,MAAM;AACX,QAAA,GAAA,CAAI,gBAAgB,eAAe,CAAA;AACnC,QAAA,GAAA,CAAI,gBAAgB,uBAAuB,CAAA;AAAA,MAC7C,CAAA;AAAA,IACF,GAAG,CAAC,MAAA,EAAQ,SAAS,EAAA,EAAI,KAAA,CAAM,WAAW,CAAC,CAAA;AAG3C,IAAA,SAAA,CAAU,MAAM;AACd,MAAA,MAAM,MAAA,GAAS,CAAC,EAAE,KAAA,EAAM,KAA6B;AACnD,QAAA,MAAM,OAAO,KAAA,CAAM,aAAA;AACnB,QAAA,IAAI,IAAA,IAAQ,OAAA,CAAQ,OAAA,EAAS,QAAA,CAAS,IAAI,CAAA,EAAG;AAC7C,QAAA,IAAI,KAAA,CAAM,KAAI,CAAE,IAAA,QAAY,GAAA,CAAI,EAAE,MAAA,EAAQ,IAAA,EAAM,CAAA;AAAA,MAClD,CAAA;AACA,MAAA,MAAA,CAAO,EAAA,CAAG,QAAQ,MAAM,CAAA;AACxB,MAAA,OAAO,MAAM;AAAE,QAAA,MAAA,CAAO,GAAA,CAAI,QAAQ,MAAM,CAAA;AAAA,MAAG,CAAA;AAAA,IAC7C,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAEX,IAAA,IAAI,CAAC,SAAS,OAAO,IAAA;AACrB,IAAA,uBACE,GAAA;AAAA,MAAC,WAAA;AAAA,MAAA;AAAA,QACC,EAAA;AAAA,QACA,KAAA,EAAM,QAAA;AAAA,QACN,OAAO,KAAA,CAAM,KAAA;AAAA,QACb,MAAM,KAAA,CAAM,IAAA;AAAA,QACZ,aAAa,KAAA,CAAM,WAAA;AAAA,QACnB,mBAAA,EAAqB,CAAC,CAAA,KAAM,KAAA,CAAM,IAAI,EAAE,WAAA,EAAa,GAAG,CAAA;AAAA,QACxD,MAAA,EAAQ,CAAC,IAAA,KAAS,IAAA,GAAO,IAAI,CAAA;AAAA,QAC7B,UAAA,EAAY,MAAM,MAAA,IAAS,IAAK,IAAA;AAAA,QAChC;AAAA;AAAA,KACF;AAAA,EAEJ;AAEA,EAAA,OAAO,EAAE,WAAW,IAAA,EAAK;AAC3B;AAYO,SAAS,YAAY,OAAA,EAAqD;AAC/E,EAAA,MAAM,MAAA,GAAS,UAAU,OAAO,CAAA;AAChC,EAAA,MAAM,CAAC,QAAQ,CAAA,GAAI,SAAS,MAAM,cAAA,CAAe,MAAM,CAAC,CAAA;AACxD,EAAA,OAAO,QAAA;AACT","file":"editor-mentions.js","sourcesContent":["import { useEffect, useId, useRef, useState, useSyncExternalStore, type RefObject } from \"react\";\nimport type { Editor } from \"@tiptap/react\";\nimport Mention from \"@tiptap/extension-mention\";\nimport { exitSuggestion, type SuggestionProps } from \"@tiptap/suggestion\";\nimport { Plugin, PluginKey } from \"@tiptap/pm/state\";\nimport { useOverlayLayer } from \"./focus\";\nimport { useLatest } from \"./use-latest\";\nimport { MentionList, matchMentions, mentionOptionId, shownMentions, type MentionSuggestion } from \"../components/MentionList\";\nimport type { RichTextEditorMentions } from \"../components/RichTextEditor\";\n\nexport type UseMentionsOptions =\n /** The people to mention: each offered when its name or description matches what follows \"@\". */\n | { people: MentionSuggestion[]; search?: undefined }\n /** For a large team: the people matching what follows \"@\", looked up as it's typed. An answer to an older query is dropped. */\n | { search: (query: string) => MentionSuggestion[] | Promise<MentionSuggestion[]>; people?: undefined };\n\ninterface ListState {\n /** A mention is being typed. */\n open: boolean;\n /** Focus left the editor while one was being typed: the list waits for the next keystroke in it. */\n hidden: boolean;\n /** The people shown: the best matches, at most a list's limit. */\n items: MentionSuggestion[];\n /** How many more match than are shown. */\n more: number;\n activeIndex: number;\n /** The editor the mention is typed in: one result passed to two editors draws its list in that one alone. */\n owner: Editor | null;\n}\n\nconst CLOSED: ListState = { open: false, hidden: false, items: [], more: 0, activeIndex: 0, owner: null };\n\nfunction createStore(initial: ListState) {\n let state = initial;\n const listeners = new Set<() => void>();\n return {\n get: () => state,\n set(patch: Partial<ListState>) {\n state = { ...state, ...patch };\n for (const listener of listeners) listener();\n },\n subscribe(listener: () => void) {\n listeners.add(listener);\n return () => { listeners.delete(listener); };\n },\n };\n}\n\nfunction createMentions(options: RefObject<UseMentionsOptions>): RichTextEditorMentions {\n const store = createStore(CLOSED);\n const pluginKey = new PluginKey(\"gridsmith-mentions\");\n let pick: ((item: MentionSuggestion) => void) | null = null;\n let anchor: (() => DOMRect | null) | null = null;\n /** The newest query looked up, and its answer once it has come: an answer to an older query is never shown. */\n let asked: string | null = null;\n let answer: MentionSuggestion[] | null = null;\n const shown = () => { const s = store.get(); return s.open && !s.hidden && s.items.length > 0; };\n\n // Before each lookup answers (Sprint 25.17's review: a slow search): the range and the caret are the mention as typed\n // now, so Enter replaces all of it, and the people shown stay until the new answer comes, with no blink between keys\n const typed = (props: SuggestionProps<MentionSuggestion>) => {\n pick = (item) => props.command({ id: item.id, label: item.label });\n anchor = props.clientRect ?? null;\n store.set({ open: true, hidden: false, owner: props.editor as Editor });\n };\n // A lookup answered. tiptap hands every callback the newest props, whose items may still be an older lookup's or\n // none: the list shows the newest query's own answer, when it has come.\n const answered = (props: SuggestionProps<MentionSuggestion>) => {\n if (props.query !== asked || answer === null) return;\n typed(props);\n store.set({ ...shownMentions(answer), activeIndex: 0 });\n };\n\n // Escape closes the list; with no list shown (no one matches, or focus left and came back), the mention typed so far\n // stays as text and the Escape is the page's, so an enclosing Dialog closes, as with MentionInput. tiptap's suggestion\n // takes every Escape while a mention is typed, so this runs before it and ends the mention first.\n const escape = new Plugin({\n props: {\n handleKeyDown(view, event) {\n if ((event.key === \"Escape\" || event.key === \"Esc\") && !shown() && pluginKey.getState(view.state)?.active) exitSuggestion(view, pluginKey);\n return false;\n },\n },\n });\n\n const extension = Mention.extend({\n addProseMirrorPlugins() {\n return [escape, ...(this.parent?.() ?? [])];\n },\n }).configure({\n // one token: Backspace deletes the whole mention, where tiptap's default leaves the \"@\" and offers the list again\n deleteTriggerWithBackspace: true,\n HTMLAttributes: { class: \"rte-mention\" },\n suggestion: {\n pluginKey,\n items: async ({ query }) => {\n asked = query;\n answer = null;\n const o = options.current;\n let found: MentionSuggestion[];\n try {\n found = o.search ? await o.search(query) : matchMentions(o.people ?? [], query);\n } catch {\n found = [];\n }\n if (query === asked) answer = found;\n return found;\n },\n render: () => ({\n onBeforeStart: typed,\n onBeforeUpdate: typed,\n onStart: answered,\n onUpdate: answered,\n onExit: () => {\n pick = null;\n asked = null;\n answer = null;\n store.set(CLOSED);\n },\n // MentionInput's keys: the arrows move round the list, Enter or Tab inserts, Escape closes (the suggestion ends\n // it); with no list shown every key is the editor's\n onKeyDown: ({ event }) => {\n if (!shown()) return false;\n const { items, activeIndex } = store.get();\n if (event.key === \"ArrowDown\") store.set({ activeIndex: (activeIndex + 1) % items.length });\n else if (event.key === \"ArrowUp\") store.set({ activeIndex: (activeIndex - 1 + items.length) % items.length });\n else if (event.key === \"Enter\" || (event.key === \"Tab\" && !event.shiftKey)) pick?.(items[activeIndex]);\n else return event.key === \"Escape\";\n return true;\n },\n }),\n },\n });\n\n function List({ editor }: { editor: Editor }) {\n const state = useSyncExternalStore(store.subscribe, store.get, store.get);\n const id = useId();\n const listRef = useRef<HTMLDivElement>(null);\n const visible = state.open && !state.hidden && state.items.length > 0 && state.owner === editor;\n // the top layer while it shows, so an enclosing overlay's trap stands aside for it\n useOverlayLayer(visible);\n\n // while it shows, the editable area names the list it controls and the active option (aria-activedescendant)\n useEffect(() => {\n if (!visible) return;\n const dom = editor.view.dom;\n dom.setAttribute(\"aria-controls\", id);\n dom.setAttribute(\"aria-activedescendant\", mentionOptionId(id, state.activeIndex));\n return () => {\n dom.removeAttribute(\"aria-controls\");\n dom.removeAttribute(\"aria-activedescendant\");\n };\n }, [editor, visible, id, state.activeIndex]);\n\n // focus leaving the editor hides the list; typing on in the mention shows it again\n useEffect(() => {\n const onBlur = ({ event }: { event: FocusEvent }) => {\n const next = event.relatedTarget as Node | null;\n if (next && listRef.current?.contains(next)) return;\n if (store.get().open) store.set({ hidden: true });\n };\n editor.on(\"blur\", onBlur);\n return () => { editor.off(\"blur\", onBlur); };\n }, [editor]);\n\n if (!visible) return null;\n return (\n <MentionList\n id={id}\n label=\"People\"\n items={state.items}\n more={state.more}\n activeIndex={state.activeIndex}\n onActiveIndexChange={(i) => store.set({ activeIndex: i })}\n onPick={(item) => pick?.(item)}\n anchorRect={() => anchor?.() ?? null}\n listRef={listRef}\n />\n );\n }\n\n return { extension, List };\n}\n\n/**\n * @mentions for RichTextEditor (Sprint 25.17 A17, R28-32): pass the result as the editor's `mentions`, from the first\n * render. Typing \"@\" offers the people whose name (or description) matches what follows, in MentionInput's list, at the\n * caret; the arrows move, Enter or Tab inserts, Escape closes. A mention is one token, read by its name, deleted whole,\n * and carried in onChange's HTML with the person's id (`<span data-type=\"mention\" data-id=\"…\" data-label=\"…\">`), so\n * the page can notify them. `people` can change from render to render; for a large team, `search` looks them up.\n *\n * const mentions = useMentions({ people: members.map((m) => ({ id: m.id, label: m.name, avatar: m.photo })) })\n * <RichTextEditor content={doc} onChange={save} mentions={mentions} />\n */\nexport function useMentions(options: UseMentionsOptions): RichTextEditorMentions {\n const latest = useLatest(options);\n const [mentions] = useState(() => createMentions(latest));\n return mentions;\n}\n"]}
1
+ {"version":3,"sources":["../../../showcase/src/lib/use-mentions.tsx"],"names":[],"mappings":"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","file":"editor-mentions.js","sourcesContent":["import { useEffect, useId, useRef, useState, useSyncExternalStore, type RefObject } from \"react\";\nimport type { Editor } from \"@tiptap/react\";\nimport Mention from \"@tiptap/extension-mention\";\nimport { exitSuggestion, type SuggestionProps } from \"@tiptap/suggestion\";\nimport { Plugin, PluginKey } from \"@tiptap/pm/state\";\nimport { useOverlayLayer } from \"./focus\";\nimport { useLatest } from \"./use-latest\";\nimport { MentionList, matchMentions, mentionOptionId, shownMentions, type MentionSuggestion } from \"../components/MentionList\";\nimport type { RichTextEditorMentions } from \"../components/RichTextEditor\";\n\nexport type UseMentionsOptions =\n /** The people to mention: each offered when its name or description matches what follows \"@\". */\n | { people: MentionSuggestion[]; search?: undefined }\n /** For a large team: the people matching what follows \"@\", looked up as it's typed. An answer to an older query is dropped. */\n | { search: (query: string) => MentionSuggestion[] | Promise<MentionSuggestion[]>; people?: undefined };\n\ninterface ListState {\n /** A mention is being typed. */\n open: boolean;\n /** Focus left the editor while one was being typed: the list waits for the next keystroke in it. */\n hidden: boolean;\n /** The people shown: the best matches, at most a list's limit. */\n items: MentionSuggestion[];\n /** How many more match than are shown. */\n more: number;\n activeIndex: number;\n /** The editor the mention is typed in: one result passed to two editors draws its list in that one alone. */\n owner: Editor | null;\n}\n\nconst CLOSED: ListState = { open: false, hidden: false, items: [], more: 0, activeIndex: 0, owner: null };\n\nfunction createStore(initial: ListState) {\n let state = initial;\n const listeners = new Set<() => void>();\n return {\n get: () => state,\n set(patch: Partial<ListState>) {\n state = { ...state, ...patch };\n for (const listener of listeners) listener();\n },\n subscribe(listener: () => void) {\n listeners.add(listener);\n return () => { listeners.delete(listener); };\n },\n };\n}\n\nfunction createMentions(options: RefObject<UseMentionsOptions>): RichTextEditorMentions {\n const store = createStore(CLOSED);\n const pluginKey = new PluginKey(\"gridsmith-mentions\");\n let pick: ((item: MentionSuggestion) => void) | null = null;\n let anchor: (() => DOMRect | null) | null = null;\n /** The newest query looked up, and its answer once it has come: an answer to an older query is never shown. */\n let asked: string | null = null;\n let answer: MentionSuggestion[] | null = null;\n const shown = () => { const s = store.get(); return s.open && !s.hidden && s.items.length > 0; };\n\n // Before each lookup answers (Sprint 25.17's review: a slow search): the range and the caret are the mention as typed\n // now, so Enter replaces all of it, and the people shown stay until the new answer comes, with no blink between keys\n const typed = (props: SuggestionProps<MentionSuggestion>) => {\n pick = (item) => props.command({ id: item.id, label: item.label });\n anchor = props.clientRect ?? null;\n store.set({ open: true, hidden: false, owner: props.editor as Editor });\n };\n // A lookup answered. tiptap hands every callback the newest props, whose items may still be an older lookup's or\n // none: the list shows the newest query's own answer, when it has come.\n const answered = (props: SuggestionProps<MentionSuggestion>) => {\n if (props.query !== asked || answer === null) return;\n typed(props);\n store.set({ ...shownMentions(answer), activeIndex: 0 });\n };\n\n // Escape closes the list; with no list shown (no one matches, or focus left and came back), the mention typed so far\n // stays as text and the Escape is the page's, so an enclosing Dialog closes, as with MentionInput. tiptap's suggestion\n // takes every Escape while a mention is typed, so this runs before it and ends the mention first.\n const escape = new Plugin({\n props: {\n handleKeyDown(view, event) {\n if ((event.key === \"Escape\" || event.key === \"Esc\") && !shown() && pluginKey.getState(view.state)?.active) exitSuggestion(view, pluginKey);\n return false;\n },\n },\n });\n\n const extension = Mention.extend({\n addProseMirrorPlugins() {\n return [escape, ...(this.parent?.() ?? [])];\n },\n }).configure({\n // one token: Backspace deletes the whole mention, where tiptap's default leaves the \"@\" and offers the list again\n deleteTriggerWithBackspace: true,\n HTMLAttributes: { class: \"rte-mention\" },\n suggestion: {\n pluginKey,\n items: async ({ query }) => {\n asked = query;\n answer = null;\n const o = options.current;\n let found: MentionSuggestion[];\n try {\n found = o.search ? await o.search(query) : matchMentions(o.people ?? [], query);\n } catch {\n found = [];\n }\n if (query === asked) answer = found;\n return found;\n },\n render: () => ({\n onBeforeStart: typed,\n onBeforeUpdate: typed,\n onStart: answered,\n onUpdate: answered,\n onExit: () => {\n pick = null;\n asked = null;\n answer = null;\n store.set(CLOSED);\n },\n // MentionInput's keys: the arrows move round the list, Enter or Tab inserts, Escape closes (the suggestion ends\n // it); with no list shown every key is the editor's\n onKeyDown: ({ event }) => {\n if (!shown()) return false;\n const { items, activeIndex } = store.get();\n if (event.key === \"ArrowDown\") store.set({ activeIndex: (activeIndex + 1) % items.length });\n else if (event.key === \"ArrowUp\") store.set({ activeIndex: (activeIndex - 1 + items.length) % items.length });\n else if (event.key === \"Enter\" || (event.key === \"Tab\" && !event.shiftKey)) pick?.(items[activeIndex]);\n else return event.key === \"Escape\";\n return true;\n },\n }),\n },\n });\n\n function List({ editor }: { editor: Editor }) {\n const state = useSyncExternalStore(store.subscribe, store.get, store.get);\n const id = useId();\n const listRef = useRef<HTMLDivElement>(null);\n const visible = state.open && !state.hidden && state.items.length > 0 && state.owner === editor;\n // the top layer while it shows, so an enclosing overlay's trap stands aside for it\n useOverlayLayer(visible);\n\n // while it shows, the editable area names the list it controls and the active option (aria-activedescendant)\n useEffect(() => {\n if (!visible) return;\n const dom = editor.view.dom;\n dom.setAttribute(\"aria-controls\", id);\n dom.setAttribute(\"aria-activedescendant\", mentionOptionId(id, state.activeIndex));\n return () => {\n dom.removeAttribute(\"aria-controls\");\n dom.removeAttribute(\"aria-activedescendant\");\n };\n }, [editor, visible, id, state.activeIndex]);\n\n // focus leaving the editor hides the list; typing on in the mention shows it again\n useEffect(() => {\n const onBlur = ({ event }: { event: FocusEvent }) => {\n const next = event.relatedTarget as Node | null;\n if (next && listRef.current?.contains(next)) return;\n if (store.get().open) store.set({ hidden: true });\n };\n editor.on(\"blur\", onBlur);\n return () => { editor.off(\"blur\", onBlur); };\n }, [editor]);\n\n if (!visible) return null;\n return (\n <MentionList\n id={id}\n label=\"People\"\n items={state.items}\n more={state.more}\n activeIndex={state.activeIndex}\n onActiveIndexChange={(i) => store.set({ activeIndex: i })}\n onPick={(item) => pick?.(item)}\n anchorRect={() => anchor?.() ?? null}\n listRef={listRef}\n />\n );\n }\n\n return { extension, List };\n}\n\n/**\n * @mentions for RichTextEditor (Sprint 25.17 A17, R28-32): pass the result as the editor's `mentions`, from the first\n * render. Typing \"@\" offers the people whose name (or description) matches what follows, in MentionInput's list, at the\n * caret; the arrows move, Enter or Tab inserts, Escape closes. A mention is one token, read by its name, deleted whole,\n * and carried in onChange's HTML with the person's id (`<span data-type=\"mention\" data-id=\"…\" data-label=\"…\">`), so\n * the page can notify them. `people` can change from render to render; for a large team, `search` looks them up.\n *\n * const mentions = useMentions({ people: members.map((m) => ({ id: m.id, label: m.name, avatar: m.photo })) })\n * <RichTextEditor content={doc} onChange={save} mentions={mentions} />\n */\nexport function useMentions(options: UseMentionsOptions): RichTextEditorMentions {\n const latest = useLatest(options);\n const [mentions] = useState(() => createMentions(latest));\n return mentions;\n}\n"]}
package/dist/editor.js CHANGED
@@ -1,8 +1,9 @@
1
+ "use client";
1
2
  import { useScrollEdges } from './chunk-3BRQRKDO.js';
2
3
  import { useBreakpoint } from './chunk-CRQ6KCRD.js';
3
4
  import { FormChangeCtx } from './chunk-XVB55M3N.js';
4
5
  import { useOverlayLayer, useCloseOnFocusOut } from './chunk-ZI3OQDET.js';
5
- import { warnOnce, Icon } from './chunk-HXVXJUGV.js';
6
+ import { warnOnce, Icon } from './chunk-TJEV7YAY.js';
6
7
  import { useLatest } from './chunk-WH2FUFAC.js';
7
8
  import { cn, ACTIVE_RING, FOCUS_RING } from './chunk-M2QRNBDQ.js';
8
9
  import { useContext, useRef, useState, useEffect, useCallback, useImperativeHandle } from 'react';
@@ -250,7 +251,7 @@ function RichTextEditor({
250
251
  ref,
251
252
  className: cn(
252
253
  "flex flex-col rounded-[var(--ds-radius-md)] overflow-hidden",
253
- // Sprint 25.14 A20: a field's edge, at 3:1 like every other control's
254
+ // a field's resting edge, every other control's (Sprint 25.14 A20; the soft border again since 25.19 K1)
254
255
  "border-[length:var(--ds-border-width)] border-[var(--ds-input-border)]",
255
256
  "bg-[var(--ds-bg-surface)]",
256
257
  className