@arbidocs/blocks 0.4.31 → 0.4.33

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 (179) hide show
  1. package/dist/agents/index.cjs +256 -214
  2. package/dist/agents/index.js +7 -5
  3. package/dist/agents/tasks/ConversationListView.d.ts +58 -0
  4. package/dist/agents/tasks/ConversationTurnSpeaker.d.ts +16 -0
  5. package/dist/agents/tasks/NewThreadDialog.d.ts +1 -1
  6. package/dist/agents/tasks/TaskActivityTimeline.d.ts +1 -1
  7. package/dist/agents/tasks/TaskFlow.d.ts +22 -0
  8. package/dist/agents/tasks/TaskInbox.d.ts +26 -0
  9. package/dist/agents/tasks/TaskReviewDialog.d.ts +22 -0
  10. package/dist/agents/tasks/TaskRowMenu.d.ts +10 -2
  11. package/dist/agents/tasks/TaskRunsDialog.d.ts +8 -3
  12. package/dist/agents/tasks/TaskStartDialog.d.ts +24 -0
  13. package/dist/agents/tasks/TaskTable.d.ts +1 -1
  14. package/dist/agents/tasks/ThreadNotifyDialog.d.ts +11 -0
  15. package/dist/agents/tasks/WorkflowComposer.d.ts +1 -1
  16. package/dist/agents/tasks/WorkflowsTable.d.ts +7 -0
  17. package/dist/agents/tasks/compact-thread-activity.d.ts +8 -0
  18. package/dist/agents/tasks/index.d.ts +10 -0
  19. package/dist/agents/tasks/taskComposerTypes.d.ts +16 -1
  20. package/dist/agents/tasks/taskRequest.d.ts +1 -0
  21. package/dist/agents/tasks/testGrid.d.ts +24 -0
  22. package/dist/agents/tasks/workflowColumns.d.ts +2 -1
  23. package/dist/agents/tasks/workflowRows.d.ts +6 -0
  24. package/dist/agents/workflows/types.d.ts +2 -0
  25. package/dist/auth/index.cjs +27 -27
  26. package/dist/auth/index.js +1 -1
  27. package/dist/chat/Message.d.ts +8 -2
  28. package/dist/chat/index.cjs +132 -120
  29. package/dist/chat/index.d.ts +2 -0
  30. package/dist/chat/index.js +2 -2
  31. package/dist/chat/participant-tints.d.ts +1 -0
  32. package/dist/chat/useRecipientDraft.d.ts +14 -0
  33. package/dist/{chunk-KF4EC5XU.js → chunk-24KQJYSB.js} +3 -3
  34. package/dist/{chunk-KF4EC5XU.js.map → chunk-24KQJYSB.js.map} +1 -1
  35. package/dist/{chunk-GVQOBJKR.cjs → chunk-2EAE5JP6.cjs} +7 -4
  36. package/dist/chunk-2EAE5JP6.cjs.map +1 -0
  37. package/dist/{chunk-S5HZBXZA.cjs → chunk-2QTT2RZE.cjs} +242 -2
  38. package/dist/chunk-2QTT2RZE.cjs.map +1 -0
  39. package/dist/chunk-3AFWGEDJ.cjs +53 -0
  40. package/dist/chunk-3AFWGEDJ.cjs.map +1 -0
  41. package/dist/{chunk-4XJZ6AAY.js → chunk-4AWS54US.js} +244 -6
  42. package/dist/chunk-4AWS54US.js.map +1 -0
  43. package/dist/{chunk-56BUD74K.cjs → chunk-65THHQVB.cjs} +27 -27
  44. package/dist/{chunk-56BUD74K.cjs.map → chunk-65THHQVB.cjs.map} +1 -1
  45. package/dist/{chunk-5B4PXAKI.cjs → chunk-6DNYPLCD.cjs} +21 -7
  46. package/dist/chunk-6DNYPLCD.cjs.map +1 -0
  47. package/dist/{chunk-Y2LWA4ZO.js → chunk-6RXUMBTK.js} +1855 -501
  48. package/dist/chunk-6RXUMBTK.js.map +1 -0
  49. package/dist/{chunk-UTYQPVIW.cjs → chunk-7QDX2CO4.cjs} +6 -6
  50. package/dist/{chunk-UTYQPVIW.cjs.map → chunk-7QDX2CO4.cjs.map} +1 -1
  51. package/dist/{chunk-FRRDPYBR.cjs → chunk-AZ75JUIH.cjs} +74 -5
  52. package/dist/chunk-AZ75JUIH.cjs.map +1 -0
  53. package/dist/{chunk-NUPVHEJW.js → chunk-BUHKUKKB.js} +7 -4
  54. package/dist/chunk-BUHKUKKB.js.map +1 -0
  55. package/dist/chunk-C7FGONCM.js +124 -0
  56. package/dist/chunk-C7FGONCM.js.map +1 -0
  57. package/dist/{chunk-KXMDOTGW.js → chunk-DLBUFHLY.js} +10 -2
  58. package/dist/chunk-DLBUFHLY.js.map +1 -0
  59. package/dist/{chunk-ZHLMDJCO.cjs → chunk-DLVX6R6B.cjs} +62 -26
  60. package/dist/chunk-DLVX6R6B.cjs.map +1 -0
  61. package/dist/{chunk-JGZTRLKL.cjs → chunk-IA7RTPT3.cjs} +7 -4
  62. package/dist/chunk-IA7RTPT3.cjs.map +1 -0
  63. package/dist/{chunk-NJL4LIXX.js → chunk-LFGJAZ5H.js} +11 -8
  64. package/dist/chunk-LFGJAZ5H.js.map +1 -0
  65. package/dist/{chunk-IAKUTBPX.js → chunk-LYUO3E6V.js} +3 -3
  66. package/dist/{chunk-IAKUTBPX.js.map → chunk-LYUO3E6V.js.map} +1 -1
  67. package/dist/{chunk-EYPPB5CY.cjs → chunk-M2YGPC5N.cjs} +4 -4
  68. package/dist/{chunk-EYPPB5CY.cjs.map → chunk-M2YGPC5N.cjs.map} +1 -1
  69. package/dist/{chunk-5ZBP7TCD.cjs → chunk-MJCCBMM5.cjs} +10 -2
  70. package/dist/chunk-MJCCBMM5.cjs.map +1 -0
  71. package/dist/chunk-MZL67U2E.cjs +128 -0
  72. package/dist/chunk-MZL67U2E.cjs.map +1 -0
  73. package/dist/{chunk-OJSWQM4G.js → chunk-OZJ5PXA6.js} +29 -4
  74. package/dist/chunk-OZJ5PXA6.js.map +1 -0
  75. package/dist/{chunk-UBNVIIBT.js → chunk-PXFJDX2C.js} +21 -7
  76. package/dist/chunk-PXFJDX2C.js.map +1 -0
  77. package/dist/{chunk-RGHQFJOL.cjs → chunk-QFUF4A4J.cjs} +28 -2
  78. package/dist/chunk-QFUF4A4J.cjs.map +1 -0
  79. package/dist/chunk-RFXJYIDV.js +50 -0
  80. package/dist/chunk-RFXJYIDV.js.map +1 -0
  81. package/dist/{chunk-CQWRVIJC.cjs → chunk-SEQWI6E4.cjs} +1882 -517
  82. package/dist/chunk-SEQWI6E4.cjs.map +1 -0
  83. package/dist/{chunk-QN42OA5J.js → chunk-SFXVNFES.js} +4 -4
  84. package/dist/chunk-SFXVNFES.js.map +1 -0
  85. package/dist/{chunk-3NZR6PAG.js → chunk-V6U5KVAR.js} +70 -4
  86. package/dist/chunk-V6U5KVAR.js.map +1 -0
  87. package/dist/{chunk-YVIOCITQ.cjs → chunk-VUEZARW5.cjs} +3 -3
  88. package/dist/chunk-VUEZARW5.cjs.map +1 -0
  89. package/dist/{chunk-JLOYWXRB.js → chunk-VZGBCBYB.js} +3 -3
  90. package/dist/chunk-VZGBCBYB.js.map +1 -0
  91. package/dist/{chunk-ZVPTFTGV.cjs → chunk-WBDK4PIA.cjs} +11 -8
  92. package/dist/chunk-WBDK4PIA.cjs.map +1 -0
  93. package/dist/{chunk-ZORQ5M3W.cjs → chunk-WQFGG2BV.cjs} +4 -4
  94. package/dist/chunk-WQFGG2BV.cjs.map +1 -0
  95. package/dist/{chunk-C75S6USL.js → chunk-WYVCXY7R.js} +7 -4
  96. package/dist/chunk-WYVCXY7R.js.map +1 -0
  97. package/dist/{chunk-WSJVHSGN.js → chunk-XWEJ5LV2.js} +63 -27
  98. package/dist/chunk-XWEJ5LV2.js.map +1 -0
  99. package/dist/{chunk-YMHGF6R5.js → chunk-ZCF2JJFA.js} +3 -3
  100. package/dist/{chunk-YMHGF6R5.js.map → chunk-ZCF2JJFA.js.map} +1 -1
  101. package/dist/collaboration/index.cjs +45 -41
  102. package/dist/collaboration/index.js +1 -1
  103. package/dist/collaboration/mail/MailMessagePreview.d.ts +11 -0
  104. package/dist/collaboration/mail/index.d.ts +1 -0
  105. package/dist/connect/index.cjs +33 -33
  106. package/dist/connect/index.js +4 -4
  107. package/dist/facts/FactsFilterInput.d.ts +2 -46
  108. package/dist/facts/FactsToolbar.d.ts +5 -5
  109. package/dist/facts/index.cjs +27 -124
  110. package/dist/facts/index.cjs.map +1 -1
  111. package/dist/facts/index.js +13 -118
  112. package/dist/facts/index.js.map +1 -1
  113. package/dist/files/FilesPage.d.ts +1 -1
  114. package/dist/files/FilesToolbar.d.ts +1 -1
  115. package/dist/files/FolderPicker.d.ts +2 -1
  116. package/dist/files/ViewerChrome.d.ts +1 -1
  117. package/dist/files/bulk/FolderFilterButton.d.ts +3 -2
  118. package/dist/files/cells/BulkLabelSelect.d.ts +11 -0
  119. package/dist/files/cells/LabelMultiSelect.d.ts +2 -1
  120. package/dist/files/cells/index.d.ts +1 -0
  121. package/dist/files/index.cjs +108 -165
  122. package/dist/files/index.cjs.map +1 -1
  123. package/dist/files/index.js +94 -157
  124. package/dist/files/index.js.map +1 -1
  125. package/dist/home/index.cjs +19 -19
  126. package/dist/home/index.cjs.map +1 -1
  127. package/dist/home/index.js +4 -4
  128. package/dist/home/index.js.map +1 -1
  129. package/dist/index.cjs +790 -767
  130. package/dist/index.cjs.map +1 -1
  131. package/dist/index.d.ts +1 -0
  132. package/dist/index.js +20 -68
  133. package/dist/index.js.map +1 -1
  134. package/dist/settings/SettingsPanel.d.ts +1 -1
  135. package/dist/settings/index.cjs +55 -280
  136. package/dist/settings/index.cjs.map +1 -1
  137. package/dist/settings/index.js +17 -248
  138. package/dist/settings/index.js.map +1 -1
  139. package/dist/shell/FilterInput.d.ts +46 -0
  140. package/dist/shell/TabHeader.d.ts +5 -1
  141. package/dist/shell/index.cjs +61 -48
  142. package/dist/shell/index.d.ts +1 -0
  143. package/dist/shell/index.js +3 -2
  144. package/dist/site/index.cjs +62 -62
  145. package/dist/site/index.js +2 -2
  146. package/dist/studio/index.cjs +74 -74
  147. package/dist/studio/index.js +5 -5
  148. package/dist/workspaces/WorkspaceCard.d.ts +2 -2
  149. package/dist/workspaces/index.cjs +9 -2
  150. package/dist/workspaces/index.cjs.map +1 -1
  151. package/dist/workspaces/index.js +9 -2
  152. package/dist/workspaces/index.js.map +1 -1
  153. package/package.json +3 -3
  154. package/src/blocks.css +4 -0
  155. package/src/components/grid.css +10 -0
  156. package/dist/chunk-3NZR6PAG.js.map +0 -1
  157. package/dist/chunk-4XJZ6AAY.js.map +0 -1
  158. package/dist/chunk-5B4PXAKI.cjs.map +0 -1
  159. package/dist/chunk-5ZBP7TCD.cjs.map +0 -1
  160. package/dist/chunk-C75S6USL.js.map +0 -1
  161. package/dist/chunk-CQWRVIJC.cjs.map +0 -1
  162. package/dist/chunk-FRRDPYBR.cjs.map +0 -1
  163. package/dist/chunk-GVQOBJKR.cjs.map +0 -1
  164. package/dist/chunk-JGZTRLKL.cjs.map +0 -1
  165. package/dist/chunk-JLOYWXRB.js.map +0 -1
  166. package/dist/chunk-KXMDOTGW.js.map +0 -1
  167. package/dist/chunk-NJL4LIXX.js.map +0 -1
  168. package/dist/chunk-NUPVHEJW.js.map +0 -1
  169. package/dist/chunk-OJSWQM4G.js.map +0 -1
  170. package/dist/chunk-QN42OA5J.js.map +0 -1
  171. package/dist/chunk-RGHQFJOL.cjs.map +0 -1
  172. package/dist/chunk-S5HZBXZA.cjs.map +0 -1
  173. package/dist/chunk-UBNVIIBT.js.map +0 -1
  174. package/dist/chunk-WSJVHSGN.js.map +0 -1
  175. package/dist/chunk-Y2LWA4ZO.js.map +0 -1
  176. package/dist/chunk-YVIOCITQ.cjs.map +0 -1
  177. package/dist/chunk-ZHLMDJCO.cjs.map +0 -1
  178. package/dist/chunk-ZORQ5M3W.cjs.map +0 -1
  179. package/dist/chunk-ZVPTFTGV.cjs.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/files/grid-test-ids.ts","../src/files/GridView.tsx","../src/files/SelectionBar.tsx"],"names":["jsx","useRef","jsxs"],"mappings":"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","file":"chunk-NUPVHEJW.js","sourcesContent":["/**\n * Test-id hooks for AG Grid, which owns its row and cell DOM. AG Grid stamps every row with a\n * `row-id` attribute and every cell with `col-id`; these helpers turn them into `data-testid`s\n * a host chooses, so a custom UI keeps its own test-id scheme.\n */\n\nexport interface GridTestIdOptions<T> {\n /** Test id of the row for `item` (set on the centre-column row element). */\n getRowTestId?: (item: T) => string\n /** Test id of the cell in column `colId` of `item`. */\n getCellTestId?: (colId: string, item: T) => string\n}\n\n/** Stamp `data-testid`s onto the rows and cells under `root`. Idempotent. */\nexport function applyGridTestIds<T>(\n root: ParentNode,\n itemsById: Map<string, T>,\n { getRowTestId, getCellTestId }: GridTestIdOptions<T>\n): void {\n if (!getRowTestId && !getCellTestId) return\n root.querySelectorAll<HTMLElement>('.ag-center-cols-container .ag-row[row-id]').forEach((row) => {\n const item = itemsById.get(row.getAttribute('row-id') ?? '')\n if (item === undefined) return\n if (getRowTestId) row.setAttribute('data-testid', getRowTestId(item))\n if (getCellTestId) {\n row.querySelectorAll<HTMLElement>('.ag-cell[col-id]').forEach((cell) => {\n cell.setAttribute('data-testid', getCellTestId(cell.getAttribute('col-id') ?? '', item))\n })\n }\n })\n}\n\n/**\n * Keep the ids applied as AG Grid creates and recycles rows (it virtualises). Returns the\n * disconnect function.\n */\nexport function watchGridTestIds<T>(\n root: HTMLElement,\n getItemsById: () => Map<string, T>,\n options: GridTestIdOptions<T>\n): () => void {\n if (!options.getRowTestId && !options.getCellTestId) return () => {}\n const run = () => applyGridTestIds(root, getItemsById(), options)\n run()\n if (typeof MutationObserver === 'undefined') return () => {}\n const observer = new MutationObserver(run)\n observer.observe(root, { childList: true, subtree: true })\n return () => observer.disconnect()\n}\n","/**\n * GridView — a flexible AG Grid presentational core.\n *\n * Pure and app-agnostic: it owns no global state and pulls in no store. Column\n * state persistence (order / width / visibility / sort / filter) is exposed as a\n * controlled/uncontrolled prop pair — `gridState` (initial state, read once at\n * mount) and `onGridStateChange` (called whenever AG Grid's state changes). An\n * app wires those to wherever it keeps the state (Zustand, localStorage, a URL,\n * a server) via a thin adapter; the core stays decoupled.\n *\n * Themed here (colours/fonts/borders via the host CSS variables, so it inherits the host's\n * light/dark theme). The structural helper classes (cell-numeric, multiline clamp, scrollbars,\n * row kebabs) live in `@arbidocs/blocks/grid.css`, which the consuming app imports globally.\n */\n\nimport React, { useRef, useCallback, useMemo, useEffect } from 'react'\nimport { AgGridReact } from 'ag-grid-react'\nimport {\n ColDef,\n GridOptions,\n GridApi,\n IRowNode,\n GridState,\n themeQuartz,\n CellValueChangedEvent,\n GridReadyEvent,\n RowClickedEvent,\n} from 'ag-grid-community'\nimport { AllCommunityModule } from 'ag-grid-community'\nimport { BREAKPOINT_QUERIES, useMediaQuery } from '../lib/use-media-query'\nimport { watchGridTestIds } from './grid-test-ids'\n\n// Create the custom ARBI theme using themeQuartz\n// Colours reference the host CSS variables (hsl(var(--token))), so dark mode follows the app.\n// This enables dark mode support and consistent theming\nconst cssVar = (name: string, alpha?: number): string =>\n alpha === undefined ? `hsl(var(--${name}))` : `hsl(var(--${name}) / ${alpha})`\n\nconst arbiTheme = themeQuartz.withParams({\n // Variant B palette: white canvas, quiet header, muted hover nudge, accent-tint selection.\n // Every colour is a host CSS variable, so light/dark follow the app with no .dark overrides.\n backgroundColor: cssVar('background'),\n foregroundColor: cssVar('foreground'),\n borderColor: cssVar('border'),\n headerBackgroundColor: cssVar('background'),\n headerTextColor: cssVar('muted-foreground'),\n oddRowBackgroundColor: cssVar('background'),\n rowHoverColor: cssVar('muted', 0.6),\n // Checkbox-selected rows: a light accent tint. A row opened elsewhere (e.g. the viewer) may take\n // the full accent, so the two states stay distinguishable.\n selectedRowBackgroundColor: cssVar('accent', 0.6),\n rangeSelectionBackgroundColor: cssVar('accent'),\n accentColor: cssVar('primary'),\n inputFocusBorder: { color: cssVar('primary') },\n headerColumnBorder: false,\n headerColumnResizeHandleColor: 'transparent', // still draggable, no visible divider\n\n // Font settings — inherit the host app's font. A googleFont here never\n // loaded under the apps' CSP, so every grid silently fell back to the\n // browser's default SERIF and read as unstyled.\n fontFamily: 'inherit',\n fontSize: 14,\n headerFontSize: 12.5,\n headerFontWeight: 500,\n\n // Sizing\n headerHeight: 44,\n rowHeight: 40,\n cellHorizontalPadding: 16,\n\n // Borders - structural settings only.\n // Row border is a real hairline in the theme border colour (not hardcoded\n // white, which was invisible on the light-mode background and wrong in dark\n // mode) so adjacent rows are clearly separated — important now that rows can\n // be tall and multi-line (e.g. the Abstract column).\n rowBorder: { style: 'solid', width: 1, color: 'hsl(var(--border))' },\n columnBorder: false, // Row hairlines only\n wrapperBorder: false,\n\n // No rounded corners for clean look (except checkboxes)\n borderRadius: 0,\n wrapperBorderRadius: 0,\n checkboxBorderRadius: 2, // Keep checkboxes square\n})\n\n// Selection configuration\nexport interface GridViewSelection<T> {\n mode: 'single' | 'multiple'\n selected: T[]\n onSelectionChange: (items: T[]) => void\n /**\n * Keep the grid's ticked rows equal to `selected` after mount (default: `selected` only seeds the\n * grid). For a host that changes the selection itself, e.g. ticking a parent ticks its sub-tasks.\n */\n controlled?: boolean\n}\n\n// Empty state configuration\nexport interface GridViewEmptyState {\n icon?: React.ReactNode\n title?: string\n message?: string\n action?: React.ReactNode\n}\n\n// Generic props to make this grid reusable with different data types\nexport interface GridViewProps<T> {\n // Core data\n items: T[]\n // Column configuration\n columnDefs: ColDef<T>[]\n // Row identity function\n getItemId: (item: T) => string\n // Selection handling\n selection?: GridViewSelection<T>\n // Empty state\n emptyState?: GridViewEmptyState\n // Loading state\n isLoading?: boolean\n loadingMessage?: string\n // Grid options\n gridOptions?: Partial<GridOptions<T>>\n // Grid initialization\n onGridReady?: (params: { api: GridApi<T> }) => void\n // Cell value changes\n onCellValueChanged?: (event: CellValueChangedEvent<T>) => void\n // Row click handler\n onRowClick?: (item: T) => void\n // State persistence.\n // The core is decoupled from any store: when `persistState` is on it seeds\n // AG Grid from `gridState` (read once at mount) and reports every subsequent\n // state change through `onGridStateChange`. An app-adapter wires these to its\n // own store. `gridId` is retained as an opaque identity hint for adapters\n // (the core itself does not read it).\n persistState?: boolean\n gridId?: string\n // Persisted column/sort/filter state to restore at mount (controlled input).\n gridState?: GridState\n // Called whenever AG Grid's state changes so an adapter can persist it.\n onGridStateChange?: (state: GridState) => void\n // Initial visible columns (applied when no saved state exists)\n initialVisibleColumns?: string[]\n // Basic styling\n className?: string\n height?: string | number\n // Per-instance row height. Applied via the theme (not just gridOptions) so the\n // theme's calculated line-height tracks it and cell content stays vertically\n // centered. Fixed height — keeps row virtualization on the fast path.\n rowHeight?: number\n testId?: string\n // Pinned rows\n pinnedBottomRowData?: T[]\n pinnedTopRowData?: T[]\n // Pagination (disabled by default)\n pagination?: boolean\n paginationPageSizeSelector?: number[]\n // Test-id hooks: the grid owns its row/cell DOM, so ids are stamped onto it after render.\n // `getRowTestId` names a row; `getCellTestId` a cell (by colId). Without them AG Grid's own\n // `row-id` / `col-id` attributes are still there to select by.\n getRowTestId?: (item: T) => string\n getCellTestId?: (colId: string, item: T) => string\n // Force empty-state UI even when items.length > 0.\n // Used when rows are present but all hidden by an external filter.\n showEmpty?: boolean\n}\n\n/** Minimum row height on coarse pointers: 44px touch target + the 1px row border + breathing room. */\nconst TOUCH_ROW_HEIGHT = 52\n\nexport function GridView<T>({\n items,\n columnDefs,\n getItemId,\n selection,\n emptyState,\n isLoading = false,\n loadingMessage = 'Loading...',\n gridOptions,\n onGridReady,\n onCellValueChanged,\n onRowClick,\n persistState = false,\n gridState,\n onGridStateChange,\n initialVisibleColumns,\n className = 'w-full',\n height = 500,\n rowHeight: rowHeightProp,\n testId = 'grid-view',\n pinnedBottomRowData,\n pinnedTopRowData,\n pagination = false,\n paginationPageSizeSelector,\n getRowTestId,\n getCellTestId,\n showEmpty,\n}: GridViewProps<T>) {\n // Reference to the grid API\n const gridApiRef = useRef<GridApi<T> | null>(null)\n\n // On touch screens rows grow to a 44px-hit-area-friendly height: AG Grid clips cell content\n // (pills, filename buttons, avatar chips) to the row, so a taller hit area needs a taller row.\n const isCoarsePointer = useMediaQuery(BREAKPOINT_QUERIES.coarsePointer)\n const rowHeight = isCoarsePointer\n ? Math.max(rowHeightProp ?? gridOptions?.rowHeight ?? 40, TOUCH_ROW_HEIGHT)\n : rowHeightProp\n\n // Initial row height, captured once so it can live in the (stable) default\n // grid options. rowHeight is NOT passed as a reactive prop — that would make\n // the AgGridReact wrapper re-process grid options on every change and snap\n // manually-resized columns back to their colDef widths. Subsequent changes are\n // applied imperatively (see effect below).\n const initialRowHeightRef = useRef(rowHeight)\n\n // Persisted state to seed the grid with — captured once at mount so a reactive\n // `gridState` prop (e.g. an adapter re-reading its store each render) can never\n // re-initialise the grid mid-session. Mirrors AG Grid's own initialState,\n // which is read once.\n const initialGridStateRef = useRef(gridState)\n\n // Get initial state for the grid (read once at mount)\n const initialState = useMemo(() => {\n if (!persistState) return undefined\n return initialGridStateRef.current\n }, [persistState])\n\n // Save grid state via the adapter using modern AG Grid state API\n const saveGridState = useCallback(() => {\n if (!persistState || !onGridStateChange || !gridApiRef.current) return\n\n // Use AG Grid's comprehensive state API to capture complete state\n // This includes: filters, sort, column order, column visibility, column widths, etc.\n const state = gridApiRef.current.getState()\n\n onGridStateChange(state)\n }, [persistState, onGridStateChange])\n\n // Ensure selection column is visible after grid initialization\n const ensureSelectionColumnVisible = useCallback(() => {\n if (!gridApiRef.current || !selection?.mode) return\n\n // IMPORTANT: Force selection column to be visible after state restoration\n // This ensures even old saved states don't hide the selection column\n // Also handles case where selection column is completely missing from state\n const currentState = gridApiRef.current.getColumnState()\n const selectionColumn = currentState.find((col) => col.colId === 'ag-Grid-SelectionColumn')\n const selectionColumnIndex = currentState.findIndex(\n (col) => col.colId === 'ag-Grid-SelectionColumn'\n )\n\n // Fix if column is hidden OR missing entirely OR not in first position\n if (!selectionColumn || selectionColumn.hide || selectionColumnIndex !== 0) {\n // Use setColumnsVisible for more reliable visibility control\n gridApiRef.current.setColumnsVisible(['ag-Grid-SelectionColumn'], true)\n\n // Also apply state to ensure proper width\n gridApiRef.current.applyColumnState({\n state: [\n {\n colId: 'ag-Grid-SelectionColumn',\n hide: false,\n width: selectionColumn?.width || 48,\n pinned: null, // Ensure not pinned in wrong position\n },\n ],\n defaultState: { hide: undefined },\n applyOrder: false,\n })\n\n // Move selection column to first position if it's not there\n if (selectionColumnIndex !== 0) {\n gridApiRef.current.moveColumns(['ag-Grid-SelectionColumn'], 0)\n }\n }\n }, [selection?.mode])\n\n // Stamp host test ids onto AG Grid's rows and cells (it virtualises, so keep watching).\n const containerRef = useRef<HTMLDivElement>(null)\n const itemsRef = useRef(items)\n itemsRef.current = items\n const getItemIdRef = useRef(getItemId)\n getItemIdRef.current = getItemId\n const hasTestIdHooks = Boolean(getRowTestId || getCellTestId)\n useEffect(() => {\n const root = containerRef.current\n if (!root || !hasTestIdHooks) return\n return watchGridTestIds(\n root,\n () => new Map(itemsRef.current.map((item) => [getItemIdRef.current(item), item])),\n { getRowTestId, getCellTestId }\n )\n }, [hasTestIdHooks, getRowTestId, getCellTestId, isLoading])\n\n // Handle row ID\n const getRowId = useCallback(\n (params: { data: T }) => {\n return getItemId(params.data)\n },\n [getItemId]\n )\n\n // Refs for selection — avoids handleGridReady/handleSelectionChanged recreating\n // when selection object changes (which happens on every selectionConfig recompute)\n const selectionRef = useRef(selection)\n selectionRef.current = selection\n\n const onSelectionChangeRef = useRef(selection?.onSelectionChange)\n onSelectionChangeRef.current = selection?.onSelectionChange\n\n const syncingSelectionRef = useRef(false)\n\n const handleSelectionChanged = useCallback(() => {\n if (syncingSelectionRef.current) return\n if (!onSelectionChangeRef.current || !gridApiRef.current) return\n\n const selectedNodes = gridApiRef.current.getSelectedNodes()\n const selectedData = selectedNodes\n .map((node) => node.data)\n .filter((item): item is T => item !== undefined)\n\n onSelectionChangeRef.current(selectedData)\n }, [])\n\n // Handle row clicks\n // A controlled selection: tick and untick rows so the grid shows exactly `selection.selected`.\n const controlledSelected = selection?.controlled ? selection.selected : undefined\n useEffect(() => {\n const api = gridApiRef.current\n if (!api || api.isDestroyed() || !controlledSelected) return\n const wanted = new Set(controlledSelected.map(getItemId))\n const tick: IRowNode<T>[] = []\n const untick: IRowNode<T>[] = []\n api.forEachNode((node) => {\n if (!node.data) return\n const want = wanted.has(getItemId(node.data))\n if (want && !node.isSelected()) tick.push(node)\n else if (!want && node.isSelected()) untick.push(node)\n })\n syncingSelectionRef.current = true\n try {\n if (tick.length) api.setNodesSelected({ nodes: tick, newValue: true, source: 'api' })\n if (untick.length) api.setNodesSelected({ nodes: untick, newValue: false, source: 'api' })\n } finally {\n syncingSelectionRef.current = false\n }\n }, [controlledSelected, getItemId])\n\n const handleRowClicked = useCallback(\n (event: RowClickedEvent<T>) => {\n if (!onRowClick || !event.data) return\n // Don't fire when the click originated from an interactive element inside the cell\n // (e.g. action buttons). AG Grid fires rowClicked regardless of DOM stopPropagation.\n const target = event.event?.target as HTMLElement | null\n if (target?.closest('button, input, a, select, textarea, [role=\"button\"]')) return\n onRowClick(event.data)\n },\n [onRowClick]\n )\n\n // The visibility the user actually intends, per colId. AG Grid re-processes the\n // column definitions on some React re-renders even when the `columnDefs`\n // reference is unchanged, and that reset restores each colDef's `hide` — so a\n // column the user turned on (e.g. via a fields menu) silently disappears the\n // next time the host re-renders (opening an editor, selecting a row, …). We\n // remember the intended visibility and restore it whenever such a reset fires.\n // A Map (not a Set of hidden ids) so a genuinely NEW column from a real\n // columnDefs change — one we've never seen — is left at its colDef default\n // rather than force-shown.\n const desiredHiddenRef = useRef<Map<string, boolean> | null>(null)\n\n const snapshotDesiredHidden = useCallback(() => {\n const api = gridApiRef.current\n if (!api) return\n desiredHiddenRef.current = new Map(api.getColumnState().map((c) => [c.colId, !!c.hide]))\n }, [])\n\n // Handle grid ready\n const handleGridReady = useCallback(\n (event: GridReadyEvent<T>) => {\n gridApiRef.current = event.api\n\n // Apply initial visible columns when no saved state exists\n // This prevents showing all columns by default for new users\n if (!initialState && initialVisibleColumns?.length) {\n const currentState = event.api.getColumnState()\n const stateMap = new Map(currentState.map((col) => [col.colId, col]))\n const visibleSet = new Set(initialVisibleColumns)\n\n // Build ordered state: selection column first (always visible), then visible columns, then hidden\n const selectionCol = stateMap.get('ag-Grid-SelectionColumn')\n const orderedState = [\n // Selection column first - ALWAYS visible, create if not in state\n selectionCol\n ? { ...selectionCol, hide: false }\n : { colId: 'ag-Grid-SelectionColumn', hide: false, width: 48 },\n // Visible columns in specified order\n ...initialVisibleColumns\n .filter((colId) => colId !== 'ag-Grid-SelectionColumn') // Don't duplicate selection column\n .map((colId) => {\n const col = stateMap.get(colId)\n return col ? { ...col, hide: false } : undefined\n }),\n // Hidden columns (everything else)\n ...currentState\n .filter((col) => col.colId !== 'ag-Grid-SelectionColumn' && !visibleSet.has(col.colId))\n .map((col) => ({ ...col, hide: true })),\n ].filter((col): col is NonNullable<typeof col> => col !== undefined)\n\n event.api.applyColumnState({ state: orderedState, applyOrder: true })\n }\n\n // When restoring persisted state, detect columns from columnDefs that\n // aren't in the saved state (e.g. newly added columns) and append them.\n // AG Grid's maintainColumnOrder adds them but may place them inconsistently;\n // this ensures they appear as hidden at the end so the navigator picks them up.\n if (initialState && initialVisibleColumns?.length) {\n const currentState = event.api.getColumnState()\n const savedColIds = new Set(\n initialState.columnOrder?.orderedColIds ?? currentState.map((c) => c.colId)\n )\n const newCols = currentState.filter(\n (col) => !savedColIds.has(col.colId) && col.colId !== 'ag-Grid-SelectionColumn'\n )\n if (newCols.length > 0) {\n // Make new columns visible if they're in the default visible set\n const defaultVisible = new Set(initialVisibleColumns)\n event.api.applyColumnState({\n state: newCols.map((col) => ({\n ...col,\n hide: !defaultVisible.has(col.colId),\n })),\n })\n }\n }\n\n // Ensure selection column is visible (in case saved state hides it)\n ensureSelectionColumnVisible()\n\n // Seed the intended column visibility from the state AG Grid settled on\n // (colDefs + restored persisted state) so a later colDef-driven reset can\n // be undone rather than silently hiding a user-shown column.\n snapshotDesiredHidden()\n\n // Call the provided onGridReady callback\n if (onGridReady) {\n onGridReady({ api: event.api })\n }\n\n // Restore selection state if needed (read from ref to keep callback stable)\n const sel = selectionRef.current\n if (sel && sel.selected.length > 0) {\n const selectedIds = new Set(sel.selected.map(getItemId))\n event.api.forEachNode((node) => {\n if (node.data && selectedIds.has(getItemId(node.data))) {\n node.setSelected(true)\n }\n })\n }\n },\n [\n onGridReady,\n getItemId,\n ensureSelectionColumnVisible,\n snapshotDesiredHidden,\n initialState,\n initialVisibleColumns,\n ]\n )\n\n // Undo AG Grid's colDef-driven visibility reset; record genuine user changes.\n const handleColumnVisible = useCallback(\n (event: { source?: string }) => {\n const api = gridApiRef.current\n if (!api) return\n // A columnDefs re-apply reports `gridOptionsChanged`; a real toggle reports\n // an interaction source (api, toolPanelUi, columnMenu, …).\n if (event.source === 'gridOptionsChanged') {\n const desired = desiredHiddenRef.current\n if (!desired) return\n // Only correct columns we've seen before (in the snapshot); a brand-new\n // column keeps its colDef default.\n const fixes = api\n .getColumnState()\n .filter(\n (c) =>\n c.colId !== 'ag-Grid-SelectionColumn' &&\n desired.has(c.colId) &&\n desired.get(c.colId) !== !!c.hide\n )\n .map((c) => ({ colId: c.colId, hide: desired.get(c.colId) }))\n if (fixes.length) api.applyColumnState({ state: fixes })\n } else {\n // Genuine change — this is now the intended visibility.\n snapshotDesiredHidden()\n }\n },\n [snapshotDesiredHidden]\n )\n\n // Handle first data rendered - no auto-sizing, let flex columns handle it\n const handleFirstDataRendered = useCallback(() => {\n // Columns with flex will auto-fill, columns with width stay fixed\n // Also ensure selection column is visible as a backup (handles timing issues with initialState)\n ensureSelectionColumnVisible()\n // Seed the intended visibility from the state AG Grid settled on (colDefs +\n // any restored persisted state), so later resets can be undone.\n snapshotDesiredHidden()\n }, [ensureSelectionColumnVisible, snapshotDesiredHidden])\n\n // Track when AG Grid processes row updates\n const handleModelUpdated = useCallback(() => {\n // AG Grid handles model updates internally\n }, [])\n\n // Track row data changes for AG Grid updates\n const prevItemsRef = useRef<T[]>([])\n useEffect(() => {\n prevItemsRef.current = items\n }, [items])\n\n // Handle state updates - save state when it changes (modern AG Grid approach)\n const handleStateUpdated = useCallback(() => {\n saveGridState()\n }, [saveGridState])\n\n // Removed problematic useEffect that caused unnecessary re-renders\n // AG Grid handles selection internally, only sync on initial load\n\n // Default grid options with minimal settings - memoized to prevent re-renders\n const defaultOptions: GridOptions<T> = useMemo(() => {\n return {\n // Initial row height (stable — captured once). Live changes go through the\n // imperative effect, not this option, to avoid column-state churn.\n rowHeight: initialRowHeightRef.current,\n suppressMenuHide: true, // Prevent hiding columns since we don't have enterprise sidebar\n maintainColumnOrder: true, // Preserve column order when columns are added/removed\n\n // Row virtualization: Render rows as needed for performance\n // rowBuffer renders extra rows above/below viewport for smoother scrolling\n rowBuffer: 10, // Render 10 extra rows above/below viewport for smooth scrolling\n suppressColumnVirtualisation: false, // Keep column virtualization enabled\n suppressRowVirtualisation: false, // ENABLE row virtualization - only render visible rows\n animateRows: false, // Disable row animations\n suppressColumnMoveAnimation: true, // Disable column move/resize animations\n\n // Efficient updates with React Query cache\n // getRowId enables change detection - grid only re-renders changed rows\n // Works perfectly with React Query's cache updates\n getRowId: getRowId,\n\n rowSelection: selection?.mode\n ? {\n mode: selection.mode === 'single' ? 'singleRow' : 'multiRow',\n selectAll: 'filtered', // Header checkbox selects all filtered rows (across all pages)\n // In multi-row mode, only checkboxes should toggle selection (clicking row body would replace selection)\n enableClickSelection: selection.mode === 'single',\n checkboxes: true,\n headerCheckbox: selection.mode === 'multiple',\n }\n : undefined,\n selectionColumnDef: selection?.mode\n ? {\n sortable: selection.mode === 'multiple',\n width: 48,\n lockVisible: true, // Cannot be hidden\n suppressMovable: true, // Cannot be moved\n }\n : undefined,\n // Use normal layout for better performance - autoHeight causes forced reflows\n domLayout: 'normal',\n // Stop editing when clicking outside the cell/grid\n stopEditingWhenCellsLoseFocus: true,\n // Additional performance optimizations\n suppressCellFocus: true, // Don't focus cells on click (faster)\n suppressRowHoverHighlight: true, // Disable hover highlight - reduces DOM manipulation during scroll\n suppressScrollOnNewData: true, // Don't scroll when data updates\n suppressAggFuncInHeader: true, // Don't show aggregation functions (faster)\n // Tooltip UX: the AG Grid default show-delay is 2 s which hurts\n // discoverability for cells where tooltips carry the \"reveal full\n // content\" affordance for non-editable users. 300 ms is snappy\n // without being accidental. tooltipInteraction lets users hover\n // onto the tooltip itself (e.g. to select / copy long text).\n // These are AG Grid's native tooltip controls — no React / Radix\n // provider involved, zero per-row cost; tooltip DOM is created on\n // demand when hover-delay elapses and destroyed on mouseout.\n tooltipShowDelay: 300,\n tooltipHideDelay: 4000,\n tooltipInteraction: true,\n // Pagination (disabled by default)\n pagination,\n paginationPageSizeSelector,\n defaultColDef: {\n sortable: true,\n resizable: true,\n unSortIcon: false, // Sort glyph only on the sorted column (every header carrying one was noise)\n sortingOrder: ['asc', 'desc', null], // 3-way sorting: asc → desc → unsorted (AG Grid default)\n wrapText: false, // Disable text wrapping for cleaner display\n autoHeight: false, // Use fixed row height from theme\n wrapHeaderText: false, // Disable header text wrapping for cleaner look\n autoHeaderHeight: false, // Fixed header height\n filterParams: {\n maxNumConditions: 1,\n buttons: ['reset'],\n },\n },\n }\n }, [selection?.mode, getRowId, pagination, paginationPageSizeSelector])\n\n // Combine default options with passed options - memoized to prevent re-renders\n const combinedOptions = useMemo(\n () => ({ ...defaultOptions, ...gridOptions }),\n [defaultOptions, gridOptions]\n )\n\n // Apply fixed height for better performance — autoHeight causes forced\n // reflows by measuring all rows, avoid it.\n //\n // Also derive the geometry the wrapping multiline columns (.cell-multiline —\n // Abstract, Author, custom text fields) need so their overflow clip lands on\n // a WHOLE-line boundary (never mid-line, which reads as a half-line\n // \"bleeding\" into the neighbouring row). All computed once here per\n // row-height change and handed to CSS as variables — zero per-row cost on the\n // million-row grid:\n // --multiline-line-clamp : whole number of lines that fit — drives the CSS\n // line-clamp that hides overflow lines entirely.\n // --multiline-pad-y : vertical cell padding, shrunk on very short rows so\n // at least one whole line always fits.\n // --multiline-max-h : cap of exactly N whole lines + TOP padding + borders.\n // Deliberately excludes the bottom padding: AG Grid\n // forces cell height, so overflow clips at the\n // padding-box edge and any bottom padding becomes a\n // window onto the next (clamped-away) line. Ending the\n // box right at line N's bottom puts the clip on the\n // line boundary; the row supplies the visual gap below.\n const containerStyle = useMemo(() => {\n const style: React.CSSProperties = { height }\n if (rowHeight) {\n const LINE_PX = 14 * 1.35 // grid font-size × multiline line-height (18.9px)\n const BORDER = 2 // multiline cell top + bottom border (1px each, border-box)\n const PREFERRED_PAD = 16 // preferred total vertical padding (8px top + 8px bottom)\n // Don't let padding eat the room a single line needs on short rows.\n const padTotal = Math.max(0, Math.min(PREFERRED_PAD, rowHeight - BORDER - LINE_PX))\n const lines = Math.max(1, Math.floor((rowHeight - BORDER - padTotal) / LINE_PX))\n const vars = style as Record<string, string | number>\n vars['--multiline-line-clamp'] = `${lines}`\n vars['--multiline-pad-y'] = `${padTotal / 2}px`\n vars['--multiline-max-h'] = `${lines * LINE_PX + padTotal / 2 + BORDER}px`\n }\n return style\n }, [height, rowHeight])\n\n // Apply rowHeight changes imperatively via the grid option (not the theme —\n // recreating the theme would re-initialise the grid). This only re-lays-out\n // rows; columns, row virtualization, and the transaction bus are untouched.\n useEffect(() => {\n const api = gridApiRef.current\n if (!api || api.isDestroyed() || !rowHeight) return\n api.setGridOption('rowHeight', rowHeight)\n api.resetRowHeights()\n }, [rowHeight])\n\n // Add professional shadow for 3D effect\n // Add overflow-visible only for autoHeight layout\n const containerClassName = useMemo(() => {\n const baseClass = className || ''\n const shadowClass = 'shadow-sm' // Tailwind shadow for professional look\n // Height-adjustable grids vertically center cell content (CSS) so a\n // one-line cell or a lone pill sits in the middle of the row, and multi-line\n // text (e.g. Abstract) is balanced top-to-bottom — flagged here, applied in\n // grid.css.\n const alignClass = rowHeight ? 'ag-cells-centered' : ''\n return [baseClass, shadowClass, alignClass].filter(Boolean).join(' ')\n }, [className, rowHeight])\n\n // Show loading state — grey skeleton rows so the page transition feels instant\n if (isLoading) {\n const skeletonRowCount = 12\n return (\n <div\n data-testid={`${testId}-loading`}\n className={containerClassName}\n style={containerStyle}\n aria-busy=\"true\"\n aria-label={loadingMessage}\n >\n {/* Header skeleton */}\n <div className=\"flex h-11 items-center gap-4 border-b border-border/40 px-4\">\n <div className=\"h-3 w-6 rounded bg-muted animate-pulse\" />\n <div className=\"h-3 w-32 rounded bg-muted animate-pulse\" />\n <div className=\"h-3 w-24 rounded bg-muted animate-pulse\" />\n <div className=\"h-3 w-20 rounded bg-muted animate-pulse\" />\n <div className=\"h-3 w-28 rounded bg-muted animate-pulse\" />\n <div className=\"h-3 w-16 rounded bg-muted animate-pulse ml-auto\" />\n </div>\n {/* Row skeletons */}\n {Array.from({ length: skeletonRowCount }).map((_, rowIdx) => (\n <div key={rowIdx} className=\"flex h-10 items-center gap-4 border-b border-border/20 px-4\">\n <div className=\"h-4 w-4 rounded-sm bg-muted/70 animate-pulse\" />\n <div\n className=\"h-3 rounded bg-muted/70 animate-pulse\"\n style={{ width: `${20 + ((rowIdx * 17) % 40)}%` }}\n />\n <div\n className=\"h-3 rounded bg-muted/60 animate-pulse\"\n style={{ width: `${8 + ((rowIdx * 11) % 12)}%` }}\n />\n <div\n className=\"h-3 rounded bg-muted/60 animate-pulse\"\n style={{ width: `${6 + ((rowIdx * 7) % 10)}%` }}\n />\n <div\n className=\"h-3 rounded bg-muted/50 animate-pulse ml-auto\"\n style={{ width: `${5 + ((rowIdx * 5) % 8)}%` }}\n />\n </div>\n ))}\n </div>\n )\n }\n\n // Show empty state\n // showEmpty lets callers force this UI (e.g. when an external filter hid\n // every row but the underlying items array is non-empty).\n if ((showEmpty ?? items.length === 0) && emptyState) {\n return (\n <div\n data-testid={`${testId}-empty`}\n // Capped by its container (a landscape phone is shorter than 24rem) and scrollable, with the\n // content centred by auto margins so a tall one still starts at the top.\n className=\"flex h-96 max-h-full flex-col items-center overflow-y-auto p-6 text-center\"\n >\n <div className=\"my-auto flex flex-col items-center\">\n {emptyState.icon && (\n <div className=\"text-muted-foreground/60 mb-4\">{emptyState.icon}</div>\n )}\n {emptyState.title && <h3 className=\"text-xl font-medium mb-2\">{emptyState.title}</h3>}\n {emptyState.message && (\n <p className=\"text-muted-foreground mb-6 max-w-md\">{emptyState.message}</p>\n )}\n {emptyState.action}\n </div>\n </div>\n )\n }\n\n return (\n <div\n ref={containerRef}\n className={containerClassName}\n style={containerStyle}\n data-testid={testId}\n >\n <AgGridReact\n theme={arbiTheme}\n modules={[AllCommunityModule]}\n columnDefs={columnDefs}\n rowData={items}\n pinnedBottomRowData={pinnedBottomRowData}\n pinnedTopRowData={pinnedTopRowData}\n getRowId={getRowId}\n initialState={initialState}\n onGridReady={handleGridReady}\n onFirstDataRendered={handleFirstDataRendered}\n onModelUpdated={handleModelUpdated}\n onSelectionChanged={handleSelectionChanged}\n onCellValueChanged={onCellValueChanged}\n onRowClicked={handleRowClicked}\n onStateUpdated={handleStateUpdated}\n onColumnVisible={handleColumnVisible}\n {...combinedOptions}\n />\n </div>\n )\n}\n","import { useLayoutEffect, useRef, useState } from 'react'\nimport type { ReactNode } from 'react'\nimport type { LucideIcon } from 'lucide-react'\nimport { BookOpen, X } from 'lucide-react'\nimport { Button, Tooltip, TooltipContent, TooltipTrigger, cn } from '@arbidocs/react/ui'\nimport { testIdOr } from '../chat/test-id'\nimport { observeResize } from '../lib/observe-resize'\n\nexport interface SelectionBarActionItem {\n id: string\n icon: LucideIcon\n label: string\n onClick: () => void\n disabled?: boolean\n variant?: 'default' | 'outline' | 'destructive' | 'ghost' | 'secondary'\n /** Tooltip text; falls back to `label`. */\n tooltip?: string\n testId?: string\n className?: string\n}\n\n/** Container width below which the bar is \"narrow\" (phones): only the essentials stay inline. */\nconst NARROW_BELOW_PX = 480\n\n/** Every fixed string of the selection bar. Pass a partial `labels` to translate or reword. */\nexport interface SelectionBarLabels {\n selected: string\n clearSelection: string\n review: string\n selectionActions: string\n}\n\nexport const DEFAULT_SELECTION_BAR_LABELS: SelectionBarLabels = {\n selected: 'selected',\n clearSelection: 'Clear selection',\n review: 'Review',\n selectionActions: 'Selection actions',\n}\n\nexport interface SelectionBarTestIds {\n toolbar: string\n count: string\n clear: string\n review: string\n}\n\nexport interface SelectionBarProps {\n /** Number of selected rows. The bar renders only while this is > 0 (or `status` is set). */\n count: number\n onClear: () => void\n /** Primary-in-bar \"Review\" shortcut (tonal, not the view's filled primary). */\n onReview?: () => void\n /** Actions as data. Rendered icon-only automatically when the bar is narrow. */\n actions?: SelectionBarActionItem[]\n /**\n * Free-form actions; a function receives `isCompact` (icon-only) and `isNarrow` (a phone-width\n * container: fold secondary actions into an overflow menu). Rendered after `actions`.\n */\n children?: ReactNode | ((isCompact: boolean, isNarrow: boolean) => ReactNode)\n /** Always-legible content before the actions (e.g. a running budget); never dimmed. */\n status?: ReactNode\n /** Singular noun shown after the count; wins over `labels.selected`. */\n selectedLabel?: string\n labels?: Partial<SelectionBarLabels>\n /** Overrides for the control test ids (defaults keep the current ids). */\n testIds?: Partial<SelectionBarTestIds>\n className?: string\n}\n\n/**\n * SelectionBar: the floating bar that appears while rows are selected.\n *\n * Stays on ONE row: when the actions overflow it flips to compact mode (icon-only actions and a\n * count-only badge) instead of wrapping. Sticky zero-height anchor, so showing/hiding it never\n * reflows the content beneath. Every control is always visible (nothing hover-only) and 44px on\n * coarse pointers.\n */\nexport function SelectionBar(props: SelectionBarProps) {\n if (props.count === 0 && !props.status) return null\n return <SelectionBarInner {...props} />\n}\n\nfunction SelectionBarInner({\n count,\n onClear,\n onReview,\n actions,\n children,\n status,\n selectedLabel,\n labels,\n testIds,\n className,\n}: SelectionBarProps) {\n const l = { ...DEFAULT_SELECTION_BAR_LABELS, ...labels }\n const hasSelection = count > 0\n const rootRef = useRef<HTMLDivElement>(null)\n const actionsRef = useRef<HTMLDivElement>(null)\n const [isCompact, setIsCompact] = useState(false)\n const [isNarrow, setIsNarrow] = useState(false)\n // Root width at which the labelled actions last overflowed. Compared against the (stable) root\n // width, never the actions' own width, which changes when we collapse labels and would oscillate.\n const overflowRootWidthRef = useRef(Number.POSITIVE_INFINITY)\n\n const measureRef = useRef<() => void>(() => {})\n measureRef.current = () => {\n const root = rootRef.current\n const el = actionsRef.current\n if (!root || !el) return\n // The bar is content-sized, so judge narrowness by the space it is given (its anchor).\n const available = root.parentElement?.clientWidth ?? 0\n setIsNarrow(available > 0 && available < NARROW_BELOW_PX)\n if (!isCompact) {\n if (el.scrollWidth > el.clientWidth + 1) {\n overflowRootWidthRef.current = root.clientWidth\n setIsCompact(true)\n }\n } else if (root.clientWidth > overflowRootWidthRef.current + 64) {\n setIsCompact(false)\n }\n }\n\n useLayoutEffect(() => {\n measureRef.current()\n const root = rootRef.current\n if (!root) return\n return observeResize(root, () => measureRef.current())\n }, [])\n // The bar is capped by its anchor, so its own size does not change when the actions overflow, and\n // the actions' text widens once the web font loads. Re-measure after every render and whenever\n // an action changes size. The measurement only sets state on a change, so this cannot loop.\n useLayoutEffect(() => {\n measureRef.current()\n const inner = actionsRef.current\n if (!inner || typeof ResizeObserver === 'undefined') return\n const observer = new ResizeObserver(() => measureRef.current())\n inner.querySelectorAll('button').forEach((button) => observer.observe(button))\n return () => observer.disconnect()\n })\n useLayoutEffect(() => {\n let isCancelled = false\n void document.fonts?.ready.then(() => {\n if (!isCancelled) measureRef.current()\n })\n return () => {\n isCancelled = true\n }\n }, [])\n\n return (\n <div\n data-slot=\"selection-bar\"\n className={cn('pointer-events-none sticky bottom-0 z-30 h-0', className)}\n >\n <div className=\"absolute inset-x-0 bottom-4 flex justify-center px-3\">\n <div\n ref={rootRef}\n role=\"toolbar\"\n aria-label={l.selectionActions}\n data-testid={testIdOr(testIds?.toolbar, { testId: 'bulk-actions-toolbar' })}\n data-narrow={isNarrow || undefined}\n className=\"pointer-events-auto flex min-h-12 max-w-full items-center rounded-lg border border-border bg-popover px-2 py-1.5 shadow-xl\"\n >\n <div className=\"flex min-w-0 flex-1 items-center gap-2 px-1\">\n <div\n data-testid={testIdOr(testIds?.count, { testId: 'bulk-selected-count' })}\n aria-live=\"polite\"\n className={cn(\n 'flex shrink-0 items-center rounded-full bg-accent text-sm font-semibold tabular-nums text-accent-foreground',\n isCompact ? 'gap-1 px-2.5 py-1' : 'gap-2 px-3 py-1'\n )}\n >\n <span>\n {count}\n {!isCompact && ` ${selectedLabel ?? l.selected}`}\n </span>\n {hasSelection && (\n <button\n type=\"button\"\n onClick={onClear}\n aria-label={l.clearSelection}\n data-testid={testIdOr(testIds?.clear, { testId: 'bulk-clear-selection-button' })}\n className=\"rounded-full p-0.5 transition-colors hover:bg-foreground/10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring pointer-coarse:p-[15px]\"\n >\n <X className=\"size-3.5\" />\n </button>\n )}\n </div>\n\n {onReview && (\n <button\n type=\"button\"\n onClick={onReview}\n aria-label={isNarrow ? l.review : undefined}\n data-testid={testIdOr(testIds?.review, { testId: 'bulk-review-button' })}\n className=\"flex h-8 shrink-0 items-center gap-1.5 rounded-md bg-accent px-2.5 text-sm font-medium text-accent-foreground transition-colors hover:bg-accent/70 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring pointer-coarse:h-11\"\n >\n <BookOpen className=\"size-3.5\" />\n {!isNarrow && l.review}\n </button>\n )}\n\n <div className=\"h-6 w-px shrink-0 bg-border\" />\n\n <div\n ref={actionsRef}\n className=\"flex min-w-0 flex-1 items-center gap-2 overflow-x-auto overscroll-x-contain [scrollbar-width:none]\"\n >\n {status && <div className=\"flex shrink-0 items-center gap-2\">{status}</div>}\n <div\n className={cn(\n 'flex min-w-0 items-center gap-2',\n !hasSelection && 'pointer-events-none opacity-40'\n )}\n >\n {actions?.map((a) => (\n <SelectionBarAction key={a.id} {...a} isCompact={isCompact} />\n ))}\n {typeof children === 'function' ? children(isCompact, isNarrow) : children}\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n )\n}\n\nexport interface SelectionBarActionProps extends Omit<SelectionBarActionItem, 'id'> {\n /** Icon-only (the bar passes this when narrow). */\n isCompact?: boolean\n}\n\n/** One action button in the bar: icon + label, icon-only when compact, always with a tooltip. */\nexport function SelectionBarAction({\n icon: Icon,\n label,\n onClick,\n disabled = false,\n variant = 'ghost',\n tooltip,\n testId,\n className,\n isCompact = false,\n}: SelectionBarActionProps) {\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant={variant}\n size=\"sm\"\n onClick={onClick}\n disabled={disabled}\n aria-label={isCompact ? label : undefined}\n data-testid={testId}\n className={cn(\n 'h-8 shrink-0 gap-1.5 whitespace-nowrap px-2 disabled:opacity-50 pointer-coarse:h-11',\n className\n )}\n >\n <Icon className=\"size-4\" />\n {!isCompact && <span className=\"text-sm\">{label}</span>}\n </Button>\n </TooltipTrigger>\n <TooltipContent>\n <p>{tooltip ?? label}</p>\n </TooltipContent>\n </Tooltip>\n )\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/collaboration/members/WorkspaceMembers.tsx","../src/collaboration/contacts/parseEmails.ts","../src/collaboration/contacts/AddContactsParts.tsx","../src/collaboration/contacts/vcard.ts","../src/collaboration/contacts/ContactCard.tsx","../src/collaboration/direct-messages/DirectMessages.tsx","../src/collaboration/direct-messages/DmParts.tsx","../src/collaboration/mail/mailFolders.ts","../src/collaboration/mail/MailFolderTree.tsx"],"names":["jsxs","Fragment","jsx","Button","useMemo","DropdownMenu","DropdownMenuTrigger","DropdownMenuContent","DropdownMenuItem","AtSign","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","Tooltip","TooltipTrigger","TooltipContent","cn"],"mappings":"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","file":"chunk-OJSWQM4G.js","sourcesContent":["import type { ReactNode } from 'react'\nimport { Clock, Trash2, UserMinus } from 'lucide-react'\nimport {\n Button,\n cn,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from '@arbidocs/react/ui'\nimport { RoleBadge } from '../../workspaces/WorkspaceBadges'\n\n/** One assignable role. `badgeClass` is the host's palette for the role. */\nexport interface MemberRoleOption {\n value: string\n label: string\n badgeClass: string\n}\n\n/** Tooltip + grid-cell text of the members table, kept in one place. */\nexport function MemberMutedText({\n children,\n title,\n className,\n}: {\n children: ReactNode\n title?: string\n className?: string\n}) {\n return (\n <span className={cn('text-sm text-muted-foreground', className)} title={title}>\n {children}\n </span>\n )\n}\n\n/** Layout of the Name cell: identity chip followed by optional contact toggle. */\nexport function MemberNameCell({ children }: { children: ReactNode }) {\n return <div className=\"flex h-full items-center gap-2\">{children}</div>\n}\n\nexport interface MemberRoleCellProps {\n role: string\n roles: MemberRoleOption[]\n /** Tooltip: why the role is locked, or what the role means. */\n tooltip: string\n canChange: boolean\n isPending: boolean\n onChange: (role: string) => void\n /** Session-scoped (temporary) grant: adds a clock with its explanation. */\n temporaryHint?: string\n}\n\n/** Inline role dropdown of a member row (always rendered so chevrons align). */\nexport function MemberRoleCell({\n role,\n roles,\n tooltip,\n canChange,\n isPending,\n onChange,\n temporaryHint,\n}: MemberRoleCellProps) {\n const current = roles.find((r) => r.value === role)\n return (\n <div className=\"flex h-full items-center gap-1\">\n <Tooltip>\n <TooltipTrigger asChild>\n <span>\n <Select value={role} onValueChange={onChange} disabled={!canChange || isPending}>\n <SelectTrigger\n className={cn(\n 'h-6 w-[130px] border-0 bg-transparent text-sm focus:ring-0 focus:ring-offset-0 disabled:opacity-100',\n canChange ? 'hover:bg-muted/50' : 'cursor-not-allowed [&>svg]:opacity-30'\n )}\n >\n <RoleBadge label={current?.label ?? role} badgeClass={current?.badgeClass ?? ''} />\n </SelectTrigger>\n <SelectContent>\n {roles.map((r) => (\n <SelectItem key={r.value} value={r.value}>\n <RoleBadge label={r.label} badgeClass={r.badgeClass} />\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </span>\n </TooltipTrigger>\n <TooltipContent side=\"right\" className=\"max-w-[300px]\">\n <p>{tooltip}</p>\n </TooltipContent>\n </Tooltip>\n {temporaryHint && (\n <Tooltip>\n <TooltipTrigger asChild>\n <Clock\n className=\"size-3.5 shrink-0 cursor-default text-muted-foreground\"\n aria-label={temporaryHint}\n />\n </TooltipTrigger>\n <TooltipContent side=\"right\" className=\"max-w-[300px]\">\n <p>{temporaryHint}</p>\n </TooltipContent>\n </Tooltip>\n )}\n </div>\n )\n}\n\n/** Loading strip of the members list. */\nexport function MemberListLoading({ label = 'Loading users...' }: { label?: string }) {\n return (\n <div\n className=\"rounded-md bg-blue-bg p-3 text-center text-sm\"\n data-testid=\"workspace-users-loading\"\n >\n <div className=\"mr-2 inline-block size-4 animate-spin rounded-full border-2 border-primary/30 border-t-primary\" />\n {label}\n </div>\n )\n}\n\nexport interface MemberBulkActionsProps {\n /** Roles a bulk change may assign. */\n roles: { value: string; label: string }[]\n onChangeRole: (role: string) => void\n isRoleDisabled: boolean\n roleTooltip: string\n /** Only the workspace owner can use either control (also styles them muted). */\n isOwner: boolean\n onRemove: () => void\n isRemoveDisabled: boolean\n removeTooltip: string\n changeRolePlaceholder?: string\n}\n\n/** Role change dropdown + remove button inside the selection bar of the members table. */\nexport function MemberBulkActions({\n roles,\n onChangeRole,\n isRoleDisabled,\n roleTooltip,\n isOwner,\n onRemove,\n isRemoveDisabled,\n removeTooltip,\n changeRolePlaceholder = 'Change role',\n}: MemberBulkActionsProps) {\n return (\n <>\n <Tooltip>\n <TooltipTrigger asChild onFocusCapture={(e) => e.stopPropagation()}>\n <span tabIndex={!isOwner ? 0 : undefined}>\n <Select value=\"\" onValueChange={onChangeRole} disabled={isRoleDisabled}>\n <SelectTrigger\n className={cn(\n 'h-7 w-[120px] text-sm pointer-coarse:h-11',\n isRoleDisabled ? 'border-border text-muted-foreground' : 'border-input'\n )}\n >\n <SelectValue placeholder={changeRolePlaceholder} />\n </SelectTrigger>\n <SelectContent>\n {roles.map((r) => (\n <SelectItem key={r.value} value={r.value}>\n {r.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </span>\n </TooltipTrigger>\n <TooltipContent>\n <p>{roleTooltip}</p>\n </TooltipContent>\n </Tooltip>\n\n <Tooltip>\n <TooltipTrigger asChild>\n <span tabIndex={!isOwner ? 0 : undefined}>\n <Button\n variant=\"outline\"\n size=\"icon\"\n onClick={onRemove}\n disabled={isRemoveDisabled}\n aria-label={removeTooltip}\n className={cn(\n 'size-7 pointer-coarse:size-11',\n isOwner\n ? 'border-destructive/30 text-destructive hover:bg-destructive hover:text-destructive-foreground'\n : 'border-border text-muted-foreground'\n )}\n >\n <UserMinus className=\"size-4\" />\n </Button>\n </span>\n </TooltipTrigger>\n <TooltipContent>\n <p>{removeTooltip}</p>\n </TooltipContent>\n </Tooltip>\n </>\n )\n}\n\nexport interface WorkspaceDeleteButtonProps {\n canDelete: boolean\n /** Why deletion is not allowed (tooltip on the disabled button). */\n disabledReason?: string\n isDeleting?: boolean\n onDelete: () => void\n labels?: { delete: string; deleting: string }\n}\n\n/** Destructive \"Delete\" of a workspace; disabled with an explanation when not allowed. */\nexport function WorkspaceDeleteButton({\n canDelete,\n disabledReason = '',\n isDeleting = false,\n onDelete,\n labels = { delete: 'Delete', deleting: 'Deleting...' },\n}: WorkspaceDeleteButtonProps) {\n const button = (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={canDelete ? onDelete : undefined}\n disabled={!canDelete || isDeleting}\n className=\"h-7 px-2 text-sm text-destructive hover:bg-destructive/10 hover:text-destructive pointer-coarse:h-11\"\n data-testid=\"workspace-delete-button\"\n >\n <Trash2 className=\"mr-1 size-3.5\" />\n <span>{isDeleting ? labels.deleting : labels.delete}</span>\n </Button>\n )\n\n if (canDelete || !disabledReason) return button\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <span tabIndex={0}>{button}</span>\n </TooltipTrigger>\n <TooltipContent>\n <p>{disabledReason}</p>\n </TooltipContent>\n </Tooltip>\n )\n}\n\nexport interface RoleSelectProps {\n value: string\n roles: MemberRoleOption[]\n onChange: (role: string) => void\n /** Tooltip: what the selected role allows. */\n description: string\n}\n\n/** Role picker shown beside a user selector (e.g. when sharing a workspace). */\nexport function RoleSelect({ value, roles, onChange, description }: RoleSelectProps) {\n const current = roles.find((r) => r.value === value)\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <span>\n <Select value={value} onValueChange={onChange}>\n <SelectTrigger className=\"h-8 w-[140px] pointer-coarse:h-11\">\n <SelectValue>\n <RoleBadge label={current?.label ?? value} badgeClass={current?.badgeClass ?? ''} />\n </SelectValue>\n </SelectTrigger>\n <SelectContent>\n {roles.map((r) => (\n <SelectItem key={r.value} value={r.value}>\n <RoleBadge label={r.label} badgeClass={r.badgeClass} />\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </span>\n </TooltipTrigger>\n <TooltipContent side=\"left\" className=\"max-w-[300px]\">\n <p>{description}</p>\n </TooltipContent>\n </Tooltip>\n )\n}\n","import type { components } from '@arbidocs/client'\nimport type { AddContactsResultRow } from './AddContactsParts'\n\n/** The most addresses one add-contacts request may carry (the API's own limit). */\nexport const MAX_INVITE_EMAILS = 100\n\nconst EMAIL = /^[^\\s@,;]+@[^\\s@,;]+\\.[^\\s@,;]+$/\n\n/**\n * Distinct, lower-cased, well-formed addresses typed or pasted into the invite box. Commas,\n * semicolons, spaces and new lines all separate; anything that is not an address is dropped.\n */\nexport function parseEmails(text: string): string[] {\n const parts = text.split(/[\\s,;]+/).map((e) => e.trim().toLowerCase())\n return [...new Set(parts.filter((e) => EMAIL.test(e)))]\n}\n\ntype ContactRow = Pick<\n components['schemas']['ContactResponse'],\n 'email' | 'status' | 'outcome' | 'outcome_detail'\n>\n\n/** One plain sentence per outcome the backend reports. */\nexport interface ContactOutcomeLabels {\n contact_added: string\n already_contact: string\n invited: string\n reinvited: string\n not_resent_still_pending: string\n /** Fallback when the backend gives no detail for a failure. */\n failed: string\n}\n\nexport const DEFAULT_CONTACT_OUTCOME_LABELS: ContactOutcomeLabels = {\n contact_added: 'Added to your colleagues',\n already_contact: 'Already one of your colleagues',\n invited: 'Invitation sent',\n reinvited: 'Invitation sent again',\n not_resent_still_pending: 'Invitation already pending',\n failed: 'Could not add this address',\n}\n\n/** A backend add-contact row as an {@link AddContactsResultRow} for `AddContactsResults`. */\nexport function toAddContactsRow(\n row: ContactRow,\n labels: Partial<ContactOutcomeLabels> = {}\n): AddContactsResultRow {\n const l = { ...DEFAULT_CONTACT_OUTCOME_LABELS, ...labels }\n switch (row.outcome) {\n case 'contact_added':\n case 'already_contact':\n case 'invited':\n case 'reinvited':\n return { email: row.email, status: 'success', message: l[row.outcome] }\n case 'not_resent_still_pending':\n return { email: row.email, status: 'pending', message: l.not_resent_still_pending }\n default:\n return {\n email: row.email,\n status: row.status === 'failed' || row.outcome === 'failed' ? 'failed' : 'pending',\n message: row.outcome_detail ?? l.failed,\n }\n }\n}\n\n/** Map every row of an add-contacts response. */\nexport const toAddContactsRows = (\n rows: ContactRow[],\n labels?: Partial<ContactOutcomeLabels>\n): AddContactsResultRow[] => rows.map((r) => toAddContactsRow(r, labels))\n","import { useMemo, type ReactNode } from 'react'\nimport { AlertCircle, AtSign, CheckCircle, Gift, XCircle } from 'lucide-react'\nimport { Button, Textarea } from '@arbidocs/react/ui'\nimport { ModalSection, ModalSectionTitle } from '../../settings/ModalScaffold'\nimport { MAX_INVITE_EMAILS, parseEmails } from './parseEmails'\n\n/** Every fixed string of the add-contacts flow. */\nexport interface AddContactsLabels {\n placeholder: string\n hint: string\n add: (count: number) => string\n addOverMax: (count: number, max: number) => string\n adding: string\n cancel: string\n results: string\n email: string\n status: string\n done: string\n addMore: string\n /** The invite-reward banner text for a formatted amount. */\n reward: (amount: string) => ReactNode\n}\n\nexport const DEFAULT_ADD_CONTACTS_LABELS: AddContactsLabels = {\n placeholder: 'name@example.com',\n hint: 'Paste one or multiple emails — separated by commas, spaces, or new lines.',\n add: (count) => `Add${count > 0 ? ` (${count})` : ''}`,\n addOverMax: (count, max) => `Add (${count}) - Max ${max}`,\n adding: 'Adding...',\n cancel: 'Cancel',\n results: 'Results',\n email: 'Email',\n status: 'Status',\n done: 'Done',\n addMore: 'Add More',\n reward: (amount) => (\n <>\n Get <span className=\"font-semibold text-foreground\">{amount} off your next invoice</span> for\n every invited contact who goes Pro. They get {amount} off theirs.\n </>\n ),\n}\n\nexport interface AddContactsFormProps {\n value: string\n onChange: (value: string) => void\n /**\n * How many addresses `value` holds. Omit it: the form parses `value` itself with\n * {@link parseEmails} (commas, semicolons, spaces and new lines; distinct, valid, lower-cased).\n */\n emailCount?: number\n /** The most addresses one submit may carry. Default {@link MAX_INVITE_EMAILS} (the API's own limit). */\n maxEmails?: number\n isPending: boolean\n /** Receives the parsed addresses, ready to send. */\n onSubmit: (emails: string[]) => void\n onCancel?: () => void\n /** Formatted referral reward (\"$10\"); omit to hide the banner. */\n rewardAmount?: string\n labels?: Partial<AddContactsLabels>\n}\n\n/** Email invite form: a textarea for one or many addresses, and Add / Cancel. */\nexport function AddContactsForm({\n value,\n onChange,\n emailCount: emailCountProp,\n maxEmails = MAX_INVITE_EMAILS,\n isPending,\n onSubmit,\n onCancel,\n rewardAmount,\n labels,\n}: AddContactsFormProps) {\n const l = useMemo(() => ({ ...DEFAULT_ADD_CONTACTS_LABELS, ...labels }), [labels])\n const emails = useMemo(() => parseEmails(value), [value])\n const emailCount = emailCountProp ?? emails.length\n const overMax = emailCount > maxEmails\n return (\n <div className=\"space-y-4\" data-slot=\"add-contacts-form\">\n {rewardAmount && (\n <div\n className=\"flex items-start gap-2 rounded-md bg-green-bg p-3 text-sm\"\n data-testid=\"invite-reward-banner\"\n >\n <Gift className=\"mt-0.5 size-4 shrink-0 text-green-text\" />\n <p className=\"text-muted-foreground\">{l.reward(rewardAmount)}</p>\n </div>\n )}\n <div>\n <Textarea\n id=\"invite-emails\"\n value={value}\n onChange={(e) => onChange(e.target.value)}\n disabled={isPending}\n placeholder={l.placeholder}\n rows={2}\n autoFocus\n data-testid=\"invite-emails-input\"\n />\n <p className=\"mt-1.5 text-sm text-muted-foreground\">{l.hint}</p>\n </div>\n\n <div className=\"flex flex-col gap-2 pt-2\">\n <Button\n onClick={() => onSubmit(emails)}\n disabled={emailCount === 0 || overMax || isPending}\n className=\"w-full\"\n data-testid=\"invite-send-button\"\n >\n {isPending ? (\n l.adding\n ) : (\n <>\n <AtSign className=\"mr-2 size-4\" />\n {overMax ? l.addOverMax(emailCount, maxEmails) : l.add(emailCount)}\n </>\n )}\n </Button>\n <Button variant=\"outline\" onClick={onCancel} disabled={isPending} className=\"w-full\">\n {l.cancel}\n </Button>\n </div>\n </div>\n )\n}\n\nexport interface AddContactsResultRow {\n email: string\n status: 'success' | 'failed' | 'pending'\n message: string\n}\n\nexport interface AddContactsResultsProps {\n rows: AddContactsResultRow[]\n onDone?: () => void\n onAddMore: () => void\n labels?: Partial<AddContactsLabels>\n}\n\nconst STATUS_ICON = {\n success: <CheckCircle className=\"size-4 shrink-0 text-green-text\" />,\n failed: <XCircle className=\"size-4 shrink-0 text-red-text\" />,\n pending: <AlertCircle className=\"size-4 shrink-0 text-yellow-text\" />,\n} as const\n\n/** Per-address outcome table with Done / Add More. */\nexport function AddContactsResults({ rows, onDone, onAddMore, labels }: AddContactsResultsProps) {\n const l = useMemo(() => ({ ...DEFAULT_ADD_CONTACTS_LABELS, ...labels }), [labels])\n return (\n <ModalSection>\n <ModalSectionTitle>{l.results}</ModalSectionTitle>\n <div className=\"max-h-80 overflow-y-auto rounded-md border\">\n <table className=\"w-full\">\n <thead className=\"sticky top-0 bg-muted/50\">\n <tr>\n <th className=\"p-2 text-left font-medium\">{l.email}</th>\n <th className=\"p-2 text-left font-medium\">{l.status}</th>\n </tr>\n </thead>\n <tbody>\n {rows.map((row, index) => (\n <tr\n key={index}\n className=\"border-t hover:bg-muted/30\"\n data-testid={`email-status-row-${index}`}\n >\n <td className=\"p-2\">{row.email}</td>\n <td className=\"p-2\">\n <div className=\"flex items-center gap-2\">\n {STATUS_ICON[row.status]}\n <span className=\"text-muted-foreground\">{row.message}</span>\n </div>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n\n <div className=\"flex flex-col gap-2 pt-4\">\n <Button onClick={onDone} className=\"w-full\" data-testid=\"close-results-button\">\n {l.done}\n </Button>\n <Button\n variant=\"outline\"\n onClick={onAddMore}\n className=\"w-full\"\n data-testid=\"start-over-button\"\n >\n {l.addMore}\n </Button>\n </div>\n </ModalSection>\n )\n}\n","/**\n * vCard (.vcf) generation for a contact: a real, importable card. No dependencies: it assembles\n * vCard 3.0 text (RFC 2426, understood by every address book) and triggers a Blob download.\n */\n\n/** What a card can carry. Only `name` is required; empty fields are left out. */\nexport interface VCardContact {\n /** Full display name (\"Ada Lovelace\"). */\n name: string\n email?: string\n phone?: string\n /** Company or organisation. */\n organisation?: string\n /** Job title or role. */\n title?: string\n /** One-line postal address. */\n address?: string\n /** A web page or profile link. */\n url?: string\n note?: string\n}\n\n/** Escape a text value (RFC 2426 section 4): backslash, comma, semicolon and new lines. */\nfunction escapeText(value: string): string {\n return value\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/([,;])/g, '\\\\$1')\n .replace(/\\r\\n|\\r|\\n/g, '\\\\n')\n}\n\n/** Fold a content line at 75 octets with a CRLF + space continuation (RFC 2426 section 2.6). */\nfunction fold(line: string): string {\n const encoder = new TextEncoder()\n if (encoder.encode(line).length <= 75) return line\n const out: string[] = []\n let current = ''\n let size = 0\n for (const ch of line) {\n const bytes = encoder.encode(ch).length\n // Continuation lines start with a space that counts toward their 75 octets.\n const limit = out.length === 0 ? 75 : 74\n if (size + bytes > limit) {\n out.push(current)\n current = ''\n size = 0\n }\n current += ch\n size += bytes\n }\n out.push(current)\n return out.join('\\r\\n ')\n}\n\n/** Split \"Ada Byron Lovelace\" into family name (last word) and given names (the rest). */\nfunction splitName(name: string): { family: string; given: string } {\n const words = name.trim().split(/\\s+/).filter(Boolean)\n const family = words.length > 1 ? (words[words.length - 1] ?? '') : ''\n const given = words.length > 1 ? words.slice(0, -1).join(' ') : (words[0] ?? '')\n return { family, given }\n}\n\n/** The vCard 3.0 text for a contact, CRLF separated. */\nexport function contactToVCard(contact: VCardContact): string {\n const name = contact.name.trim()\n const { family, given } = splitName(name)\n const lines = [\n 'BEGIN:VCARD',\n 'VERSION:3.0',\n `N:${escapeText(family)};${escapeText(given)};;;`,\n `FN:${escapeText(name)}`,\n contact.organisation && `ORG:${escapeText(contact.organisation)}`,\n contact.title && `TITLE:${escapeText(contact.title)}`,\n contact.email && `EMAIL;TYPE=INTERNET,WORK:${escapeText(contact.email)}`,\n contact.phone && `TEL;TYPE=WORK,VOICE:${escapeText(contact.phone)}`,\n contact.address && `ADR;TYPE=WORK:;;${escapeText(contact.address)};;;;`,\n contact.url && `URL:${contact.url}`,\n contact.note && `NOTE:${escapeText(contact.note)}`,\n 'END:VCARD',\n ].filter((line): line is string => Boolean(line))\n return lines.map(fold).join('\\r\\n') + '\\r\\n'\n}\n\n/** A safe file name for a contact: \"ada-lovelace.vcf\" (\"contact.vcf\" when nothing usable is left). */\nexport function vCardFilename(contact: Pick<VCardContact, 'name'>): string {\n const slug = contact.name\n .normalize('NFKD')\n .replace(/[̀-ͯ]/g, '')\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n return `${slug || 'contact'}.vcf`\n}\n\n/** Save the contact as a .vcf file through a temporary link click. Browser only. */\nexport function downloadVCard(contact: VCardContact): void {\n const blob = new Blob([contactToVCard(contact)], { type: 'text/vcard;charset=utf-8' })\n const url = URL.createObjectURL(blob)\n const link = document.createElement('a')\n link.href = url\n link.download = vCardFilename(contact)\n document.body.appendChild(link)\n link.click()\n link.remove()\n // Revoke after the click has been handled: some browsers cancel the download otherwise.\n setTimeout(() => URL.revokeObjectURL(url), 0)\n}\n","import type { ReactNode } from 'react'\nimport { Contact, Download, Mail, MoreHorizontal, Phone } from 'lucide-react'\nimport {\n Avatar,\n AvatarFallback,\n AvatarImage,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@arbidocs/react/ui'\nimport { downloadVCard, type VCardContact } from './vcard'\n\n/** Every fixed string of the contact card. */\nexport interface ContactCardLabels {\n /** Accessible name of the menu button. */\n actions: string\n /** The export menu item. */\n exportVCard: string\n}\n\nexport const DEFAULT_CONTACT_CARD_LABELS: ContactCardLabels = {\n actions: 'Contact actions',\n exportVCard: 'Save to address book (.vcf)',\n}\n\n/** An extra menu entry a host adds next to the built-in export. */\nexport interface ContactCardAction {\n id: string\n label: string\n icon?: ReactNode\n onSelect: () => void\n destructive?: boolean\n}\n\nexport interface ContactCardProps {\n contact: VCardContact & { avatarUrl?: string }\n /** A badge or status text under the name (\"Invitation pending\"). */\n status?: ReactNode\n /**\n * Called when \"Save to address book\" is chosen. Omit it to use the built-in\n * {@link downloadVCard}; pass your own to log, or to hand the card to a native share sheet.\n */\n onExportVCard?: (contact: VCardContact) => void\n /** Hide the export item entirely (a contact with no usable details). Default true. */\n exportable?: boolean\n /** More menu entries, listed after the export. */\n actions?: ContactCardAction[]\n labels?: Partial<ContactCardLabels>\n className?: string\n 'data-testid'?: string\n}\n\nfunction initials(name: string): string {\n const words = name.trim().split(/\\s+/).filter(Boolean)\n return (\n (words[0]?.[0] ?? '') + (words.length > 1 ? (words[words.length - 1]?.[0] ?? '') : '')\n ).toUpperCase()\n}\n\n/**\n * A contact as a card: avatar, name, role, email and phone, and a menu that exports the contact\n * as a vCard. The export is built in ({@link downloadVCard}); `onExportVCard` replaces it, and\n * `actions` adds host entries. Presentational: no SDK, store or router.\n */\nexport function ContactCard({\n contact,\n status,\n onExportVCard = downloadVCard,\n exportable = true,\n actions = [],\n labels,\n className,\n 'data-testid': testId = 'contact-card',\n}: ContactCardProps) {\n const l = { ...DEFAULT_CONTACT_CARD_LABELS, ...labels }\n const subtitle = [contact.title, contact.organisation].filter(Boolean).join(', ')\n const hasMenu = exportable || actions.length > 0\n const { avatarUrl, ...vcard } = contact\n return (\n <div\n data-slot=\"contact-card\"\n data-testid={testId}\n className={`flex min-w-0 items-center gap-3 rounded-lg border border-border bg-card p-3 text-card-foreground ${className ?? ''}`}\n >\n <Avatar className=\"size-10 shrink-0\">\n {avatarUrl && <AvatarImage src={avatarUrl} alt=\"\" />}\n <AvatarFallback>{initials(contact.name) || <Contact className=\"size-4\" />}</AvatarFallback>\n </Avatar>\n <div className=\"min-w-0 flex-1\">\n <p className=\"truncate text-sm font-medium\" data-testid={`${testId}-name`}>\n {contact.name}\n </p>\n {subtitle && <p className=\"truncate text-xs text-muted-foreground\">{subtitle}</p>}\n {contact.email && (\n <p className=\"flex min-w-0 items-center gap-1 text-xs text-muted-foreground\">\n <Mail className=\"size-3 shrink-0\" aria-hidden=\"true\" />\n <span className=\"truncate\">{contact.email}</span>\n </p>\n )}\n {contact.phone && (\n <p className=\"flex min-w-0 items-center gap-1 text-xs text-muted-foreground\">\n <Phone className=\"size-3 shrink-0\" aria-hidden=\"true\" />\n <span className=\"truncate\">{contact.phone}</span>\n </p>\n )}\n {status && <div className=\"mt-1 text-xs\">{status}</div>}\n </div>\n {hasMenu && (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n aria-label={l.actions}\n data-testid={`${testId}-menu`}\n className=\"flex size-8 pointer-coarse:size-11 shrink-0 items-center justify-center rounded text-muted-foreground transition-colors hover:bg-muted hover:text-foreground data-[state=open]:bg-muted\"\n >\n <MoreHorizontal className=\"size-4\" aria-hidden=\"true\" />\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {exportable && (\n <DropdownMenuItem\n onSelect={() => onExportVCard(vcard)}\n data-testid={`${testId}-export-vcard`}\n >\n <Download className=\"mr-2 size-4\" aria-hidden=\"true\" />\n {l.exportVCard}\n </DropdownMenuItem>\n )}\n {actions.map((a) => (\n <DropdownMenuItem\n key={a.id}\n onSelect={a.onSelect}\n className={a.destructive ? 'text-red-text focus:text-red-text' : undefined}\n data-testid={`${testId}-action-${a.id}`}\n >\n {a.icon}\n {a.label}\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n </div>\n )\n}\n","import { useMemo, type ReactNode } from 'react'\nimport { UserPlus } from 'lucide-react'\n\n/** Every fixed string of the invite chip. `title` / `description` props win. */\nexport interface DmInviteChipLabels {\n title: string\n description: string\n}\n\nexport const DEFAULT_DM_INVITE_CHIP_LABELS: DmInviteChipLabels = {\n title: 'Add a contact by email',\n description: 'Send an invitation to join you on ARBI',\n}\n\n/** Leading call to action of the conversation list, styled as a chip so it reads as one of the rows. */\nexport function DmInviteChip({\n onClick,\n title,\n description,\n testId = 'dm-invite-chip',\n labels,\n}: {\n onClick: () => void\n title?: string\n description?: string\n testId?: string\n labels?: Partial<DmInviteChipLabels>\n}) {\n const l = useMemo(() => ({ ...DEFAULT_DM_INVITE_CHIP_LABELS, ...labels }), [labels])\n return (\n <button\n type=\"button\"\n onClick={onClick}\n data-testid={testId}\n className=\"flex w-full items-center gap-3 border-b border-border px-4 py-3 text-left transition-colors hover:bg-accent/60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring pointer-coarse:min-h-11\"\n >\n <span className=\"flex size-9 shrink-0 items-center justify-center rounded-full bg-ai-accent-soft\">\n <UserPlus className=\"size-4 text-ai-accent\" />\n </span>\n <span className=\"min-w-0\">\n <span className=\"block text-sm font-semibold text-foreground\">{title ?? l.title}</span>\n <span className=\"block text-xs text-muted-foreground\">{description ?? l.description}</span>\n </span>\n </button>\n )\n}\n\nexport interface DmThreadHeaderProps {\n /** Peer avatar (with presence dot). Omitted while the conversation loads. */\n avatar?: ReactNode\n name: string\n /** Marks the peer as an agent. */\n badge?: ReactNode\n /** Presence in words, next to the address. */\n presence?: ReactNode\n email?: string\n /** Overflow menu, sitting after the identity. */\n menu?: ReactNode\n testId?: string\n}\n\n/**\n * The open conversation's identity, pinned above the thread: who you are talking to, static (no\n * switcher dropdown; back out to the list to pick another conversation).\n */\nexport function DmThreadHeader({\n avatar,\n name,\n badge,\n presence,\n email,\n menu,\n testId = 'dm-active-chip',\n}: DmThreadHeaderProps) {\n return (\n <div\n className=\"flex items-center gap-1 border-b border-border pr-2\"\n data-slot=\"dm-thread-header\"\n >\n <div data-testid={testId} className=\"flex min-w-0 flex-1 items-center gap-3 px-4 py-2.5\">\n {avatar}\n <span className=\"min-w-0 flex-1\">\n <span className=\"flex min-w-0 items-center gap-1.5\">\n <span className=\"truncate text-sm font-semibold text-foreground\">{name}</span>\n {badge}\n </span>\n <span className=\"flex min-w-0 items-center gap-1.5\">\n {presence}\n {presence && <span className=\"text-xs text-muted-foreground\">·</span>}\n <span className=\"min-w-0 truncate text-xs text-muted-foreground\">{email ?? ''}</span>\n </span>\n </span>\n </div>\n {menu}\n </div>\n )\n}\n","import { useMemo, type ReactNode, type Ref } from 'react'\nimport {\n AtSign,\n ChevronsUpDown,\n KeyRound,\n Loader2,\n MoreVertical,\n Plus,\n Bell,\n BellOff,\n X,\n} from 'lucide-react'\nimport {\n Button,\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n Popover,\n PopoverContent,\n PopoverTrigger,\n ScrollArea,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from '@arbidocs/react/ui'\nimport { ModalSectionTitle } from '../../settings/ModalScaffold'\n\n/** Every fixed string of the access-request banner. */\nexport interface DmAccessRequestBannerLabels {\n /** Text after the bold peer name (keep the leading space). */\n requestedAccess: string\n review: string\n}\n\nexport const DEFAULT_DM_ACCESS_REQUEST_BANNER_LABELS: DmAccessRequestBannerLabels = {\n requestedAccess: ' requested workspace access',\n review: 'Review',\n}\n\n/** Every fixed string of the thread frame. */\nexport interface DmThreadFrameLabels {\n noMessages: string\n}\n\nexport const DEFAULT_DM_THREAD_FRAME_LABELS: DmThreadFrameLabels = {\n noMessages: 'No messages yet — say hi 👋',\n}\n\n/** Every fixed string of the grant-access dialog. */\nexport interface DmGrantAccessDialogLabels {\n title: string\n description: (peerName: string) => string\n noWorkspace: string\n workspace: string\n role: string\n cancel: string\n grantAccess: string\n}\n\nexport const DEFAULT_DM_GRANT_ACCESS_DIALOG_LABELS: DmGrantAccessDialogLabels = {\n title: 'Grant workspace access',\n description: (peerName) =>\n `Give ${peerName} access to one of your workspaces. Access is permanent until you remove it.`,\n noWorkspace:\n 'Open the workspace you want to share, as its owner, and you can grant access to it from here.',\n workspace: 'Workspace',\n role: 'Role',\n cancel: 'Cancel',\n grantAccess: 'Grant access',\n}\n\n/** Every fixed string of the recipient picker. */\nexport interface RecipientPickerLabels {\n to: string\n unmuteNotifications: string\n muteNotifications: string\n removeRecipient: string\n selectRecipient: string\n addRecipient: string\n searchUsers: string\n noKnownUsers: string\n noMatchingUsers: string\n addContactsHint: string\n}\n\nexport const DEFAULT_RECIPIENT_PICKER_LABELS: RecipientPickerLabels = {\n to: 'To',\n unmuteNotifications: 'Unmute notifications',\n muteNotifications: 'Mute notifications',\n removeRecipient: 'Remove recipient',\n selectRecipient: 'Select recipient...',\n addRecipient: 'Add recipient',\n searchUsers: 'Search users...',\n noKnownUsers: 'No known users',\n noMatchingUsers: 'No matching users',\n addContactsHint: 'Add contacts or join workspaces to send private messages',\n}\n\nexport type ActionMenuEntry =\n | {\n id: string\n label: ReactNode\n icon?: ReactNode\n onSelect: () => void\n testId?: string\n destructive?: boolean\n }\n | { id: string; separator: true }\n\nexport interface ActionMenuProps {\n /** Accessible name of the trigger. */\n label: string\n testId?: string\n entries: ActionMenuEntry[]\n /** Width class of the menu. */\n contentClassName?: string\n}\n\n/** A single ⋮ overflow menu: the occasional actions on a row or header. */\nexport function ActionMenu({ label, testId, entries, contentClassName = 'w-56' }: ActionMenuProps) {\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-7 shrink-0 text-muted-foreground hover:text-foreground pointer-coarse:size-11\"\n aria-label={label}\n data-testid={testId}\n onClick={(e) => e.stopPropagation()}\n >\n <MoreVertical className=\"size-4\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className={contentClassName}>\n {entries.map((entry) =>\n 'separator' in entry ? (\n <DropdownMenuSeparator key={entry.id} />\n ) : (\n <DropdownMenuItem\n key={entry.id}\n onClick={entry.onSelect}\n className={entry.destructive ? 'text-destructive focus:text-destructive' : undefined}\n data-testid={entry.testId}\n >\n {entry.icon && (\n <span className=\"mr-2 inline-flex size-4 items-center\">{entry.icon}</span>\n )}\n {entry.label}\n </DropdownMenuItem>\n )\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n )\n}\n\n/** Round \"@\" mark standing in for the face of a pending invitation. */\nexport function DmInviteAvatar() {\n return (\n <span className=\"flex size-9 shrink-0 items-center justify-center rounded-full bg-muted text-muted-foreground\">\n <AtSign className=\"size-4\" />\n </span>\n )\n}\n\n/** Round \"+\" tab icon of a new (compose) conversation. */\nexport function DmNewTabIcon() {\n return (\n <div className=\"flex h-5 w-5 items-center justify-center rounded-full bg-primary/10\">\n <Plus className=\"h-3 w-3 text-primary\" />\n </div>\n )\n}\n\n/** Banner at the top of a thread: the peer asked for workspace access; Review opens the grant flow. */\nexport function DmAccessRequestBanner({\n name,\n onReview,\n labels,\n}: {\n name: string\n onReview: () => void\n labels?: Partial<DmAccessRequestBannerLabels>\n}) {\n const l = useMemo(() => ({ ...DEFAULT_DM_ACCESS_REQUEST_BANNER_LABELS, ...labels }), [labels])\n return (\n <div className=\"mx-4 mt-3 flex items-center gap-3 rounded-lg bg-muted px-3 py-2.5\">\n <KeyRound className=\"h-4 w-4 shrink-0 text-primary\" />\n <span className=\"min-w-0 flex-1 text-sm text-foreground\">\n <span className=\"font-medium\">{name}</span>\n {l.requestedAccess}\n </span>\n <Button size=\"sm\" onClick={onReview} data-testid=\"dm-review-access-button\">\n {l.review}\n </Button>\n </div>\n )\n}\n\nexport interface DmThreadFrameProps {\n /** Recipient picker, shown above everything in compose mode. */\n recipientPicker?: ReactNode\n accessBanner?: ReactNode\n /** A recipient is chosen: the history area shows. */\n hasRecipient: boolean\n /** The history is still decrypting. */\n isLoading: boolean\n /** Messages (and the typing indicator), rendered inside the scroll area. */\n history: ReactNode\n /** No messages yet. */\n isEmpty: boolean\n /** Prompt shown when there is no recipient and users exist to pick from. */\n noRecipientPrompt?: ReactNode\n /** Ref to the history wrapper (the host scrolls its viewport). */\n historyRef?: Ref<HTMLDivElement>\n composer: ReactNode\n labels?: Partial<DmThreadFrameLabels>\n}\n\n/** Layout of one direct-message thread: picker, banner, scrolling history, composer. */\nexport function DmThreadFrame({\n recipientPicker,\n accessBanner,\n hasRecipient,\n isLoading,\n history,\n isEmpty,\n noRecipientPrompt,\n historyRef,\n composer,\n labels,\n}: DmThreadFrameProps) {\n const l = useMemo(() => ({ ...DEFAULT_DM_THREAD_FRAME_LABELS, ...labels }), [labels])\n return (\n <div className=\"flex h-full flex-col bg-background\">\n {recipientPicker}\n {accessBanner}\n\n {/* Clean page surface: the peer bubble is `bg-card` and the own bubble a soft tint. */}\n {hasRecipient && (\n <div className=\"min-h-0 flex-1 overflow-hidden bg-background\" ref={historyRef}>\n <ScrollArea className=\"h-full\">\n <div className=\"px-4 py-3\">\n {isLoading ? (\n <div className=\"flex h-32 items-center justify-center\">\n <Loader2 className=\"h-6 w-6 animate-spin text-muted-foreground\" />\n </div>\n ) : !isEmpty ? (\n history\n ) : (\n <div className=\"flex h-32 items-center justify-center text-sm text-muted-foreground\">\n {l.noMessages}\n </div>\n )}\n </div>\n </ScrollArea>\n </div>\n )}\n\n {!hasRecipient && noRecipientPrompt && (\n <div className=\"flex min-h-0 flex-1 items-center justify-center bg-background p-4\">\n <p className=\"text-center text-sm text-muted-foreground\">{noRecipientPrompt}</p>\n </div>\n )}\n\n <div className=\"shrink-0\">{composer}</div>\n </div>\n )\n}\n\nexport interface DmGrantAccessDialogViewProps {\n open: boolean\n onOpenChange: (open: boolean) => void\n peerName: string\n /** The one workspace that can be shared; `null` when none is eligible. */\n workspaceName: string | null\n role: string\n onRoleChange: (role: string) => void\n roles: { value: string; label: string; hint: string }[]\n isGranting: boolean\n onGrant: () => void\n labels?: Partial<DmGrantAccessDialogLabels>\n}\n\n/** Offer a person access to the open workspace: the workspace, a role, a grant button. */\nexport function DmGrantAccessDialogView({\n open,\n onOpenChange,\n peerName,\n workspaceName,\n role,\n onRoleChange,\n roles,\n isGranting,\n onGrant,\n labels,\n}: DmGrantAccessDialogViewProps) {\n const l = useMemo(() => ({ ...DEFAULT_DM_GRANT_ACCESS_DIALOG_LABELS, ...labels }), [labels])\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent presentation=\"sheet\" data-testid=\"dm-grant-access-modal\">\n <DialogHeader>\n <DialogTitle>{l.title}</DialogTitle>\n <DialogDescription>{l.description(peerName)}</DialogDescription>\n </DialogHeader>\n\n {workspaceName === null ? (\n <p className=\"text-sm text-muted-foreground\" data-testid=\"dm-grant-none\">\n {l.noWorkspace}\n </p>\n ) : (\n <div className=\"space-y-4\">\n <div className=\"space-y-1.5\">\n <label className=\"text-sm font-medium\">{l.workspace}</label>\n <p className=\"rounded-lg bg-muted px-3 py-2 text-sm\" data-testid=\"dm-grant-workspace\">\n {workspaceName}\n </p>\n </div>\n <div className=\"space-y-1.5\">\n <label className=\"text-sm font-medium\">{l.role}</label>\n <Select value={role} onValueChange={onRoleChange}>\n <SelectTrigger data-testid=\"dm-grant-role\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {roles.map((r) => (\n <SelectItem key={r.value} value={r.value}>\n {r.label} — {r.hint}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </div>\n )}\n\n <DialogFooter>\n <Button variant=\"ghost\" onClick={() => onOpenChange(false)} disabled={isGranting}>\n {l.cancel}\n </Button>\n <Button\n onClick={onGrant}\n disabled={isGranting || workspaceName === null}\n data-testid=\"dm-grant-submit\"\n >\n {isGranting && <Loader2 className=\"mr-2 size-4 animate-spin\" />}\n {l.grantAccess}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n )\n}\n\nexport interface RecipientView {\n id: string\n /** Avatar + name pill. */\n identity: ReactNode\n isMuted: boolean\n muteTooltip: string\n onToggleMute: () => void\n isMuteBusy?: boolean\n}\n\nexport interface RecipientCandidate {\n id: string\n identity: ReactNode\n}\n\nexport interface RecipientPickerProps {\n selected: RecipientView[]\n onRemove: (id: string) => void\n candidates: RecipientCandidate[]\n onPick: (id: string) => void\n /** Hide the add control (the maximum is reached). */\n canAdd: boolean\n isOpen: boolean\n onOpenChange: (open: boolean) => void\n search: string\n onSearchChange: (value: string) => void\n /** There is nobody at all to pick from (vs. no search match). */\n hasNoKnownUsers: boolean\n labels?: Partial<RecipientPickerLabels>\n}\n\n/** \"To:\" row of the compose view: chosen recipients (mutable) and a searchable add control. */\nexport function RecipientPicker({\n selected,\n onRemove,\n candidates,\n onPick,\n canAdd,\n isOpen,\n onOpenChange,\n search,\n onSearchChange,\n hasNoKnownUsers,\n labels,\n}: RecipientPickerProps) {\n const l = useMemo(() => ({ ...DEFAULT_RECIPIENT_PICKER_LABELS, ...labels }), [labels])\n return (\n <div className=\"shrink-0 border-b px-6 py-4\">\n <div className=\"flex items-start gap-3\">\n <ModalSectionTitle className=\"mb-0 shrink-0 py-1.5\">{l.to}</ModalSectionTitle>\n\n <div className=\"flex flex-1 flex-col gap-1.5\">\n {selected.map((recipient) => (\n <div\n key={recipient.id}\n className=\"flex items-center justify-between gap-2 rounded-md bg-muted/50 px-3 py-1.5\"\n >\n <div className=\"flex items-center gap-2\">\n {recipient.identity}\n <Tooltip>\n <TooltipTrigger\n onClick={recipient.onToggleMute}\n aria-label={recipient.isMuted ? l.unmuteNotifications : l.muteNotifications}\n aria-pressed={recipient.isMuted}\n className={`rounded p-1 transition-colors hover:bg-muted pointer-coarse:p-3 ${\n recipient.isMuted\n ? 'text-muted-foreground'\n : 'text-muted-foreground/40 hover:text-muted-foreground'\n }`}\n disabled={recipient.isMuteBusy}\n >\n {recipient.isMuted ? (\n <BellOff size={14} fill=\"currentColor\" />\n ) : (\n <Bell size={14} />\n )}\n </TooltipTrigger>\n <TooltipContent className=\"max-w-[250px]\">{recipient.muteTooltip}</TooltipContent>\n </Tooltip>\n </div>\n <button\n type=\"button\"\n onClick={() => onRemove(recipient.id)}\n className=\"p-1 text-muted-foreground hover:text-destructive pointer-coarse:p-3\"\n title={l.removeRecipient}\n aria-label={l.removeRecipient}\n >\n <X className=\"h-4 w-4\" />\n </button>\n </div>\n ))}\n\n {canAdd && (\n <Popover open={isOpen} onOpenChange={onOpenChange}>\n <PopoverTrigger asChild>\n {selected.length === 0 ? (\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={candidates.length === 0}\n className=\"w-full justify-start text-muted-foreground\"\n >\n <ChevronsUpDown className=\"mr-2 h-4 w-4\" />\n {l.selectRecipient}\n </Button>\n ) : (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n disabled={candidates.length === 0}\n className=\"h-7 w-7 rounded-full\"\n title={l.addRecipient}\n aria-label={l.addRecipient}\n >\n <Plus className=\"h-4 w-4\" />\n </Button>\n )}\n </PopoverTrigger>\n <PopoverContent\n className=\"w-72 p-0\"\n align=\"start\"\n onPointerDownOutside={(e) => e.preventDefault()}\n >\n <Command shouldFilter={false}>\n <CommandInput\n placeholder={l.searchUsers}\n value={search}\n onValueChange={onSearchChange}\n />\n <CommandList>\n {candidates.length === 0 ? (\n <CommandEmpty>\n {hasNoKnownUsers ? l.noKnownUsers : l.noMatchingUsers}\n </CommandEmpty>\n ) : (\n <CommandGroup>\n {candidates.map((candidate) => (\n <CommandItem\n key={candidate.id}\n onSelect={() => onPick(candidate.id)}\n className=\"cursor-pointer justify-start\"\n >\n {candidate.identity}\n </CommandItem>\n ))}\n </CommandGroup>\n )}\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n )}\n\n {hasNoKnownUsers && <p className=\"text-sm text-muted-foreground\">{l.addContactsHint}</p>}\n </div>\n </div>\n </div>\n )\n}\n","/** A selectable mail folder (Outlook) or label (Gmail). */\nexport interface MailFolder {\n id: string\n /** Full path, e.g. \"Inbox/Clients/Acme\". */\n name: string\n /** Total messages (null/undefined when unavailable). */\n count?: number | null\n}\n\nexport interface MailFolderNode {\n key: string\n label: string\n /** null for a path segment with no folder of its own (a grouping row). */\n folder: MailFolder | null\n children: MailFolderNode[]\n}\n\nexport const isInboxFolder = (f: MailFolder) => f.id === 'INBOX' || /^inbox$/i.test(f.name)\n\n/** Build the folder tree from full-path names; Inbox first, then alphabetical. */\nexport function buildMailFolderTree(folders: MailFolder[]): MailFolderNode[] {\n const root: MailFolderNode = { key: '', label: '', folder: null, children: [] }\n const byPath = new Map<string, MailFolderNode>([['', root]])\n // Parents before children so a real folder claims its node before descendants.\n const sorted = [...folders].sort((a, b) => a.name.split('/').length - b.name.split('/').length)\n for (const f of sorted) {\n const parts = f.name.split('/')\n let path = ''\n let parent = root\n parts.forEach((part, i) => {\n path = path ? `${path}/${part}` : part\n let node = byPath.get(path)\n if (!node) {\n node = { key: path, label: part, folder: null, children: [] }\n byPath.set(path, node)\n parent.children.push(node)\n }\n if (i === parts.length - 1 && !node.folder) node.folder = f\n parent = node\n })\n }\n const order = (nodes: MailFolderNode[]) => {\n nodes.sort((a, b) => {\n const ai = a.folder ? isInboxFolder(a.folder) : false\n const bi = b.folder ? isInboxFolder(b.folder) : false\n if (ai !== bi) return ai ? -1 : 1\n return a.label.localeCompare(b.label)\n })\n nodes.forEach((n) => order(n.children))\n }\n order(root.children)\n return root.children\n}\n\n/** Ids of every real folder beneath `node`. */\nexport function descendantFolderIds(node: MailFolderNode): string[] {\n return node.children.flatMap((c) => [\n ...(c.folder ? [c.folder.id] : []),\n ...descendantFolderIds(c),\n ])\n}\n\n/**\n * Selection after toggling `node`: untick removes it; tick adds it and, when `cascade`, drops any\n * selected descendants (the parent already covers its subtree, so only the top-most is kept).\n */\nexport function toggleMailFolder(\n selected: string[],\n node: MailFolderNode,\n cascade: boolean\n): string[] {\n const id = node.folder?.id\n if (!id) return selected\n if (selected.includes(id)) return selected.filter((s) => s !== id)\n const covered = cascade ? new Set(descendantFolderIds(node)) : new Set<string>()\n return [...selected.filter((s) => !covered.has(s)), id]\n}\n","import { useEffect, useRef, useState } from 'react'\nimport { ChevronDown, ChevronRight } from 'lucide-react'\nimport { Checkbox, cn } from '@arbidocs/react/ui'\nimport { testIdOr } from '../../chat/test-id'\nimport { isInboxFolder, toggleMailFolder, type MailFolderNode } from './mailFolders'\n\nfunction hasSelectedDescendant(node: MailFolderNode, selected: string[]): boolean {\n return node.children.some(\n (c) => (c.folder && selected.includes(c.folder.id)) || hasSelectedDescendant(c, selected)\n )\n}\n\nexport interface MailFolderTreeLabels {\n collapse: string\n expand: string\n recommended: string\n}\n\nexport const DEFAULT_MAIL_FOLDER_TREE_LABELS: MailFolderTreeLabels = {\n collapse: 'Collapse folder',\n expand: 'Expand folder',\n recommended: 'Recommended',\n}\n\nexport interface MailFolderTreeTestIds {\n /** Builds the id of a node's expand toggle from its key. */\n toggle: (nodeKey: string) => string\n /** Builds the id of a folder checkbox from its folder id. */\n checkbox: (folderId: string) => string\n}\n\ninterface RowProps {\n labels: MailFolderTreeLabels\n testIds?: Partial<MailFolderTreeTestIds>\n node: MailFolderNode\n depth: number\n selected: string[]\n onToggle: (node: MailFolderNode) => void\n ancestorSelected: boolean\n cascade: boolean\n expandAllNonce: number\n collapseAllNonce: number\n}\n\nfunction MailFolderRow({\n labels,\n testIds,\n node,\n depth,\n selected,\n onToggle,\n ancestorSelected,\n cascade,\n expandAllNonce,\n collapseAllNonce,\n}: RowProps) {\n const f = node.folder\n // Open a selected folder (so its checked subfolders show) or a branch holding a selection;\n // later ticks never force a node open.\n const [expanded, setExpanded] = useState(\n () =>\n (!!f && selected.includes(f.id)) ||\n hasSelectedDescendant(node, selected) ||\n expandAllNonce > collapseAllNonce\n )\n // \"Expand all\" / \"Collapse all\": each bump of a nonce opens / closes this node.\n const applied = useRef({ expand: expandAllNonce, collapse: collapseAllNonce })\n useEffect(() => {\n if (expandAllNonce > applied.current.expand) setExpanded(true)\n if (collapseAllNonce > applied.current.collapse) setExpanded(false)\n applied.current = { expand: expandAllNonce, collapse: collapseAllNonce }\n }, [expandAllNonce, collapseAllNonce])\n const isSelected = ancestorSelected || (!!f && selected.includes(f.id))\n return (\n <div>\n <div\n className=\"flex items-center gap-1.5 rounded px-1 py-1 text-sm hover:bg-muted/50 pointer-coarse:min-h-11\"\n style={{ paddingLeft: depth * 18 + 4 }}\n >\n {node.children.length > 0 ? (\n <button\n type=\"button\"\n className=\"flex size-4 shrink-0 items-center justify-center text-muted-foreground pointer-coarse:size-8\"\n onClick={() => setExpanded((e) => !e)}\n aria-label={expanded ? labels.collapse : labels.expand}\n aria-expanded={expanded}\n data-testid={testIdOr(testIds?.toggle?.(node.key), {\n testId: `mail-folder-toggle-${node.key}`,\n })}\n >\n {expanded ? (\n <ChevronDown className=\"size-3.5\" />\n ) : (\n <ChevronRight className=\"size-3.5\" />\n )}\n </button>\n ) : (\n <span className=\"size-4 shrink-0\" />\n )}\n {f ? (\n <label className=\"flex min-w-0 flex-1 cursor-pointer items-center gap-2\">\n <Checkbox\n checked={isSelected}\n disabled={ancestorSelected}\n onCheckedChange={() => onToggle(node)}\n data-testid={testIdOr(testIds?.checkbox?.(f.id), {\n testId: `mail-folder-checkbox-${f.id}`,\n })}\n />\n <span className=\"truncate\" title={f.name}>\n {node.label}\n </span>\n {typeof f.count === 'number' && (\n <span className=\"shrink-0 text-xs text-muted-foreground\">\n ({f.count.toLocaleString()})\n </span>\n )}\n {isInboxFolder(f) && (\n <span className=\"ml-auto shrink-0 rounded bg-muted px-1.5 py-0.5 text-xs text-muted-foreground\">\n {labels.recommended}\n </span>\n )}\n </label>\n ) : (\n <span className=\"truncate font-medium text-muted-foreground\">{node.label}</span>\n )}\n </div>\n {expanded &&\n node.children.map((c) => (\n <MailFolderRow\n labels={labels}\n testIds={testIds}\n key={c.key}\n node={c}\n depth={depth + 1}\n selected={selected}\n onToggle={onToggle}\n ancestorSelected={cascade && isSelected}\n cascade={cascade}\n expandAllNonce={expandAllNonce}\n collapseAllNonce={collapseAllNonce}\n />\n ))}\n </div>\n )\n}\n\nexport interface MailFolderTreeProps {\n nodes: MailFolderNode[]\n /** Selected folder ids. */\n selected: string[]\n onChange: (selected: string[]) => void\n /** Selecting a folder includes its subfolders (default). Descendants show checked + locked. */\n cascade?: boolean\n /** Bump to open every node. */\n expandAllNonce?: number\n /** Bump to close every node. */\n collapseAllNonce?: number\n labels?: Partial<MailFolderTreeLabels>\n testIds?: Partial<MailFolderTreeTestIds>\n className?: string\n}\n\n/**\n * A mailbox's folders / labels as an expandable checkbox tree. Build `nodes` with\n * `buildMailFolderTree`. With `cascade` only the top-most selected folder is stored; the server\n * expands it at sync time so new subfolders are picked up too.\n */\nexport function MailFolderTree({\n nodes,\n selected,\n onChange,\n cascade = true,\n expandAllNonce = 0,\n collapseAllNonce = 0,\n labels,\n testIds,\n className,\n}: MailFolderTreeProps) {\n const l = { ...DEFAULT_MAIL_FOLDER_TREE_LABELS, ...labels }\n return (\n <div className={cn('space-y-0.5', className)} data-slot=\"mail-folder-tree\">\n {nodes.map((n) => (\n <MailFolderRow\n labels={l}\n testIds={testIds}\n key={n.key}\n node={n}\n depth={0}\n selected={selected}\n onToggle={(node) => onChange(toggleMailFolder(selected, node, cascade))}\n ancestorSelected={false}\n cascade={cascade}\n expandAllNonce={expandAllNonce}\n collapseAllNonce={collapseAllNonce}\n />\n ))}\n </div>\n )\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/auth/AuthLayout.tsx","../src/auth/AuthForm.tsx","../src/auth/SsoLoginButton.tsx","../src/auth/AuthFooter.tsx","../src/auth/RecoveryDialogs.tsx"],"names":["jsxs","jsx","cn","useMemo","Button","AlertCircle","useId","Input","Fragment","Loader2","useState"],"mappings":"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","file":"chunk-QN42OA5J.js","sourcesContent":["import type { LucideIcon } from 'lucide-react'\nimport { ArrowRight } from 'lucide-react'\nimport type { ReactNode } from 'react'\nimport { cn } from '@arbidocs/react/ui'\n\nexport interface AuthLayoutProps {\n /** The form column content. */\n children: ReactNode\n /** Sits above the form: the Login / Register tabs, or an offline badge. */\n headerRight?: ReactNode\n /** Hero panel: the right half on desktop, hidden on mobile. Omit for a single centred column. */\n aside?: ReactNode\n /** Brand mark shown top-left of the form column (logo + name). */\n brand?: ReactNode\n /** Pinned bottom-right over the hero on desktop (e.g. a deployment indicator). */\n corner?: ReactNode\n className?: string\n testId?: string\n}\n\n/**\n * Full-bleed split: a calm form column on the left, the hero (`aside`) on the right. On mobile the\n * hero is hidden and the form fills the screen. With no `aside` it is a single centred column.\n */\nexport function AuthLayout({\n children,\n headerRight,\n aside,\n brand,\n corner,\n className,\n testId = 'auth-layout',\n}: AuthLayoutProps) {\n return (\n <div\n data-slot=\"auth-layout\"\n className={cn(\n 'min-h-screen bg-background text-foreground',\n // The hero needs height: a phone held sideways (under 32rem tall) gets the form alone.\n aside && 'md:grid [@media(min-height:32rem)]:md:grid-cols-2',\n className\n )}\n data-testid={testId}\n >\n {corner}\n <section className=\"flex min-h-screen flex-col px-4 py-5 sm:px-8 md:px-12 md:py-6\">\n {brand && (\n <div className=\"flex items-center gap-3 font-semibold text-foreground\">{brand}</div>\n )}\n {/* Top-aligned at a fixed offset (not vertically centred) so switching tabs never moves the tabs. */}\n <div className=\"mx-auto mt-10 flex w-full max-w-sm flex-col gap-5 py-8 md:mt-[14vh]\">\n {headerRight && <div className=\"flex items-center\">{headerRight}</div>}\n {children}\n </div>\n </section>\n {aside && <div className=\"hidden [@media(min-height:32rem)]:md:flex\">{aside}</div>}\n </div>\n )\n}\n\nexport interface AuthHeroPillar {\n icon: LucideIcon\n title: string\n body: string\n}\n\nexport interface AuthHeroProps {\n /** First line of the headline. */\n headline?: ReactNode\n /** Second headline line, set in italic accent. */\n emphasis?: string\n lead?: ReactNode\n pillars?: AuthHeroPillar[]\n link?: { href: string; label: string }\n /** Cover image behind the content (any CSS `url(...)` source). A tint keeps text legible. */\n backgroundImage?: string\n /** Extra content under the pillars (a quote, a logo row, a screenshot). */\n children?: ReactNode\n className?: string\n testId?: string\n}\n\n/** The value-proposition panel for {@link AuthLayout}'s `aside`: headline, lead, pillars, link. */\nexport function AuthHero({\n headline,\n emphasis,\n lead,\n pillars = [],\n link,\n backgroundImage,\n children,\n className,\n testId = 'product-pillars',\n}: AuthHeroProps) {\n return (\n <div\n data-slot=\"auth-hero\"\n className={cn(\n 'relative flex w-full flex-col justify-center gap-6 overflow-hidden bg-hero px-12 py-16 text-white',\n className\n )}\n data-testid={testId}\n >\n {backgroundImage && (\n <>\n <div\n aria-hidden=\"true\"\n data-slot=\"auth-hero-image\"\n className=\"absolute inset-0 bg-cover bg-center\"\n style={{ backgroundImage: `url(${backgroundImage})` }}\n />\n <div aria-hidden=\"true\" className=\"absolute inset-0 bg-hero/70\" />\n </>\n )}\n {headline && (\n <h2 className=\"relative max-w-[18ch] text-3xl font-semibold leading-tight text-white\">\n {headline}\n {emphasis && (\n <>\n <br />\n <span className=\"italic text-theme-cyan-bright\">{emphasis}</span>\n </>\n )}\n </h2>\n )}\n {lead && <p className=\"relative max-w-[44ch] text-base text-white/70\">{lead}</p>}\n\n <ul className=\"relative flex max-w-[46ch] flex-col gap-5\">\n {pillars.map(({ icon: Icon, title, body }) => (\n <li key={title} className=\"flex gap-3\">\n <Icon className=\"mt-0.5 h-5 w-5 shrink-0 text-theme-cyan-bright\" aria-hidden=\"true\" />\n <div>\n <h3 className=\"text-base font-semibold leading-snug text-white\">{title}</h3>\n <p className=\"text-sm leading-relaxed text-white/70\">{body}</p>\n </div>\n </li>\n ))}\n </ul>\n\n {children && <div className=\"relative\">{children}</div>}\n\n {link && (\n <a\n href={link.href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"relative inline-flex items-center gap-1 text-sm font-medium text-theme-cyan-bright transition-colors hover:text-white\"\n >\n {link.label}\n <ArrowRight className=\"h-4 w-4\" />\n </a>\n )}\n </div>\n )\n}\n","import { AlertCircle, Eye, EyeOff, Loader2, WifiOff } from 'lucide-react'\nimport {\n createContext,\n useContext,\n useId,\n useMemo,\n useState,\n type ComponentProps,\n type ReactNode,\n} from 'react'\nimport * as TabsPrimitive from '@radix-ui/react-tabs'\nimport { Button, cn, Input } from '@arbidocs/react/ui'\nimport { testIdOr } from '../chat/test-id'\n\n/** Title + one-line description above an auth form. */\nexport function AuthHeading({ title, description }: { title: ReactNode; description?: ReactNode }) {\n return (\n <div data-slot=\"auth-heading\">\n <h1 className=\"text-2xl font-semibold tracking-tight text-foreground\">{title}</h1>\n {description && <p className=\"mt-1.5 text-sm text-muted-foreground\">{description}</p>}\n </div>\n )\n}\n\n/** A text-style action under or beside a field (\"Forgot your password?\", \"Clear form\"). */\nexport function AuthLink({ className, type = 'button', ...props }: ComponentProps<'button'>) {\n return (\n <button\n type={type}\n data-slot=\"auth-link\"\n className={cn(\n 'text-sm text-primary hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring pointer-coarse:min-h-11',\n className\n )}\n {...props}\n />\n )\n}\n\ninterface AuthFieldContextValue {\n id: string\n errorId?: string\n}\n\n/** What an `AuthField` hands to the control inside: its id and the id of its error message. */\nconst AuthFieldContext = createContext<AuthFieldContextValue | null>(null)\n\n/** Merge space-separated id lists for `aria-describedby`. */\nfunction joinIds(...ids: Array<string | undefined>): string | undefined {\n const joined = ids.filter(Boolean).join(' ')\n return joined || undefined\n}\n\nexport interface AuthFieldProps {\n /** Id of the control inside, for the label. Omit it to use a generated (`useId`) id that the\n * `AuthInput` / `RevealablePasswordInput` inside picks up automatically. */\n htmlFor?: string\n /** Field-level error: shown under the control, linked with `aria-describedby`, and marks the\n * control `aria-invalid`. */\n error?: ReactNode\n errorTestId?: string\n label: ReactNode\n required?: boolean\n /** Right-aligned action in the label row (e.g. \"Clear form\"). */\n labelAction?: ReactNode\n /** Overlaid at the right edge of the control (e.g. a \"Verified\" badge). */\n trailing?: ReactNode\n className?: string\n children: ReactNode\n}\n\n/** Label (with required marker) above a control. */\nexport function AuthField({\n htmlFor,\n error,\n errorTestId,\n label,\n required,\n labelAction,\n trailing,\n className,\n children,\n}: AuthFieldProps) {\n const generatedId = useId()\n const id = htmlFor ?? generatedId\n const errorId = error ? `${id}-error` : undefined\n const context = useMemo(() => ({ id, errorId }), [id, errorId])\n return (\n <AuthFieldContext.Provider value={context}>\n <div data-slot=\"auth-field\" className={className}>\n <div className=\"mb-1 flex items-center justify-between\">\n <label htmlFor={id} className=\"block text-sm font-medium text-foreground\">\n {label} {required && <span className=\"text-red-text\">*</span>}\n </label>\n {labelAction}\n </div>\n {trailing ? (\n <div className=\"relative\">\n {children}\n {trailing}\n </div>\n ) : (\n children\n )}\n {error && (\n <p\n id={errorId}\n role=\"alert\"\n className=\"mt-1 text-sm text-red-text\"\n data-testid={errorTestId}\n >\n {error}\n </p>\n )}\n </div>\n </AuthFieldContext.Provider>\n )\n}\n\n/** Input styled for auth forms (faint placeholder). */\nexport function AuthInput({\n className,\n id,\n 'aria-describedby': describedBy,\n 'aria-invalid': invalid,\n ...props\n}: ComponentProps<typeof Input>) {\n const field = useContext(AuthFieldContext)\n return (\n <Input\n id={id ?? field?.id}\n aria-describedby={joinIds(describedBy, field?.errorId)}\n aria-invalid={invalid ?? (field?.errorId ? true : undefined)}\n className={cn('placeholder:text-muted-foreground', className)}\n {...props}\n />\n )\n}\n\n/** Every fixed string of the revealable password input. */\nexport interface RevealablePasswordInputLabels {\n hidePassword: string\n showPassword: string\n}\n\nexport const DEFAULT_REVEALABLE_PASSWORD_INPUT_LABELS: RevealablePasswordInputLabels = {\n hidePassword: 'Hide password',\n showPassword: 'Show password',\n}\n\n/** Every fixed string of the offline badge. */\nexport interface AuthOfflineBadgeLabels {\n offline: string\n}\n\nexport const DEFAULT_AUTH_OFFLINE_BADGE_LABELS: AuthOfflineBadgeLabels = {\n offline: 'Offline',\n}\n\nexport interface RevealablePasswordInputProps extends Omit<ComponentProps<typeof Input>, 'type'> {\n /** Controlled reveal state. Omit it and the input manages its own (see `defaultRevealed`). */\n isRevealed?: boolean\n /** Initial state when uncontrolled. */\n defaultRevealed?: boolean\n /** Called on every toggle press, controlled or not. */\n onToggleReveal?: () => void\n labels?: Partial<RevealablePasswordInputLabels>\n /** Show/hide button id (default `toggle-password-visibility`); `data-testid` goes to the input. */\n toggleTestId?: string\n}\n\n/** Password input with a show/hide button inside the field. */\nexport function RevealablePasswordInput({\n isRevealed: controlledRevealed,\n defaultRevealed = false,\n onToggleReveal,\n className,\n labels,\n toggleTestId,\n ...props\n}: RevealablePasswordInputProps) {\n const [innerRevealed, setInnerRevealed] = useState(defaultRevealed)\n const isControlled = controlledRevealed !== undefined\n const isRevealed = isControlled ? controlledRevealed : innerRevealed\n const l = useMemo(() => ({ ...DEFAULT_REVEALABLE_PASSWORD_INPUT_LABELS, ...labels }), [labels])\n return (\n <div className=\"relative\">\n <AuthInput\n type={isRevealed ? 'text' : 'password'}\n className={cn('pr-10', className)}\n {...props}\n />\n <button\n type=\"button\"\n onClick={() => {\n if (!isControlled) setInnerRevealed((prev) => !prev)\n onToggleReveal?.()\n }}\n aria-label={isRevealed ? l.hidePassword : l.showPassword}\n aria-pressed={isRevealed}\n className=\"absolute inset-y-0 right-0 flex w-10 items-center justify-center rounded-r-md text-muted-foreground hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring pointer-coarse:w-11\"\n data-testid={testIdOr(toggleTestId, { testId: 'toggle-password-visibility' })}\n >\n {isRevealed ? (\n <EyeOff className=\"h-4 w-4\" aria-hidden=\"true\" />\n ) : (\n <Eye className=\"h-4 w-4\" aria-hidden=\"true\" />\n )}\n </button>\n </div>\n )\n}\n\n/** Small pill on a locked field, e.g. \"Verified\". */\nexport function AuthFieldBadge({\n icon,\n children,\n testId,\n}: {\n icon?: ReactNode\n children: ReactNode\n testId?: string\n}) {\n return (\n <span\n className=\"pointer-events-none absolute inset-y-0 right-3 flex items-center gap-1 text-xs font-medium text-green-text\"\n data-testid={testId}\n >\n {icon}\n {children}\n </span>\n )\n}\n\n/** Centred muted sentence under a step's primary action. */\nexport function AuthNote({ className, ...props }: ComponentProps<'p'>) {\n return <p className={cn('text-center text-sm text-muted-foreground', className)} {...props} />\n}\n\n/** Error / status message box for a form. */\nexport function AuthAlert({\n children,\n withIcon = false,\n testId,\n id,\n}: {\n children: ReactNode\n withIcon?: boolean\n testId?: string\n /** Lets a field point at this message with `aria-describedby`. */\n id?: string\n}) {\n return (\n <div\n id={id}\n role=\"alert\"\n data-testid={testId}\n className=\"flex gap-2 rounded-md bg-red-bg p-3 text-sm text-red-text\"\n >\n {withIcon && <AlertCircle className=\"h-5 w-5 flex-shrink-0\" aria-hidden=\"true\" />}\n <div>{children}</div>\n </div>\n )\n}\n\nexport interface AuthSubmitButtonProps extends ComponentProps<typeof Button> {\n /** Shows a spinner and sets `aria-busy`. */\n isBusy?: boolean\n /** Shorthand for `data-testid`. */\n testId?: string\n}\n\n/** Full-width primary submit with a spinner while busy. */\nexport function AuthSubmitButton({\n isBusy,\n testId,\n children,\n className,\n ...props\n}: AuthSubmitButtonProps) {\n return (\n <Button\n type=\"submit\"\n className={cn('w-full', className)}\n aria-busy={isBusy || undefined}\n data-testid={testId}\n {...props}\n >\n {isBusy && <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" />}\n {children}\n </Button>\n )\n}\n\n/** \"or continue with\" separator between the form and the SSO button. */\nexport function AuthDivider({ label, testId }: { label: string; testId?: string }) {\n return (\n <div\n data-slot=\"auth-divider\"\n data-testid={testIdOr(testId, { testId: 'login-divider' })}\n className=\"relative\"\n >\n <div className=\"absolute inset-0 flex items-center\">\n <div className=\"w-full border-t border-border\" />\n </div>\n <div className=\"relative flex justify-center text-xs\">\n <span className=\"bg-background px-2 text-muted-foreground\">{label}</span>\n </div>\n </div>\n )\n}\n\nexport interface AuthTabOption<T extends string> {\n value: T\n label: string\n testId?: string\n}\n\n/**\n * Underline tab pair (Login / Register) above the form. Radix Tabs: one tab stop, arrow keys,\n * Home and End move between tabs and select them (the form below swaps with the selection).\n */\nexport function AuthTabs<T extends string>({\n value,\n onChange,\n tabs,\n ariaLabel,\n}: {\n value: T\n onChange: (value: T) => void\n tabs: AuthTabOption<T>[]\n ariaLabel: string\n}) {\n return (\n <TabsPrimitive.Root value={value} onValueChange={(next) => onChange(next as T)}>\n <TabsPrimitive.List aria-label={ariaLabel} className=\"inline-flex items-center gap-6\">\n {tabs.map((tab) => (\n <TabsPrimitive.Trigger\n key={tab.value}\n value={tab.value}\n data-testid={tab.testId}\n className={cn(\n '-mb-px border-b-2 py-2 text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring pointer-coarse:min-w-11 pointer-coarse:py-3',\n tab.value === value\n ? 'border-primary text-foreground'\n : 'border-transparent text-muted-foreground hover:text-foreground'\n )}\n >\n {tab.label}\n </TabsPrimitive.Trigger>\n ))}\n </TabsPrimitive.List>\n {/* The form the tabs switch lives outside this component; these empty, hidden panels only\n give each tab's `aria-controls` a valid target. */}\n {tabs.map((tab) => (\n <TabsPrimitive.Content\n key={tab.value}\n value={tab.value}\n tabIndex={-1}\n aria-hidden=\"true\"\n className=\"hidden\"\n />\n ))}\n </TabsPrimitive.Root>\n )\n}\n\n/** Pill shown instead of the tabs when the device is offline. */\nexport function AuthOfflineBadge({\n label,\n title,\n testId,\n labels,\n}: {\n label?: string\n title?: string\n testId?: string\n labels?: Partial<AuthOfflineBadgeLabels>\n}) {\n const text = label ?? labels?.offline ?? DEFAULT_AUTH_OFFLINE_BADGE_LABELS.offline\n return (\n <span\n data-testid={testIdOr(testId, { testId: 'login-offline-indicator' })}\n className=\"inline-flex items-center gap-1.5 rounded-md bg-yellow-bg px-2.5 py-1.5 text-sm font-medium text-yellow-text\"\n title={title}\n >\n <WifiOff className=\"h-4 w-4 shrink-0\" />\n {text}\n </span>\n )\n}\n","import { useMemo } from 'react'\nimport { Button } from '@arbidocs/react/ui'\nimport { testIdOr } from '../chat/test-id'\n\n/** Every fixed string of the SSO button. `brandIconAlt` prop wins over `brandIconAlt` label. */\nexport interface SsoLoginButtonLabels {\n loginWith: string\n brandIconAlt: string\n}\n\nexport const DEFAULT_SSO_LOGIN_BUTTON_LABELS: SsoLoginButtonLabels = {\n loginWith: 'Login with',\n brandIconAlt: 'ARBI Docs',\n}\n\nexport interface SsoLoginButtonProps {\n labels?: Partial<SsoLoginButtonLabels>\n onClick: () => void\n /** Source of the brand mark shown first. */\n brandIconSrc?: string\n brandIconAlt?: string\n /** Button test id (default `login-with-arbi-button`). */\n testId?: string\n /** Wrapper test id (default `sso-login-button-container`). */\n containerTestId?: string\n}\n\n/** \"Login with\" button showing the ARBI mark and the supported identity providers. */\nexport function SsoLoginButton({\n onClick,\n brandIconSrc = '/favicon.svg',\n brandIconAlt,\n testId,\n containerTestId,\n labels,\n}: SsoLoginButtonProps) {\n const l = useMemo(() => ({ ...DEFAULT_SSO_LOGIN_BUTTON_LABELS, ...labels }), [labels])\n return (\n <div\n data-slot=\"sso-login\"\n data-testid={testIdOr(containerTestId, { testId: 'sso-login-button-container' })}\n className=\"text-center\"\n >\n <Button\n onClick={onClick}\n className=\"flex w-full items-center justify-center gap-3\"\n variant=\"outline\"\n data-testid={testIdOr(testId, { testId: 'login-with-arbi-button' })}\n >\n <span>{l.loginWith}</span>\n <div className=\"flex items-center gap-3 pr-1\">\n <img\n src={brandIconSrc}\n alt={brandIconAlt ?? l.brandIconAlt}\n className=\"h-5 w-5 rounded object-contain\"\n />\n\n {/* LinkedIn */}\n <svg className=\"h-5 w-5\" viewBox=\"0 0 24 24\" fill=\"#0A66C2\" aria-hidden=\"true\">\n <path d=\"M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z\" />\n </svg>\n\n {/* Google */}\n <svg className=\"h-5 w-5\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <path\n fill=\"#4285F4\"\n d=\"M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z\"\n />\n <path\n fill=\"#34A853\"\n d=\"M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z\"\n />\n <path\n fill=\"#FBBC05\"\n d=\"M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z\"\n />\n <path\n fill=\"#EA4335\"\n d=\"M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z\"\n />\n </svg>\n\n {/* Apple */}\n <svg className=\"h-5 w-5\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M17.05 20.28c-.98.95-2.05.8-3.08.35-1.09-.46-2.09-.48-3.24 0-1.44.62-2.2.44-3.06-.35C2.79 15.25 3.51 7.59 9.05 7.31c1.35.07 2.29.74 3.08.8 1.18-.24 2.31-.93 3.57-.84 1.51.12 2.65.72 3.4 1.8-3.12 1.87-2.38 5.98.48 7.13-.57 1.5-1.31 2.99-2.54 4.09l.01-.01zM12.03 7.25c-.15-2.23 1.66-4.07 3.74-4.25.29 2.58-2.34 4.5-3.74 4.25z\" />\n </svg>\n </div>\n </Button>\n </div>\n )\n}\n","import { useMemo, type ReactNode } from 'react'\nimport { MoreVertical } from 'lucide-react'\nimport {\n Checkbox,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@arbidocs/react/ui'\nimport { testIdOr } from '../chat/test-id'\n\nexport interface AuthLegalLink {\n href: string\n label: string\n}\n\nexport interface AuthConsentProps {\n termsAccepted: boolean\n onTermsAcceptedChange: (accepted: boolean) => void\n /** Whether to download a recovery key on signup (opt-out; unchecking shows the warning). */\n saveRecoveryKey: boolean\n onSaveRecoveryKeyChange: (save: boolean) => void\n termsLink: AuthLegalLink\n privacyLink: AuthLegalLink\n /** Shown (role=\"alert\") only when the recovery-key box is unchecked. */\n noRecoveryKeyWarning: string\n labels?: Partial<AuthConsentLabels>\n /** Part ids; defaults are the current ids. */\n testIds?: Partial<\n Record<'termsCheckbox' | 'recoveryKeyCheckbox' | 'noRecoveryKeyWarning', string>\n >\n}\n\n/** Every fixed string of the sign-up consent block. */\nexport interface AuthConsentLabels {\n /** Text before the terms link. */\n acknowledge: string\n /** Text between the terms and privacy links. */\n and: string\n downloadRecoveryKey: string\n}\n\nexport const DEFAULT_AUTH_CONSENT_LABELS: AuthConsentLabels = {\n acknowledge: 'I acknowledge the',\n and: 'and',\n downloadRecoveryKey: 'Download my recovery key',\n}\n\n/** Every fixed string of the sign-in footer. */\nexport interface AuthFooterLinksLabels {\n installOptions: string\n install: string\n}\n\nexport const DEFAULT_AUTH_FOOTER_LINKS_LABELS: AuthFooterLinksLabels = {\n installOptions: 'Install options',\n install: 'Install',\n}\n\nconst LEGAL_LINK_CLASS = 'underline transition-colors hover:text-primary'\n\n/** Sign-up consent: required terms checkbox and the opt-out \"download recovery key\" checkbox. */\nexport function AuthConsent({\n termsAccepted,\n onTermsAcceptedChange,\n saveRecoveryKey,\n onSaveRecoveryKeyChange,\n termsLink,\n privacyLink,\n noRecoveryKeyWarning,\n labels,\n testIds,\n}: AuthConsentProps) {\n const l = useMemo(() => ({ ...DEFAULT_AUTH_CONSENT_LABELS, ...labels }), [labels])\n return (\n <div data-slot=\"auth-consent\" className=\"space-y-2\">\n <div className=\"flex items-start gap-2\">\n <Checkbox\n id=\"accept-terms\"\n checked={termsAccepted}\n onCheckedChange={(checked) => onTermsAcceptedChange(checked === true)}\n data-testid={testIdOr(testIds?.termsCheckbox, { testId: 'accept-terms-checkbox' })}\n />\n <label\n htmlFor=\"accept-terms\"\n className=\"cursor-pointer text-sm leading-relaxed text-muted-foreground\"\n >\n {l.acknowledge}{' '}\n <a\n href={termsLink.href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={LEGAL_LINK_CLASS}\n >\n {termsLink.label}\n </a>{' '}\n {l.and}{' '}\n <a\n href={privacyLink.href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={LEGAL_LINK_CLASS}\n >\n {privacyLink.label}\n </a>\n </label>\n </div>\n <div className=\"flex items-start gap-2\">\n <Checkbox\n id=\"save-recovery-key\"\n checked={saveRecoveryKey}\n onCheckedChange={(checked) => onSaveRecoveryKeyChange(checked === true)}\n data-testid={testIdOr(testIds?.recoveryKeyCheckbox, {\n testId: 'save-recovery-key-checkbox',\n })}\n />\n <label\n htmlFor=\"save-recovery-key\"\n className=\"cursor-pointer text-sm leading-relaxed text-muted-foreground\"\n >\n {l.downloadRecoveryKey}\n </label>\n </div>\n {/* Only shown on opt-out: the default path stays free of warnings. */}\n {!saveRecoveryKey && (\n <p\n className=\"text-sm text-red-text\"\n role=\"alert\"\n data-testid={testIdOr(testIds?.noRecoveryKeyWarning, {\n testId: 'no-recovery-key-warning',\n })}\n >\n {noRecoveryKeyWarning}\n </p>\n )}\n </div>\n )\n}\n\nexport interface AuthInstallOption {\n id: string\n label: ReactNode\n icon?: ReactNode\n onSelect: () => void\n disabled?: boolean\n testId?: string\n}\n\nexport interface AuthFooterLinksProps {\n privacyLink: AuthLegalLink\n /** Entries of the \"Install\" kebab menu. Omit/empty to hide the menu. */\n installOptions?: AuthInstallOption[]\n /** Dialog or other overlay owned by the host, rendered inside the footer. */\n children?: ReactNode\n labels?: Partial<AuthFooterLinksLabels>\n /** Install menu trigger id (default `install-options-trigger`). */\n installTriggerTestId?: string\n}\n\n/** Sign-in footer: privacy link on the left, an \"Install\" kebab menu on the right. */\nexport function AuthFooterLinks({\n privacyLink,\n installOptions = [],\n children,\n labels,\n installTriggerTestId,\n}: AuthFooterLinksProps) {\n const l = useMemo(() => ({ ...DEFAULT_AUTH_FOOTER_LINKS_LABELS, ...labels }), [labels])\n return (\n <div\n data-slot=\"auth-footer-links\"\n className=\"flex items-center justify-between pt-2 text-sm text-muted-foreground\"\n >\n <a\n href={privacyLink.href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center transition-colors hover:text-primary pointer-coarse:min-h-11\"\n >\n {privacyLink.label}\n </a>\n\n {installOptions.length > 0 && (\n <DropdownMenu>\n <DropdownMenuTrigger\n className=\"flex items-center gap-1 rounded-md px-1.5 py-1 transition-colors hover:text-primary focus:outline-none focus-visible:ring-1 focus-visible:ring-ring pointer-coarse:min-h-11\"\n aria-label={l.installOptions}\n data-testid={testIdOr(installTriggerTestId, { testId: 'install-options-trigger' })}\n >\n {l.install}\n <MoreVertical size={14} />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {installOptions.map((option) => (\n <DropdownMenuItem\n key={option.id}\n onClick={option.onSelect}\n disabled={option.disabled}\n className=\"gap-2\"\n data-testid={option.testId}\n >\n {option.icon}\n {option.label}\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n {children}\n </div>\n )\n}\n","import {\n useMemo,\n useRef,\n useState,\n type DragEvent,\n type FormEvent,\n type ReactNode,\n useId,\n} from 'react'\nimport { AlertCircle, Key, Loader2, Shield, Upload } from 'lucide-react'\nimport {\n Button,\n cn,\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n Input,\n} from '@arbidocs/react/ui'\nimport { testIdOr } from '../chat/test-id'\n\nfunction ErrorBox({ message, id }: { message: string; id?: string }) {\n return (\n <div id={id} role=\"alert\" className=\"rounded-md bg-red-bg p-3\">\n <div className=\"flex gap-2\">\n <AlertCircle className=\"h-5 w-5 flex-shrink-0 text-red-text\" aria-hidden=\"true\" />\n <p className=\"text-sm text-red-text\">{message}</p>\n </div>\n </div>\n )\n}\n\n/** Every fixed string of the recovery-key dialog. `title` / description props win. */\nexport interface RecoveryKeyDialogLabels {\n title: string\n verifiedDescription: string\n unverifiedDescription: string\n done: string\n currentPassword: string\n passwordPlaceholder: string\n cancel: string\n verifying: string\n verify: string\n}\n\nexport const DEFAULT_RECOVERY_KEY_DIALOG_LABELS: RecoveryKeyDialogLabels = {\n title: 'Save your recovery key',\n verifiedDescription:\n \"If you forget your password, this is the only way to get back into your account. Save it to your password manager so it's there when you need it.\",\n unverifiedDescription: 'Confirm your password to continue.',\n done: 'Done',\n currentPassword: 'Current Password',\n passwordPlaceholder: 'Enter your password',\n cancel: 'Cancel',\n verifying: 'Verifying...',\n verify: 'Verify',\n}\n\n/** Every fixed string of the account-recovery dialog. */\nexport interface AccountRecoveryDialogLabels {\n title: string\n description: string\n emailAddress: string\n emailPlaceholder: string\n keyLoadedFromLink: string\n ssoProtectedKeyNotice: string\n recoveryKey: string\n ssoProtectedKey: string\n dropKeyHere: string\n uploadKeyPrompt: string\n ssoSignInNotice: string\n ssoSignIn: string\n afterRecoveryNotice: string\n cancel: string\n recovering: string\n recoverAccount: string\n}\n\nexport const DEFAULT_ACCOUNT_RECOVERY_DIALOG_LABELS: AccountRecoveryDialogLabels = {\n title: 'Recover Your Account',\n description: 'Upload your recovery key to regain access to your account',\n emailAddress: 'Email Address',\n emailPlaceholder: 'Enter your email',\n keyLoadedFromLink: 'Recovery key loaded from link',\n ssoProtectedKeyNotice: 'SSO-protected key — you must be signed into the matching SSO account.',\n recoveryKey: 'Recovery Key',\n ssoProtectedKey: 'SSO Protected Key',\n dropKeyHere: 'Drop your recovery key here',\n uploadKeyPrompt: 'Click or drag to upload your recovery key (.key file)',\n ssoSignInNotice:\n 'This account signs in with single sign-on. Sign in with your identity provider to continue — you won\\u2019t need your forgotten master password for that step.',\n ssoSignIn: 'Sign in with Auth0 to continue',\n afterRecoveryNotice:\n 'After successful recovery, you will be prompted to set a new password to secure your account.',\n cancel: 'Cancel',\n recovering: 'Recovering...',\n recoverAccount: 'Recover Account',\n}\n\nexport interface RecoveryKeyDialogProps {\n labels?: Partial<RecoveryKeyDialogLabels>\n open: boolean\n onClose: () => void\n /** Content shown once the password is verified (the key download). `null` while verifying. */\n verified: ReactNode | null\n password: string\n onPasswordChange: (password: string) => void\n onVerify: () => void\n isVerifying: boolean\n error: string | null\n title?: string\n verifiedDescription?: string\n unverifiedDescription?: string\n /** Dialog test id (default `download-recovery-key-dialog`). */\n testId?: string\n /** Part ids; defaults are the current ids. */\n testIds?: Partial<Record<'passwordInput', string>>\n}\n\n/**\n * \"Save your recovery key\": confirm the account password first, then reveal the key download\n * (`verified`) with a Done button.\n */\nexport function RecoveryKeyDialog({\n open,\n onClose,\n verified,\n password,\n onPasswordChange,\n onVerify,\n isVerifying,\n error,\n title,\n verifiedDescription,\n unverifiedDescription,\n labels,\n testId,\n testIds,\n}: RecoveryKeyDialogProps) {\n const verifyPasswordId = useId()\n const l = useMemo(() => ({ ...DEFAULT_RECOVERY_KEY_DIALOG_LABELS, ...labels }), [labels])\n const handleSubmit = (e: FormEvent) => {\n e.preventDefault()\n onVerify()\n }\n\n return (\n <Dialog open={open} onOpenChange={onClose}>\n <DialogContent\n presentation=\"sheet\"\n className=\"sm:max-w-md\"\n data-testid={testIdOr(testId, { testId: 'download-recovery-key-dialog' })}\n >\n <DialogHeader>\n <DialogTitle className=\"font-heading\">{title ?? l.title}</DialogTitle>\n <DialogDescription>\n {verified\n ? (verifiedDescription ?? l.verifiedDescription)\n : (unverifiedDescription ?? l.unverifiedDescription)}\n </DialogDescription>\n </DialogHeader>\n\n {verified ? (\n <div className=\"space-y-4\">\n {verified}\n <div className=\"flex justify-end\">\n <Button onClick={onClose}>{l.done}</Button>\n </div>\n </div>\n ) : (\n <form onSubmit={handleSubmit} className=\"space-y-4\">\n <div className=\"space-y-2\">\n <label htmlFor={verifyPasswordId} className=\"text-sm font-medium\">\n {l.currentPassword}\n </label>\n <Input\n id={verifyPasswordId}\n type=\"password\"\n value={password}\n onChange={(e) => onPasswordChange(e.target.value)}\n placeholder={l.passwordPlaceholder}\n disabled={isVerifying}\n autoComplete=\"current-password\"\n aria-invalid={error ? true : undefined}\n aria-describedby={error ? `${verifyPasswordId}-error` : undefined}\n data-testid={testIdOr(testIds?.passwordInput, { testId: 'verify-password-input' })}\n />\n </div>\n\n {error && <ErrorBox message={error} id={`${verifyPasswordId}-error`} />}\n\n <div className=\"flex flex-col-reverse sm:flex-row sm:justify-end gap-3\">\n <Button type=\"button\" variant=\"outline\" onClick={onClose} disabled={isVerifying}>\n {l.cancel}\n </Button>\n <Button type=\"submit\" disabled={isVerifying || !password}>\n {isVerifying ? (\n <>\n <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" />\n {l.verifying}\n </>\n ) : (\n l.verify\n )}\n </Button>\n </div>\n </form>\n )}\n </DialogContent>\n </Dialog>\n )\n}\n\nexport interface AccountRecoveryDialogProps {\n labels?: Partial<AccountRecoveryDialogLabels>\n open: boolean\n onClose: () => void\n email: string\n onEmailChange: (email: string) => void\n /** The key arrived in the page URL (the /recover link): show a \"loaded\" notice, no file picker. */\n isKeyFromLink: boolean\n /** Name of the chosen key file, once one is loaded. */\n keyFileName: string | null\n /** The loaded key is wrapped with the user's SSO identity. */\n isKeyEncrypted: boolean\n /** A file was picked or dropped. */\n onKeyFile: (file: File) => void\n error: string | null\n /** SSO sign-in is the next required step (SSO-wrapped key or SSO-linked account). */\n needsSsoSignIn: boolean\n onSsoSignIn: () => void\n isProcessing: boolean\n /** Enables the submit button (email and key present). */\n canSubmit: boolean\n onSubmit: () => void\n /** Dialog test id (default `forgot-password-modal`). */\n testId?: string\n /** Part ids; defaults are the current ids. */\n testIds?: Partial<\n Record<'emailInput' | 'keyDropzone' | 'keyInput' | 'ssoSignIn' | 'cancel' | 'submit', string>\n >\n}\n\n/**\n * Account recovery: email + recovery key (file or link) -> sign in with the key. When the account\n * is SSO-linked, the SSO prompt replaces the submit button.\n */\nexport function AccountRecoveryDialog({\n open,\n onClose,\n email,\n onEmailChange,\n isKeyFromLink,\n keyFileName,\n isKeyEncrypted,\n onKeyFile,\n error,\n needsSsoSignIn,\n onSsoSignIn,\n isProcessing,\n canSubmit,\n onSubmit,\n labels,\n testId,\n testIds,\n}: AccountRecoveryDialogProps) {\n const recoveryEmailId = useId()\n const l = useMemo(() => ({ ...DEFAULT_ACCOUNT_RECOVERY_DIALOG_LABELS, ...labels }), [labels])\n const fileInputRef = useRef<HTMLInputElement>(null)\n const [isDragActive, setIsDragActive] = useState(false)\n\n const handleDragOver = (e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragActive(true)\n }\n const handleDragLeave = (e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragActive(false)\n }\n const handleDrop = (e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragActive(false)\n const file = e.dataTransfer.files?.[0]\n if (file) onKeyFile(file)\n }\n\n return (\n <Dialog open={open} onOpenChange={onClose}>\n <DialogContent\n presentation=\"sheet\"\n className=\"sm:max-w-md\"\n data-testid={testIdOr(testId, { testId: 'forgot-password-modal' })}\n >\n <DialogHeader>\n <DialogTitle className=\"flex items-center gap-2\">\n <Key className=\"h-5 w-5 text-primary\" />\n {l.title}\n </DialogTitle>\n <DialogDescription>{l.description}</DialogDescription>\n </DialogHeader>\n\n <div className=\"space-y-4\">\n <div className=\"space-y-2\">\n <label htmlFor={recoveryEmailId} className=\"text-sm font-medium\">\n {l.emailAddress}\n </label>\n <Input\n id={recoveryEmailId}\n type=\"email\"\n value={email}\n onChange={(e) => onEmailChange(e.target.value)}\n placeholder={l.emailPlaceholder}\n disabled={isProcessing}\n data-testid={testIdOr(testIds?.emailInput, { testId: 'recovery-email-input' })}\n />\n </div>\n\n {isKeyFromLink ? (\n <div className=\"rounded-md bg-green-bg p-3\">\n <div className=\"flex items-center gap-2 text-sm\">\n <Key className=\"h-4 w-4 text-green-text\" />\n <span className=\"font-medium text-green-text\">{l.keyLoadedFromLink}</span>\n </div>\n {isKeyEncrypted && (\n <p className=\"mt-1 inline-flex items-center gap-1 text-sm text-primary\">\n <Shield className=\"h-3 w-3\" />\n {l.ssoProtectedKeyNotice}\n </p>\n )}\n </div>\n ) : (\n <div className=\"space-y-2\">\n <label className=\"text-sm font-medium\">{l.recoveryKey}</label>\n <div\n role=\"button\"\n tabIndex={0}\n className={cn(\n 'cursor-pointer rounded-lg p-4 text-center transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',\n isDragActive ? 'bg-accent' : 'bg-muted hover:bg-muted/70'\n )}\n onClick={() => fileInputRef.current?.click()}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n fileInputRef.current?.click()\n }\n }}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n data-testid={testIdOr(testIds?.keyDropzone, { testId: 'recovery-key-dropzone' })}\n >\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\".key\"\n onClick={(e) => e.stopPropagation()}\n onChange={(e) => {\n const file = e.target.files?.[0]\n if (file) onKeyFile(file)\n }}\n className=\"hidden\"\n data-testid={testIdOr(testIds?.keyInput, { testId: 'recovery-key-input' })}\n />\n {keyFileName ? (\n <div className=\"flex flex-col items-center gap-1\">\n <div className=\"flex items-center justify-center gap-2 text-sm\">\n <Key className=\"h-4 w-4 text-green-text\" />\n <span className=\"font-medium text-green-text\">{keyFileName}</span>\n </div>\n {isKeyEncrypted && (\n <span className=\"inline-flex items-center gap-1 text-sm text-primary\">\n <Shield className=\"h-3 w-3\" />\n {l.ssoProtectedKey}\n </span>\n )}\n </div>\n ) : (\n <div className=\"space-y-2\">\n <Upload className=\"mx-auto h-8 w-8 text-muted-foreground\" />\n <p className=\"text-sm text-muted-foreground\">\n {isDragActive ? l.dropKeyHere : l.uploadKeyPrompt}\n </p>\n </div>\n )}\n </div>\n </div>\n )}\n\n {error && <ErrorBox message={error} />}\n\n {needsSsoSignIn ? (\n <div className=\"space-y-2 rounded-lg bg-muted p-3\">\n <div className=\"flex gap-2\">\n <Shield className=\"h-5 w-5 flex-shrink-0 text-primary\" />\n <p className=\"text-sm\">{l.ssoSignInNotice}</p>\n </div>\n <Button\n onClick={onSsoSignIn}\n className=\"w-full\"\n data-testid={testIdOr(testIds?.ssoSignIn, { testId: 'recovery-sso-signin-button' })}\n >\n {l.ssoSignIn}\n </Button>\n </div>\n ) : (\n <div className=\"rounded-md bg-muted p-3\">\n <p className=\"text-sm text-muted-foreground\">{l.afterRecoveryNotice}</p>\n </div>\n )}\n </div>\n\n <DialogFooter className=\"gap-2\">\n <Button\n variant=\"outline\"\n onClick={onClose}\n disabled={isProcessing}\n data-testid={testIdOr(testIds?.cancel, { testId: 'forgot-password-cancel' })}\n >\n {l.cancel}\n </Button>\n {/* Hidden when SSO sign-in is the next step, to avoid two competing options. */}\n {!needsSsoSignIn && (\n <Button\n onClick={onSubmit}\n disabled={isProcessing || !canSubmit}\n data-testid={testIdOr(testIds?.submit, { testId: 'forgot-password-submit' })}\n >\n {isProcessing ? (\n <>\n <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" />\n {l.recovering}\n </>\n ) : (\n l.recoverAccount\n )}\n </Button>\n )}\n </DialogFooter>\n </DialogContent>\n </Dialog>\n )\n}\n"]}