refacto: token-driven button variants, radius tokens & DRY component rendering#7
Conversation
…nt rendering Make the gem expressive enough that downstream forks (DsCta/DsInfoBox) are unnecessary: customization happens through token configuration, not component rewrites. - tokens: generalize storage/emission behind a GROUPS table (adding a group is one entry), add a radius group, a button_style(variant) resolver, a bulk load(...) helper, and a single to_h snapshot reader - extract ButtonStyle (value object + .from factory) and ScssSerializer (SRP) - Cta/Button share a bulletproof_button_table scaffold in Base; Cta is token-inline-driven (now supporting outline secondary via tokens) while Button stays CSS-driven; drop the hardcoded 4px radius - InfoBox: box-scoped info_box_* tokens (fall back to page palette) + box radius - SCSS: radius always applied on .button/.cta (drop opt-in .radius), mirror secondary color/border and info-box radius from tokens - document new tokens + bulk loader in the generator initializer
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
There are 2 total unresolved issues (including 1 from previous review).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit e58a15a. Configure here.
…text - Cta inlined the secondary border on both the cell and the nested anchor; keep it on the cell only (a stacked <a> border doubles the line in many clients) - dark mode forced button-text on .secondary, unreadable on an outline (light) fill; restore the secondary text color in both dark-mode strategies - mirror the cell-only border in the .button/.cta SCSS
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
There are 4 total unresolved issues (including 2 from previous reviews).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit f3600df. Configure here.
| .cta.secondary table td, | ||
| .cta.secondary a { | ||
| background: $am-color-secondary !important; | ||
| color: $am-button-secondary-color !important; |
There was a problem hiding this comment.
Dark mode ignores secondary_text
High Severity
Dark-mode rules force secondary .cta/.button link text to $am-button-secondary-color, which is aliased to button_text, not the secondary_text color token. Token-driven outline secondaries inline a dark secondary_text color, but !important stylesheet rules override it—often yielding light-on-light text when secondary is a light fill.
Additional Locations (2)
Reviewed by Cursor Bugbot for commit f3600df. Configure here.
| .cta.secondary table td, | ||
| .cta.secondary a { | ||
| background: $am-color-secondary !important; | ||
| color: $am-button-secondary-color !important; |
There was a problem hiding this comment.
Dark mode overrides info box tokens
Medium Severity
Dark-mode panel rules apply !important background, border, and text colors to .info-box td, overriding the inline styles built from info_box_background, info_box_border, and info_box_text. Custom box-scoped tokens work in light rendering but are replaced by generic dark panel colors in dark mode.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit f3600df. Configure here.


Contexte
Trois implémentations parallèles d'un même bouton/box coexistaient : composants natifs
Cta/InfoBox(token-driven mais jamais consommés), forks applicatifsDsCta/DsInfoBox(mêmes structures, source de tokens différente), et classes CSS. Les forks ne différaient du natif que par la source des tokens et par deux capacités manquantes côté gem : unborder-radiusparamétrable et une vraie variante outline.Objectif : rendre la gem assez expressive pour qu'aucun fork ne soit jamais nécessaire — la personnalisation passe par la configuration de tokens (Open/Closed), pas par la réécriture de composants.
Changements
Tokens
GROUPS(ajouter un groupe = une entrée), nouveau grouperadius.button_style(variant)→ fond / texte / bordure / radius : variante outline par config seule, défauts 100 % rétro-compatibles.tokens.load(color: {...}, radius: {...}), lecteur uniqueto_h.Tokens::ButtonStyle(+ factory.from) etTokens::ScssSerializer.Composants
bulletproof_button_tabledansBase, consommé parCtaetButton.Ctainline ses styles token-driven (gain : outline secondary) ;Buttonreste CSS-driven (modèle de robustesse distinct, rendu inchangé). Padding centralisé.border-radius:4pxhardcodé dansCta→ tokenradius!(:button).InfoBox: tokens dédiésinfo_box_*(fallback vers la palette page, anti-collision) + radiusbox.SCSS
.button/.cta(plus d'opt-in.radius).Divers
.rubocop.yml:CountAsOne: [array, hash]surMetrics/ClassLength(tables de tokens = données déclaratives).Tests
282 runs / 761 assertions, 0 échec. RuboCop 0 offense. Sorbet clean. Nouveau
info_box_test, couverture radius / outline / bulk-loader.