From efd80c263434018a22acec65a345a21a0246f966 Mon Sep 17 00:00:00 2001 From: Guillaume Fontorbe Date: Thu, 8 Feb 2024 10:48:43 +0100 Subject: [PATCH] Styling documentation Signed-off-by: Guillaume Fontorbe --- hugo/content/docs/styling.md | 135 +++++++++++++++++++++ hugo/themes/hugo-geekdoc/static/custom.css | 4 + 2 files changed, 139 insertions(+) create mode 100644 hugo/content/docs/styling.md diff --git a/hugo/content/docs/styling.md b/hugo/content/docs/styling.md new file mode 100644 index 0000000..3dafb6e --- /dev/null +++ b/hugo/content/docs/styling.md @@ -0,0 +1,135 @@ +--- +title: 'Styling' +--- + +{{}} + +Sprotty is designed to be highly customizable. Styling of diagram elements is done using CSS, preferably using CSS classes. There are several ways to apply styles to an element depending on the level of granularity you need. + +## Predefined Styling + +### Available Views + +Sprotty comes with a handful of views that can be used to represent nodes, edges, and labels of your diagram. These views correspond to the most common SVG elements such as `rect`, `circle`, `text`, and `path`. + +The following views can be used for visualizing nodes and ports: + +* `CircularNodeView`: A circular representation of a node. Produces a `circle` SVG element. +* `RectangularNodeView`: A rectangular representation of a node. Produces a `rect` SVG element. +* `DiamondNodeView`: A diamond-shaped representation of a node. Produces a `polygon` SVG element. + +For representing edges, the following views are available: + +* `PolylineEdgeView`: A succession of straight lines between two nodes. Produces a `path` SVG element. +* `JumpingPolylineEdgeView`: A succession of straight lines between two nodes with an arc where two or more edges intersect. Produces a `path` SVG element. +* `PolylineEdgeViewWithGapsOnIntersections`: A succession of straight lines between two nodes with a gap where two or more edges intersect. Produces a `path` SVG element. +* `BezierCurveEdgeView`: An succession of Bezier curves. Produces a `path` SVG element. + +For representing labels, the following view is available: + +* `SLabelView`: A simple text label. Produces a `text` SVG element. + +### Default CSS Classes + +Those default views assume that your are using the default implementations of diagram elements, namely `SGraphImpl`, `SNodeImpl`, `SPortImpl`, `SEdgeImpl`, and `SLabelImpl`. + +The default views listed above use the following CSS classes to style the SVG elements: + +* `sprotty-graph`: class for the root SVG element of the diagram. +* `sprotty-node`: class for the SVG element representing a node. +* `sprotty-port`: class for the SVG element representing a port. +* `sprotty-edge`: class for the SVG element representing an edge. +* `sprotty-label`: class for the SVG element representing a label. + +By using those CSS classes, you can easily style all nodes, ports, edges, and labels of your diagram in a uniform way. + +## Using Subtypes for Styling + +When dealing with diagrams with different types of nodes, ports, edges, or labels, it is common to want different styling for each type. Using the default CSS classes is not enough in this case as it would apply the same style to all nodes, ports, edges, or labels. + +By convention, Sprotty uses the `type` property, which is a string of the shape `main-type:sub-type`, to distinguish between different types of diagram elements. For example, a node of type `node:my-node` has the main type `node` and the sub-type `my-node`. + +Using this convention, you can add a CSS class for each diagram element sub-type. For example: + +* A node of type `node:my-node` using the `RectangularNodeView` would have the following CSS classes: `sprotty-node` and `my-node`. +* A node of type `node:my-other-node` using the `RectangularNodeView` would have the following CSS classes: `sprotty-node` and `my-other-node`. + +This allows for more control over the styling of your diagram elements. + +## Styling on a Per-Element Basis + +If the granularity of elements base type and sub-type is not enough for your use case, you can also style each diagram element individually. This can be done by adding a `cssClasses` property to the `SModelElement` that you want to style. This property should be an array of strings representing the CSS classes you want to apply to the element. + +```typescript +const myNode: SNode = { + id: 'node1', + type: 'node:my-node', + cssClasses: ['special-node', 'some-other-css-class'] + ... +}; +``` + +Assuming that this node is implementing the `RectangularNodeView`, the resulting SVG element would have the following CSS classes: `sprotty-node`, `my-node`, `special-node`, and `some-other-css-class`. + +## Styling from Custom Views + +The highest level of control over the styling of your diagram elements is achieved by creating custom views. By creating a custom view, you can define the exact SVG elements that should be used to represent your diagram elements and apply any CSS classes you want. + +To add a class to an SVG element, you need to use the `class-my-class={boolean}` convention inside of the SVG element. For example: + +```typescript + +``` + +Sprotty will internally convert this to the expected class attribute if the boolean is `true`. + +This convention can be used to apply CSS classes to the SVG elements if a certain condition is met. For example, you could use this to apply a CSS class to an element if a certain property meets a condition: + +```typescript +class MyNodeImpl extends SNodeImpl { + value: number; +} + +class MyNodeView extends ShapeView { + render(node: MyNodeImpl, context: RenderingContext, args?: ViewArgs): VNode | undefined { + return + = 10} + /> + {context.renderChildren(node)} + ; + } +} +``` + +## Styling on User Interaction + +Taking advantage of the conditional CSS classes, you can also apply styles to your diagram elements based on user interaction. For example, you could apply a CSS class to a node when it is selected. Without going into the details of how to handle user interaction, let's look at how Sprotty's default views handle this. + +`SNodeImpl` has the default feature `selectFeature`, meaning that when a node is selected, its `selected` property is set to `true`. This property can be used in the corresponding view to add a CSS class to the selected element. For example in the `RectangularNodeView`: + +```typescript +export class RectangularNodeView extends ShapeView { + render(node: Readonly, context: RenderingContext, args?: IViewArgs): VNode | undefined { + if (!this.isVisible(node, context)) { + return undefined; + } + return + + {context.renderChildren(node)} + ; + } +} +``` + +Note the `class-selected={node.selected}`. This will apply the CSS class `selected` to the SVG element when the `selected` property of the node is `true`. + +Similarly, you can see that the `class-mouseover={node.hoverFeedback}` applies the CSS class `mouseover` to the SVG element when the `hoverFeedback` property of the node is `true`. For this the `hoverFeedbackFeature` must be enabled on the node. diff --git a/hugo/themes/hugo-geekdoc/static/custom.css b/hugo/themes/hugo-geekdoc/static/custom.css index a4d24d7..e8c64df 100644 --- a/hugo/themes/hugo-geekdoc/static/custom.css +++ b/hugo/themes/hugo-geekdoc/static/custom.css @@ -1,4 +1,8 @@ /* You can add custom styles here. */ +:root .chroma .err { + background-color: inherit !important; +} + pre { max-height: 500px !important; } \ No newline at end of file