@bsol-oss/react-datatable5 13.0.1-beta.34 → 13.0.1-beta.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1069,6 +1069,20 @@ interface TimeViewportGridProps {
1069
1069
  animationDurationMs?: number;
1070
1070
  animationEasing?: string;
1071
1071
  }
1072
+ interface TimeViewportBlockRenderArgs {
1073
+ block: TimeViewportBlockItem;
1074
+ geometry: {
1075
+ leftPercent: number;
1076
+ widthPercent: number;
1077
+ };
1078
+ index: number;
1079
+ }
1080
+ interface TimeViewportTrackRenderArgs {
1081
+ trackIndex: number;
1082
+ trackKey?: string | number;
1083
+ trackBlocks: TimeViewportBlockItem[];
1084
+ defaultContent: ReactNode;
1085
+ }
1072
1086
  interface TimeViewportBlocksProps {
1073
1087
  blocks: TimeViewportBlockItem[];
1074
1088
  viewportStart?: TimeInput;
@@ -1093,6 +1107,10 @@ interface TimeViewportBlocksProps {
1093
1107
  trackBlocks: TimeViewportBlockItem[];
1094
1108
  trackKey?: string | number;
1095
1109
  }) => ReactNode;
1110
+ /** Custom render function for block content. The returned node is placed inside a positioning wrapper that handles translateX and transitions. */
1111
+ renderBlock?: (args: TimeViewportBlockRenderArgs) => ReactNode;
1112
+ /** Custom render function for an entire track row. Receives the default rendered content so you can wrap or replace it. */
1113
+ renderTrack?: (args: TimeViewportTrackRenderArgs) => ReactNode;
1096
1114
  onBlockClick?: (block: TimeViewportBlockItem) => void;
1097
1115
  /** Enable virtual scrolling for large track lists. */
1098
1116
  virtualize?: boolean;
@@ -1183,7 +1201,7 @@ declare function TimeViewportHeader({ viewportStart, viewportEnd, tickCount, tic
1183
1201
  * Render inside a relative container that also contains blocks.
1184
1202
  */
1185
1203
  declare function TimeViewportGrid({ viewportStart, viewportEnd, tickCount, tickStrategy, tickUnit, tickStep, format, minorDivisions, majorLineColor, minorLineColor, showMinorLines, zIndex, animationDurationMs, animationEasing, }: TimeViewportGridProps): react_jsx_runtime.JSX.Element | null;
1186
- declare function TimeViewportBlocks({ blocks, viewportStart, viewportEnd, height, minWidthPx, borderRadius, defaultColorPalette, showLabel, hideWhenOutOfView, hideEmptyTracks, gap, allowOverlap, overlapOpacity, renderTrackPrefix, renderTrackSuffix, onBlockClick, virtualize, virtualHeight, overscan, }: TimeViewportBlocksProps): react_jsx_runtime.JSX.Element;
1204
+ declare function TimeViewportBlocks({ blocks, viewportStart, viewportEnd, height, minWidthPx, borderRadius, defaultColorPalette, showLabel, hideWhenOutOfView, hideEmptyTracks, gap, allowOverlap, overlapOpacity, renderTrackPrefix, renderTrackSuffix, renderBlock, renderTrack, onBlockClick, virtualize, virtualHeight, overscan, }: TimeViewportBlocksProps): react_jsx_runtime.JSX.Element;
1187
1205
  declare function TimeRangeZoom({ range, onRangeChange, minDurationMs, maxDurationMs, zoomFactor, resetDurationMs, showResetButton, disabled, labels, }: TimeRangeZoomProps): react_jsx_runtime.JSX.Element;
1188
1206
  declare function useTimeRangeZoom({ range, onRangeChange, minDurationMs, maxDurationMs, zoomFactor, resetDurationMs, disabled, labels, }: TimeRangeZoomProps): UseTimeRangeZoomResult;
1189
1207
 
@@ -1460,4 +1478,4 @@ declare module '@tanstack/react-table' {
1460
1478
  }
1461
1479
  }
1462
1480
 
1463
- export { CalendarDisplay, type CalendarDisplayProps, type CalendarEvent, type CalendarProps, CardHeader, type CardHeaderProps, type CustomJSONSchema7, type CustomJSONSchema7Definition, type CustomQueryFn, type CustomQueryFnParams, type CustomQueryFnResponse, DataDisplay, type DataDisplayProps, type DataResponse, DataTable, type DataTableDefaultState, type DataTableProps, DataTableServer, type DataTableServerProps, DatePickerContext, DatePickerInput, type DatePickerInputProps, type DatePickerLabels, type DatePickerProps, type DateTimePickerLabels, DefaultCardTitle, DefaultForm, type DefaultFormProps, DefaultTable, type DefaultTableProps, DefaultTableServer, type DefaultTableServerProps, DensityToggleButton, type DensityToggleButtonProps, type EditFilterButtonProps, EditSortingButton, type EditSortingButtonProps, type EditViewButtonProps, EmptyState, type EmptyStateProps, type EnumPickerLabels, ErrorAlert, type ErrorAlertProps, type FilePickerLabels, type FilePickerMediaFile, type FilePickerProps, FilterDialog, FormBody, type FormButtonLabels, FormRoot, type FormRootProps, FormTitle, type GetDateColorProps, type GetMultiDatesProps, type GetRangeDatesProps, type GetStyleProps, type GetVariantProps, GlobalFilter, type IdPickerLabels, type LoadInitialValuesParams, type LoadInitialValuesResult, MediaLibraryBrowser, type MediaLibraryBrowserProps, PageSizeControl, type PageSizeControlProps, Pagination, type QueryParams, type RangeCalendarProps, type RangeDatePickerLabels, type RangeDatePickerProps, RecordDisplay, type RecordDisplayProps, ReloadButton, type ReloadButtonProps, ResetFilteringButton, ResetSelectionButton, ResetSortingButton, type Result, RowCountText, SelectAllRowsToggle, type SelectAllRowsToggleProps, Table, TableBody, type TableBodyProps, TableCardContainer, type TableCardContainerProps, TableCards, type TableCardsProps, TableComponent, TableControls, type TableControlsProps, TableDataDisplay, type TableDataDisplayProps, TableFilter, TableFilterTags, type TableFilterTagsProps, TableFooter, type TableFooterProps, TableHeader, type TableHeaderProps, type TableHeaderTexts, TableLoadingComponent, type TableLoadingComponentProps, type TableProps, type TableRendererProps, type TableRowSelectorProps, TableSelector, TableSorter, TableViewer, TextCell, type TextCellProps, type TimePickerLabels, TimeRangeZoom, type TimeRangeZoomLabels, type TimeRangeZoomProps, TimeViewportBlock, type TimeViewportBlockItem, type TimeViewportBlockProps, TimeViewportBlocks, type TimeViewportBlocksProps, TimeViewportGrid, type TimeViewportGridProps, TimeViewportHeader, type TimeViewportHeaderProps, type TimeViewportHeaderTick, TimeViewportMarkerLine, type TimeViewportMarkerLineProps, TimeViewportRoot, type TimeViewportRootProps, type UseDataTableProps, type UseDataTableReturn, type UseDataTableServerProps, type UseDataTableServerReturn, type UseFormProps, type UseTimeRangeZoomResult, type UseTimeViewportBlockGeometryResult, type UseTimeViewportDerivedResult, type UseTimeViewportTicksResult, type ValidationErrorType, ViewDialog, type ViewableTimeRange, defaultRenderDisplay, getMultiDates, getRangeDates, useDataTable, useDataTableContext, useDataTableServer, useForm, useTimeRangeZoom, useTimeViewport, useTimeViewportBlockGeometry, useTimeViewportHeader, useTimeViewportTicks };
1481
+ export { CalendarDisplay, type CalendarDisplayProps, type CalendarEvent, type CalendarProps, CardHeader, type CardHeaderProps, type CustomJSONSchema7, type CustomJSONSchema7Definition, type CustomQueryFn, type CustomQueryFnParams, type CustomQueryFnResponse, DataDisplay, type DataDisplayProps, type DataResponse, DataTable, type DataTableDefaultState, type DataTableProps, DataTableServer, type DataTableServerProps, DatePickerContext, DatePickerInput, type DatePickerInputProps, type DatePickerLabels, type DatePickerProps, type DateTimePickerLabels, DefaultCardTitle, DefaultForm, type DefaultFormProps, DefaultTable, type DefaultTableProps, DefaultTableServer, type DefaultTableServerProps, DensityToggleButton, type DensityToggleButtonProps, type EditFilterButtonProps, EditSortingButton, type EditSortingButtonProps, type EditViewButtonProps, EmptyState, type EmptyStateProps, type EnumPickerLabels, ErrorAlert, type ErrorAlertProps, type FilePickerLabels, type FilePickerMediaFile, type FilePickerProps, FilterDialog, FormBody, type FormButtonLabels, FormRoot, type FormRootProps, FormTitle, type GetDateColorProps, type GetMultiDatesProps, type GetRangeDatesProps, type GetStyleProps, type GetVariantProps, GlobalFilter, type IdPickerLabels, type LoadInitialValuesParams, type LoadInitialValuesResult, MediaLibraryBrowser, type MediaLibraryBrowserProps, PageSizeControl, type PageSizeControlProps, Pagination, type QueryParams, type RangeCalendarProps, type RangeDatePickerLabels, type RangeDatePickerProps, RecordDisplay, type RecordDisplayProps, ReloadButton, type ReloadButtonProps, ResetFilteringButton, ResetSelectionButton, ResetSortingButton, type Result, RowCountText, SelectAllRowsToggle, type SelectAllRowsToggleProps, Table, TableBody, type TableBodyProps, TableCardContainer, type TableCardContainerProps, TableCards, type TableCardsProps, TableComponent, TableControls, type TableControlsProps, TableDataDisplay, type TableDataDisplayProps, TableFilter, TableFilterTags, type TableFilterTagsProps, TableFooter, type TableFooterProps, TableHeader, type TableHeaderProps, type TableHeaderTexts, TableLoadingComponent, type TableLoadingComponentProps, type TableProps, type TableRendererProps, type TableRowSelectorProps, TableSelector, TableSorter, TableViewer, TextCell, type TextCellProps, type TimePickerLabels, TimeRangeZoom, type TimeRangeZoomLabels, type TimeRangeZoomProps, TimeViewportBlock, type TimeViewportBlockItem, type TimeViewportBlockProps, type TimeViewportBlockRenderArgs, TimeViewportBlocks, type TimeViewportBlocksProps, TimeViewportGrid, type TimeViewportGridProps, TimeViewportHeader, type TimeViewportHeaderProps, type TimeViewportHeaderTick, TimeViewportMarkerLine, type TimeViewportMarkerLineProps, TimeViewportRoot, type TimeViewportRootProps, type TimeViewportTrackRenderArgs, type UseDataTableProps, type UseDataTableReturn, type UseDataTableServerProps, type UseDataTableServerReturn, type UseFormProps, type UseTimeRangeZoomResult, type UseTimeViewportBlockGeometryResult, type UseTimeViewportDerivedResult, type UseTimeViewportTicksResult, type ValidationErrorType, ViewDialog, type ViewableTimeRange, defaultRenderDisplay, getMultiDates, getRangeDates, useDataTable, useDataTableContext, useDataTableServer, useForm, useTimeRangeZoom, useTimeViewport, useTimeViewportBlockGeometry, useTimeViewportHeader, useTimeViewportTicks };
package/dist/index.js CHANGED
@@ -8096,7 +8096,7 @@ function TimeViewportRoot({ viewportStart, viewportEnd, children, onViewportChan
8096
8096
  return (jsxRuntime.jsx(TimeViewportContext.Provider, { value: { viewportStart, viewportEnd }, children: jsxRuntime.jsx(react.Box, { ref: containerRef, position: "relative", width: "100%", cursor: enableDragPan ? (isDragging ? 'grabbing' : 'grab') : 'default', userSelect: enableDragPan ? 'none' : undefined, onPointerDown: handlePointerDown, onPointerMove: handlePointerMove, onPointerUp: stopDragging, onPointerCancel: stopDragging, onWheel: handleWheel, children: children }) }));
8097
8097
  }
8098
8098
  function TimeViewportTrackRow({ trackKey, blocks, resolvedHeight, prefix, suffix, renderBlockNode, }) {
8099
- return (jsxRuntime.jsxs(react.HStack, { width: "100%", overflowX: 'hidden', align: "stretch", gap: 2, children: [prefix ? (jsxRuntime.jsx(react.Box, { minW: "fit-content", display: "flex", alignItems: "center", children: prefix })) : null, jsxRuntime.jsx(react.Box, { position: "relative", width: "100%", height: resolvedHeight, children: blocks.map((item, index) => renderBlockNode(item, index)) }), suffix ? (jsxRuntime.jsx(react.Box, { minW: "fit-content", display: "flex", alignItems: "center", children: suffix })) : null] }, trackKey));
8099
+ return (jsxRuntime.jsxs(react.Box, { width: "100%", overflowX: 'hidden', position: "relative", height: resolvedHeight, children: [jsxRuntime.jsx(react.Box, { position: "relative", width: "100%", height: "100%", children: blocks.map((item, index) => renderBlockNode(item, index)) }), prefix ? (jsxRuntime.jsx(react.Box, { position: "absolute", top: 0, insetInlineStart: 0, zIndex: 2, pointerEvents: "auto", children: prefix })) : null, suffix ? (jsxRuntime.jsx(react.Box, { position: "absolute", top: 0, insetInlineEnd: 0, zIndex: 2, pointerEvents: "auto", children: suffix })) : null] }, trackKey));
8100
8100
  }
8101
8101
  const defaultLabels = {
8102
8102
  zoomIn: 'Zoom in',
@@ -8334,7 +8334,7 @@ function TimeViewportMarkerLine({ timestamp, viewportStart, viewportEnd, height
8334
8334
  return null;
8335
8335
  if (hideWhenOutOfView && !marker.inView)
8336
8336
  return null;
8337
- return (jsxRuntime.jsx(react.Box, { position: "absolute", insetInlineStart: 0, insetInlineEnd: 0, top: 0, bottom: 0, pointerEvents: "none", zIndex: 100, height: height, children: jsxRuntime.jsxs(react.Box, { width: "100%", height: "100%", transform: `translateX(${marker.percent}%)`, transition: VIEWPORT_TRANSITION, transformOrigin: "left center", children: [jsxRuntime.jsx(react.Box, { width: `${lineWidthPx}px`, height: "100%", bg: color ?? `${colorPalette}.500`, _dark: { bg: color ?? `${colorPalette}.300` }, transform: "translateX(-50%)" }), showLabel && label ? (jsxRuntime.jsx(react.Text, { position: "absolute", insetInlineStart: 0, top: "100%", mt: 1, display: "inline-block", fontSize: "xs", whiteSpace: "nowrap", color: color ?? `${colorPalette}.700`, _dark: { color: color ?? `${colorPalette}.200` }, transform: "translateX(-50%)", children: label })) : null] }) }));
8337
+ return (jsxRuntime.jsx(react.Box, { position: "absolute", insetInlineStart: 0, insetInlineEnd: 0, top: 0, bottom: 0, pointerEvents: "none", zIndex: 100, height: height, children: jsxRuntime.jsxs(react.Box, { width: "100%", height: "100%", transform: `translateX(${marker.percent}%)`, transition: VIEWPORT_TRANSITION, transformOrigin: "left center", children: [jsxRuntime.jsx(react.Box, { width: `${lineWidthPx}px`, height: "100%", bg: color ?? `${colorPalette}.500`, _dark: { bg: color ?? `${colorPalette}.500` }, transform: "translateX(-50%)" }), showLabel && label ? (jsxRuntime.jsx(react.Text, { position: "absolute", insetInlineStart: 0, top: "100%", mt: 1, display: "inline-block", fontSize: "xs", whiteSpace: "nowrap", color: color ?? `${colorPalette}.700`, _dark: { color: color ?? `${colorPalette}.500` }, transform: "translateX(-50%)", children: label })) : null] }) }));
8338
8338
  }
8339
8339
  /**
8340
8340
  * Header labels for timeline viewport time scale.
@@ -8380,7 +8380,7 @@ function TimeViewportGrid({ viewportStart, viewportEnd, tickCount = 8, tickStrat
8380
8380
  : [];
8381
8381
  return (jsxRuntime.jsxs(react.Box, { position: "absolute", inset: 0, pointerEvents: "none", zIndex: zIndex, children: [minorTicks.map((percent, index) => (jsxRuntime.jsx(react.Box, { position: "absolute", inset: 0, transform: `translateX(${percent}%)`, transition: transitionValue, children: jsxRuntime.jsx(react.Box, { position: "absolute", insetInlineStart: 0, top: 0, bottom: 0, width: "1px", bg: minorLineColor, _dark: { bg: 'gray.700' } }) }, `minor-grid-${index}`))), majorTicks.map((tick) => (jsxRuntime.jsx(react.Box, { position: "absolute", inset: 0, transform: `translateX(${tick.percent}%)`, transition: transitionValue, children: jsxRuntime.jsx(react.Box, { position: "absolute", insetInlineStart: 0, top: 0, bottom: 0, width: "1px", bg: majorLineColor, _dark: { bg: 'gray.600' } }) }, `major-grid-${tick.index}`)))] }));
8382
8382
  }
8383
- function VirtualizedTrackList({ tracks, resolvedHeight, gap, virtualHeight, overscan, renderTrackPrefix, renderTrackSuffix, renderBlockNode, }) {
8383
+ function VirtualizedTrackList({ tracks, resolvedHeight, gap, virtualHeight, overscan, renderTrackPrefix, renderTrackSuffix, renderTrack, renderBlockNode, }) {
8384
8384
  const parentRef = React.useRef(null);
8385
8385
  const rowHeightPx = parseInt(resolvedHeight, 10) || 28;
8386
8386
  const gapPx = gap * 4; // Chakra spacing token to px (1 unit = 4px)
@@ -8403,10 +8403,19 @@ function VirtualizedTrackList({ tracks, resolvedHeight, gap, virtualHeight, over
8403
8403
  trackBlocks,
8404
8404
  trackKey: track.trackKeyRaw,
8405
8405
  });
8406
- return (jsxRuntime.jsx(react.Box, { position: "absolute", top: 0, left: 0, width: "100%", transform: `translateY(${virtualRow.start}px)`, children: jsxRuntime.jsx(TimeViewportTrackRow, { trackKey: track.trackKey, blocks: track.blocks, resolvedHeight: resolvedHeight, prefix: prefix, suffix: suffix, renderBlockNode: renderBlockNode }) }, track.trackKey));
8406
+ const defaultContent = (jsxRuntime.jsx(TimeViewportTrackRow, { trackKey: track.trackKey, blocks: track.blocks, resolvedHeight: resolvedHeight, prefix: prefix, suffix: suffix, renderBlockNode: renderBlockNode }));
8407
+ const trackContent = renderTrack
8408
+ ? renderTrack({
8409
+ trackIndex: virtualRow.index,
8410
+ trackKey: track.trackKeyRaw,
8411
+ trackBlocks,
8412
+ defaultContent,
8413
+ })
8414
+ : defaultContent;
8415
+ return (jsxRuntime.jsx(react.Box, { position: "absolute", top: 0, left: 0, width: "100%", transform: `translateY(${virtualRow.start}px)`, children: trackContent }, track.trackKey));
8407
8416
  }) }) }));
8408
8417
  }
8409
- function TimeViewportBlocks({ blocks, viewportStart, viewportEnd, height = '28px', minWidthPx = 2, borderRadius = 'sm', defaultColorPalette = 'blue', showLabel = true, hideWhenOutOfView = true, hideEmptyTracks = true, gap = 2, allowOverlap = false, overlapOpacity = 0.9, renderTrackPrefix, renderTrackSuffix, onBlockClick, virtualize = false, virtualHeight = 400, overscan = 5, }) {
8418
+ function TimeViewportBlocks({ blocks, viewportStart, viewportEnd, height = '28px', minWidthPx = 2, borderRadius = 'sm', defaultColorPalette = 'blue', showLabel = true, hideWhenOutOfView = true, hideEmptyTracks = true, gap = 2, allowOverlap = false, overlapOpacity = 0.9, renderTrackPrefix, renderTrackSuffix, renderBlock, renderTrack, onBlockClick, virtualize = false, virtualHeight = 400, overscan = 5, }) {
8410
8419
  const { getGeometry, toTimeMs } = useTimeViewportBlockGeometry(viewportStart, viewportEnd);
8411
8420
  const resolvedHeight = typeof height === 'number' ? `${height}px` : height;
8412
8421
  const expandedBlocks = flattenTrackBlocks(blocks);
@@ -8441,11 +8450,11 @@ function TimeViewportBlocks({ blocks, viewportStart, viewportEnd, height = '28px
8441
8450
  onBlockClick?.(block);
8442
8451
  };
8443
8452
  const isBlockClickable = Boolean(block.onClick || onBlockClick);
8444
- return (jsxRuntime.jsx(react.Box, { height: "100%", position: "absolute", inset: 0, pointerEvents: "none", transform: `translateX(${geometry.leftPercent}%)`, transition: VIEWPORT_TRANSITION, children: jsxRuntime.jsx(react.Box, { width: `max(${geometry.widthPercent}%, ${minWidthPx}px)`, height: "100%", borderRadius: borderRadius, bg: block.background ??
8445
- `${block.colorPalette ?? defaultColorPalette}.500`, _dark: {
8446
- bg: block.background ??
8447
- `${block.colorPalette ?? defaultColorPalette}.900`,
8448
- }, display: "flex", alignItems: "center", justifyContent: "center", px: 2, overflow: "hidden", opacity: allowOverlap ? overlapOpacity : 1, zIndex: indexInLayer + 1, pointerEvents: "auto", onClick: isBlockClickable ? handleBlockClick : undefined, cursor: isBlockClickable ? 'pointer' : 'default', children: showLabel && block.label ? (jsxRuntime.jsx(react.Text, { fontSize: "xs", lineClamp: 1, color: "white", _dark: { color: 'gray.100' }, children: block.label })) : null }) }, block.id));
8453
+ const content = renderBlock ? (renderBlock({ block, geometry, index: indexInLayer })) : (jsxRuntime.jsx(react.Box, { width: `max(${geometry.widthPercent}%, ${minWidthPx}px)`, height: "100%", borderRadius: borderRadius, bg: block.background ?? `${block.colorPalette ?? defaultColorPalette}.500`, _dark: {
8454
+ bg: block.background ??
8455
+ `${block.colorPalette ?? defaultColorPalette}.900`,
8456
+ }, display: "flex", alignItems: "center", justifyContent: "center", px: 2, overflow: "hidden", opacity: allowOverlap ? overlapOpacity : 1, zIndex: indexInLayer + 1, pointerEvents: "auto", onClick: isBlockClickable ? handleBlockClick : undefined, cursor: isBlockClickable ? 'pointer' : 'default', children: showLabel && block.label ? (jsxRuntime.jsx(react.Text, { fontSize: "xs", lineClamp: 1, children: block.label })) : null }));
8457
+ return (jsxRuntime.jsx(react.Box, { height: "100%", position: "absolute", inset: 0, pointerEvents: "none", transform: `translateX(${geometry.leftPercent}%)`, transition: VIEWPORT_TRANSITION, children: content }, block.id));
8449
8458
  };
8450
8459
  // ---------- Resolve tracks ----------
8451
8460
  const explicitTrackKeys = Array.from(new Set(expandedBlocks
@@ -8493,7 +8502,7 @@ function TimeViewportBlocks({ blocks, viewportStart, viewportEnd, height = '28px
8493
8502
  }, [allowOverlap, explicitTrackKeys, hideEmptyTracks, parsedBlocks]);
8494
8503
  // ---------- Render ----------
8495
8504
  if (virtualize) {
8496
- return (jsxRuntime.jsx(VirtualizedTrackList, { tracks: resolvedTracks, resolvedHeight: resolvedHeight, gap: gap, virtualHeight: virtualHeight, overscan: overscan, renderTrackPrefix: renderTrackPrefix, renderTrackSuffix: renderTrackSuffix, renderBlockNode: renderBlockNode }));
8505
+ return (jsxRuntime.jsx(VirtualizedTrackList, { tracks: resolvedTracks, resolvedHeight: resolvedHeight, gap: gap, virtualHeight: virtualHeight, overscan: overscan, renderTrackPrefix: renderTrackPrefix, renderTrackSuffix: renderTrackSuffix, renderTrack: renderTrack, renderBlockNode: renderBlockNode }));
8497
8506
  }
8498
8507
  return (jsxRuntime.jsx(react.VStack, { align: "stretch", gap: gap, children: resolvedTracks.map((track, trackIndex) => {
8499
8508
  const trackBlocks = track.blocks.map((item) => item.block);
@@ -8507,7 +8516,15 @@ function TimeViewportBlocks({ blocks, viewportStart, viewportEnd, height = '28px
8507
8516
  trackBlocks,
8508
8517
  trackKey: track.trackKeyRaw,
8509
8518
  });
8510
- return (jsxRuntime.jsx(TimeViewportTrackRow, { trackKey: track.trackKey, blocks: track.blocks, resolvedHeight: resolvedHeight, prefix: prefix, suffix: suffix, renderBlockNode: renderBlockNode }));
8519
+ const defaultContent = (jsxRuntime.jsx(TimeViewportTrackRow, { trackKey: track.trackKey, blocks: track.blocks, resolvedHeight: resolvedHeight, prefix: prefix, suffix: suffix, renderBlockNode: renderBlockNode }));
8520
+ return renderTrack
8521
+ ? renderTrack({
8522
+ trackIndex,
8523
+ trackKey: track.trackKeyRaw,
8524
+ trackBlocks,
8525
+ defaultContent,
8526
+ })
8527
+ : defaultContent;
8511
8528
  }) }));
8512
8529
  }
8513
8530
  function TimeRangeZoom({ range, onRangeChange, minDurationMs = DEFAULT_MIN_DURATION_MS, maxDurationMs = DEFAULT_MAX_DURATION_MS, zoomFactor = DEFAULT_ZOOM_FACTOR, resetDurationMs, showResetButton = true, disabled = false, labels, }) {
package/dist/index.mjs CHANGED
@@ -8076,7 +8076,7 @@ function TimeViewportRoot({ viewportStart, viewportEnd, children, onViewportChan
8076
8076
  return (jsx(TimeViewportContext.Provider, { value: { viewportStart, viewportEnd }, children: jsx(Box, { ref: containerRef, position: "relative", width: "100%", cursor: enableDragPan ? (isDragging ? 'grabbing' : 'grab') : 'default', userSelect: enableDragPan ? 'none' : undefined, onPointerDown: handlePointerDown, onPointerMove: handlePointerMove, onPointerUp: stopDragging, onPointerCancel: stopDragging, onWheel: handleWheel, children: children }) }));
8077
8077
  }
8078
8078
  function TimeViewportTrackRow({ trackKey, blocks, resolvedHeight, prefix, suffix, renderBlockNode, }) {
8079
- return (jsxs(HStack, { width: "100%", overflowX: 'hidden', align: "stretch", gap: 2, children: [prefix ? (jsx(Box, { minW: "fit-content", display: "flex", alignItems: "center", children: prefix })) : null, jsx(Box, { position: "relative", width: "100%", height: resolvedHeight, children: blocks.map((item, index) => renderBlockNode(item, index)) }), suffix ? (jsx(Box, { minW: "fit-content", display: "flex", alignItems: "center", children: suffix })) : null] }, trackKey));
8079
+ return (jsxs(Box, { width: "100%", overflowX: 'hidden', position: "relative", height: resolvedHeight, children: [jsx(Box, { position: "relative", width: "100%", height: "100%", children: blocks.map((item, index) => renderBlockNode(item, index)) }), prefix ? (jsx(Box, { position: "absolute", top: 0, insetInlineStart: 0, zIndex: 2, pointerEvents: "auto", children: prefix })) : null, suffix ? (jsx(Box, { position: "absolute", top: 0, insetInlineEnd: 0, zIndex: 2, pointerEvents: "auto", children: suffix })) : null] }, trackKey));
8080
8080
  }
8081
8081
  const defaultLabels = {
8082
8082
  zoomIn: 'Zoom in',
@@ -8314,7 +8314,7 @@ function TimeViewportMarkerLine({ timestamp, viewportStart, viewportEnd, height
8314
8314
  return null;
8315
8315
  if (hideWhenOutOfView && !marker.inView)
8316
8316
  return null;
8317
- return (jsx(Box, { position: "absolute", insetInlineStart: 0, insetInlineEnd: 0, top: 0, bottom: 0, pointerEvents: "none", zIndex: 100, height: height, children: jsxs(Box, { width: "100%", height: "100%", transform: `translateX(${marker.percent}%)`, transition: VIEWPORT_TRANSITION, transformOrigin: "left center", children: [jsx(Box, { width: `${lineWidthPx}px`, height: "100%", bg: color ?? `${colorPalette}.500`, _dark: { bg: color ?? `${colorPalette}.300` }, transform: "translateX(-50%)" }), showLabel && label ? (jsx(Text, { position: "absolute", insetInlineStart: 0, top: "100%", mt: 1, display: "inline-block", fontSize: "xs", whiteSpace: "nowrap", color: color ?? `${colorPalette}.700`, _dark: { color: color ?? `${colorPalette}.200` }, transform: "translateX(-50%)", children: label })) : null] }) }));
8317
+ return (jsx(Box, { position: "absolute", insetInlineStart: 0, insetInlineEnd: 0, top: 0, bottom: 0, pointerEvents: "none", zIndex: 100, height: height, children: jsxs(Box, { width: "100%", height: "100%", transform: `translateX(${marker.percent}%)`, transition: VIEWPORT_TRANSITION, transformOrigin: "left center", children: [jsx(Box, { width: `${lineWidthPx}px`, height: "100%", bg: color ?? `${colorPalette}.500`, _dark: { bg: color ?? `${colorPalette}.500` }, transform: "translateX(-50%)" }), showLabel && label ? (jsx(Text, { position: "absolute", insetInlineStart: 0, top: "100%", mt: 1, display: "inline-block", fontSize: "xs", whiteSpace: "nowrap", color: color ?? `${colorPalette}.700`, _dark: { color: color ?? `${colorPalette}.500` }, transform: "translateX(-50%)", children: label })) : null] }) }));
8318
8318
  }
8319
8319
  /**
8320
8320
  * Header labels for timeline viewport time scale.
@@ -8360,7 +8360,7 @@ function TimeViewportGrid({ viewportStart, viewportEnd, tickCount = 8, tickStrat
8360
8360
  : [];
8361
8361
  return (jsxs(Box, { position: "absolute", inset: 0, pointerEvents: "none", zIndex: zIndex, children: [minorTicks.map((percent, index) => (jsx(Box, { position: "absolute", inset: 0, transform: `translateX(${percent}%)`, transition: transitionValue, children: jsx(Box, { position: "absolute", insetInlineStart: 0, top: 0, bottom: 0, width: "1px", bg: minorLineColor, _dark: { bg: 'gray.700' } }) }, `minor-grid-${index}`))), majorTicks.map((tick) => (jsx(Box, { position: "absolute", inset: 0, transform: `translateX(${tick.percent}%)`, transition: transitionValue, children: jsx(Box, { position: "absolute", insetInlineStart: 0, top: 0, bottom: 0, width: "1px", bg: majorLineColor, _dark: { bg: 'gray.600' } }) }, `major-grid-${tick.index}`)))] }));
8362
8362
  }
8363
- function VirtualizedTrackList({ tracks, resolvedHeight, gap, virtualHeight, overscan, renderTrackPrefix, renderTrackSuffix, renderBlockNode, }) {
8363
+ function VirtualizedTrackList({ tracks, resolvedHeight, gap, virtualHeight, overscan, renderTrackPrefix, renderTrackSuffix, renderTrack, renderBlockNode, }) {
8364
8364
  const parentRef = useRef(null);
8365
8365
  const rowHeightPx = parseInt(resolvedHeight, 10) || 28;
8366
8366
  const gapPx = gap * 4; // Chakra spacing token to px (1 unit = 4px)
@@ -8383,10 +8383,19 @@ function VirtualizedTrackList({ tracks, resolvedHeight, gap, virtualHeight, over
8383
8383
  trackBlocks,
8384
8384
  trackKey: track.trackKeyRaw,
8385
8385
  });
8386
- return (jsx(Box, { position: "absolute", top: 0, left: 0, width: "100%", transform: `translateY(${virtualRow.start}px)`, children: jsx(TimeViewportTrackRow, { trackKey: track.trackKey, blocks: track.blocks, resolvedHeight: resolvedHeight, prefix: prefix, suffix: suffix, renderBlockNode: renderBlockNode }) }, track.trackKey));
8386
+ const defaultContent = (jsx(TimeViewportTrackRow, { trackKey: track.trackKey, blocks: track.blocks, resolvedHeight: resolvedHeight, prefix: prefix, suffix: suffix, renderBlockNode: renderBlockNode }));
8387
+ const trackContent = renderTrack
8388
+ ? renderTrack({
8389
+ trackIndex: virtualRow.index,
8390
+ trackKey: track.trackKeyRaw,
8391
+ trackBlocks,
8392
+ defaultContent,
8393
+ })
8394
+ : defaultContent;
8395
+ return (jsx(Box, { position: "absolute", top: 0, left: 0, width: "100%", transform: `translateY(${virtualRow.start}px)`, children: trackContent }, track.trackKey));
8387
8396
  }) }) }));
8388
8397
  }
8389
- function TimeViewportBlocks({ blocks, viewportStart, viewportEnd, height = '28px', minWidthPx = 2, borderRadius = 'sm', defaultColorPalette = 'blue', showLabel = true, hideWhenOutOfView = true, hideEmptyTracks = true, gap = 2, allowOverlap = false, overlapOpacity = 0.9, renderTrackPrefix, renderTrackSuffix, onBlockClick, virtualize = false, virtualHeight = 400, overscan = 5, }) {
8398
+ function TimeViewportBlocks({ blocks, viewportStart, viewportEnd, height = '28px', minWidthPx = 2, borderRadius = 'sm', defaultColorPalette = 'blue', showLabel = true, hideWhenOutOfView = true, hideEmptyTracks = true, gap = 2, allowOverlap = false, overlapOpacity = 0.9, renderTrackPrefix, renderTrackSuffix, renderBlock, renderTrack, onBlockClick, virtualize = false, virtualHeight = 400, overscan = 5, }) {
8390
8399
  const { getGeometry, toTimeMs } = useTimeViewportBlockGeometry(viewportStart, viewportEnd);
8391
8400
  const resolvedHeight = typeof height === 'number' ? `${height}px` : height;
8392
8401
  const expandedBlocks = flattenTrackBlocks(blocks);
@@ -8421,11 +8430,11 @@ function TimeViewportBlocks({ blocks, viewportStart, viewportEnd, height = '28px
8421
8430
  onBlockClick?.(block);
8422
8431
  };
8423
8432
  const isBlockClickable = Boolean(block.onClick || onBlockClick);
8424
- return (jsx(Box, { height: "100%", position: "absolute", inset: 0, pointerEvents: "none", transform: `translateX(${geometry.leftPercent}%)`, transition: VIEWPORT_TRANSITION, children: jsx(Box, { width: `max(${geometry.widthPercent}%, ${minWidthPx}px)`, height: "100%", borderRadius: borderRadius, bg: block.background ??
8425
- `${block.colorPalette ?? defaultColorPalette}.500`, _dark: {
8426
- bg: block.background ??
8427
- `${block.colorPalette ?? defaultColorPalette}.900`,
8428
- }, display: "flex", alignItems: "center", justifyContent: "center", px: 2, overflow: "hidden", opacity: allowOverlap ? overlapOpacity : 1, zIndex: indexInLayer + 1, pointerEvents: "auto", onClick: isBlockClickable ? handleBlockClick : undefined, cursor: isBlockClickable ? 'pointer' : 'default', children: showLabel && block.label ? (jsx(Text, { fontSize: "xs", lineClamp: 1, color: "white", _dark: { color: 'gray.100' }, children: block.label })) : null }) }, block.id));
8433
+ const content = renderBlock ? (renderBlock({ block, geometry, index: indexInLayer })) : (jsx(Box, { width: `max(${geometry.widthPercent}%, ${minWidthPx}px)`, height: "100%", borderRadius: borderRadius, bg: block.background ?? `${block.colorPalette ?? defaultColorPalette}.500`, _dark: {
8434
+ bg: block.background ??
8435
+ `${block.colorPalette ?? defaultColorPalette}.900`,
8436
+ }, display: "flex", alignItems: "center", justifyContent: "center", px: 2, overflow: "hidden", opacity: allowOverlap ? overlapOpacity : 1, zIndex: indexInLayer + 1, pointerEvents: "auto", onClick: isBlockClickable ? handleBlockClick : undefined, cursor: isBlockClickable ? 'pointer' : 'default', children: showLabel && block.label ? (jsx(Text, { fontSize: "xs", lineClamp: 1, children: block.label })) : null }));
8437
+ return (jsx(Box, { height: "100%", position: "absolute", inset: 0, pointerEvents: "none", transform: `translateX(${geometry.leftPercent}%)`, transition: VIEWPORT_TRANSITION, children: content }, block.id));
8429
8438
  };
8430
8439
  // ---------- Resolve tracks ----------
8431
8440
  const explicitTrackKeys = Array.from(new Set(expandedBlocks
@@ -8473,7 +8482,7 @@ function TimeViewportBlocks({ blocks, viewportStart, viewportEnd, height = '28px
8473
8482
  }, [allowOverlap, explicitTrackKeys, hideEmptyTracks, parsedBlocks]);
8474
8483
  // ---------- Render ----------
8475
8484
  if (virtualize) {
8476
- return (jsx(VirtualizedTrackList, { tracks: resolvedTracks, resolvedHeight: resolvedHeight, gap: gap, virtualHeight: virtualHeight, overscan: overscan, renderTrackPrefix: renderTrackPrefix, renderTrackSuffix: renderTrackSuffix, renderBlockNode: renderBlockNode }));
8485
+ return (jsx(VirtualizedTrackList, { tracks: resolvedTracks, resolvedHeight: resolvedHeight, gap: gap, virtualHeight: virtualHeight, overscan: overscan, renderTrackPrefix: renderTrackPrefix, renderTrackSuffix: renderTrackSuffix, renderTrack: renderTrack, renderBlockNode: renderBlockNode }));
8477
8486
  }
8478
8487
  return (jsx(VStack, { align: "stretch", gap: gap, children: resolvedTracks.map((track, trackIndex) => {
8479
8488
  const trackBlocks = track.blocks.map((item) => item.block);
@@ -8487,7 +8496,15 @@ function TimeViewportBlocks({ blocks, viewportStart, viewportEnd, height = '28px
8487
8496
  trackBlocks,
8488
8497
  trackKey: track.trackKeyRaw,
8489
8498
  });
8490
- return (jsx(TimeViewportTrackRow, { trackKey: track.trackKey, blocks: track.blocks, resolvedHeight: resolvedHeight, prefix: prefix, suffix: suffix, renderBlockNode: renderBlockNode }));
8499
+ const defaultContent = (jsx(TimeViewportTrackRow, { trackKey: track.trackKey, blocks: track.blocks, resolvedHeight: resolvedHeight, prefix: prefix, suffix: suffix, renderBlockNode: renderBlockNode }));
8500
+ return renderTrack
8501
+ ? renderTrack({
8502
+ trackIndex,
8503
+ trackKey: track.trackKeyRaw,
8504
+ trackBlocks,
8505
+ defaultContent,
8506
+ })
8507
+ : defaultContent;
8491
8508
  }) }));
8492
8509
  }
8493
8510
  function TimeRangeZoom({ range, onRangeChange, minDurationMs = DEFAULT_MIN_DURATION_MS, maxDurationMs = DEFAULT_MAX_DURATION_MS, zoomFactor = DEFAULT_ZOOM_FACTOR, resetDurationMs, showResetButton = true, disabled = false, labels, }) {
@@ -117,6 +117,20 @@ export interface TimeViewportGridProps {
117
117
  animationDurationMs?: number;
118
118
  animationEasing?: string;
119
119
  }
120
+ export interface TimeViewportBlockRenderArgs {
121
+ block: TimeViewportBlockItem;
122
+ geometry: {
123
+ leftPercent: number;
124
+ widthPercent: number;
125
+ };
126
+ index: number;
127
+ }
128
+ export interface TimeViewportTrackRenderArgs {
129
+ trackIndex: number;
130
+ trackKey?: string | number;
131
+ trackBlocks: TimeViewportBlockItem[];
132
+ defaultContent: ReactNode;
133
+ }
120
134
  export interface TimeViewportBlocksProps {
121
135
  blocks: TimeViewportBlockItem[];
122
136
  viewportStart?: TimeInput;
@@ -141,6 +155,10 @@ export interface TimeViewportBlocksProps {
141
155
  trackBlocks: TimeViewportBlockItem[];
142
156
  trackKey?: string | number;
143
157
  }) => ReactNode;
158
+ /** Custom render function for block content. The returned node is placed inside a positioning wrapper that handles translateX and transitions. */
159
+ renderBlock?: (args: TimeViewportBlockRenderArgs) => ReactNode;
160
+ /** Custom render function for an entire track row. Receives the default rendered content so you can wrap or replace it. */
161
+ renderTrack?: (args: TimeViewportTrackRenderArgs) => ReactNode;
144
162
  onBlockClick?: (block: TimeViewportBlockItem) => void;
145
163
  /** Enable virtual scrolling for large track lists. */
146
164
  virtualize?: boolean;
@@ -231,7 +249,7 @@ export declare function TimeViewportHeader({ viewportStart, viewportEnd, tickCou
231
249
  * Render inside a relative container that also contains blocks.
232
250
  */
233
251
  export declare function TimeViewportGrid({ viewportStart, viewportEnd, tickCount, tickStrategy, tickUnit, tickStep, format, minorDivisions, majorLineColor, minorLineColor, showMinorLines, zIndex, animationDurationMs, animationEasing, }: TimeViewportGridProps): import("react/jsx-runtime").JSX.Element | null;
234
- export declare function TimeViewportBlocks({ blocks, viewportStart, viewportEnd, height, minWidthPx, borderRadius, defaultColorPalette, showLabel, hideWhenOutOfView, hideEmptyTracks, gap, allowOverlap, overlapOpacity, renderTrackPrefix, renderTrackSuffix, onBlockClick, virtualize, virtualHeight, overscan, }: TimeViewportBlocksProps): import("react/jsx-runtime").JSX.Element;
252
+ export declare function TimeViewportBlocks({ blocks, viewportStart, viewportEnd, height, minWidthPx, borderRadius, defaultColorPalette, showLabel, hideWhenOutOfView, hideEmptyTracks, gap, allowOverlap, overlapOpacity, renderTrackPrefix, renderTrackSuffix, renderBlock, renderTrack, onBlockClick, virtualize, virtualHeight, overscan, }: TimeViewportBlocksProps): import("react/jsx-runtime").JSX.Element;
235
253
  export declare function TimeRangeZoom({ range, onRangeChange, minDurationMs, maxDurationMs, zoomFactor, resetDurationMs, showResetButton, disabled, labels, }: TimeRangeZoomProps): import("react/jsx-runtime").JSX.Element;
236
254
  export declare function useTimeRangeZoom({ range, onRangeChange, minDurationMs, maxDurationMs, zoomFactor, resetDurationMs, disabled, labels, }: TimeRangeZoomProps): UseTimeRangeZoomResult;
237
255
  export {};
@@ -6,4 +6,4 @@ export { TimeRangeZoom, TimeViewportRoot, TimeViewportBlock, TimeViewportBlocks,
6
6
  export { UniversalPicker } from './UniversalPicker';
7
7
  export { DatePickerInput } from './DatePicker';
8
8
  export type { DatePickerProps, CalendarProps, GetDateColorProps, GetVariantProps, } from './DatePicker';
9
- export type { ViewableTimeRange, TimeRangeZoomLabels, TimeRangeZoomProps, TimeViewportRootProps, TimeViewportBlockProps, TimeViewportBlockItem, TimeViewportBlocksProps, TimeViewportGridProps, TimeViewportHeaderProps, TimeViewportMarkerLineProps, } from './TimeRangeZoom';
9
+ export type { ViewableTimeRange, TimeRangeZoomLabels, TimeRangeZoomProps, TimeViewportRootProps, TimeViewportBlockProps, TimeViewportBlockItem, TimeViewportBlocksProps, TimeViewportBlockRenderArgs, TimeViewportTrackRenderArgs, TimeViewportGridProps, TimeViewportHeaderProps, TimeViewportMarkerLineProps, } from './TimeRangeZoom';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bsol-oss/react-datatable5",
3
- "version": "13.0.1-beta.34",
3
+ "version": "13.0.1-beta.35",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",