@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/README.md +50 -0
- package/dist/index.cjs +28 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +56 -1
- package/dist/index.d.ts +56 -1
- package/dist/index.js +28 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -407,12 +407,61 @@ Common rendering props:
|
|
|
407
407
|
- `loadingState?: React.ReactNode`
|
|
408
408
|
- `errorState?: React.ReactNode | ((error: Error) => React.ReactNode)`
|
|
409
409
|
- `fileTooLargeState?: React.ReactNode | ((props: XlsxFileTooLargeRenderProps) => React.ReactNode)`
|
|
410
|
+
- `getCellStyle?: (context: XlsxCellStyleContext) => React.CSSProperties | null | undefined`
|
|
410
411
|
- `renderImage?: (props: XlsxImageRenderProps) => React.ReactNode`
|
|
411
412
|
- `renderImageSelection?: (props: XlsxImageSelectionRenderProps) => React.ReactNode`
|
|
412
413
|
- `renderChartLoading?: (props: XlsxChartLoadingRenderProps) => React.ReactNode`
|
|
413
414
|
- `renderTableHeaderMenu?: (props: XlsxTableHeaderMenuRenderProps) => React.ReactNode`
|
|
414
415
|
- `renderScroller?: (props: XlsxScrollerRenderProps) => React.ReactNode`
|
|
415
416
|
|
|
417
|
+
### Custom Cell Styling
|
|
418
|
+
|
|
419
|
+
`getCellStyle` is an escape hatch for styling individual cells without forking the workbook data. It is called for every rendered cell and returns a partial `React.CSSProperties` that merges on top of the viewer's resolved style. Return `undefined` (or `null`) to leave a cell untouched.
|
|
420
|
+
|
|
421
|
+
```tsx
|
|
422
|
+
import { XlsxViewer, type XlsxViewerProps } from "@extend-ai/react-xlsx";
|
|
423
|
+
|
|
424
|
+
function Workbook({ buffer, highlighted }: { buffer: ArrayBuffer; highlighted: Set<string> }) {
|
|
425
|
+
const getCellStyle = React.useCallback<NonNullable<XlsxViewerProps["getCellStyle"]>>(
|
|
426
|
+
({ cell, isTableHeader }) => {
|
|
427
|
+
if (isTableHeader) {
|
|
428
|
+
return undefined;
|
|
429
|
+
}
|
|
430
|
+
if (highlighted.has(`${cell.row}:${cell.col}`)) {
|
|
431
|
+
return { backgroundColor: "rgba(37, 99, 235, 0.12)", outline: "1px solid #2563eb" };
|
|
432
|
+
}
|
|
433
|
+
return undefined;
|
|
434
|
+
},
|
|
435
|
+
[highlighted]
|
|
436
|
+
);
|
|
437
|
+
|
|
438
|
+
return <XlsxViewer file={buffer} getCellStyle={getCellStyle} />;
|
|
439
|
+
}
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
The `context` passed to `getCellStyle` is an `XlsxCellStyleContext`:
|
|
443
|
+
|
|
444
|
+
| Field | Type | Notes |
|
|
445
|
+
| --- | --- | --- |
|
|
446
|
+
| `cell` | `XlsxCellAddress` | Address of the cell being styled. |
|
|
447
|
+
| `workbookSheetIndex` | `number` | Workbook sheet index of the cell's sheet. |
|
|
448
|
+
| `sheetName` | `string` | Display name of the cell's sheet. |
|
|
449
|
+
| `resolvedStyle` | `React.CSSProperties` | The style the viewer computed (workbook formatting + built-ins). Read-only. |
|
|
450
|
+
| `value` | `string` | The cell's resolved display value. |
|
|
451
|
+
| `hasValidation` | `boolean` | Cell has a data validation rule. |
|
|
452
|
+
| `hasHyperlink` | `boolean` | Cell has a hyperlink. |
|
|
453
|
+
| `hasConditionalFormat` | `boolean` | Cell is affected by a color scale, data bar, or icon set. |
|
|
454
|
+
| `hasChartHighlight` | `boolean` | Cell is in a selected chart's highlighted source range. |
|
|
455
|
+
| `isMerged` | `boolean` | Cell is the anchor of a merged range. |
|
|
456
|
+
| `isTableHeader` | `boolean` | Cell is a table header cell. |
|
|
457
|
+
|
|
458
|
+
Notes:
|
|
459
|
+
|
|
460
|
+
- Keep the callback stable (e.g. `useCallback`) so cell styling is not recomputed every render. When the callback identity changes, the viewer re-resolves and repaints cells.
|
|
461
|
+
- The DOM renderer (`experimentalCanvas={false}`) applies every returned CSS property.
|
|
462
|
+
- The canvas renderer (the default) honors the subset it can paint: `backgroundColor`, `backgroundImage` gradients, `color`, the four `border*` sides, `padding`, `textAlign`, `textDecoration`, `textOverflow`, and font properties. CSS-only effects such as `boxShadow`, `outline`, or `animation` apply in the DOM renderer.
|
|
463
|
+
- `getCellStyle` is not applied to worksheet thumbnails painted via `useXlsxViewerThumbnails(...)`.
|
|
464
|
+
|
|
416
465
|
### Custom Scroll Area
|
|
417
466
|
|
|
418
467
|
By default, the viewer renders its native scroll viewport with the browser scrollbar. To use a custom scroll area, provide `renderScroller` and spread `viewportProps` onto the actual scrollable viewport element:
|
|
@@ -478,6 +527,7 @@ The package exports the main types you are likely to use for custom integrations
|
|
|
478
527
|
- `XlsxViewerCharts`
|
|
479
528
|
- `XlsxViewerThumbnails`
|
|
480
529
|
- `XlsxScrollerRenderProps`
|
|
530
|
+
- `XlsxCellStyleContext`
|
|
481
531
|
- `XlsxSheetThumbnail`
|
|
482
532
|
- `UseXlsxViewerThumbnailsOptions`
|
|
483
533
|
- `XlsxChart`, `XlsxChartSeries`, `XlsxChartAxis`, `XlsxChartsheet`
|
package/dist/index.cjs
CHANGED
|
@@ -21545,6 +21545,7 @@ function XlsxGrid({
|
|
|
21545
21545
|
enableCanvasSelectionAnimation = true,
|
|
21546
21546
|
errorState,
|
|
21547
21547
|
fileTooLargeState,
|
|
21548
|
+
getCellStyle,
|
|
21548
21549
|
loadingComponent,
|
|
21549
21550
|
loadingState,
|
|
21550
21551
|
renderChartLoading,
|
|
@@ -23504,7 +23505,7 @@ function XlsxGrid({
|
|
|
23504
23505
|
const viewportRowBatch = getRowsBatchAsync ? asyncViewportRowBatch : syncViewportRowBatch;
|
|
23505
23506
|
React4.useEffect(() => {
|
|
23506
23507
|
cellRenderCacheRef.current.clear();
|
|
23507
|
-
}, [activeSheetIndex, displayColLimit, displayRowLimit, palette, revision, viewportRowBatch, worksheet, zoomFactor]);
|
|
23508
|
+
}, [activeSheetIndex, displayColLimit, displayRowLimit, getCellStyle, palette, revision, viewportRowBatch, worksheet, zoomFactor]);
|
|
23508
23509
|
React4.useEffect(() => {
|
|
23509
23510
|
setAsyncViewportRowBatch(null);
|
|
23510
23511
|
}, [activeSheetIndex, revision]);
|
|
@@ -23629,6 +23630,29 @@ function XlsxGrid({
|
|
|
23629
23630
|
validation: resolveCellDataValidation(row, col, activeSheet),
|
|
23630
23631
|
value: sparkline ? "" : checkboxState !== null ? "" : batchCoversRow || !worksheet ? batchedCell?.value ?? "" : getCellDisplayValue(worksheet, row, col, activeSheet)
|
|
23631
23632
|
};
|
|
23633
|
+
if (getCellStyle) {
|
|
23634
|
+
const styleOverrides = getCellStyle({
|
|
23635
|
+
cell: { row, col },
|
|
23636
|
+
hasChartHighlight: Boolean(nextData.chartHighlight),
|
|
23637
|
+
hasConditionalFormat: Boolean(
|
|
23638
|
+
nextData.conditionalColorScale || nextData.conditionalDataBar || nextData.conditionalIcon
|
|
23639
|
+
),
|
|
23640
|
+
hasHyperlink: Boolean(nextData.hyperlink),
|
|
23641
|
+
hasValidation: Boolean(nextData.validation),
|
|
23642
|
+
isMerged: Boolean(nextData.colSpan || nextData.rowSpan),
|
|
23643
|
+
isTableHeader: Boolean(nextData.isTableHeader),
|
|
23644
|
+
resolvedStyle: { ...nextData.style },
|
|
23645
|
+
sheetName: activeSheet?.name ?? "",
|
|
23646
|
+
value: nextData.value,
|
|
23647
|
+
workbookSheetIndex: activeSheet?.workbookSheetIndex ?? -1
|
|
23648
|
+
});
|
|
23649
|
+
if (styleOverrides) {
|
|
23650
|
+
nextData.style = { ...nextData.style, ...styleOverrides };
|
|
23651
|
+
if (nextData.conditionalColorScale && (styleOverrides.backgroundColor !== void 0 || styleOverrides.background !== void 0)) {
|
|
23652
|
+
nextData.conditionalColorScale = null;
|
|
23653
|
+
}
|
|
23654
|
+
}
|
|
23655
|
+
}
|
|
23632
23656
|
nextData.canvas = buildCanvasCellStyleCache(nextData.style);
|
|
23633
23657
|
if (canCellTextOverflow(nextData)) {
|
|
23634
23658
|
const startColIndex = colIndexByActual.get(col);
|
|
@@ -23714,6 +23738,7 @@ function XlsxGrid({
|
|
|
23714
23738
|
displayDefaultColWidth,
|
|
23715
23739
|
displayEffectiveColWidths,
|
|
23716
23740
|
effectiveTables,
|
|
23741
|
+
getCellStyle,
|
|
23717
23742
|
palette,
|
|
23718
23743
|
sparklinesByCell,
|
|
23719
23744
|
viewportRowBatch,
|
|
@@ -28749,6 +28774,7 @@ function XlsxViewerInner({
|
|
|
28749
28774
|
errorState,
|
|
28750
28775
|
experimentalCanvas = true,
|
|
28751
28776
|
fileTooLargeState,
|
|
28777
|
+
getCellStyle,
|
|
28752
28778
|
height,
|
|
28753
28779
|
isDark = false,
|
|
28754
28780
|
loadingComponent,
|
|
@@ -28812,6 +28838,7 @@ function XlsxViewerInner({
|
|
|
28812
28838
|
errorState,
|
|
28813
28839
|
experimentalCanvas,
|
|
28814
28840
|
fileTooLargeState,
|
|
28841
|
+
getCellStyle,
|
|
28815
28842
|
loadingComponent,
|
|
28816
28843
|
loadingState,
|
|
28817
28844
|
palette,
|