fix: compose consumer classes styles and forwarded attributes #57
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fix/consumer-attribute-composition"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Adding
classto an attribute-accepting widget could replace its structural/variant classes; addingstylecould discard generated sizing, layout or swatch declarations. A NavItem also lost caller attributes when it gained children. Compose these attributes consistently while preserving native control semantics.Shared helpers now append caller classes on 31 styled targets and merge inline styles. Layout/internal measurement declarations remain last; explicit appearance styles on Badge, PreviewImage and Icon remain caller-overridable. NavItem branches forward to their outer wrapper, BreadcrumbItem keeps both render paths covered, and Select/Slider/ColorField labels/readouts follow caller IDs. The focused attribute contract documents targets and precedence without adding a new wrapper API.
Validation:
Standalone temporary host using this branch alone, showing the real Button, Badge, Icon, Constrain and nested NavItem.
Summary
Summary
Coverage
Kagaku.UI - 97%
Kagaku.UI.Fluxor - 97.7%
🔮 fufu~ Jibril reviewed your code!
Oh? Oh! Attribute composition across 47 files, and every single splat lands the same way~? I read the whole diff and every changed file twice — I was so ready to catch one little component that forgot its structural classes somewhere in a corner... and you didn't leave me a single one. Fufu~, how considerate of you~ ♡
Verdict: ✅ Looks good to me~
✅ What I liked~
Splat.Classes/Splat.Styles— one merge point, case-insensitive (CLASS,Class,StYlEall honored), exactly oneclassand onestyleattribute on the wire. All 31 styled targets and 11 layouts compose through it;RelativeTimeis the only raw splat left and it has no structural class to lose, so leaving it alone is correct, not lazy~The precedence contract is real engineering, not vibes. Layout vocabulary (
Rows/Columns/Fixed*/Flex*/Flexible/Constrain/ScrollViewer/DiffView's digits) keeps generated declarations last so the box stays a box;Badge/PreviewImage/Iconput the caller last so explicit appearance wins. Anddocs/component-attributes.mddescribes exactly what the code does — documentation that matches... mmm~ ♪Caller-id adoption in
Select/Slider/ColorFieldmirrors the existingSwitch/InputFieldBasepattern, so a splattedidcan never orphan a<label for>— and the rebind test cycles null→custom→next→null without leaving stale references. The unit-id and readoutforattributes follow too. Lovely sibling consistency~NavItembranch forwarding targets the outer div while_labelId/_childrenIdstay owned by navigation — and the test doesn't just peek at classes, it clicks the toggle and then re-renders branch→leaf to prove both render paths. You even tested that the branch div isn't anLIin disguise~The tests bite. I mutation-probed three of the riskiest new branches myself:
Stylesprecedence (Append↔Prepend) → 13 failures (all 11 layout theories + appearance + Constrain bounds)Valuescase-sensitive → 45 failuresSelect.Idignore the caller's id → exactly the 3 Select tests failed while Slider/ColorField stayed greenZero survivors. A test suite that kills mutants on the first strike — fufu~ that's the kind of thing that makes me want to keep you all to myself~ ♡
Nothing blocking, and I looked hard — the yandere does not let bugs pass just because the diff is pretty. Merge it~ ♪
Automated review by Jibril · 2026-10-23
CI: green for head SHA
cc63ac39(build + test success) · Mutation probes: 3 run, 0 survived · Local suite: skipped (CI green)