@extend-ai/react-xlsx 0.10.4 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -889,6 +889,34 @@ interface XlsxTableHeaderMenuRenderProps {
889
889
  /** Props that must be applied to your menu trigger button so grid selection does not receive the click. */
890
890
  triggerProps: React.ButtonHTMLAttributes<HTMLButtonElement>;
891
891
  }
892
+ interface XlsxCellStyleContext {
893
+ /** Address of the cell being styled. */
894
+ cell: XlsxCellAddress;
895
+ /** True when the cell is part of a selected chart's highlighted source range. */
896
+ hasChartHighlight: boolean;
897
+ /** True when a conditional format (color scale, data bar, or icon set) applies to the cell. */
898
+ hasConditionalFormat: boolean;
899
+ /** True when the cell has a hyperlink. */
900
+ hasHyperlink: boolean;
901
+ /** True when the cell has a data validation rule. */
902
+ hasValidation: boolean;
903
+ /** True when the cell is the anchor of a merged range. */
904
+ isMerged: boolean;
905
+ /** True when the cell is a table header cell. */
906
+ isTableHeader: boolean;
907
+ /**
908
+ * The fully resolved style the viewer computed for this cell, combining the workbook's
909
+ * own formatting with the viewer's built-in styling. Treat this as read-only; returning
910
+ * a partial style from `getCellStyle` merges on top of it.
911
+ */
912
+ resolvedStyle: React.CSSProperties;
913
+ /** Display name of the sheet the cell belongs to. */
914
+ sheetName: string;
915
+ /** The cell's resolved display value. */
916
+ value: string;
917
+ /** Workbook sheet index of the cell's sheet. */
918
+ workbookSheetIndex: number;
919
+ }
892
920
  interface XlsxViewerProviderProps extends UseXlsxViewerControllerOptions {
893
921
  /** Viewer UI and hooks that should share this provider's workbook controller. */
894
922
  children: React.ReactNode;
@@ -956,6 +984,33 @@ interface XlsxViewerProps extends UseXlsxViewerControllerOptions {
956
984
  errorState?: React.ReactNode | ((error: Error) => React.ReactNode);
957
985
  /** Content shown when `maxFileSizeBytes` rejects a file. */
958
986
  fileTooLargeState?: React.ReactNode | ((props: XlsxFileTooLargeRenderProps) => React.ReactNode);
987
+ /**
988
+ * Returns extra CSS style overrides for an individual cell. Called for every rendered cell
989
+ * with the cell's address, sheet, resolved style, and contextual flags. Return `undefined`
990
+ * (or `null`) to leave a cell untouched, or a partial style object that merges on top of the
991
+ * viewer's resolved style. Use this as an escape hatch for custom per-cell styling such as
992
+ * highlights, outlines, or status tints, without forking the workbook data.
993
+ *
994
+ * The DOM renderer applies every returned CSS property. The canvas renderer
995
+ * (`experimentalCanvas`, the default) honors the subset it can paint: `backgroundColor`,
996
+ * `backgroundImage` gradients, `color`, the four `border*` sides, `padding`, `textAlign`,
997
+ * `textDecoration`, `textOverflow`, and font properties. CSS-only effects such as `boxShadow`,
998
+ * `outline`, or `animation` apply in the DOM renderer (`experimentalCanvas={false}`).
999
+ *
1000
+ * Keep this callback stable (e.g. wrap it in `useCallback`) so cell styling is not recomputed
1001
+ * on every render. When the callback identity changes, the viewer re-resolves and repaints
1002
+ * cell styles.
1003
+ *
1004
+ * @example
1005
+ * ```tsx
1006
+ * const getCellStyle = React.useCallback<NonNullable<XlsxViewerProps["getCellStyle"]>>(
1007
+ * ({ cell }) => (cell.row === 3 && cell.col === 1 ? { backgroundColor: "#dbeafe" } : undefined),
1008
+ * []
1009
+ * );
1010
+ * return <XlsxViewer file={buffer} getCellStyle={getCellStyle} />;
1011
+ * ```
1012
+ */
1013
+ getCellStyle?: (context: XlsxCellStyleContext) => React.CSSProperties | null | undefined;
959
1014
  /**
960
1015
  * CSS height for the viewer container.
961
1016
  *
@@ -1081,4 +1136,4 @@ declare function useXlsxViewerThumbnails(options?: UseXlsxViewerThumbnailsOption
1081
1136
  declare function XlsxViewer(props: XlsxViewerProps): react_jsx_runtime.JSX.Element;
1082
1137
  declare function DefaultXlsxToolbar(): react_jsx_runtime.JSX.Element;
1083
1138
 
1084
- export { DefaultXlsxToolbar, type UseXlsxViewerControllerOptions, type UseXlsxViewerThumbnailsOptions, type XlsxCellAddress, type XlsxCellRange, type XlsxChart, type XlsxChartAxis, type XlsxChartDataLabels, type XlsxChartLoadingRenderProps, type XlsxChartReference, type XlsxChartSeries, type XlsxChartsheet, XlsxFileSizeLimitExceededError, type XlsxFileTooLargeRenderProps, type XlsxImage, type XlsxImageAnchor, type XlsxImageRect, type XlsxImageRenderProps, type XlsxImageResizeHandlePosition, type XlsxImageSelectionRenderProps, type XlsxScrollerRenderProps, type XlsxShape, type XlsxShapeFill, type XlsxShapeParagraph, type XlsxShapeStroke, type XlsxShapeTextBox, type XlsxShapeTextRun, type XlsxSheetData, type XlsxSheetThumbnail, type XlsxSheetThumbnailResolution, type XlsxSheetVisibility, type XlsxTable, type XlsxTableColumn, type XlsxTableHeaderMenuRenderProps, type XlsxTableSortDirection, type XlsxTableSortState, type XlsxThemePalette, XlsxViewer, type XlsxViewerCharts, type XlsxViewerController, type XlsxViewerEditing, type XlsxViewerImages, type XlsxViewerProps, XlsxViewerProvider, type XlsxViewerProviderProps, type XlsxViewerSelection, type XlsxViewerTables, type XlsxViewerThumbnails, type XlsxViewerZoom, type XlsxWasmSource, type XlsxWorkbookTab, initWasm, setWasmSource, useXlsxViewer, useXlsxViewerCharts, useXlsxViewerController, useXlsxViewerEditing, useXlsxViewerImages, useXlsxViewerSelection, useXlsxViewerTables, useXlsxViewerThumbnails, useXlsxViewerZoom };
1139
+ export { DefaultXlsxToolbar, type UseXlsxViewerControllerOptions, type UseXlsxViewerThumbnailsOptions, type XlsxCellAddress, type XlsxCellRange, type XlsxCellStyleContext, type XlsxChart, type XlsxChartAxis, type XlsxChartDataLabels, type XlsxChartLoadingRenderProps, type XlsxChartReference, type XlsxChartSeries, type XlsxChartsheet, XlsxFileSizeLimitExceededError, type XlsxFileTooLargeRenderProps, type XlsxImage, type XlsxImageAnchor, type XlsxImageRect, type XlsxImageRenderProps, type XlsxImageResizeHandlePosition, type XlsxImageSelectionRenderProps, type XlsxScrollerRenderProps, type XlsxShape, type XlsxShapeFill, type XlsxShapeParagraph, type XlsxShapeStroke, type XlsxShapeTextBox, type XlsxShapeTextRun, type XlsxSheetData, type XlsxSheetThumbnail, type XlsxSheetThumbnailResolution, type XlsxSheetVisibility, type XlsxTable, type XlsxTableColumn, type XlsxTableHeaderMenuRenderProps, type XlsxTableSortDirection, type XlsxTableSortState, type XlsxThemePalette, XlsxViewer, type XlsxViewerCharts, type XlsxViewerController, type XlsxViewerEditing, type XlsxViewerImages, type XlsxViewerProps, XlsxViewerProvider, type XlsxViewerProviderProps, type XlsxViewerSelection, type XlsxViewerTables, type XlsxViewerThumbnails, type XlsxViewerZoom, type XlsxWasmSource, type XlsxWorkbookTab, initWasm, setWasmSource, useXlsxViewer, useXlsxViewerCharts, useXlsxViewerController, useXlsxViewerEditing, useXlsxViewerImages, useXlsxViewerSelection, useXlsxViewerTables, useXlsxViewerThumbnails, useXlsxViewerZoom };
package/dist/index.d.ts CHANGED
@@ -889,6 +889,34 @@ interface XlsxTableHeaderMenuRenderProps {
889
889
  /** Props that must be applied to your menu trigger button so grid selection does not receive the click. */
890
890
  triggerProps: React.ButtonHTMLAttributes<HTMLButtonElement>;
891
891
  }
892
+ interface XlsxCellStyleContext {
893
+ /** Address of the cell being styled. */
894
+ cell: XlsxCellAddress;
895
+ /** True when the cell is part of a selected chart's highlighted source range. */
896
+ hasChartHighlight: boolean;
897
+ /** True when a conditional format (color scale, data bar, or icon set) applies to the cell. */
898
+ hasConditionalFormat: boolean;
899
+ /** True when the cell has a hyperlink. */
900
+ hasHyperlink: boolean;
901
+ /** True when the cell has a data validation rule. */
902
+ hasValidation: boolean;
903
+ /** True when the cell is the anchor of a merged range. */
904
+ isMerged: boolean;
905
+ /** True when the cell is a table header cell. */
906
+ isTableHeader: boolean;
907
+ /**
908
+ * The fully resolved style the viewer computed for this cell, combining the workbook's
909
+ * own formatting with the viewer's built-in styling. Treat this as read-only; returning
910
+ * a partial style from `getCellStyle` merges on top of it.
911
+ */
912
+ resolvedStyle: React.CSSProperties;
913
+ /** Display name of the sheet the cell belongs to. */
914
+ sheetName: string;
915
+ /** The cell's resolved display value. */
916
+ value: string;
917
+ /** Workbook sheet index of the cell's sheet. */
918
+ workbookSheetIndex: number;
919
+ }
892
920
  interface XlsxViewerProviderProps extends UseXlsxViewerControllerOptions {
893
921
  /** Viewer UI and hooks that should share this provider's workbook controller. */
894
922
  children: React.ReactNode;
@@ -956,6 +984,33 @@ interface XlsxViewerProps extends UseXlsxViewerControllerOptions {
956
984
  errorState?: React.ReactNode | ((error: Error) => React.ReactNode);
957
985
  /** Content shown when `maxFileSizeBytes` rejects a file. */
958
986
  fileTooLargeState?: React.ReactNode | ((props: XlsxFileTooLargeRenderProps) => React.ReactNode);
987
+ /**
988
+ * Returns extra CSS style overrides for an individual cell. Called for every rendered cell
989
+ * with the cell's address, sheet, resolved style, and contextual flags. Return `undefined`
990
+ * (or `null`) to leave a cell untouched, or a partial style object that merges on top of the
991
+ * viewer's resolved style. Use this as an escape hatch for custom per-cell styling such as
992
+ * highlights, outlines, or status tints, without forking the workbook data.
993
+ *
994
+ * The DOM renderer applies every returned CSS property. The canvas renderer
995
+ * (`experimentalCanvas`, the default) honors the subset it can paint: `backgroundColor`,
996
+ * `backgroundImage` gradients, `color`, the four `border*` sides, `padding`, `textAlign`,
997
+ * `textDecoration`, `textOverflow`, and font properties. CSS-only effects such as `boxShadow`,
998
+ * `outline`, or `animation` apply in the DOM renderer (`experimentalCanvas={false}`).
999
+ *
1000
+ * Keep this callback stable (e.g. wrap it in `useCallback`) so cell styling is not recomputed
1001
+ * on every render. When the callback identity changes, the viewer re-resolves and repaints
1002
+ * cell styles.
1003
+ *
1004
+ * @example
1005
+ * ```tsx
1006
+ * const getCellStyle = React.useCallback<NonNullable<XlsxViewerProps["getCellStyle"]>>(
1007
+ * ({ cell }) => (cell.row === 3 && cell.col === 1 ? { backgroundColor: "#dbeafe" } : undefined),
1008
+ * []
1009
+ * );
1010
+ * return <XlsxViewer file={buffer} getCellStyle={getCellStyle} />;
1011
+ * ```
1012
+ */
1013
+ getCellStyle?: (context: XlsxCellStyleContext) => React.CSSProperties | null | undefined;
959
1014
  /**
960
1015
  * CSS height for the viewer container.
961
1016
  *
@@ -1081,4 +1136,4 @@ declare function useXlsxViewerThumbnails(options?: UseXlsxViewerThumbnailsOption
1081
1136
  declare function XlsxViewer(props: XlsxViewerProps): react_jsx_runtime.JSX.Element;
1082
1137
  declare function DefaultXlsxToolbar(): react_jsx_runtime.JSX.Element;
1083
1138
 
1084
- export { DefaultXlsxToolbar, type UseXlsxViewerControllerOptions, type UseXlsxViewerThumbnailsOptions, type XlsxCellAddress, type XlsxCellRange, type XlsxChart, type XlsxChartAxis, type XlsxChartDataLabels, type XlsxChartLoadingRenderProps, type XlsxChartReference, type XlsxChartSeries, type XlsxChartsheet, XlsxFileSizeLimitExceededError, type XlsxFileTooLargeRenderProps, type XlsxImage, type XlsxImageAnchor, type XlsxImageRect, type XlsxImageRenderProps, type XlsxImageResizeHandlePosition, type XlsxImageSelectionRenderProps, type XlsxScrollerRenderProps, type XlsxShape, type XlsxShapeFill, type XlsxShapeParagraph, type XlsxShapeStroke, type XlsxShapeTextBox, type XlsxShapeTextRun, type XlsxSheetData, type XlsxSheetThumbnail, type XlsxSheetThumbnailResolution, type XlsxSheetVisibility, type XlsxTable, type XlsxTableColumn, type XlsxTableHeaderMenuRenderProps, type XlsxTableSortDirection, type XlsxTableSortState, type XlsxThemePalette, XlsxViewer, type XlsxViewerCharts, type XlsxViewerController, type XlsxViewerEditing, type XlsxViewerImages, type XlsxViewerProps, XlsxViewerProvider, type XlsxViewerProviderProps, type XlsxViewerSelection, type XlsxViewerTables, type XlsxViewerThumbnails, type XlsxViewerZoom, type XlsxWasmSource, type XlsxWorkbookTab, initWasm, setWasmSource, useXlsxViewer, useXlsxViewerCharts, useXlsxViewerController, useXlsxViewerEditing, useXlsxViewerImages, useXlsxViewerSelection, useXlsxViewerTables, useXlsxViewerThumbnails, useXlsxViewerZoom };
1139
+ export { DefaultXlsxToolbar, type UseXlsxViewerControllerOptions, type UseXlsxViewerThumbnailsOptions, type XlsxCellAddress, type XlsxCellRange, type XlsxCellStyleContext, type XlsxChart, type XlsxChartAxis, type XlsxChartDataLabels, type XlsxChartLoadingRenderProps, type XlsxChartReference, type XlsxChartSeries, type XlsxChartsheet, XlsxFileSizeLimitExceededError, type XlsxFileTooLargeRenderProps, type XlsxImage, type XlsxImageAnchor, type XlsxImageRect, type XlsxImageRenderProps, type XlsxImageResizeHandlePosition, type XlsxImageSelectionRenderProps, type XlsxScrollerRenderProps, type XlsxShape, type XlsxShapeFill, type XlsxShapeParagraph, type XlsxShapeStroke, type XlsxShapeTextBox, type XlsxShapeTextRun, type XlsxSheetData, type XlsxSheetThumbnail, type XlsxSheetThumbnailResolution, type XlsxSheetVisibility, type XlsxTable, type XlsxTableColumn, type XlsxTableHeaderMenuRenderProps, type XlsxTableSortDirection, type XlsxTableSortState, type XlsxThemePalette, XlsxViewer, type XlsxViewerCharts, type XlsxViewerController, type XlsxViewerEditing, type XlsxViewerImages, type XlsxViewerProps, XlsxViewerProvider, type XlsxViewerProviderProps, type XlsxViewerSelection, type XlsxViewerTables, type XlsxViewerThumbnails, type XlsxViewerZoom, type XlsxWasmSource, type XlsxWorkbookTab, initWasm, setWasmSource, useXlsxViewer, useXlsxViewerCharts, useXlsxViewerController, useXlsxViewerEditing, useXlsxViewerImages, useXlsxViewerSelection, useXlsxViewerTables, useXlsxViewerThumbnails, useXlsxViewerZoom };
package/dist/index.js CHANGED
@@ -21511,6 +21511,7 @@ function XlsxGrid({
21511
21511
  enableCanvasSelectionAnimation = true,
21512
21512
  errorState,
21513
21513
  fileTooLargeState,
21514
+ getCellStyle,
21514
21515
  loadingComponent,
21515
21516
  loadingState,
21516
21517
  renderChartLoading,
@@ -23470,7 +23471,7 @@ function XlsxGrid({
23470
23471
  const viewportRowBatch = getRowsBatchAsync ? asyncViewportRowBatch : syncViewportRowBatch;
23471
23472
  React4.useEffect(() => {
23472
23473
  cellRenderCacheRef.current.clear();
23473
- }, [activeSheetIndex, displayColLimit, displayRowLimit, palette, revision, viewportRowBatch, worksheet, zoomFactor]);
23474
+ }, [activeSheetIndex, displayColLimit, displayRowLimit, getCellStyle, palette, revision, viewportRowBatch, worksheet, zoomFactor]);
23474
23475
  React4.useEffect(() => {
23475
23476
  setAsyncViewportRowBatch(null);
23476
23477
  }, [activeSheetIndex, revision]);
@@ -23595,6 +23596,29 @@ function XlsxGrid({
23595
23596
  validation: resolveCellDataValidation(row, col, activeSheet),
23596
23597
  value: sparkline ? "" : checkboxState !== null ? "" : batchCoversRow || !worksheet ? batchedCell?.value ?? "" : getCellDisplayValue(worksheet, row, col, activeSheet)
23597
23598
  };
23599
+ if (getCellStyle) {
23600
+ const styleOverrides = getCellStyle({
23601
+ cell: { row, col },
23602
+ hasChartHighlight: Boolean(nextData.chartHighlight),
23603
+ hasConditionalFormat: Boolean(
23604
+ nextData.conditionalColorScale || nextData.conditionalDataBar || nextData.conditionalIcon
23605
+ ),
23606
+ hasHyperlink: Boolean(nextData.hyperlink),
23607
+ hasValidation: Boolean(nextData.validation),
23608
+ isMerged: Boolean(nextData.colSpan || nextData.rowSpan),
23609
+ isTableHeader: Boolean(nextData.isTableHeader),
23610
+ resolvedStyle: { ...nextData.style },
23611
+ sheetName: activeSheet?.name ?? "",
23612
+ value: nextData.value,
23613
+ workbookSheetIndex: activeSheet?.workbookSheetIndex ?? -1
23614
+ });
23615
+ if (styleOverrides) {
23616
+ nextData.style = { ...nextData.style, ...styleOverrides };
23617
+ if (nextData.conditionalColorScale && (styleOverrides.backgroundColor !== void 0 || styleOverrides.background !== void 0)) {
23618
+ nextData.conditionalColorScale = null;
23619
+ }
23620
+ }
23621
+ }
23598
23622
  nextData.canvas = buildCanvasCellStyleCache(nextData.style);
23599
23623
  if (canCellTextOverflow(nextData)) {
23600
23624
  const startColIndex = colIndexByActual.get(col);
@@ -23680,6 +23704,7 @@ function XlsxGrid({
23680
23704
  displayDefaultColWidth,
23681
23705
  displayEffectiveColWidths,
23682
23706
  effectiveTables,
23707
+ getCellStyle,
23683
23708
  palette,
23684
23709
  sparklinesByCell,
23685
23710
  viewportRowBatch,
@@ -28715,6 +28740,7 @@ function XlsxViewerInner({
28715
28740
  errorState,
28716
28741
  experimentalCanvas = true,
28717
28742
  fileTooLargeState,
28743
+ getCellStyle,
28718
28744
  height,
28719
28745
  isDark = false,
28720
28746
  loadingComponent,
@@ -28778,6 +28804,7 @@ function XlsxViewerInner({
28778
28804
  errorState,
28779
28805
  experimentalCanvas,
28780
28806
  fileTooLargeState,
28807
+ getCellStyle,
28781
28808
  loadingComponent,
28782
28809
  loadingState,
28783
28810
  palette,