This document describes the Stylesheet class and the style resolution algorithm that transforms cell-specific style declarations into computed styles used for rendering. The stylesheet acts as a central registry for named styles and implements a cascading merge strategy to combine default styles, registered styles, and cell-specific properties.
For information about the overall style system architecture and registries, see Style System Overview. For details about the CellStyle and CellStateStyle type definitions, see CellStyle and CellStateStyle. For information about how resolved styles are used during rendering, see CellRenderer and Shape Creation.
The Stylesheet class serves as the central style registry and resolution engine. It stores named style definitions and provides methods to merge them into computed styles for cells.
Sources: packages/core/src/view/style/Stylesheet.ts49-61
The stylesheet automatically initializes two built-in styles during construction:
| Style Name | Purpose | Key Properties |
|---|---|---|
defaultVertex | Default style for vertices | shape: 'rectangle', perimeter: 'rectanglePerimeter', fillColor: '#C3D9FF', strokeColor: '#6482B9' |
defaultEdge | Default style for edges | shape: 'connector', endArrow: 'classic', strokeColor: '#6482B9' |
These defaults are created by createDefaultVertexStyle() and createDefaultEdgeStyle() methods and registered with putDefaultVertexStyle() and putDefaultEdgeStyle().
Sources: packages/core/src/view/style/Stylesheet.ts66-120
Custom styles are registered using the putCellStyle() method:
The style is then referenced in cells using the baseStyleNames property:
Sources: packages/core/src/view/style/Stylesheet.ts122-154
The getCellStyle() method implements the cascading style resolution algorithm that transforms a CellStyle object (with baseStyleNames and cell-specific properties) into a computed CellStateStyle object.
Sources: packages/core/src/view/style/Stylesheet.ts171-197
The algorithm starts by either:
{} if cellStyle.ignoreDefaultStyle === truedefaultStyle parameter: { ...defaultStyle }Sources: packages/core/src/view/style/Stylesheet.ts172
If cellStyle.baseStyleNames is defined and non-empty, the algorithm iterates through the array and merges each registered style:
Important: The order in baseStyleNames matters. Styles are merged left to right, so later styles override earlier ones if they define the same property.
Sources: packages/core/src/view/style/Stylesheet.ts173-180
All properties defined directly in the cellStyle parameter are merged into the result:
Properties with undefined values are filtered out, allowing fallback to earlier styles in the cascade.
Sources: packages/core/src/view/style/Stylesheet.ts184-190
NONE KeywordThe special keyword NONE (constant defined in Constants.ts) can be used to explicitly unset a property, even if it was defined in the default style or base styles:
Sources: packages/core/src/view/style/Stylesheet.ts188 packages/core/src/util/Constants.ts
The final step removes properties that are specific to CellStyle and should not appear in the computed CellStateStyle:
Sources: packages/core/src/view/style/Stylesheet.ts193-194
Merge Priority:
dashed: true — from default stylefillColor: 'blue' — from style-1shape: 'cloud' — from cell style (overrides style-1 and default)strokeColor: 'yellow' — from cell style (overrides default)Sources: packages/core/__tests__/view/style/StyleSheet.test.ts86-105
Key Observation: The fillColor property is defined in all three base styles, but 'chartreuse' from style3 wins because it appears last in the baseStyleNames array.
Sources: packages/core/__tests__/view/style/StyleSheet.test.ts108-142
NONE to Unset PropertiesSources: packages/core/__tests__/view/style/StyleSheet.test.ts206-228
When ignoreDefaultStyle: true is set, the default style is completely skipped:
Note: The fillColor: 'red' from the default style does not appear in the result.
Sources: packages/core/__tests__/view/style/StyleSheet.test.ts276-314
Sources: packages/core/src/view/Graph.ts73-75 packages/core/src/view/cell/CellRenderer.ts177-192
The Graph class creates a default Stylesheet instance during initialization:
This stylesheet is then set on the graph and used by the view for all style resolution operations.
Sources: packages/core/src/view/Graph.ts73-75
The CellRenderer uses the resolved style when configuring shapes:
CellRenderer.configureShape() is called during shape initializationshape.apply(state) where state.style is a computed CellStateStyleSources: packages/core/src/view/cell/CellRenderer.ts177-192
After style resolution, CellRenderer performs an additional resolution pass for special color value keywords like 'inherit', 'swimlane', and 'indicated'. This is distinct from the cascading merge performed by Stylesheet.getCellStyle() and happens at render time.
| Keyword | Behavior |
|---|---|
'inherit' | Use the color from the direct parent cell |
'swimlane' | Use the indicator color of the parent swimlane |
'indicated' | Use the indicator color of the current shape |
'none' | Explicitly set no color |
Resolution Method: CellRenderer.resolveColor() and CellRenderer.postConfigureShape()
Sources: packages/core/src/view/cell/CellRenderer.ts200-281
The Stylesheet class implements a flexible cascading style system:
| Component | Role |
|---|---|
Stylesheet | Central registry for named styles |
getCellStyle() | Cascading merge algorithm |
styles Map | Storage for named CellStateStyle objects |
CellStyle | Input with baseStyleNames and cell-specific properties |
CellStateStyle | Computed output with 80+ rendering properties |
Key Features:
putCellStyle()baseStyleNames array for style composition (left-to-right merge)ignoreDefaultStyle flag to skip default style'none' keyword to explicitly unset propertiesundefined property values allow fallback to earlier cascade layersSources: packages/core/src/view/style/Stylesheet.ts23-198 packages/core/src/types.ts44-75
Refresh this wiki