@12-apps/ui 6.39.1 → 6.39.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/dist/_internal/components/data-display/LazyImage/LazyImage.js +1 -1
  2. package/dist/_internal/components/data-display/Table/Table.helpers.js +10 -3
  3. package/dist/_internal/components/data-display/Table/Table.hooks.js +1 -1
  4. package/dist/_internal/components/data-display/Table/Table.js +4 -4
  5. package/dist/_internal/components/data-display/Table/TableParts.hooks.js +2 -3
  6. package/dist/_internal/components/data-display/Table/TableParts.js +2 -3
  7. package/dist/_internal/components/data-display/index.js +5 -5
  8. package/dist/_internal/components/index.js +9 -9
  9. package/dist/_internal/components/utility/WorkflowStep/WorkflowStep.helpers.js +15 -1
  10. package/dist/_internal/components/utility/WorkflowStep/WorkflowStep.js +17 -4
  11. package/dist/_internal/components/utility/WorkflowStep/WorkflowStep.parts.js +15 -2
  12. package/dist/_internal/components/utility/WorkflowStep/WorkflowStepRow.js +16 -3
  13. package/dist/_internal/components/utility/index.js +17 -4
  14. package/dist/{chunk-YZVR5ROE.js → chunk-5HQNHZ6Z.js} +12 -10
  15. package/dist/chunk-5HQNHZ6Z.js.map +1 -0
  16. package/dist/{chunk-3YOXVNO4.js → chunk-BOGTTXPA.js} +32 -30
  17. package/dist/chunk-BOGTTXPA.js.map +1 -0
  18. package/dist/{chunk-MC4KYGSX.js → chunk-GFQ4U6WZ.js} +3 -5
  19. package/dist/chunk-GFQ4U6WZ.js.map +1 -0
  20. package/dist/{chunk-5LWB4BYX.js → chunk-RGT6DM5W.js} +21 -47
  21. package/dist/chunk-RGT6DM5W.js.map +1 -0
  22. package/dist/{chunk-FF2D7V7T.js → chunk-SDK5LPPC.js} +13 -10
  23. package/dist/chunk-SDK5LPPC.js.map +1 -0
  24. package/dist/{chunk-SNURSSTN.js → chunk-VLOUXTEM.js} +3 -3
  25. package/dist/{chunk-V5KKBMAT.js → chunk-VXQOSADY.js} +6 -3
  26. package/dist/{chunk-V5KKBMAT.js.map → chunk-VXQOSADY.js.map} +1 -1
  27. package/dist/{chunk-BVLMKSHX.js → chunk-WDVNRW3Q.js} +2 -2
  28. package/dist/chunk-XS3REOPN.js +86 -0
  29. package/dist/chunk-XS3REOPN.js.map +1 -0
  30. package/dist/data-display/LazyImage.js +1 -1
  31. package/dist/data-display/Table.js +4 -4
  32. package/dist/types/components/data-display/LazyImage/LazyImage.d.ts.map +1 -1
  33. package/dist/types/components/data-display/LazyImage/LazyImage.types.d.ts +15 -3
  34. package/dist/types/components/data-display/LazyImage/LazyImage.types.d.ts.map +1 -1
  35. package/dist/types/components/data-display/Table/Table.d.ts.map +1 -1
  36. package/dist/types/components/data-display/Table/Table.helpers.d.ts +20 -0
  37. package/dist/types/components/data-display/Table/Table.helpers.d.ts.map +1 -1
  38. package/dist/types/components/data-display/Table/Table.hooks.d.ts +8 -11
  39. package/dist/types/components/data-display/Table/Table.hooks.d.ts.map +1 -1
  40. package/dist/types/components/data-display/Table/Table.types.d.ts +17 -2
  41. package/dist/types/components/data-display/Table/Table.types.d.ts.map +1 -1
  42. package/dist/types/components/data-display/Table/TableParts.d.ts.map +1 -1
  43. package/dist/types/components/utility/WorkflowStep/WorkflowStep.helpers.d.ts +6 -1
  44. package/dist/types/components/utility/WorkflowStep/WorkflowStep.helpers.d.ts.map +1 -1
  45. package/dist/types/components/utility/WorkflowStep/WorkflowStep.parts.d.ts.map +1 -1
  46. package/dist/utility/WorkflowStep.js +17 -4
  47. package/package.json +1 -1
  48. package/src/components/data-display/LazyImage/LazyImage.md +22 -15
  49. package/src/components/data-display/LazyImage/LazyImage.tsx +26 -9
  50. package/src/components/data-display/LazyImage/LazyImage.types.ts +15 -3
  51. package/src/components/data-display/Table/Table.helpers.ts +93 -0
  52. package/src/components/data-display/Table/Table.hooks.ts +20 -11
  53. package/src/components/data-display/Table/Table.tsx +34 -31
  54. package/src/components/data-display/Table/Table.types.ts +18 -2
  55. package/src/components/data-display/Table/TableParts.tsx +23 -52
  56. package/src/components/utility/WorkflowStep/WorkflowStep.helpers.ts +9 -3
  57. package/src/components/utility/WorkflowStep/WorkflowStep.parts.tsx +1 -5
  58. package/dist/chunk-3YOXVNO4.js.map +0 -1
  59. package/dist/chunk-5LWB4BYX.js.map +0 -1
  60. package/dist/chunk-FF2D7V7T.js.map +0 -1
  61. package/dist/chunk-JWZJSXI5.js +0 -29
  62. package/dist/chunk-JWZJSXI5.js.map +0 -1
  63. package/dist/chunk-MC4KYGSX.js.map +0 -1
  64. package/dist/chunk-YZVR5ROE.js.map +0 -1
  65. /package/dist/{chunk-SNURSSTN.js.map → chunk-VLOUXTEM.js.map} +0 -0
  66. /package/dist/{chunk-BVLMKSHX.js.map → chunk-WDVNRW3Q.js.map} +0 -0
@@ -303,6 +303,22 @@ export interface TableHeaderProps {
303
303
  onSelectAll?: (selected: boolean) => void;
304
304
  density?: TableDensity;
305
305
  stickyHeader?: boolean;
306
+ /** The `<thead>`, so the virtual window can subtract its height from the scroller's offset. */
307
+ headRef?: React.Ref<globalThis.HTMLTableSectionElement>;
308
+ }
309
+
310
+ /**
311
+ * The rows a virtualised body mounts. Computed by `useVirtualScrolling` in the
312
+ * table, which owns the one scroll container, and handed down to the body.
313
+ */
314
+ export interface VirtualWindow {
315
+ startIndex: number;
316
+ endIndex: number;
317
+ items: Record<string, unknown>[];
318
+ /** Every row at the scaled pitch, as CSS. */
319
+ totalHeight: string;
320
+ /** Where the first mounted row sits, in design px. */
321
+ offsetY: number;
306
322
  }
307
323
 
308
324
  export interface TableBodyProps {
@@ -320,9 +336,9 @@ export interface TableBodyProps {
320
336
  renderRow?: (rowData: Record<string, unknown>, index: number, isSelected: boolean) => React.ReactNode;
321
337
  renderCell?: (value: unknown, column: ColumnConfig, rowData: Record<string, unknown>, rowIndex: number) => React.ReactNode;
322
338
  virtualScrolling?: boolean;
323
- containerHeight?: number;
339
+ /** Set only when the body is virtualised: the rows in view and where they sit. */
340
+ virtualWindow?: VirtualWindow;
324
341
  rowHeight?: number;
325
- overscan?: number;
326
342
  }
327
343
 
328
344
  export interface VirtualTableBodyProps extends TableBodyProps {
@@ -1,4 +1,3 @@
1
- import Box from '@mui/material/Box/index.js';
2
1
  import Checkbox from '@mui/material/Checkbox/index.js';
3
2
  import TableBody from '@mui/material/TableBody/index.js';
4
3
  import TableCell from '@mui/material/TableCell/index.js';
@@ -11,9 +10,8 @@ import React, { useCallback } from 'react';
11
10
  import { rem } from '../../../tokens/relative';
12
11
 
13
12
  import { tableRowHeight } from './Table.helpers';
14
- import { useVirtualScrolling } from './Table.hooks';
15
13
  import { useTableRowRenderer } from './TableParts.hooks';
16
- import type { ColumnConfig, TableBodyProps, TableHeaderProps } from './Table.types';
14
+ import type { ColumnConfig, TableBodyProps, TableHeaderProps, VirtualWindow } from './Table.types';
17
15
 
18
16
  // Mirrors the visible sort indicator for assistive technology; undefined when
19
17
  // the column is not sorted, which is what removes the attribute entirely.
@@ -77,7 +75,8 @@ export const EnhancedTableHeader: React.FC<TableHeaderProps> = React.memo(({
77
75
  onSortChange,
78
76
  selectable,
79
77
  selectedRows = [],
80
- onSelectAll }) => {
78
+ onSelectAll,
79
+ headRef }) => {
81
80
  const handleSort = useCallback(
82
81
  (columnKey: string) => {
83
82
  if (!sortable || !onSortChange) return;
@@ -98,7 +97,7 @@ export const EnhancedTableHeader: React.FC<TableHeaderProps> = React.memo(({
98
97
  );
99
98
 
100
99
  return (
101
- <TableHead>
100
+ <TableHead ref={headRef}>
102
101
  <TableRow>
103
102
  {selectable && (
104
103
  <TableCell padding="checkbox">
@@ -205,46 +204,28 @@ export const TableDataRow: React.FC<{
205
204
  };
206
205
 
207
206
  // Only the rows in view are rendered, positioned by absolute offset inside a
208
- // spacer sized to the full data set. `rowHeight`, `containerHeight` and every
209
- // offset are design px, drawn through `rem`.
207
+ // body sized to the full data set. `rowHeight` and every offset are design px,
208
+ // drawn through `rem`. The `<tbody>` sits directly in the `<table>`; the one
209
+ // scroll container wraps the whole table, header included (FUT-2658).
210
210
  const VirtualisedBody: React.FC<{
211
- visibleItems: {
212
- items: Record<string, unknown>[];
213
- startIndex: number;
214
- offsetY: number;
215
- /** As CSS. */
216
- totalHeight: string;
217
- };
211
+ visibleItems: VirtualWindow;
218
212
  rowHeight: number;
219
- containerHeight: number;
220
- onScroll: (event: React.UIEvent<HTMLDivElement>) => void;
221
213
  renderTableRow: (
222
214
  rowData: Record<string, unknown>,
223
215
  index: number,
224
216
  offsetY?: number,
225
217
  ) => React.ReactNode;
226
- }> = ({ visibleItems, rowHeight, containerHeight, onScroll, renderTableRow }) => {
227
- const theme = useTheme();
228
- return (
229
- <Box
230
- onScroll={onScroll}
231
- style={{
232
- height: rem(theme, containerHeight),
233
- overflow: 'auto',
234
- position: 'relative' }}
235
- >
236
- <TableBody
237
- style={{
238
- height: visibleItems.totalHeight,
239
- position: 'relative' }}
240
- >
241
- {visibleItems.items.map((rowData, index) =>
242
- renderTableRow(rowData, visibleItems.startIndex + index, visibleItems.offsetY + index * rowHeight)
243
- )}
244
- </TableBody>
245
- </Box>
246
- );
247
- };
218
+ }> = ({ visibleItems, rowHeight, renderTableRow }) => (
219
+ <TableBody
220
+ style={{
221
+ height: visibleItems.totalHeight,
222
+ position: 'relative' }}
223
+ >
224
+ {visibleItems.items.map((rowData, index) =>
225
+ renderTableRow(rowData, visibleItems.startIndex + index, visibleItems.offsetY + index * rowHeight)
226
+ )}
227
+ </TableBody>
228
+ );
248
229
 
249
230
  const PlainBody: React.FC<{
250
231
  data: TableBodyProps['data'];
@@ -258,26 +239,16 @@ const PlainBody: React.FC<{
258
239
 
259
240
  // Enhanced Table Body Component
260
241
  export const EnhancedTableBody: React.FC<TableBodyProps> = React.memo((props) => {
261
- const { data, virtualScrolling, containerHeight, overscan = 5 } = props;
242
+ const { data, virtualWindow } = props;
262
243
  // The row renderer takes the body's own props; its `rowHeight` stays the
263
244
  // caller's design px, and the row resolves the default where it draws it.
264
245
  const renderTableRow = useTableRowRenderer({ ...props, selectedRows: props.selectedRows ?? [] });
265
- const rowHeight = tableRowHeight(props.rowHeight);
266
-
267
- const { visibleItems, handleScroll } = useVirtualScrolling(
268
- data,
269
- rowHeight || 40,
270
- typeof containerHeight === 'number' ? containerHeight : 400,
271
- overscan
272
- );
273
246
 
274
- if (virtualScrolling && containerHeight && rowHeight) {
247
+ if (virtualWindow) {
275
248
  return (
276
249
  <VirtualisedBody
277
- visibleItems={visibleItems}
278
- rowHeight={rowHeight}
279
- containerHeight={containerHeight}
280
- onScroll={handleScroll}
250
+ visibleItems={virtualWindow}
251
+ rowHeight={tableRowHeight(props.rowHeight)}
281
252
  renderTableRow={renderTableRow}
282
253
  />
283
254
  );
@@ -2,6 +2,7 @@ import type { Theme } from '@mui/material/styles/index.js';
2
2
 
3
3
  import type { WorkflowStepItem, WorkflowStepProps } from './WorkflowStep.types';
4
4
  import { neutralTones } from '../../../tokens/ink';
5
+ import { paletteKey } from '../../../tokens/scales';
5
6
 
6
7
  type StepColor = NonNullable<WorkflowStepProps['color']>;
7
8
  type StepSize = NonNullable<WorkflowStepProps['size']>;
@@ -22,9 +23,15 @@ interface StepPalette {
22
23
  contrastText: string;
23
24
  }
24
25
 
25
- /** `neutral` has no MUI palette entry, so its pair is derived from grey. */
26
+ /**
27
+ * The step's colour pair, keyed through `paletteKey` so `danger` reads MUI's
28
+ * `error` (the palette has no `danger`). `neutral` lands on `grey`, a ramp with
29
+ * no `main`, so its pair is derived from the ramp — with the contrast computed,
30
+ * not assumed.
31
+ */
26
32
  export const stepPalette = (theme: Theme, color?: StepColor): StepPalette => {
27
- if (color === 'neutral') {
33
+ const key = paletteKey(color || 'primary');
34
+ if (key === 'grey') {
28
35
  const main = neutralTones(theme).emphasis;
29
36
  return {
30
37
  main,
@@ -32,7 +39,6 @@ export const stepPalette = (theme: Theme, color?: StepColor): StepPalette => {
32
39
  };
33
40
  }
34
41
 
35
- const key = (color || 'primary') as 'primary' | 'secondary' | 'success' | 'warning' | 'error';
36
42
  return theme.palette[key];
37
43
  };
38
44
 
@@ -167,11 +167,7 @@ const StepConnector = styled(Box, {
167
167
  color: WorkflowStepProps['color'];
168
168
  variant: WorkflowStepProps['variant'];
169
169
  }>(({ theme, orientation, isCompleted, color, variant }) => {
170
- const colorKey = color || 'primary';
171
- const colorValue = colorKey === 'neutral'
172
- ? { main: neutralTones(theme).emphasis }
173
- : theme.palette[colorKey as 'primary' | 'secondary' | 'success' | 'warning' | 'error'];
174
- const connectorColor = isCompleted ? colorValue.main : neutralTones(theme).track;
170
+ const connectorColor = isCompleted ? stepPalette(theme, color).main : neutralTones(theme).track;
175
171
 
176
172
  return {
177
173
  flex: 1,
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/data-display/Table/Table.tsx"],"sourcesContent":["import MoreVertIcon from '@mui/icons-material/MoreVert';\nimport Box from '@mui/material/Box/index.js';\nimport FormControlLabel from '@mui/material/FormControlLabel/index.js';\nimport IconButton from '@mui/material/IconButton/index.js';\nimport Menu from '@mui/material/Menu/index.js';\nimport MenuItem from '@mui/material/MenuItem/index.js';\nimport Skeleton from '@mui/material/Skeleton/index.js';\nimport Switch from '@mui/material/Switch/index.js';\nimport MuiTable from '@mui/material/Table/index.js';\nimport TableBody from '@mui/material/TableBody/index.js';\nimport TableCell from '@mui/material/TableCell/index.js';\nimport TableContainer from '@mui/material/TableContainer/index.js';\nimport TableRow from '@mui/material/TableRow/index.js';\nimport { styled, useTheme, type Theme } from '@mui/material/styles/index.js';\nimport React from 'react';\n\nimport type {\n ColumnConfig,\n TableDensity,\n TableProps,\n TableStripeColor} from './Table.types';\nimport { TABLE_DEFAULTS, definedProps } from './Table.helpers';\nimport { useTableSelection } from './Table.hooks';\nimport { EnhancedTableBody, EnhancedTableHeader } from './TableParts';\nimport { EmptyRow, NoDataPlaceholder } from './TableStates';\nimport {\n tableStyles } from './Table.styles';\nimport { rem } from '../../../tokens/relative';\n\n/** The scroll box's height: a number is design px, 400 unless the caller says otherwise. */\nconst scrollHeight = (theme: Theme, containerHeight: number | string | undefined): string => {\n const box = containerHeight || 400;\n return typeof box === 'number' ? rem(theme, box) : box;\n};\n\n// Define pulse animation\nconst StyledTableContainer = styled(TableContainer, {\n shouldForwardProp: (prop) => !['virtualScrolling', 'containerHeight'].includes(prop as string) })<{ \n virtualScrolling?: boolean; \n containerHeight?: number | string;\n}>(({ theme, virtualScrolling, containerHeight }) => ({\n ...(virtualScrolling && {\n height: scrollHeight(theme, containerHeight),\n overflow: 'auto' }) }));\n\n// Helper function to get stripe color from theme\nconst StyledTable = styled(MuiTable, {\n shouldForwardProp: (prop) =>\n !['customVariant', 'glow', 'pulse', 'hoverable', 'density', 'stickyHeader', 'stripeColor'].includes(prop as string) })<{\n customVariant?: string;\n glow?: boolean;\n pulse?: boolean;\n hoverable?: boolean;\n density?: TableDensity;\n stickyHeader?: boolean;\n stripeColor?: TableStripeColor;\n}>(({ theme, customVariant, glow, pulse, hoverable, density, stickyHeader, stripeColor = 'neutral' }) => {\n return tableStyles({\n theme,\n customVariant,\n glow,\n pulse,\n hoverable,\n density,\n stickyHeader,\n stripeColor });\n});\n\n// Virtual Scrolling Hook\nconst TableShell: React.FC<{\n innerRef: React.Ref<globalThis.HTMLTableElement>;\n variant?: string;\n stripeColor?: TableStripeColor;\n glow?: boolean;\n pulse?: boolean;\n hoverable?: boolean;\n density?: TableDensity;\n stickyHeader?: boolean;\n header: React.ReactNode;\n rest: Record<string, unknown>;\n children: React.ReactNode;\n}> = ({\n innerRef,\n variant,\n stripeColor,\n glow,\n pulse,\n hoverable,\n density,\n stickyHeader,\n header,\n rest,\n children }) => (\n <StyledTableContainer>\n <StyledTable\n ref={innerRef}\n customVariant={variant}\n stripeColor={stripeColor}\n glow={glow}\n pulse={pulse}\n hoverable={hoverable}\n density={density}\n stickyHeader={stickyHeader}\n {...rest}\n >\n {header}\n {children}\n </StyledTable>\n </StyledTableContainer>\n);\n\nconst SKELETON_ROW_COUNT = 5;\n\nconst LoadingSkeletonRows: React.FC<{ columns?: ColumnConfig[] }> = ({ columns }) => {\n const theme = useTheme();\n return (\n <>\n {Array.from({ length: SKELETON_ROW_COUNT }, (_, index) => (\n <TableRow key={index}>\n {columns?.map((column) => (\n <TableCell key={column.key}>\n <Skeleton height={rem(theme, 20)} />\n </TableCell>\n ))}\n </TableRow>\n ))}\n </>\n );\n};\n\nexport type TableShellProps = Omit<React.ComponentProps<typeof TableShell>, 'children'>;\n\ntype Selection = ReturnType<typeof useTableSelection>;\n\ninterface RendererProps {\n resolved: TableProps;\n selection: Selection;\n innerRef: React.Ref<globalThis.HTMLTableElement>;\n rest: Record<string, unknown>;\n}\n\n// The column-visibility control, shown only when responsive mode has actually\n// hidden something on a narrow viewport.\nconst ColumnToggleMenu: React.FC<{\n columns: ColumnConfig[];\n hiddenColumns: number[];\n anchor: HTMLElement | null;\n setAnchor: (element: HTMLElement | null) => void;\n setHiddenColumns: (next: number[]) => void;\n}> = ({ columns, hiddenColumns, anchor, setAnchor, setHiddenColumns }) => (\n <Box position=\"absolute\" top={8} right={8}>\n <IconButton onClick={(event) => setAnchor(event.currentTarget)} size=\"small\">\n <MoreVertIcon />\n </IconButton>\n <Menu anchorEl={anchor} open={Boolean(anchor)} onClose={() => setAnchor(null)}>\n {columns.map((column, index) => (\n <MenuItem key={column.key}>\n <FormControlLabel\n control={\n <Switch\n checked={!hiddenColumns.includes(index)}\n onChange={(event) =>\n setHiddenColumns(\n event.target.checked\n ? hiddenColumns.filter((i: number) => i !== index)\n : [...hiddenColumns, index],\n )\n }\n size=\"small\"\n />\n }\n label={column.label}\n />\n </MenuItem>\n ))}\n </Menu>\n </Box>\n);\n\n// The populated table. Local because StyledTableContainer and StyledTable\n// cannot cross a module boundary (TS2742).\nconst columnsFor = (resolved: TableProps, selection: Selection): ColumnConfig[] =>\n (resolved.responsive ? selection.visibleColumns : resolved.columns) ?? [];\n\n// The toggle only earns its place when responsive mode has actually hidden\n// something on a narrow viewport.\nconst showsColumnToggle = (resolved: TableProps, selection: Selection): boolean =>\n Boolean(\n resolved.responsive &&\n selection.isMobile &&\n resolved.showColumnToggle &&\n selection.hiddenColumns.length > 0,\n );\n\nconst AdvancedTable: React.FC<RendererProps> = ({ resolved: p, selection, innerRef, rest }) => {\n const finalColumns = columnsFor(p, selection);\n const showToggle = showsColumnToggle(p, selection);\n\n return (\n <Box position=\"relative\">\n <StyledTableContainer\n virtualScrolling={p.virtualScrolling}\n containerHeight={p.containerHeight}\n >\n <StyledTable\n ref={innerRef}\n customVariant={p.variant}\n stripeColor={p.stripeColor}\n glow={p.glow}\n pulse={p.pulse}\n hoverable={p.hoverable}\n density={p.density}\n stickyHeader={p.stickyHeader}\n {...rest}\n >\n <EnhancedTableHeader\n columns={finalColumns}\n data={p.data ?? []}\n sortable={p.sortable}\n sortConfig={p.sortConfig}\n onSortChange={p.onSortChange}\n selectable={p.selectable}\n selectedRows={p.selectedRows}\n onSelectAll={selection.handleSelectAll}\n density={p.density}\n stickyHeader={p.stickyHeader}\n />\n <EnhancedTableBody\n data={p.data ?? []}\n columns={finalColumns}\n selectedRows={p.selectedRows}\n onRowClick={p.onRowClick}\n onRowFocus={p.onRowFocus}\n onRowBlur={p.onRowBlur}\n onSelectionChange={selection.handleSelectionChange}\n rowKeyExtractor={p.rowKeyExtractor}\n density={p.density}\n selectable={p.selectable}\n hoverable={p.hoverable}\n renderRow={p.renderRow}\n renderCell={p.renderCell}\n virtualScrolling={p.virtualScrolling}\n containerHeight={typeof p.containerHeight === 'number' ? p.containerHeight : undefined}\n rowHeight={p.rowHeight}\n overscan={p.overscan}\n />\n </StyledTable>\n </StyledTableContainer>\n\n {showToggle && (\n <ColumnToggleMenu\n columns={p.columns ?? []}\n hiddenColumns={selection.hiddenColumns}\n anchor={selection.columnMenuAnchor}\n setAnchor={selection.setColumnMenuAnchor}\n setHiddenColumns={selection.setHiddenColumns}\n />\n )}\n </Box>\n );\n};\n\n// The loading and empty states render the same shell as the populated table, so\n// they share TableShell rather than repeating it three times.\nconst buildShell = ({\n resolved,\n selection,\n innerRef,\n rest,\n finalColumns }: RendererProps & { finalColumns?: ColumnConfig[] }) => ({\n innerRef,\n variant: resolved.variant,\n stripeColor: resolved.stripeColor,\n glow: resolved.glow,\n pulse: resolved.pulse,\n hoverable: resolved.hoverable,\n density: resolved.density,\n stickyHeader: resolved.stickyHeader,\n header: resolved.columns ? (\n <EnhancedTableHeader\n columns={finalColumns ?? []}\n data={[]}\n sortable={resolved.sortable}\n sortConfig={resolved.sortConfig}\n onSortChange={resolved.onSortChange}\n selectable={resolved.selectable}\n selectedRows={resolved.selectedRows}\n onSelectAll={selection.handleSelectAll}\n density={resolved.density}\n stickyHeader={resolved.stickyHeader}\n />\n ) : null,\n rest: rest as Record<string, unknown> });\n\nconst TableLoadingState: React.FC<{\n shell: TableShellProps;\n loadingComponent?: React.ReactNode;\n columns?: ColumnConfig[];\n}> = ({ shell, loadingComponent, columns }) => (\n <TableShell {...shell}>\n <TableBody data-testid=\"table-loading\">\n {loadingComponent || <LoadingSkeletonRows columns={columns} />}\n </TableBody>\n </TableShell>\n);\n\nconst TableEmptyState: React.FC<{\n shell: TableShellProps;\n emptyStateComponent?: React.ReactNode;\n emptyText: string;\n colSpan: number;\n}> = ({ shell, emptyStateComponent, emptyText, colSpan }) => (\n <TableShell {...shell}>\n <EmptyRow colSpan={colSpan}>\n {emptyStateComponent || <NoDataPlaceholder emptyText={emptyText} />}\n </EmptyRow>\n </TableShell>\n);\n\nexport const Table = React.forwardRef<globalThis.HTMLTableElement, TableProps>(\n (tableProps, ref) => {\n const resolved = { ...TABLE_DEFAULTS, ...definedProps(tableProps) } as TableProps;\n const {\n columns,\n data,\n responsive,\n loading,\n loadingComponent,\n emptyStateComponent,\n emptyText,\n children,\n ...props\n } = resolved;\n\n const selection = useTableSelection({\n columns,\n data,\n responsive,\n columnPriorities: resolved.columnPriorities,\n selectedRows: resolved.selectedRows ?? [],\n rowKeyExtractor: resolved.rowKeyExtractor,\n onSelectionChange: resolved.onSelectionChange });\n\n const rest = props as unknown as Record<string, unknown>;\n const renderer: RendererProps = { resolved, selection, innerRef: ref, rest };\n const finalColumns = responsive ? selection.visibleColumns : columns;\n const shell = buildShell({ ...renderer, finalColumns });\n\n if (loading) {\n return (\n <TableLoadingState shell={shell} loadingComponent={loadingComponent} columns={columns} />\n );\n }\n\n if (data && data.length === 0) {\n return (\n <TableEmptyState\n shell={shell}\n emptyStateComponent={emptyStateComponent}\n emptyText={emptyText}\n colSpan={finalColumns?.length || 1}\n />\n );\n }\n\n if (columns && data) return <AdvancedTable {...renderer} />;\n\n // Basic table (backward compatibility)\n return (\n <StyledTable\n ref={ref}\n customVariant={resolved.variant}\n stripeColor={resolved.stripeColor}\n glow={resolved.glow}\n pulse={resolved.pulse}\n hoverable={resolved.hoverable}\n density={resolved.density}\n stickyHeader={resolved.stickyHeader}\n {...rest}\n >\n {children}\n </StyledTable>\n );\n },\n);\n\nTable.displayName = 'Table';"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,kBAAkB;AACzB,OAAO,SAAS;AAChB,OAAO,sBAAsB;AAC7B,OAAO,gBAAgB;AACvB,OAAO,UAAU;AACjB,OAAO,cAAc;AACrB,OAAO,cAAc;AACrB,OAAO,YAAY;AACnB,OAAO,cAAc;AACrB,OAAO,eAAe;AACtB,OAAO,eAAe;AACtB,OAAO,oBAAoB;AAC3B,OAAO,cAAc;AACrB,SAAS,QAAQ,gBAA4B;AAC7C,OAAO,WAAW;AA+EhB,SAuBE,UAvBF,KACE,YADF;AA/DF,IAAM,eAAe,CAAC,OAAc,oBAAyD;AAC3F,QAAM,MAAM,mBAAmB;AAC/B,SAAO,OAAO,QAAQ,WAAW,IAAI,OAAO,GAAG,IAAI;AACrD;AAGA,IAAM,uBAAuB,OAAO,gBAAgB;AAAA,EAClD,mBAAmB,CAAC,SAAS,CAAC,CAAC,oBAAoB,iBAAiB,EAAE,SAAS,IAAc;AAAE,CAAC,EAG/F,CAAC,EAAE,OAAO,kBAAkB,gBAAgB,OAAO;AAAA,EACpD,GAAI,oBAAoB;AAAA,IACtB,QAAQ,aAAa,OAAO,eAAe;AAAA,IAC3C,UAAU;AAAA,EAAO;AAAG,EAAE;AAG1B,IAAM,cAAc,OAAO,UAAU;AAAA,EACnC,mBAAmB,CAAC,SAClB,CAAC,CAAC,iBAAiB,QAAQ,SAAS,aAAa,WAAW,gBAAgB,aAAa,EAAE,SAAS,IAAc;AAAE,CAAC,EAQtH,CAAC,EAAE,OAAO,eAAe,MAAM,OAAO,WAAW,SAAS,cAAc,cAAc,UAAU,MAAM;AACvG,SAAO,YAAY;AAAA,IACjB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAY,CAAC;AACjB,CAAC;AAGD,IAAM,aAYD,CAAC;AAAA,EACJ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAS,MACT,oBAAC,wBACC;AAAA,EAAC;AAAA;AAAA,IACC,KAAK;AAAA,IACL,eAAe;AAAA,IACf;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACC,GAAG;AAAA,IAEH;AAAA;AAAA,MACA;AAAA;AAAA;AACH,GACF;AAGF,IAAM,qBAAqB;AAE3B,IAAM,sBAA8D,CAAC,EAAE,QAAQ,MAAM;AACnF,QAAM,QAAQ,SAAS;AACvB,SACE,gCACG,gBAAM,KAAK,EAAE,QAAQ,mBAAmB,GAAG,CAAC,GAAG,UAC9C,oBAAC,YACE,mBAAS,IAAI,CAAC,WACb,oBAAC,aACC,8BAAC,YAAS,QAAQ,IAAI,OAAO,EAAE,GAAG,KADpB,OAAO,GAEvB,CACD,KALY,KAMf,CACD,GACH;AAEJ;AAeA,IAAM,mBAMD,CAAC,EAAE,SAAS,eAAe,QAAQ,WAAW,iBAAiB,MAClE,qBAAC,OAAI,UAAS,YAAW,KAAK,GAAG,OAAO,GACtC;AAAA,sBAAC,cAAW,SAAS,CAAC,UAAU,UAAU,MAAM,aAAa,GAAG,MAAK,SACnE,8BAAC,gBAAa,GAChB;AAAA,EACA,oBAAC,QAAK,UAAU,QAAQ,MAAM,QAAQ,MAAM,GAAG,SAAS,MAAM,UAAU,IAAI,GACzE,kBAAQ,IAAI,CAAC,QAAQ,UACpB,oBAAC,YACC;AAAA,IAAC;AAAA;AAAA,MACC,SACE;AAAA,QAAC;AAAA;AAAA,UACC,SAAS,CAAC,cAAc,SAAS,KAAK;AAAA,UACtC,UAAU,CAAC,UACT;AAAA,YACE,MAAM,OAAO,UACT,cAAc,OAAO,CAAC,MAAc,MAAM,KAAK,IAC/C,CAAC,GAAG,eAAe,KAAK;AAAA,UAC9B;AAAA,UAEF,MAAK;AAAA;AAAA,MACP;AAAA,MAEF,OAAO,OAAO;AAAA;AAAA,EAChB,KAhBa,OAAO,GAiBtB,CACD,GACH;AAAA,GACF;AAKF,IAAM,aAAa,CAAC,UAAsB,eACvC,SAAS,aAAa,UAAU,iBAAiB,SAAS,YAAY,CAAC;AAI1E,IAAM,oBAAoB,CAAC,UAAsB,cAC/C;AAAA,EACE,SAAS,cACP,UAAU,YACV,SAAS,oBACT,UAAU,cAAc,SAAS;AACrC;AAEF,IAAM,gBAAyC,CAAC,EAAE,UAAU,GAAG,WAAW,UAAU,KAAK,MAAM;AAC7F,QAAM,eAAe,WAAW,GAAG,SAAS;AAC5C,QAAM,aAAa,kBAAkB,GAAG,SAAS;AAEjD,SACE,qBAAC,OAAI,UAAS,YACZ;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,kBAAkB,EAAE;AAAA,QACpB,iBAAiB,EAAE;AAAA,QAEnB;AAAA,UAAC;AAAA;AAAA,YACC,KAAK;AAAA,YACL,eAAe,EAAE;AAAA,YACjB,aAAa,EAAE;AAAA,YACf,MAAM,EAAE;AAAA,YACR,OAAO,EAAE;AAAA,YACT,WAAW,EAAE;AAAA,YACb,SAAS,EAAE;AAAA,YACX,cAAc,EAAE;AAAA,YACf,GAAG;AAAA,YAEJ;AAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,SAAS;AAAA,kBACT,MAAM,EAAE,QAAQ,CAAC;AAAA,kBACjB,UAAU,EAAE;AAAA,kBACZ,YAAY,EAAE;AAAA,kBACd,cAAc,EAAE;AAAA,kBAChB,YAAY,EAAE;AAAA,kBACd,cAAc,EAAE;AAAA,kBAChB,aAAa,UAAU;AAAA,kBACvB,SAAS,EAAE;AAAA,kBACX,cAAc,EAAE;AAAA;AAAA,cAClB;AAAA,cACA;AAAA,gBAAC;AAAA;AAAA,kBACC,MAAM,EAAE,QAAQ,CAAC;AAAA,kBACjB,SAAS;AAAA,kBACT,cAAc,EAAE;AAAA,kBAChB,YAAY,EAAE;AAAA,kBACd,YAAY,EAAE;AAAA,kBACd,WAAW,EAAE;AAAA,kBACb,mBAAmB,UAAU;AAAA,kBAC7B,iBAAiB,EAAE;AAAA,kBACnB,SAAS,EAAE;AAAA,kBACX,YAAY,EAAE;AAAA,kBACd,WAAW,EAAE;AAAA,kBACb,WAAW,EAAE;AAAA,kBACb,YAAY,EAAE;AAAA,kBACd,kBAAkB,EAAE;AAAA,kBACpB,iBAAiB,OAAO,EAAE,oBAAoB,WAAW,EAAE,kBAAkB;AAAA,kBAC7E,WAAW,EAAE;AAAA,kBACb,UAAU,EAAE;AAAA;AAAA,cACd;AAAA;AAAA;AAAA,QACF;AAAA;AAAA,IACF;AAAA,IAEC,cACC;AAAA,MAAC;AAAA;AAAA,QACC,SAAS,EAAE,WAAW,CAAC;AAAA,QACvB,eAAe,UAAU;AAAA,QACzB,QAAQ,UAAU;AAAA,QAClB,WAAW,UAAU;AAAA,QACrB,kBAAkB,UAAU;AAAA;AAAA,IAC9B;AAAA,KAEJ;AAEJ;AAIA,IAAM,aAAa,CAAC;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAa,OAA0D;AAAA,EACvE;AAAA,EACA,SAAS,SAAS;AAAA,EAClB,aAAa,SAAS;AAAA,EACtB,MAAM,SAAS;AAAA,EACf,OAAO,SAAS;AAAA,EAChB,WAAW,SAAS;AAAA,EACpB,SAAS,SAAS;AAAA,EAClB,cAAc,SAAS;AAAA,EACvB,QAAQ,SAAS,UACf;AAAA,IAAC;AAAA;AAAA,MACC,SAAS,gBAAgB,CAAC;AAAA,MAC1B,MAAM,CAAC;AAAA,MACP,UAAU,SAAS;AAAA,MACnB,YAAY,SAAS;AAAA,MACrB,cAAc,SAAS;AAAA,MACvB,YAAY,SAAS;AAAA,MACrB,cAAc,SAAS;AAAA,MACvB,aAAa,UAAU;AAAA,MACvB,SAAS,SAAS;AAAA,MAClB,cAAc,SAAS;AAAA;AAAA,EACzB,IACE;AAAA,EACJ;AAAsC;AAExC,IAAM,oBAID,CAAC,EAAE,OAAO,kBAAkB,QAAQ,MACvC,oBAAC,cAAY,GAAG,OACd,8BAAC,aAAU,eAAY,iBACpB,8BAAoB,oBAAC,uBAAoB,SAAkB,GAC9D,GACF;AAGF,IAAM,kBAKD,CAAC,EAAE,OAAO,qBAAqB,WAAW,QAAQ,MACrD,oBAAC,cAAY,GAAG,OACd,8BAAC,YAAS,SACP,iCAAuB,oBAAC,qBAAkB,WAAsB,GACnE,GACF;AAGK,IAAM,QAAQ,MAAM;AAAA,EACzB,CAAC,YAAY,QAAQ;AACnB,UAAM,WAAW,EAAE,GAAG,gBAAgB,GAAG,aAAa,UAAU,EAAE;AAClE,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAG;AAAA,IACL,IAAI;AAEJ,UAAM,YAAY,kBAAkB;AAAA,MAClC;AAAA,MACA;AAAA,MACA;AAAA,MACA,kBAAkB,SAAS;AAAA,MAC3B,cAAc,SAAS,gBAAgB,CAAC;AAAA,MACxC,iBAAiB,SAAS;AAAA,MAC1B,mBAAmB,SAAS;AAAA,IAAkB,CAAC;AAEjD,UAAM,OAAO;AACb,UAAM,WAA0B,EAAE,UAAU,WAAW,UAAU,KAAK,KAAK;AAC3E,UAAM,eAAe,aAAa,UAAU,iBAAiB;AAC7D,UAAM,QAAQ,WAAW,EAAE,GAAG,UAAU,aAAa,CAAC;AAEtD,QAAI,SAAS;AACX,aACE,oBAAC,qBAAkB,OAAc,kBAAoC,SAAkB;AAAA,IAE3F;AAEA,QAAI,QAAQ,KAAK,WAAW,GAAG;AAC7B,aACE;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA;AAAA,UACA;AAAA,UACA,SAAS,cAAc,UAAU;AAAA;AAAA,MACnC;AAAA,IAEJ;AAEA,QAAI,WAAW,KAAM,QAAO,oBAAC,iBAAe,GAAG,UAAU;AAGzD,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,eAAe,SAAS;AAAA,QACxB,aAAa,SAAS;AAAA,QACtB,MAAM,SAAS;AAAA,QACf,OAAO,SAAS;AAAA,QAChB,WAAW,SAAS;AAAA,QACpB,SAAS,SAAS;AAAA,QAClB,cAAc,SAAS;AAAA,QACtB,GAAG;AAAA,QAEH;AAAA;AAAA,IACH;AAAA,EAEJ;AACF;AAEA,MAAM,cAAc;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/data-display/Table/TableParts.hooks.tsx","../src/components/data-display/Table/TableParts.tsx"],"sourcesContent":["import type React from 'react';\nimport { useCallback } from 'react';\n\nimport { TableDataRow } from './TableParts';\nimport type { TableBodyProps } from './Table.types';\n\n// Row identity, selection and the row element itself. Split out of\n// EnhancedTableBody so that component is just the virtualised/plain choice.\n// A row's identity: the caller's extractor, else its id, else its position.\nconst useRowKey = (rowKeyExtractor: TableBodyProps['rowKeyExtractor']) =>\n useCallback(\n (rowData: Record<string, unknown>, index: number): string | number =>\n rowKeyExtractor ? rowKeyExtractor(rowData, index) : (rowData.id as string | number) || index,\n [rowKeyExtractor],\n );\n\nconst useRowSelection = ({\n selectedRows,\n onSelectionChange,\n}: {\n selectedRows: Array<string | number>;\n onSelectionChange: TableBodyProps['onSelectionChange'];\n}) =>\n useCallback(\n (event: React.MouseEvent | React.ChangeEvent, rowKey: string | number) => {\n // Stop propagation so selecting does not also fire the row click.\n event.stopPropagation();\n if (!onSelectionChange) return;\n onSelectionChange(rowKey, !selectedRows.includes(rowKey));\n },\n [onSelectionChange, selectedRows],\n );\n\nexport const useTableRowRenderer = ({\n columns,\n selectedRows,\n onRowClick,\n onRowFocus,\n onRowBlur,\n onSelectionChange,\n rowKeyExtractor,\n selectable,\n renderRow,\n renderCell,\n virtualScrolling,\n rowHeight,\n}: Pick<\n TableBodyProps,\n | 'columns'\n | 'onRowClick'\n | 'onRowFocus'\n | 'onRowBlur'\n | 'onSelectionChange'\n | 'rowKeyExtractor'\n | 'selectable'\n | 'renderRow'\n | 'renderCell'\n | 'virtualScrolling'\n | 'rowHeight'\n> & { selectedRows: Array<string | number> }) => {\n const getRowKey = useRowKey(rowKeyExtractor);\n const isRowSelected = useCallback(\n (rowKey: string | number) => selectedRows.includes(rowKey),\n [selectedRows],\n );\n const handleRowSelection = useRowSelection({ selectedRows, onSelectionChange });\n\n const renderTableRow = useCallback(\n (rowData: Record<string, unknown>, index: number, offsetY: number = 0) => {\n const rowKey = getRowKey(rowData, index);\n const selected = isRowSelected(rowKey);\n\n if (renderRow) return renderRow(rowData, index, selected);\n\n return (\n <TableDataRow\n key={rowKey}\n rowData={rowData}\n rowKey={rowKey}\n index={index}\n offsetY={offsetY}\n columns={columns}\n selected={selected}\n selectable={selectable}\n rowHeight={rowHeight}\n onRowClick={onRowClick}\n onRowFocus={onRowFocus}\n onRowBlur={onRowBlur}\n onSelect={handleRowSelection}\n virtualScrolling={virtualScrolling}\n renderCell={renderCell}\n />\n );\n },\n [\n columns,\n getRowKey,\n isRowSelected,\n handleRowSelection,\n onRowClick,\n onRowFocus,\n onRowBlur,\n renderRow,\n renderCell,\n rowHeight,\n selectable,\n virtualScrolling,\n ],\n );\n\n return renderTableRow;\n};\n","import Box from '@mui/material/Box/index.js';\nimport Checkbox from '@mui/material/Checkbox/index.js';\nimport TableBody from '@mui/material/TableBody/index.js';\nimport TableCell from '@mui/material/TableCell/index.js';\nimport TableHead from '@mui/material/TableHead/index.js';\nimport TableRow from '@mui/material/TableRow/index.js';\nimport TableSortLabel from '@mui/material/TableSortLabel/index.js';\nimport { useTheme, type Theme } from '@mui/material/styles/index.js';\nimport React, { useCallback } from 'react';\n\nimport { rem } from '../../../tokens/relative';\n\nimport { tableRowHeight } from './Table.helpers';\nimport { useVirtualScrolling } from './Table.hooks';\nimport { useTableRowRenderer } from './TableParts.hooks';\nimport type { ColumnConfig, TableBodyProps, TableHeaderProps } from './Table.types';\n\n// Mirrors the visible sort indicator for assistive technology; undefined when\n// the column is not sorted, which is what removes the attribute entirely.\nconst ariaSortFor = (\n canSort: boolean,\n isSorted: boolean,\n direction?: 'asc' | 'desc',\n): 'ascending' | 'descending' | undefined => {\n if (!canSort || !isSorted) return undefined;\n\n return direction === 'asc' ? 'ascending' : 'descending';\n};\n\n/** A column's `width`/`minWidth` as CSS: a number is design px, a string as given. */\nconst columnLength = (theme: Theme, value: number | string | undefined): string | undefined =>\n typeof value === 'number' ? rem(theme, value) : value;\n\n// One header cell. Sorting is offered when the table is sortable and the column\n// has not opted out; aria-sort mirrors the visible indicator.\nconst HeaderCell: React.FC<{\n column: ColumnConfig;\n sortable?: boolean;\n sortConfig?: { key: string; direction: 'asc' | 'desc' };\n onSort: (columnKey: string) => void;\n}> = ({ column, sortable, sortConfig, onSort }) => {\n const theme = useTheme();\n const canSort = Boolean(sortable) && column.sortable !== false;\n const isSorted = sortConfig?.key === column.key;\n\n return (\n <TableCell\n align={column.align || 'left'}\n style={{\n minWidth: columnLength(theme, column.minWidth),\n width: columnLength(theme, column.width),\n }}\n aria-sort={ariaSortFor(canSort, isSorted, sortConfig?.direction)}\n >\n {canSort ? (\n <TableSortLabel\n active={isSorted}\n direction={isSorted ? sortConfig?.direction : 'asc'}\n onClick={() => onSort(column.key)}\n data-testid=\"sort-indicator\"\n aria-label={`Sort by ${column.label}`}\n >\n {column.label}\n </TableSortLabel>\n ) : (\n column.label\n )}\n </TableCell>\n );\n};\n\nexport const EnhancedTableHeader: React.FC<TableHeaderProps> = React.memo(({\n columns,\n data,\n sortable,\n sortConfig,\n onSortChange,\n selectable,\n selectedRows = [],\n onSelectAll }) => {\n const handleSort = useCallback(\n (columnKey: string) => {\n if (!sortable || !onSortChange) return;\n \n const direction = \n sortConfig?.key === columnKey && sortConfig.direction === 'asc' ? 'desc' : 'asc';\n onSortChange(columnKey, direction);\n },\n [sortable, onSortChange, sortConfig]\n );\n\n const handleSelectAll = useCallback(\n (event: React.ChangeEvent<globalThis.HTMLInputElement>) => {\n if (!onSelectAll) return;\n onSelectAll(event.target.checked);\n },\n [onSelectAll]\n );\n\n return (\n <TableHead>\n <TableRow>\n {selectable && (\n <TableCell padding=\"checkbox\">\n <Checkbox\n indeterminate={selectedRows.length > 0 && selectedRows.length < data.length}\n checked={selectedRows.length === data.length && data.length > 0}\n onChange={handleSelectAll}\n inputProps={{ 'aria-label': 'select all' }}\n />\n </TableCell>\n )}\n {columns.map((column) => (\n <HeaderCell\n key={column.key}\n column={column}\n sortable={sortable}\n sortConfig={sortConfig}\n onSort={handleSort}\n />\n ))}\n </TableRow>\n </TableHead>\n );\n});\n\nEnhancedTableHeader.displayName = 'EnhancedTableHeader';\n\n// One data row. Split out of the memoised renderTableRow callback so the\n// callback stays a short dispatch and the row markup is readable on its own.\nexport const TableDataRow: React.FC<{\n rowData: Record<string, unknown>;\n rowKey: string | number;\n index: number;\n /** Where a virtualised row sits, in design px — drawn through `rem`, like its height. */\n offsetY: number;\n columns: ColumnConfig[];\n selected: boolean;\n selectable?: boolean;\n /** Design px; 52 when unset (`tableRowHeight`). */\n rowHeight?: number;\n onRowClick?: TableBodyProps['onRowClick'];\n onRowFocus?: TableBodyProps['onRowFocus'];\n onRowBlur?: TableBodyProps['onRowBlur'];\n onSelect: (event: React.MouseEvent | React.ChangeEvent, rowKey: string | number) => void;\n virtualScrolling?: boolean;\n renderCell?: TableBodyProps['renderCell'];\n}> = ({\n rowData,\n rowKey,\n index,\n offsetY,\n columns,\n selected,\n selectable,\n rowHeight,\n onRowClick,\n onRowFocus,\n onRowBlur,\n onSelect,\n virtualScrolling,\n renderCell }) => {\n const theme = useTheme();\n return (\n <TableRow\n key={String(rowKey)}\n selected={selected}\n className={selected ? 'selected' : ''}\n onClick={(event: React.MouseEvent<globalThis.HTMLTableRowElement>) => onRowClick?.(event, rowData)}\n onFocus={(event: React.FocusEvent<globalThis.HTMLTableRowElement>) => onRowFocus?.(event, rowData)}\n onBlur={(event: React.FocusEvent<globalThis.HTMLTableRowElement>) => onRowBlur?.(event, rowData)}\n style={virtualScrolling ? { \n transform: `translateY(${rem(theme, offsetY)})`,\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n height: rem(theme, tableRowHeight(rowHeight)) } : undefined}\n >\n {selectable && (\n <TableCell padding=\"checkbox\">\n <Checkbox\n checked={selected}\n onChange={(event) => onSelect(event, rowKey)}\n onClick={(event) => event.stopPropagation()}\n inputProps={{ 'aria-label': `select row ${index + 1}` }}\n />\n </TableCell>\n )}\n {columns.map((column) => {\n const value = rowData[column.key];\n return (\n <TableCell key={column.key} align={column.align || 'left'}>\n {renderCell \n ? renderCell(value, column, rowData, index)\n : column.render \n ? column.render(value, rowData) \n : (value as React.ReactNode)\n }\n </TableCell>\n );\n })}\n </TableRow>\n );\n};\n\n// Only the rows in view are rendered, positioned by absolute offset inside a\n// spacer sized to the full data set. `rowHeight`, `containerHeight` and every\n// offset are design px, drawn through `rem`.\nconst VirtualisedBody: React.FC<{\n visibleItems: {\n items: Record<string, unknown>[];\n startIndex: number;\n offsetY: number;\n /** As CSS. */\n totalHeight: string;\n };\n rowHeight: number;\n containerHeight: number;\n onScroll: (event: React.UIEvent<HTMLDivElement>) => void;\n renderTableRow: (\n rowData: Record<string, unknown>,\n index: number,\n offsetY?: number,\n ) => React.ReactNode;\n}> = ({ visibleItems, rowHeight, containerHeight, onScroll, renderTableRow }) => {\n const theme = useTheme();\n return (\n <Box\n onScroll={onScroll}\n style={{\n height: rem(theme, containerHeight),\n overflow: 'auto',\n position: 'relative' }}\n >\n <TableBody\n style={{\n height: visibleItems.totalHeight,\n position: 'relative' }}\n >\n {visibleItems.items.map((rowData, index) => \n renderTableRow(rowData, visibleItems.startIndex + index, visibleItems.offsetY + index * rowHeight)\n )}\n </TableBody>\n </Box>\n );\n};\n\nconst PlainBody: React.FC<{\n data: TableBodyProps['data'];\n renderTableRow: (rowData: Record<string, unknown>, index: number) => React.ReactNode;\n}> = ({ data, renderTableRow }) => (\n\n <TableBody>\n {data.map((rowData, index) => renderTableRow(rowData, index))}\n </TableBody>\n);\n\n// Enhanced Table Body Component \nexport const EnhancedTableBody: React.FC<TableBodyProps> = React.memo((props) => {\n const { data, virtualScrolling, containerHeight, overscan = 5 } = props;\n // The row renderer takes the body's own props; its `rowHeight` stays the\n // caller's design px, and the row resolves the default where it draws it.\n const renderTableRow = useTableRowRenderer({ ...props, selectedRows: props.selectedRows ?? [] });\n const rowHeight = tableRowHeight(props.rowHeight);\n\n const { visibleItems, handleScroll } = useVirtualScrolling(\n data, \n rowHeight || 40, \n typeof containerHeight === 'number' ? containerHeight : 400, \n overscan\n );\n\n if (virtualScrolling && containerHeight && rowHeight) {\n return (\n <VirtualisedBody\n visibleItems={visibleItems}\n rowHeight={rowHeight}\n containerHeight={containerHeight}\n onScroll={handleScroll}\n renderTableRow={renderTableRow}\n />\n );\n }\n\n return (\n <PlainBody data={data} renderTableRow={renderTableRow} />\n );\n});\n\nEnhancedTableBody.displayName = 'EnhancedTableBody';\n\n// Main Table Component\n"],"mappings":"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","names":["useCallback","jsx","useCallback"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/data-display/LazyImage/LazyImage.tsx"],"sourcesContent":["import Box from '@mui/material/Box/index.js';\nimport CircularProgress from '@mui/material/CircularProgress/index.js';\nimport { styled, useTheme, type Theme } from '@mui/material/styles/index.js';\nimport React from 'react';\nimport { Skeleton } from '../../layout/Skeleton';\nimport type { ResolvedLazyImageProps } from './LazyImage.hooks';\nimport { imgPassThrough, resolveLazyImageProps, useLazyImage } from './LazyImage.hooks';\nimport type { LazyImageProps } from './LazyImage.types';\nimport { sheen } from '../../../tokens/ink';\nimport { rem } from '../../../tokens/relative';\n\nconst ImageContainer = styled(Box)(() => ({\n position: 'relative',\n display: 'inline-block',\n overflow: 'hidden',\n}));\n\nconst StyledImage = styled('img')<{\n fadeIn?: boolean;\n fadeInDuration?: number;\n isLoaded?: boolean;\n}>(({ fadeIn, fadeInDuration = 300, isLoaded }) => ({\n display: 'block',\n maxWidth: '100%',\n height: 'auto',\n opacity: fadeIn ? (isLoaded ? 1 : 0) : 1,\n transition: fadeIn ? `opacity ${fadeInDuration}ms ease-in-out` : 'none',\n}));\n\nconst SpinnerOverlay = styled(Box)(({ theme }) => ({\n position: 'absolute',\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: sheen(theme, 0.8),\n borderRadius: '50%',\n padding: theme.spacing(1),\n}));\n\nconst FallbackContainer = styled(Box)(({ theme }) => ({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: theme.palette.action.disabledBackground,\n color: theme.palette.text.secondary,\n width: '100%',\n height: '100%',\n position: 'absolute',\n top: 0,\n left: 0,\n}));\n\ntype Length = number | string | undefined;\n\n/** A length prop as React `style` and MUI's `Skeleton` read it: a number is design px. */\nconst styleLength = (theme: Theme, value: Length): string | undefined =>\n typeof value === 'number' ? rem(theme, value) : value;\n\n/**\n * A length prop as `sx` reads it on a width or height: a number of 1 or less is\n * a fraction of the parent, and that stays so; any other number is design px.\n */\nconst sxLength = (theme: Theme, value: Length): string | undefined => {\n if (typeof value !== 'number') return value;\n return value <= 1 && value !== 0 ? `${value * 100}%` : rem(theme, value);\n};\n\n/** The box the image occupies, as CSS, shared by the real image and every stand-in for it. */\ninterface BoxMetrics {\n width?: string;\n height?: string;\n objectFit: NonNullable<LazyImageProps['objectFit']>;\n objectPosition: string;\n borderRadius?: string;\n}\n\ninterface IndicatorProps {\n props: ResolvedLazyImageProps;\n metrics: BoxMetrics;\n}\n\nconst SkeletonIndicator: React.FC<IndicatorProps> = ({ props }) => {\n const theme = useTheme();\n return (\n <Skeleton\n variant=\"rectangular\"\n width={styleLength(theme, props.width || '100%')}\n height={styleLength(theme, props.height || 200)}\n animation={props.skeletonProps.animation || 'pulse'}\n intensity={props.skeletonProps.intensity}\n borderRadius={styleLength(theme, props.borderRadius)}\n data-testid={`${props['data-testid']}-skeleton`}\n />\n );\n};\n\nconst SpinnerIndicator: React.FC<IndicatorProps> = ({ props }) => {\n const theme = useTheme();\n const { spinnerProps } = props;\n\n return (\n <SpinnerOverlay>\n <CircularProgress\n size={styleLength(theme, spinnerProps.size || 40)}\n thickness={spinnerProps.thickness || 4}\n sx={{ color: spinnerProps.color || theme.palette.primary.main }}\n data-testid={`${props['data-testid']}-spinner`}\n />\n </SpinnerOverlay>\n );\n};\n\nconst PlaceholderIndicator: React.FC<IndicatorProps & { hasSrc: boolean }> = ({\n props,\n metrics,\n hasSrc,\n}) => {\n // Once a src has been chosen the real <img> is on screen, so the placeholder\n // would only stack behind it.\n if (!props.placeholder || hasSrc) return null;\n\n return (\n <StyledImage\n src={props.placeholder}\n alt={`${props.alt} (loading)`}\n style={metrics}\n data-testid={`${props['data-testid']}-placeholder`}\n />\n );\n};\n\nconst LoadingIndicator: React.FC<\n IndicatorProps & { kind: NonNullable<LazyImageProps['loadingState']>; hasSrc: boolean }\n> = ({ kind, hasSrc, ...rest }) => {\n switch (kind) {\n case 'skeleton':\n return <SkeletonIndicator {...rest} />;\n case 'spinner':\n return <SpinnerIndicator {...rest} />;\n case 'placeholder':\n return <PlaceholderIndicator {...rest} hasSrc={hasSrc} />;\n default:\n return null;\n }\n};\n\nconst ErrorFallback: React.FC<IndicatorProps> = ({ props, metrics }) => {\n const theme = useTheme();\n const { alt, fallback, width, height, borderRadius } = props;\n const testId = props['data-testid'];\n\n if (!fallback) return null;\n\n if (typeof fallback === 'string') {\n return (\n <StyledImage\n src={fallback}\n alt={`${alt} (fallback)`}\n style={metrics}\n fadeIn={false}\n isLoaded={true}\n data-testid={`${testId}-fallback`}\n />\n );\n }\n\n return (\n <FallbackContainer\n sx={{ width: sxLength(theme, width), height: sxLength(theme, height), borderRadius: styleLength(theme, borderRadius) }}\n data-testid={`${testId}-fallback`}\n >\n {fallback}\n </FallbackContainer>\n );\n};\n\n/**\n * LazyImage component with enhanced features for optimized image loading\n * Supports lazy loading, placeholders, error handling, and various loading states\n */\nexport const LazyImage = React.memo<LazyImageProps>(function LazyImage(rawProps) {\n const props = resolveLazyImageProps(rawProps);\n const theme = useTheme();\n const {\n state,\n containerRef,\n effectiveLoadingState,\n handleImageLoad,\n handleImageError,\n showImage,\n showLoading,\n } = useLazyImage(props);\n\n const { width, height, borderRadius, alt } = props;\n const testId = props['data-testid'];\n const metrics: BoxMetrics = {\n width: styleLength(theme, width),\n height: styleLength(theme, height),\n objectFit: props.objectFit,\n objectPosition: props.objectPosition,\n borderRadius: styleLength(theme, borderRadius),\n };\n\n return (\n <ImageContainer\n ref={containerRef}\n className={props.className}\n sx={{\n width: sxLength(theme, width || 'auto'),\n height: sxLength(theme, height || 'auto'),\n // The same px length the image gets (`metrics`): in `sx` a bare number\n // would be a multiple of `shape.borderRadius`, and this box clips (FUT-2656).\n borderRadius: metrics.borderRadius,\n }}\n data-testid={testId}\n >\n {showLoading && (\n <LoadingIndicator\n kind={effectiveLoadingState}\n props={props}\n metrics={metrics}\n hasSrc={Boolean(state.currentSrc)}\n />\n )}\n\n {showImage && (\n <StyledImage\n src={state.currentSrc || undefined}\n alt={alt}\n onLoad={handleImageLoad}\n onError={handleImageError}\n fadeIn={props.fadeIn}\n fadeInDuration={props.fadeInDuration}\n isLoaded={!state.isLoading}\n decoding={props.decoding}\n loading={props.lazy ? 'lazy' : props.loading}\n style={{ ...metrics, ...props.sx }}\n aria-label={props['aria-label'] || alt}\n aria-describedby={props['aria-describedby']}\n role={props.role}\n data-testid={`${testId}-img`}\n {...imgPassThrough(props)}\n />\n )}\n\n {state.hasError && <ErrorFallback props={props} metrics={metrics} />}\n </ImageContainer>\n );\n});\n\nLazyImage.displayName = 'LazyImage';\n"],"mappings":"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","names":["LazyImage"]}
@@ -1,29 +0,0 @@
1
- // src/components/data-display/Table/Table.helpers.ts
2
- var tableRowHeight = (rowHeight) => rowHeight ?? 52;
3
- var TABLE_DEFAULTS = {
4
- variant: "default",
5
- stripeColor: "neutral",
6
- glow: false,
7
- pulse: false,
8
- hoverable: false,
9
- loading: false,
10
- density: "normal",
11
- stickyHeader: false,
12
- selectable: false,
13
- selectedRows: [],
14
- sortable: false,
15
- virtualScrolling: false,
16
- overscan: 5,
17
- responsive: false,
18
- showColumnToggle: true
19
- };
20
- var definedProps = (props) => Object.fromEntries(
21
- Object.entries(props).filter(([, value]) => value !== void 0)
22
- );
23
-
24
- export {
25
- tableRowHeight,
26
- TABLE_DEFAULTS,
27
- definedProps
28
- };
29
- //# sourceMappingURL=chunk-JWZJSXI5.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/data-display/Table/Table.helpers.ts"],"sourcesContent":["import type { TableProps } from './Table.types';\n\n/**\n * A virtualised row's height in design px: the caller's `rowHeight`, else 52.\n * Resolved here rather than in {@link TABLE_DEFAULTS} so the one number is read\n * where it is drawn (`rem`) and where the window is positioned with it (`remPx`).\n */\nexport const tableRowHeight = (rowHeight: number | undefined): number => rowHeight ?? 52;\n\nexport const TABLE_DEFAULTS: Partial<TableProps> = {\n variant: 'default',\n stripeColor: 'neutral',\n glow: false,\n pulse: false,\n hoverable: false,\n loading: false,\n density: 'normal',\n stickyHeader: false,\n selectable: false,\n selectedRows: [],\n sortable: false,\n virtualScrolling: false,\n overscan: 5,\n responsive: false,\n showColumnToggle: true,\n};\n\n// Strips explicitly-undefined props before the merge, so `prop={undefined}` still\n// falls back to the default as a destructuring default would. Eighteen separate\n// destructuring defaults were most of this component's branch count.\nexport const definedProps = (props: TableProps): Partial<TableProps> =>\n Object.fromEntries(\n Object.entries(props).filter(([, value]) => value !== undefined),\n ) as Partial<TableProps>;\n\n// The container + styled table + optional header, shared by the loading, empty\n// and populated renders.\n"],"mappings":";AAOO,IAAM,iBAAiB,CAAC,cAA0C,aAAa;AAE/E,IAAM,iBAAsC;AAAA,EACjD,SAAS;AAAA,EACT,aAAa;AAAA,EACb,MAAM;AAAA,EACN,OAAO;AAAA,EACP,WAAW;AAAA,EACX,SAAS;AAAA,EACT,SAAS;AAAA,EACT,cAAc;AAAA,EACd,YAAY;AAAA,EACZ,cAAc,CAAC;AAAA,EACf,UAAU;AAAA,EACV,kBAAkB;AAAA,EAClB,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,kBAAkB;AACpB;AAKO,IAAM,eAAe,CAAC,UAC3B,OAAO;AAAA,EACL,OAAO,QAAQ,KAAK,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,MAAM,UAAU,MAAS;AACjE;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/utility/WorkflowStep/WorkflowStep.parts.tsx"],"sourcesContent":["import Box from '@mui/material/Box/index.js';\nimport type { CSSObject, Theme } from '@mui/material/styles/index.js';\nimport { styled } from '@mui/material/styles/index.js';\nimport React, { forwardRef, useCallback } from 'react';\n\nimport type { StepColors } from './WorkflowStep.helpers';\nimport { indicatorSizeFor, stepColors, stepPalette } from './WorkflowStep.helpers';\nimport type {\n StepConnectorProps,\n StepContentProps,\n StepIndicatorProps,\n WorkflowStepProps,\n} from './WorkflowStep.types';\nimport { neutralTones } from '../../../tokens/ink';\nimport { rem } from '../../../tokens/relative';\n\n// `outlined` shows the surface through a coloured rim; the other three fill it and\n// differ only in what border they keep.\nconst indicatorVariantStyles = (\n theme: Theme,\n variant: WorkflowStepProps['variant'],\n { backgroundColor, borderColor, textColor }: StepColors,\n): CSSObject => {\n if (variant === 'outlined') {\n return {\n border: `${rem(theme, 2)} solid ${borderColor}`,\n backgroundColor: theme.palette.background.paper,\n };\n }\n\n const filled = { backgroundColor, color: textColor };\n\n switch (variant) {\n case 'filled':\n return filled;\n case 'minimal':\n return { ...filled, border: 'none' };\n case 'default':\n return { ...filled, border: `1px solid ${borderColor}` };\n default:\n return {};\n }\n};\n\nconst StepItem = styled(Box, {\n shouldForwardProp: (prop) => !['orientation', 'isLast'].includes(prop as string),\n})<{\n orientation: WorkflowStepProps['orientation'];\n isLast: boolean;\n}>(({ orientation, isLast }) => ({\n display: 'flex',\n flexDirection: orientation === 'vertical' ? 'column' : 'row',\n alignItems: orientation === 'vertical' ? 'flex-start' : 'center',\n flex: orientation === 'horizontal' && !isLast ? 1 : 'none',\n position: 'relative',\n minWidth: 0, // Allow content to shrink\n}));\n\nconst StepIndicator = styled(Box, {\n shouldForwardProp: (prop) => !['size', 'variant', 'color', 'isActive', 'isCompleted', 'isError', 'interactive', 'disabled'].includes(prop as string),\n})<{\n size: WorkflowStepProps['size'];\n variant: WorkflowStepProps['variant'];\n color: WorkflowStepProps['color'];\n isActive: boolean;\n isCompleted: boolean;\n isError: boolean;\n interactive: boolean;\n animated: boolean;\n disabled: boolean;\n}>(({ theme, size, variant, color, isActive, isCompleted, isError, interactive, animated, disabled }) => {\n const indicatorSize = indicatorSizeFor(size);\n const palette = stepPalette(theme, color);\n const { backgroundColor, borderColor, textColor } = stepColors(theme, palette, {\n isActive,\n isCompleted,\n isError,\n variant,\n });\n\n return {\n width: rem(theme, indicatorSize),\n height: rem(theme, indicatorSize),\n borderRadius: '50%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: rem(theme, 12),\n fontWeight: theme.typography.fontWeightMedium,\n cursor: interactive && !disabled ? 'pointer' : 'default',\n transition: animated\n ? theme.transitions.create(['background-color', 'border-color', 'transform'], {\n duration: theme.transitions.duration.short,\n })\n : 'none',\n flexShrink: 0,\n\n ...indicatorVariantStyles(theme, variant, { backgroundColor, borderColor, textColor }),\n\n // Interactive states\n ...(interactive && !disabled && {\n '&:hover': {\n transform: 'scale(1.1)',\n boxShadow: theme.shadows[2],\n },\n '&:focus-visible': {\n outline: `${rem(theme, 2)} solid ${palette.main}`,\n outlineOffset: rem(theme, 2),\n },\n }),\n\n // Disabled state\n ...(disabled && {\n opacity: 0.5,\n cursor: 'not-allowed',\n }),\n };\n});\n\nconst StepContent = styled(Box, {\n shouldForwardProp: (prop) => !['orientation', 'interactive', 'disabled'].includes(prop as string),\n})<{\n orientation: WorkflowStepProps['orientation'];\n interactive: boolean;\n disabled: boolean;\n}>(({ theme, orientation, interactive, disabled }) => ({\n display: 'flex',\n flexDirection: 'column',\n alignItems: orientation === 'vertical' ? 'flex-start' : 'center',\n textAlign: orientation === 'vertical' ? 'left' : 'center',\n marginTop: orientation === 'vertical' ? theme.spacing(1) : theme.spacing(0.5),\n marginLeft: orientation === 'horizontal' ? theme.spacing(1) : 0,\n cursor: interactive && !disabled ? 'pointer' : 'default',\n minWidth: 0,\n flex: 1,\n\n '& .step-title': {\n fontSize: rem(theme, 14),\n fontWeight: theme.typography.fontWeightMedium,\n color: theme.palette.text.primary,\n marginBottom: theme.spacing(0.5),\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n maxWidth: '100%',\n },\n\n '& .step-description': {\n fontSize: rem(theme, 12),\n color: theme.palette.text.secondary,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n maxWidth: '100%',\n },\n\n ...(disabled && {\n opacity: 0.5,\n }),\n}));\n\nconst StepConnector = styled(Box, {\n shouldForwardProp: (prop) => !['orientation', 'isCompleted', 'color', 'variant'].includes(prop as string),\n})<{\n orientation: WorkflowStepProps['orientation'];\n isCompleted: boolean;\n color: WorkflowStepProps['color'];\n variant: WorkflowStepProps['variant'];\n}>(({ theme, orientation, isCompleted, color, variant }) => {\n const colorKey = color || 'primary';\n const colorValue = colorKey === 'neutral' \n ? { main: neutralTones(theme).emphasis }\n : theme.palette[colorKey as 'primary' | 'secondary' | 'success' | 'warning' | 'error'];\n const connectorColor = isCompleted ? colorValue.main : neutralTones(theme).track;\n\n return {\n flex: 1,\n position: 'relative',\n \n ...(orientation === 'horizontal' && {\n height: rem(theme, 2),\n backgroundColor: connectorColor,\n margin: `0 ${theme.spacing(1)}`,\n minWidth: theme.spacing(2),\n }),\n \n ...(orientation === 'vertical' && {\n width: rem(theme, 2),\n backgroundColor: connectorColor,\n minHeight: theme.spacing(3),\n marginLeft: theme.spacing(2),\n position: 'absolute',\n left: '50%',\n transform: 'translateX(-50%)',\n top: '100%',\n }),\n\n transition: theme.transitions.create('background-color', {\n duration: theme.transitions.duration.short,\n }),\n\n ...(variant === 'minimal' && {\n opacity: 0.6,\n }),\n };\n});\n\n/**\n * Individual step indicator component\n */\nconst StepIndicatorComponent = forwardRef<HTMLDivElement, StepIndicatorProps>(({\n step,\n index,\n isActive,\n isCompleted,\n isError,\n variant,\n color,\n size,\n showNumbers,\n showIcons,\n completedIcon,\n errorIcon,\n interactive,\n animated,\n disabled,\n onClick,\n 'data-testid': dataTestId,\n}, ref) => {\n const handleClick = useCallback(() => {\n if (interactive && !disabled && onClick) {\n onClick(index, step);\n }\n }, [interactive, disabled, onClick, index, step]);\n\n const handleKeyDown = useCallback((event: React.KeyboardEvent) => {\n if (interactive && !disabled && (event.key === 'Enter' || event.key === ' ')) {\n event.preventDefault();\n if (onClick) {\n onClick(index, step);\n }\n }\n }, [interactive, disabled, onClick, index, step]);\n\n const renderIndicatorContent = () => {\n if (isError && errorIcon) {\n return errorIcon;\n }\n if (isCompleted && completedIcon) {\n return completedIcon;\n }\n if (showIcons && step.icon) {\n return step.icon;\n }\n if (showNumbers) {\n return index + 1;\n }\n return null;\n };\n\n return (\n <StepIndicator\n ref={ref}\n size={size}\n variant={variant}\n color={color}\n isActive={isActive}\n isCompleted={isCompleted}\n isError={isError}\n interactive={interactive}\n animated={animated}\n disabled={Boolean(disabled || step.disabled)}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n role={interactive ? 'button' : undefined}\n tabIndex={interactive && !disabled && !step.disabled ? 0 : -1}\n aria-label={`Step ${index + 1}: ${step.title}`}\n aria-current={isActive ? 'step' : undefined}\n data-testid={dataTestId}\n >\n {renderIndicatorContent()}\n </StepIndicator>\n );\n});\n\nStepIndicatorComponent.displayName = 'StepIndicator';\n\n/**\n * Step connector component\n */\nconst StepConnectorComponent = forwardRef<HTMLDivElement, StepConnectorProps>(({\n isCompleted,\n orientation,\n variant,\n color,\n 'data-testid': dataTestId,\n}, ref) => (\n <StepConnector\n ref={ref}\n orientation={orientation}\n isCompleted={isCompleted}\n color={color}\n variant={variant}\n data-testid={dataTestId}\n />\n));\n\nStepConnectorComponent.displayName = 'StepConnector';\n\n/**\n * Step content component\n */\nconst StepContentComponent = forwardRef<HTMLDivElement, StepContentProps>(({\n step,\n index,\n orientation,\n interactive,\n disabled,\n onClick,\n 'data-testid': dataTestId,\n}, ref) => {\n const handleClick = useCallback(() => {\n if (interactive && !disabled && onClick) {\n onClick(index, step);\n }\n }, [interactive, disabled, onClick, index, step]);\n\n const handleKeyDown = useCallback((event: React.KeyboardEvent) => {\n if (interactive && !disabled && (event.key === 'Enter' || event.key === ' ')) {\n event.preventDefault();\n if (onClick) {\n onClick(index, step);\n }\n }\n }, [interactive, disabled, onClick, index, step]);\n\n return (\n <StepContent\n ref={ref}\n orientation={orientation}\n interactive={interactive}\n disabled={Boolean(disabled || step.disabled)}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n role={interactive ? 'button' : undefined}\n tabIndex={interactive && !disabled && !step.disabled ? 0 : -1}\n data-testid={dataTestId}\n >\n <div className=\"step-title\">{step.title}</div>\n {step.description && (\n <div className=\"step-description\">{step.description}</div>\n )}\n </StepContent>\n );\n});\n\nStepContentComponent.displayName = 'StepContent';\n\n/**\n * A plain wrapper around the styled row. Exporting the styled component itself\n * trips TS2742 — its inferred type names a pnpm-internal @mui/system path.\n */\nexport const StepItemRow: React.FC<{\n orientation: WorkflowStepProps['orientation'];\n isLast: boolean;\n children: React.ReactNode;\n}> = ({ orientation, isLast, children }) => (\n <StepItem orientation={orientation} isLast={isLast}>\n {children}\n </StepItem>\n);\n\nexport { StepConnectorComponent, StepContentComponent, StepIndicatorComponent };\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/data-display/Table/Table.hooks.ts"],"sourcesContent":["import { useTheme } from '@mui/material/styles/index.js';\nimport useMediaQuery from '@mui/material/useMediaQuery/index.js';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\n\nimport { rem, remPx } from '../../../tokens/relative';\n\nimport type { ColumnConfig, TableProps } from './Table.types';\n\n/**\n * The virtual window. `rowHeight` and `containerHeight` are design px: the\n * window is computed in the px `scrollTop` is measured in (`remPx`), and what it\n * hands back to draw with stays in design px (`offsetY`) or is CSS already\n * (`totalHeight`), so the rows and the window share one pitch at any type scale.\n */\nexport const useVirtualScrolling = (\n data: Record<string, unknown>[],\n rowHeight: number,\n containerHeight: number,\n overscan: number = 5\n) => {\n const theme = useTheme();\n const [scrollTop, setScrollTop] = useState(0);\n \n const visibleItems = useMemo(() => {\n const pitch = remPx(theme, rowHeight);\n const startIndex = Math.floor(scrollTop / pitch);\n const endIndex = Math.min(\n data.length,\n Math.ceil((scrollTop + remPx(theme, containerHeight)) / pitch)\n );\n \n const start = Math.max(0, startIndex - overscan);\n const end = Math.min(data.length, endIndex + overscan);\n \n return {\n startIndex: start,\n endIndex: end,\n items: data.slice(start, end),\n /** Every row at the scaled pitch, as CSS. */\n totalHeight: rem(theme, data.length * rowHeight),\n /** Where the first mounted row sits, in design px. */\n offsetY: start * rowHeight,\n };\n }, [data, rowHeight, containerHeight, scrollTop, overscan, theme]);\n\n const handleScroll = useCallback((e: React.UIEvent<HTMLDivElement>) => {\n setScrollTop(e.currentTarget.scrollTop);\n }, []);\n\n return { visibleItems, handleScroll };\n};\n\n// Responsive Hook\n\nconst useResponsive = (\n columns: ColumnConfig[],\n columnPriorities?: number[]\n) => {\n const theme = useTheme();\n const isMobile = useMediaQuery(theme.breakpoints.down('md'));\n const isTablet = useMediaQuery(theme.breakpoints.down('lg'));\n \n const [hiddenColumns, setHiddenColumns] = useState<number[]>([]);\n const [columnMenuAnchor, setColumnMenuAnchor] = useState<null | HTMLElement>(null);\n\n useEffect(() => {\n if (!columnPriorities) return;\n \n let columnsToHide: number[] = [];\n \n if (isMobile) {\n // Hide lowest priority columns on mobile\n columnsToHide = columnPriorities\n .map((priority, index) => ({ priority, index }))\n .sort((a, b) => b.priority - a.priority)\n .slice(0, Math.floor(columns.length / 2))\n .map(item => item.index);\n } else if (isTablet) {\n // Hide some columns on tablet\n columnsToHide = columnPriorities\n .map((priority, index) => ({ priority, index }))\n .sort((a, b) => b.priority - a.priority)\n .slice(0, Math.floor(columns.length / 3))\n .map(item => item.index);\n }\n \n setHiddenColumns(columnsToHide);\n }, [isMobile, isTablet, columnPriorities, columns.length]);\n\n const visibleColumns = columns.filter((_, index) => !hiddenColumns.includes(index));\n\n return {\n visibleColumns,\n hiddenColumns,\n isMobile,\n columnMenuAnchor,\n setColumnMenuAnchor,\n setHiddenColumns,\n };\n};\n\n// Enhanced Table Header Component\n// Visible/hidden column split for responsive mode, plus row selection.\nexport const useTableSelection = ({\n columns,\n data,\n responsive,\n columnPriorities,\n selectedRows,\n rowKeyExtractor,\n onSelectionChange,\n}: {\n columns?: ColumnConfig[];\n data: TableProps['data'];\n responsive?: boolean;\n columnPriorities?: number[];\n selectedRows: (string | number)[];\n rowKeyExtractor?: (row: Record<string, unknown>, index: number) => string | number;\n onSelectionChange?: TableProps['onSelectionChange'];\n}) => {\n \n // Use responsive hook if responsive mode is enabled\n const {\n visibleColumns,\n hiddenColumns,\n isMobile,\n columnMenuAnchor,\n setColumnMenuAnchor,\n setHiddenColumns,\n } = useResponsive(\n columns || [],\n responsive ? columnPriorities : undefined\n );\n\n // Handle selection changes\n const handleSelectionChange = useCallback((rowKey: string | number, selected: boolean) => {\n if (!onSelectionChange) return;\n \n let newSelection: (string | number)[];\n if (selected) {\n newSelection = [...selectedRows, rowKey];\n } else {\n newSelection = selectedRows.filter(key => key !== rowKey);\n }\n onSelectionChange(newSelection);\n }, [selectedRows, onSelectionChange]);\n\n const handleSelectAll = useCallback((selected: boolean) => {\n if (!onSelectionChange || !data) return;\n \n if (selected) {\n const allKeys = data.map((rowData, index) => \n rowKeyExtractor ? rowKeyExtractor(rowData, index) : (rowData.id as string | number) || index\n );\n onSelectionChange(allKeys);\n } else {\n onSelectionChange([]);\n }\n }, [data, onSelectionChange, rowKeyExtractor]);\n\n // Loading state\n\n return {\n visibleColumns,\n hiddenColumns,\n isMobile,\n columnMenuAnchor,\n setColumnMenuAnchor,\n setHiddenColumns,\n handleSelectionChange,\n handleSelectAll,\n };\n};\n"],"mappings":";;;;;;AAAA,SAAS,gBAAgB;AACzB,OAAO,mBAAmB;AAC1B,SAAS,aAAa,WAAW,SAAS,gBAAgB;AAYnD,IAAM,sBAAsB,CACjC,MACA,WACA,iBACA,WAAmB,MAChB;AACH,QAAM,QAAQ,SAAS;AACvB,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,CAAC;AAE5C,QAAM,eAAe,QAAQ,MAAM;AACjC,UAAM,QAAQ,MAAM,OAAO,SAAS;AACpC,UAAM,aAAa,KAAK,MAAM,YAAY,KAAK;AAC/C,UAAM,WAAW,KAAK;AAAA,MACpB,KAAK;AAAA,MACL,KAAK,MAAM,YAAY,MAAM,OAAO,eAAe,KAAK,KAAK;AAAA,IAC/D;AAEA,UAAM,QAAQ,KAAK,IAAI,GAAG,aAAa,QAAQ;AAC/C,UAAM,MAAM,KAAK,IAAI,KAAK,QAAQ,WAAW,QAAQ;AAErD,WAAO;AAAA,MACL,YAAY;AAAA,MACZ,UAAU;AAAA,MACV,OAAO,KAAK,MAAM,OAAO,GAAG;AAAA;AAAA,MAE5B,aAAa,IAAI,OAAO,KAAK,SAAS,SAAS;AAAA;AAAA,MAE/C,SAAS,QAAQ;AAAA,IACnB;AAAA,EACF,GAAG,CAAC,MAAM,WAAW,iBAAiB,WAAW,UAAU,KAAK,CAAC;AAEjE,QAAM,eAAe,YAAY,CAAC,MAAqC;AACrE,iBAAa,EAAE,cAAc,SAAS;AAAA,EACxC,GAAG,CAAC,CAAC;AAEL,SAAO,EAAE,cAAc,aAAa;AACtC;AAIA,IAAM,gBAAgB,CACpB,SACA,qBACG;AACH,QAAM,QAAQ,SAAS;AACvB,QAAM,WAAW,cAAc,MAAM,YAAY,KAAK,IAAI,CAAC;AAC3D,QAAM,WAAW,cAAc,MAAM,YAAY,KAAK,IAAI,CAAC;AAE3D,QAAM,CAAC,eAAe,gBAAgB,IAAI,SAAmB,CAAC,CAAC;AAC/D,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,SAA6B,IAAI;AAEjF,YAAU,MAAM;AACd,QAAI,CAAC,iBAAkB;AAEvB,QAAI,gBAA0B,CAAC;AAE/B,QAAI,UAAU;AAEZ,sBAAgB,iBACb,IAAI,CAAC,UAAU,WAAW,EAAE,UAAU,MAAM,EAAE,EAC9C,KAAK,CAAC,GAAG,MAAM,EAAE,WAAW,EAAE,QAAQ,EACtC,MAAM,GAAG,KAAK,MAAM,QAAQ,SAAS,CAAC,CAAC,EACvC,IAAI,UAAQ,KAAK,KAAK;AAAA,IAC3B,WAAW,UAAU;AAEnB,sBAAgB,iBACb,IAAI,CAAC,UAAU,WAAW,EAAE,UAAU,MAAM,EAAE,EAC9C,KAAK,CAAC,GAAG,MAAM,EAAE,WAAW,EAAE,QAAQ,EACtC,MAAM,GAAG,KAAK,MAAM,QAAQ,SAAS,CAAC,CAAC,EACvC,IAAI,UAAQ,KAAK,KAAK;AAAA,IAC3B;AAEA,qBAAiB,aAAa;AAAA,EAChC,GAAG,CAAC,UAAU,UAAU,kBAAkB,QAAQ,MAAM,CAAC;AAEzD,QAAM,iBAAiB,QAAQ,OAAO,CAAC,GAAG,UAAU,CAAC,cAAc,SAAS,KAAK,CAAC;AAElF,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAIO,IAAM,oBAAoB,CAAC;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAQM;AAGJ,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAAA,IACF,WAAW,CAAC;AAAA,IACZ,aAAa,mBAAmB;AAAA,EAClC;AAGA,QAAM,wBAAwB,YAAY,CAAC,QAAyB,aAAsB;AACxF,QAAI,CAAC,kBAAmB;AAExB,QAAI;AACJ,QAAI,UAAU;AACZ,qBAAe,CAAC,GAAG,cAAc,MAAM;AAAA,IACzC,OAAO;AACL,qBAAe,aAAa,OAAO,SAAO,QAAQ,MAAM;AAAA,IAC1D;AACA,sBAAkB,YAAY;AAAA,EAChC,GAAG,CAAC,cAAc,iBAAiB,CAAC;AAEpC,QAAM,kBAAkB,YAAY,CAAC,aAAsB;AACzD,QAAI,CAAC,qBAAqB,CAAC,KAAM;AAEjC,QAAI,UAAU;AACZ,YAAM,UAAU,KAAK;AAAA,QAAI,CAAC,SAAS,UACjC,kBAAkB,gBAAgB,SAAS,KAAK,IAAK,QAAQ,MAA0B;AAAA,MACzF;AACA,wBAAkB,OAAO;AAAA,IAC3B,OAAO;AACL,wBAAkB,CAAC,CAAC;AAAA,IACtB;AAAA,EACF,GAAG,CAAC,MAAM,mBAAmB,eAAe,CAAC;AAI7C,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":[]}