Gradient cell fills
Linear and radial gradient fills on individual cells — round-trips XLSX and renders on canvas
Set a gradient on any cell's uf (user-entered format) and the canvas renderer paints it directly. Supports both linear (with a rotation angle) and path / radial (with axis-of-radial insets), each with two or more color stops.
Mirrors OOXML's <gradientFill> element. XLSX round-trip is full; the canvas paint uses native CanvasGradient (createLinearGradient / createRadialGradient).
Authoring
const cellData: CellData = {
ue: { sv: "Header" },
fv: "Header",
uf: {
gradient: {
type: "linear",
degree: 90, // 0 = left→right, 90 = top→bottom, 180 = right→left, 270 = bottom→top
stops: [
{ position: 0, color: "#fde68a" },
{ position: 1, color: "#dc2626" },
],
},
},
};position is on [0, 1]. At least two stops are required; three+ stops give multi-stop ramps.
Path / radial gradients
Use type: "path" with four optional inset values describing where the inner stop's "core" rectangle sits relative to the cell:
The example above produces a radial gradient centered in the cell. Shift the center off-axis by adjusting left / right / top / bottom (each 0..1 — the inset of the inner stop's core from that edge).
Three-stop ramps
Precedence over solid + pattern fills
When gradient is present on a cell's format, it takes precedence over backgroundColor and fillPattern. Excel's UI treats fills as mutually exclusive on a single cell, so the renderer matches that: pattern + solid are ignored.
The cellXfsRegistry deduplication hash includes the gradient stops, so two cells with the same gradient share a sid reference (same compression behavior as for regular fills).
XLSX round-trip
Parser reads <gradientFill> from xl/styles.xml and hydrates the gradient field on CellFormat. Exporter emits the same element with <stop position><color rgb="..."/></stop> children. Both linear and path/radial round-trip. The OOXML attributes map 1:1 onto the type's fields:
type="linear" + degree
type: "linear", degree
type="path" + left/right/top/bottom
type: "path", four inset fields
<stop position><color rgb=…/></stop>
stops array
Canvas rendering
The renderer constructs a CanvasGradient for each cell:
Linear: the gradient axis projects through the cell's centroid at the given angle; start/end points are where that axis exits the bounding box.
Path / radial: a
createRadialGradientanchored at the inset midpoint with radius = distance to the farthest corner.
setLineDash and stroke styles are preserved — gradient cells still get cell borders, conditional-format icons, etc.
Storybook example
See the compatShowcaseSheet in the storybook (Sheet 1, row 12) for a side-by-side gallery: linear 0°, linear 90°, linear 45° (3 stops), path (radial), linear 180°, and a linear vert 3-stop example. The pattern-fill row (row 11) is positioned right above so you can compare the two paint paths.
Last updated