fix(svgcanvas): Handle 'none' stroke color in SVG elements#1084
Conversation
This update modifies the stroke color handling in both the SvgCanvas and ext-connector modules. When the stroke color is set to 'none', it now correctly assigns an empty string or 'none' instead of a hex value, ensuring proper rendering of SVG elements without strokes.
Reviewer's guide (collapsed on small PRs)Reviewer's GuideAdjusts stroke color initialization so that a stroke value of 'none' is preserved (or becomes an empty string) instead of being converted to a hex color, fixing rendering of no-stroke SVG elements in both SvgCanvas and the connector extension. Class diagram for SvgCanvas stroke configuration handlingclassDiagram
class SvgCanvas {
+InitConfig curConfig
}
class InitConfig {
+InitFillConfig initFill
+InitStrokeConfig initStroke
}
class InitFillConfig {
+string color
+number opacity
}
class InitStrokeConfig {
+string color
+number opacity
+number width
}
SvgCanvas --> InitConfig : uses
InitConfig --> InitFillConfig : has
InitConfig --> InitStrokeConfig : has
class NewShapeAttributes {
+string stroke
+number stroke_opacity
+number stroke_width
}
SvgCanvas ..> NewShapeAttributes : computes
class ConnectorAttributes {
+string id
+string points
+string stroke
+number stroke_width
}
SvgCanvas ..> ConnectorAttributes : used_by_ext_connector
Flow diagram for stroke attribute computation when initStroke.color may be noneflowchart TD
A[Start: initStroke.color or curConfig.initStroke.color] --> B{Context}
B -->|SvgCanvas element init| C[Check curConfig.initStroke.color]
B -->|ext-connector connector creation| H[Check initStroke.color]
C --> D{curConfig.initStroke.color === none}
D -->|Yes| E[stroke = empty string]
D -->|No| F[stroke = # + curConfig.initStroke.color]
E --> G[Apply stroke to new SVG element]
F --> G[Apply stroke to new SVG element]
H --> I{initStroke.color === none}
I -->|Yes| J[stroke = none]
I -->|No| K[stroke = # + initStroke.color]
J --> L[Apply stroke to connector polyline]
K --> L[Apply stroke to connector polyline]
G --> M[SVG element renders with or without stroke as intended]
L --> M[Connector renders with or without stroke as intended]
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 1 issue, and left some high level feedback:
- The handling of
initStroke.color === 'none'is implemented slightly differently betweenext-connector(explicit'none') andsvgcanvas(empty string + color), which may lead to diverging behavior over time; consider centralizing stroke serialization in a small helper so both callsites stay consistent. - In
svgcanvas, the expression(this.curConfig.initStroke.color === 'none' ? '' : '#') + this.curConfig.initStroke.colorwill emit values like'none', but will also happily stringify unexpected values (e.g.,null→'#null'); it may be safer to guard for non‑string/empty stroke colors before concatenation.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The handling of `initStroke.color === 'none'` is implemented slightly differently between `ext-connector` (explicit `'none'`) and `svgcanvas` (empty string + color), which may lead to diverging behavior over time; consider centralizing stroke serialization in a small helper so both callsites stay consistent.
- In `svgcanvas`, the expression `(this.curConfig.initStroke.color === 'none' ? '' : '#') + this.curConfig.initStroke.color` will emit values like `'none'`, but will also happily stringify unexpected values (e.g., `null` → `'#null'`); it may be safer to guard for non‑string/empty stroke colors before concatenation.
## Individual Comments
### Comment 1
<location path="packages/svgcanvas/svgcanvas.js" line_range="202-208" />
<code_context>
fill_paint: null,
fill_opacity: this.curConfig.initFill.opacity,
- stroke: `#${this.curConfig.initStroke.color}`,
+ stroke:
+ (this.curConfig.initStroke.color === 'none' ? '' : '#') +
+ this.curConfig.initStroke.color,
stroke_paint: null,
</code_context>
<issue_to_address>
**suggestion:** The stroke formatting ternary is a bit opaque and could be made clearer and less error‑prone.
This relies on the reader noticing that `'' + 'none'` evaluates to `'none'`, which is correct but non-obvious and brittle if more sentinel values are added later. You could make this clearer with something like:
```js
stroke = this.curConfig.initStroke.color === 'none'
? 'none'
: `#${this.curConfig.initStroke.color}`;
```
This makes the special case explicit and separates the `#` prefixing from the value logic.
```suggestion
fill_paint: null,
fill_opacity: this.curConfig.initFill.opacity,
stroke:
this.curConfig.initStroke.color === 'none'
? 'none'
: `#${this.curConfig.initStroke.color}`,
stroke_paint: null,
stroke_opacity: this.curConfig.initStroke.opacity,
```
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| fill_paint: null, | ||
| fill_opacity: this.curConfig.initFill.opacity, | ||
| stroke: `#${this.curConfig.initStroke.color}`, | ||
| stroke: | ||
| (this.curConfig.initStroke.color === 'none' ? '' : '#') + | ||
| this.curConfig.initStroke.color, | ||
| stroke_paint: null, | ||
| stroke_opacity: this.curConfig.initStroke.opacity, |
There was a problem hiding this comment.
suggestion: The stroke formatting ternary is a bit opaque and could be made clearer and less error‑prone.
This relies on the reader noticing that '' + 'none' evaluates to 'none', which is correct but non-obvious and brittle if more sentinel values are added later. You could make this clearer with something like:
stroke = this.curConfig.initStroke.color === 'none'
? 'none'
: `#${this.curConfig.initStroke.color}`;This makes the special case explicit and separates the # prefixing from the value logic.
| fill_paint: null, | |
| fill_opacity: this.curConfig.initFill.opacity, | |
| stroke: `#${this.curConfig.initStroke.color}`, | |
| stroke: | |
| (this.curConfig.initStroke.color === 'none' ? '' : '#') + | |
| this.curConfig.initStroke.color, | |
| stroke_paint: null, | |
| stroke_opacity: this.curConfig.initStroke.opacity, | |
| fill_paint: null, | |
| fill_opacity: this.curConfig.initFill.opacity, | |
| stroke: | |
| this.curConfig.initStroke.color === 'none' | |
| ? 'none' | |
| : `#${this.curConfig.initStroke.color}`, | |
| stroke_paint: null, | |
| stroke_opacity: this.curConfig.initStroke.opacity, |
This update modifies the stroke color handling in both the SvgCanvas and ext-connector modules. When the stroke color is set to 'none', it now correctly assigns an empty string or 'none' instead of a hex value, ensuring proper rendering of SVG elements without strokes.
PR description
Checklist
Note that we require UI tests to ensure that the added feature will not be
nixed by some future fix and that there is at least some test-as-documentation
to indicate how the fix or enhancement is expected to behave.
npm test, ensuring linting passes and that Cypress UI tests keepcoverage to at least the same percent (reflected in the coverage badge
that should be updated after the tests run)
help both for future users and for the PR reviewer.
Summary by Sourcery
Handle SVG stroke color set to 'none' without converting it to a hex value, ensuring connectors and newly created elements render correctly without strokes.
Bug Fixes: