Support inherited SVG paint attributes#990
Conversation
WalkthroughThe changes add SVG stroke-related optional attributes to the root model and a nullable 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Tip 💬 Introducing [Slack Agent](https://www.coderabbit.ai/agent): Turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. 👉 Get your free trial and get 200 agent minutes per Slack user (a $50 value). Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
components/parser/kmp/svg/src/commonTest/kotlin/io/github/composegears/valkyrie/parser/kmp/svg/SVGParserTest.kt (1)
68-129: ⚡ Quick winAdd coverage for group stroke and inherited stroke opacity/miter.
The new tests only assert root stroke color/width/cap/join and group fill. The new branches in
SVG.Group.toVectorGroup()andSVG.Child.getSVGStrokeWithDefaults()for group-level stroke cascade plus inheritedstroke-opacity/stroke-miterlimitcan still regress unnoticed.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@components/parser/kmp/svg/src/commonTest/kotlin/io/github/composegears/valkyrie/parser/kmp/svg/SVGParserTest.kt` around lines 68 - 129, Add tests that exercise group-level stroke inheritance and stroke-specific attributes: create an SVG with a <g> that sets stroke (color, width, lineCap, lineJoin) plus stroke-opacity and stroke-miterlimit, containing child <path> elements without their own stroke; then assert that SVG.Group.toVectorGroup() and the stroke produced by SVG.Child.getSVGStrokeWithDefaults() propagate the group's stroke color, strokeWidth, strokeLineCap, strokeLineJoin, strokeAlpha (from stroke-opacity), and strokeLineMiter (from stroke-miterlimit) into the resulting IrStroke (e.g., IrStroke.Color with IrColor, strokeAlpha float, strokeLineWidth float, strokeLineCap enum, strokeLineJoin enum, strokeLineMiter float) so regressions in the new group-level branching are caught.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@components/parser/kmp/svg/src/commonMain/kotlin/io/github/composegears/valkyrie/parser/kmp/svg/SVGParser.kt`:
- Around line 68-76: The path default-fill logic in SVG.Path.toVectorPath uses
the inherited resolvedStrokeColor when deciding to synthesize a black fill,
causing paths to lose their default fill if a parent provides stroke; change the
condition to consider only the path's own strokeColor (not paintContext/stroke
inheritance). Specifically, after computing resolvedFill and
resolvedStrokeColor, set fillColor = if (resolvedFill == null &&
this.strokeColor == null) Black else fillColor so the default black fill is
synthesized only when the path itself has no fill and no explicit stroke
attribute.
---
Nitpick comments:
In
`@components/parser/kmp/svg/src/commonTest/kotlin/io/github/composegears/valkyrie/parser/kmp/svg/SVGParserTest.kt`:
- Around line 68-129: Add tests that exercise group-level stroke inheritance and
stroke-specific attributes: create an SVG with a <g> that sets stroke (color,
width, lineCap, lineJoin) plus stroke-opacity and stroke-miterlimit, containing
child <path> elements without their own stroke; then assert that
SVG.Group.toVectorGroup() and the stroke produced by
SVG.Child.getSVGStrokeWithDefaults() propagate the group's stroke color,
strokeWidth, strokeLineCap, strokeLineJoin, strokeAlpha (from stroke-opacity),
and strokeLineMiter (from stroke-miterlimit) into the resulting IrStroke (e.g.,
IrStroke.Color with IrColor, strokeAlpha float, strokeLineWidth float,
strokeLineCap enum, strokeLineJoin enum, strokeLineMiter float) so regressions
in the new group-level branching are caught.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: bf37b7eb-a700-487e-b625-2da46ff2d4a2
📒 Files selected for processing (6)
components/parser/kmp/svg/build.gradle.ktscomponents/parser/kmp/svg/src/commonMain/kotlin/io/github/composegears/valkyrie/parser/kmp/svg/SVG.ktcomponents/parser/kmp/svg/src/commonMain/kotlin/io/github/composegears/valkyrie/parser/kmp/svg/SVGParser.ktcomponents/parser/kmp/svg/src/commonMain/kotlin/io/github/composegears/valkyrie/parser/kmp/svg/SvgExtensions.ktcomponents/parser/kmp/svg/src/commonTest/kotlin/io/github/composegears/valkyrie/parser/kmp/svg/SVGParserTest.ktcomponents/parser/kmp/svg/src/commonTest/kotlin/io/github/composegears/valkyrie/parser/kmp/svg/Utils.kt
There was a problem hiding this comment.
🧹 Nitpick comments (1)
components/parser/kmp/svg/src/commonTest/kotlin/io/github/composegears/valkyrie/parser/kmp/svg/SVGParserTest.kt (1)
130-157: ⚡ Quick winConsider adding a group-level stroke inheritance test.
The PR claims to propagate inherited fill, stroke, and stroke styling through SVG groups and shapes. The new tests cover:
- ✅ Root stroke → path
- ✅ Root fill (null) → path defaults to black
- ✅ Group fill → path
But there is no test for group stroke → path (e.g.,
<g stroke="#ff0000" stroke-width="1.5">). Adding it would close the coverage gap and give confidence that thePaintContextcascade works symmetrically for stroke at the group level.✅ Suggested test skeleton
`@Test` fun parse_path_with_inherited_group_stroke() { val svg = svg(fill = "none") { """ <g stroke="#ff0000" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"> <path d="M4 4h16"/> </g> """ } val actual: List<IrVectorNode> = SVGParser.parse(svg).groups.single().nodes assertEquals( actual = actual, expected = listOf( IrVectorNode.IrPath( pathFillType = IrPathFillType.NonZero, fill = null, paths = listOf( IrPathNode.MoveTo(4f, 4f), IrPathNode.RelativeHorizontalTo(16f), ), fillAlpha = 1f, stroke = IrStroke.Color(IrColor(0xFFFF0000)), strokeAlpha = 1f, strokeLineWidth = 1.5f, strokeLineCap = IrStrokeLineCap.Round, strokeLineJoin = IrStrokeLineJoin.Round, strokeLineMiter = 4f, ), ), ) }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@components/parser/kmp/svg/src/commonTest/kotlin/io/github/composegears/valkyrie/parser/kmp/svg/SVGParserTest.kt` around lines 130 - 157, Add a parallel unit test that verifies group-level stroke inheritance: create a new test function (e.g., parse_path_with_inherited_group_stroke) similar to parse_path_with_inherited_group_fill that builds an SVG with <g stroke="#ff0000" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 4h16"/></g>, call SVGParser.parse(svg) and assert the single IrVectorNode.IrPath produced has stroke = IrStroke.Color(IrColor(0xFFFF0000)), strokeAlpha = 1f, strokeLineWidth = 1.5f, strokeLineCap = IrStrokeLineCap.Round, strokeLineJoin = IrStrokeLineJoin.Round and strokeLineMiter left at default (4f), while fill remains null; reference SVGParser.parse, IrVectorNode.IrPath and the stroke-related properties to locate where to assert.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In
`@components/parser/kmp/svg/src/commonTest/kotlin/io/github/composegears/valkyrie/parser/kmp/svg/SVGParserTest.kt`:
- Around line 130-157: Add a parallel unit test that verifies group-level stroke
inheritance: create a new test function (e.g.,
parse_path_with_inherited_group_stroke) similar to
parse_path_with_inherited_group_fill that builds an SVG with <g stroke="#ff0000"
stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4
4h16"/></g>, call SVGParser.parse(svg) and assert the single IrVectorNode.IrPath
produced has stroke = IrStroke.Color(IrColor(0xFFFF0000)), strokeAlpha = 1f,
strokeLineWidth = 1.5f, strokeLineCap = IrStrokeLineCap.Round, strokeLineJoin =
IrStrokeLineJoin.Round and strokeLineMiter left at default (4f), while fill
remains null; reference SVGParser.parse, IrVectorNode.IrPath and the
stroke-related properties to locate where to assert.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: ee12bd1b-c56f-4e37-a153-5087f8399997
📒 Files selected for processing (3)
components/parser/kmp/svg/src/commonMain/kotlin/io/github/composegears/valkyrie/parser/kmp/svg/SVGParser.ktcomponents/parser/kmp/svg/src/commonTest/kotlin/io/github/composegears/valkyrie/parser/kmp/svg/SVGParserTest.ktcomponents/parser/kmp/svg/src/commonTest/kotlin/io/github/composegears/valkyrie/parser/kmp/svg/Utils.kt
✅ Files skipped from review due to trivial changes (1)
- components/parser/kmp/svg/src/commonMain/kotlin/io/github/composegears/valkyrie/parser/kmp/svg/SVGParser.kt
📝 Changelog
If this PR introduces user-facing changes, please update the relevant Unreleased section in changelogs: