Skip to content

fix(bulma-ui): deprecate CSS-less color values, warn in dev, fix has-text fall-through - #491

Merged
allxsmith merged 2 commits into
mainfrom
fix/367-color-css-truth
Aug 7, 2026
Merged

allxsmith merged 2 commits into
mainfrom
fix/367-color-css-truth

Conversation

@allxsmith

@allxsmith allxsmith commented Aug 7, 2026 •

Copy link
Copy Markdown
Owner

Closes #367 (the type-level narrowing itself is deferred to #490 — see below).

Bulma 1.0.4 iterates its 11-color $colors map for component modifiers, so several of our color props accept values that emit a class no shipped CSS rule matches. This PR makes every such case visible without breaking anyone, in three moves:

1. Dead is-<color> values now warn in dev and are documented as deprecated

Progress, Notification (both the component prop and NotificationOptions for the programmatic API), and the Hero root accept the 17-value validColors union, but only primary, link, info, success, warning, danger, black, white, light, dark have shipped CSS for .progress/.notification/.hero. The seven grey/bis/ter values (plus inherit/current on the Hero root) render unstyled — the exact failure that produced the skill-loop eval's only shipped defect (run i10's silently unstyled comparison bar).

  • Each prop's TSDoc now names the CSS-backed values and the dead ones, so the generated docs tables, IDE hover, and anything reading the .d.ts see the truth inline.
  • A new internal warn-once helper (bulma-ui/src/helpers/colorDeprecations.ts, not exported from the package root) logs one development-mode console warning per component+value. Production builds are silent.
  • Types are unchanged — removal happens in the next major (bulma-ui: narrow component color unions to CSS-backed values (next major) #490).

2. Pagination and Tabs: the whole color prop is deprecated

Both emit is-${color} on their root, and Bulma ships no .pagination.is-* or .tabs.is-* color CSS at all — every value has always been a silent no-op (the prop is consumed before useBulmaClasses, so there is no has-text-* fallback either). The prop now carries an @deprecated TSDoc tag (rendered as a Deprecated. note in the docs tables) and warns once in dev. Emission is kept for now; removal lands with the follow-up major.

3. The has-text-* fall-through on nine components is now deliberate

Box, Block, Content, Delete, IconText, Image, Buttons, Card, and Container declare a 6-value color that was never destructured — it rode the props spread into useBulmaClasses, rendered has-text-<color>, and (because the spread came last) silently overrode textColor when both were set. Now:

  • color is destructured and passed as textColor ?? color: identical output when one prop is set, and textColor wins when both are (the bug fix).
  • TSDoc on each color prop states the real behavior: a text-color alias, not a filled variant.

Ripples

  • Stories: Progress/Notification color argTypes trimmed to the 10 live values and every argType given a description; both files removed from the stories-conformance LEGACY_EXEMPT list. The Pagination Colors story (showcasing the dead prop) is deleted; the Tabs color argType is removed.
  • Docs: regenerated props tables pick up the new TSDoc; hand fixes to valid-values.md (the "also component color props" claim), the color guide (<Box color="white"> → textColor, <Notification color="white"> → textColor, native <span color> → <Span textColor>), and the Pagination/Tabs overview prose.
  • Skills: bestax-theming/references/themeable-components.md warning block and the Notification/Hero/Progress/Box/Pagination/Tabs rows updated to the deprecated + dev-warn reality; bestax-layout-scaffold Hero row annotated.
  • Tests: new helper suite for the warn-once/dev-gating logic; per-component cases assert the class still renders, the warning fires exactly once, live values stay silent, production stays silent, notification.show() is covered, Hero.Body (a text helper) does not warn, and the nine fall-through components render has-text-* with textColor taking precedence.

Non-breaking throughout: no type changed, no prop removed, no emission changed. The only behavior change is the textColor-precedence bug fix in item 3. Release-wise this is a fix(bulma-ui) patch.

Summary by CodeRabbit

  • New Features
    • color now consistently works as a text-color alias across supported components, with textColor taking precedence.
  • Bug Fixes
    • Added development warnings for deprecated or unsupported color values and color props without visual CSS effects.
  • Documentation
    • Clarified color behavior, supported values, deprecations, and recommended textColor/bgColor alternatives.
    • Updated Storybook controls and examples to reflect current styling behavior.
  • Tests
    • Added coverage for color aliases, precedence rules, warning behavior, and production warning suppression.

…text fall-through

Progress, Notification, and the Hero root accept color values Bulma ships
no is-<color> CSS for; Pagination and Tabs ship no color CSS at all. Those
values now carry TSDoc deprecation notes and a warn-once dev console
warning ahead of removal in the next major. The nine components whose
color prop falls through to has-text-<color> (Box, Block, Content, Delete,
IconText, Image, Buttons, Card, Container) now document that behavior in
TSDoc and give textColor precedence when both props are set.
Copilot AI balanced review requested due to automatic review settings August 7, 2026 11:19

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai

coderabbitai Bot commented Aug 7, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@allxsmith, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 41 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 212f277a-44f8-4693-9d31-23270ba98690

📥 Commits

Reviewing files that changed from the base of the PR and between fb111eb and 117c0c0.

📒 Files selected for processing (5)
  • bulma-ui/src/helpers/__tests__/colorDeprecations.test.ts
  • bulma-ui/src/helpers/colorDeprecations.ts
  • docs/docs/guides/helpers/color.md
  • skills/bestax-layout-scaffold/references/layout-components.md
  • skills/bestax-theming/references/themeable-components.md

Walkthrough

The pull request standardizes color behavior across components. It adds text-color fallbacks, warns for CSS-less values, updates tests and Storybook controls, and synchronizes API and skill documentation.

Changes

Color behavior alignment

Layer / File(s) Summary
Color deprecation warning helpers
bulma-ui/src/helpers/colorDeprecations.ts, bulma-ui/src/helpers/__tests__/colorDeprecations.test.ts
Added warn-once helpers for CSS-less colors and deprecated color props. Tests cover environments, deduplication, resets, and component-specific values.
Text-color alias behavior
bulma-ui/src/components/Card.tsx, bulma-ui/src/elements/*, bulma-ui/src/layout/Container.tsx, bulma-ui/src/**/__tests__/*, docs/docs/api/*, docs/docs/guides/helpers/color.md
The listed components use color as a textColor fallback. textColor takes precedence. Tests and documentation describe the behavior.
CSS-less color warnings and Storybook updates
bulma-ui/src/components/{Pagination,Tabs}.*, bulma-ui/src/elements/{Notification,Progress}.*, bulma-ui/src/layout/Hero.*, bulma-ui/src/__tests__/stories-conformance.test.ts, docs/docs/api/*, skills/*
Pagination and Tabs warn for ineffective color props. Notification, Progress, and Hero warn for accepted values without matching CSS. Storybook controls, conformance exemptions, tests, and references were updated.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related issues

Possibly related PRs

Suggested labels: released, deep-review

Suggested reviewers: copilot

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR fixes the Box behavior, but #367's requested type-level narrowing remains deferred to #490. Implement per-component narrowed color unions, or update the linked issue to explicitly accept deferred type-level narrowing.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the color deprecation, development warnings, and text-color precedence fix.
Description check ✅ Passed The description gives a detailed summary, linked issue, affected areas, implementation details, tests, documentation, and compatibility impact.
Out of Scope Changes check ✅ Passed The code, tests, documentation, Storybook, and skill updates directly support the color behavior and deprecation objectives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/367-color-css-truth

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Preview Deployment

Preview URL: https://57ed6da9.bestax.pages.dev

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 53 out of 53 changed files in this pull request and generated 1 comment.

Suppressed comments (4)

docs/docs/guides/helpers/color.md:161

  • This second Box example also uses the omitted backgroundColor prop rather than the public bgColor alias, leaving the live TypeScript example invalid.
    docs/docs/guides/helpers/color.md:157
  • BoxProps omits backgroundColor and exposes this helper as bgColor, so this revised example still fails TypeScript when copied. Use the public prop name here.

This issue also appears on line 161 of the same file.
docs/docs/guides/helpers/color.md:165

  • NotificationProps exposes neither backgroundColor nor bgColor; its supported surface color is the CSS-backed color modifier. As written, this revised example does not type-check, so use color="success" for the notification background while retaining textColor.
    docs/docs/guides/helpers/color.md:99
  • The example now uses textColor, but the same section still tells readers that color universally produces has-text-* and lists every helper value under color. That is false for modifier components (and now-deprecated Pagination/Tabs), which is the distinction this PR is intended to clarify. Update the surrounding Text Color prose and tables to document textColor as the public helper and reserve color for component-specific behavior.

Comment on lines +29 to +34
// `process` may not exist for CDN/no-bundler consumers; treat that as dev.
// Read via globalThis because the library tsconfig has no Node types.
const isDev = (): boolean => {
const env = (globalThis as { process?: { env?: { NODE_ENV?: string } } })
.process?.env;
return env?.NODE_ENV !== 'production';

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deep review — 0 blocking · 1 advisory

# Severity Area Finding Location
1 🔵 Advisory Robustness Dev-gate reads globalThis.process dynamically, so it isn't statically replaced; in bundled browser prod builds where process is undefined at runtime (Vite, webpack 5 without a polyfill) isDev() returns true, so a deprecation warning can fire in production when a deprecated value/prop is actually used — contradicting the "production builds are silent" claim. bulma-ui/src/helpers/colorDeprecations.ts:31

Overall: The change is sound and non-breaking. I chased #367 to source, confirmed the failure shape (wide validColors unions emitting dead is-grey*/is-*-bis/is-*-ter modifiers, plus color silently overriding textColor on the fall-through elements), and verified the fix empirically — 410 tests across the 16 touched suites pass, the warn-once/dev-gate helper is well covered, and the textColor ?? color precedence fix behaves as documented (identical output when one prop is set, textColor wins when both are). The riskiest part is the dev/prod gate (finding #1); the maintainer should decide whether the Vite-prod warning leak is acceptable given the deliberate CDN-safety trade-off.

Residual risk:

  • Other root is-<color> emitters with the same over-wide union: refuted — grepped every component emitting is-${color}; Button, Tag, Message, InputBase, SelectBase, Panel, Steps, Badge all already restrict color to the 10 CSS-backed values. Progress, Notification, and Hero were the only ones accepting the full 17-value union, and all three are now handled.
  • Whole-prop-dead beyond Pagination/Tabs: not exhaustively re-audited, but out of #367's stated scope; the two known cases are covered and warn once in dev.
  • De-exempting Notification/Progress stories from stories-conformance: refuted — every remaining argType in both story metas now carries a description, so the conformance test stays green.

🏄 Righteous cleanup, dude — this PR doesn't rip out any types or break the lineup, it just paddles out and honestly tells everyone which colors actually catch a wave and which ones wipe out silently. One tiny ripple: the "quiet in prod" promise might splash a warning in a Vite bundle, but nothing's gonna hold you back from merging. Good to go. 🌊

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@bulma-ui/src/helpers/colorDeprecations.ts`:
- Around line 29-35: Update isDev in bulma-ui/src/helpers/colorDeprecations.ts
(lines 29-35) to use the supported build-time development flag or injected
environment predicate, defaulting unknown or missing runtime information to
false so warnings remain disabled. In
bulma-ui/src/helpers/__tests__/colorDeprecations.test.ts (lines 112-127), change
the missing-process case to assert no warning and add coverage confirming
warnings are enabled through the supported development flag.

In `@docs/docs/guides/helpers/color.md`:
- Around line 75-82: Update the color guidance to reflect the component-specific
API: use textColor for generic text-color examples and claims, remove or revise
the Button color examples because Button maps color to the filled button
variant, and scope remaining color alias documentation and examples to
components that implement it, including the affected content around the Span
examples.
- Around line 157-165: Update the two Box examples to use the supported bgColor
prop instead of backgroundColor. Verify Notification’s public prop API and
retain backgroundColor only if it is supported; otherwise replace it with the
correct prop so all examples compile.

In `@skills/bestax-layout-scaffold/references/layout-components.md`:
- Line 63: Update the Hero component’s color documentation table entry to
enumerate the exact CSS-backed Bulma color values and the complete
accepted-but-deprecated set, explicitly including inherit and current, instead
of referring generically to “Bulma color.”

In `@skills/bestax-theming/references/themeable-components.md`:
- Line 50: Update the Notification, Hero, and Progress inventory rows to
explicitly list black-bis, black-ter, and every deprecated grey color alias as
deprecated, while preserving the existing unsupported-value and removal-status
details.
🪄 Autofix

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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: cedcf1c5-5b5c-4f01-9e7f-5d7218dbf8a3

📥 Commits

Reviewing files that changed from the base of the PR and between de3cbea and fb111eb.

📒 Files selected for processing (53)
  • bulma-ui/src/__tests__/stories-conformance.test.ts
  • bulma-ui/src/components/Card.tsx
  • bulma-ui/src/components/Pagination.stories.tsx
  • bulma-ui/src/components/Pagination.tsx
  • bulma-ui/src/components/Tabs.stories.tsx
  • bulma-ui/src/components/Tabs.tsx
  • bulma-ui/src/components/__tests__/Card.test.tsx
  • bulma-ui/src/components/__tests__/Pagination.test.tsx
  • bulma-ui/src/components/__tests__/Tabs.test.tsx
  • bulma-ui/src/elements/Block.tsx
  • bulma-ui/src/elements/Box.tsx
  • bulma-ui/src/elements/Buttons.tsx
  • bulma-ui/src/elements/Content.tsx
  • bulma-ui/src/elements/Delete.tsx
  • bulma-ui/src/elements/IconText.tsx
  • bulma-ui/src/elements/Image.tsx
  • bulma-ui/src/elements/Notification.stories.tsx
  • bulma-ui/src/elements/Notification.tsx
  • bulma-ui/src/elements/Progress.stories.tsx
  • bulma-ui/src/elements/Progress.tsx
  • bulma-ui/src/elements/__tests__/Block.test.tsx
  • bulma-ui/src/elements/__tests__/Box.test.tsx
  • bulma-ui/src/elements/__tests__/Buttons.test.tsx
  • bulma-ui/src/elements/__tests__/Content.test.tsx
  • bulma-ui/src/elements/__tests__/Delete.test.tsx
  • bulma-ui/src/elements/__tests__/IconText.test.tsx
  • bulma-ui/src/elements/__tests__/Image.test.tsx
  • bulma-ui/src/elements/__tests__/Notification.test.tsx
  • bulma-ui/src/elements/__tests__/Progress.test.tsx
  • bulma-ui/src/helpers/__tests__/colorDeprecations.test.ts
  • bulma-ui/src/helpers/colorDeprecations.ts
  • bulma-ui/src/layout/Container.tsx
  • bulma-ui/src/layout/Hero.tsx
  • bulma-ui/src/layout/__tests__/Container.test.tsx
  • bulma-ui/src/layout/__tests__/Hero.test.tsx
  • docs/docs/api/components/card.md
  • docs/docs/api/components/pagination.md
  • docs/docs/api/components/tabs.md
  • docs/docs/api/elements/block.md
  • docs/docs/api/elements/box.md
  • docs/docs/api/elements/buttons.md
  • docs/docs/api/elements/content.md
  • docs/docs/api/elements/delete.md
  • docs/docs/api/elements/icontext.md
  • docs/docs/api/elements/image.md
  • docs/docs/api/elements/notification.md
  • docs/docs/api/elements/progress.md
  • docs/docs/api/helpers/valid-values.md
  • docs/docs/api/layout/container.md
  • docs/docs/api/layout/hero.md
  • docs/docs/guides/helpers/color.md
  • skills/bestax-layout-scaffold/references/layout-components.md
  • skills/bestax-theming/references/themeable-components.md
💤 Files with no reviewable changes (3)
  • bulma-ui/src/components/Pagination.stories.tsx
  • bulma-ui/src/components/Tabs.stories.tsx
  • bulma-ui/src/tests/stories-conformance.test.ts

Comment thread bulma-ui/src/helpers/colorDeprecations.ts Outdated
Comment thread docs/docs/guides/helpers/color.md
Comment thread docs/docs/guides/helpers/color.md Outdated
Comment thread skills/bestax-layout-scaffold/references/layout-components.md Outdated
Comment thread skills/bestax-theming/references/themeable-components.md Outdated
…e to real props

The dev-warning gate now reads a bare process.env.NODE_ENV in a try/catch:
bundlers replace it statically, and a runtime without process stays silent
instead of warning in production. The color guide teaches textColor/bgColor
(Title/SubTitle never had a color prop; Box/Card expose bgColor, and
Notification has no background prop at all), and the skill inventories name
black-bis/black-ter and Hero's inherit/current among the deprecated values.
Copilot AI review requested due to automatic review settings August 7, 2026 11:37
@allxsmith

Copy link
Copy Markdown
Owner Author

Addressed all review findings in 117c0c0:

  • isDev() fail-open in browser bundles (Copilot, CodeRabbit, deep review): the helper now reads a bare process.env.NODE_ENV inside try/catch, so bundlers replace it statically (dev serve warns, production builds compile the check away) and a runtime with no process at all (raw CDN ESM) lands in the catch and stays silent — fail closed, warnings can never fire in production. The missing-process test now asserts silence, and an explicit NODE_ENV=development case was added.
  • color.md scoped its color claims (CodeRabbit): the Text Color section now teaches textColor (tables renamed), explains where color means the filled is-<color> variant instead, and the example uses textColor on Title/SubTitle (which never had a color prop) and Button. The Background section teaches bgColor; the Box/Card examples use bgColor, and the Notification example uses its color variant since Notification exposes no background prop at all.
  • Hero row in the layout skill (CodeRabbit): now lists the exact CSS-backed union and the full accepted-but-deprecated set including inherit/current.
  • black-bis/black-ter aren't greys (CodeRabbit): the three inventory rows name them explicitly, the Hero row and the warning block also call out inherit/current on the Hero root.

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Preview Deployment

Preview URL: https://2b1d244e.bestax.pages.dev

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 53 out of 53 changed files in this pull request and generated no new comments.

@allxsmith
allxsmith merged commit 013cc32 into main Aug 7, 2026
14 checks passed
@allxsmith
allxsmith deleted the fix/367-color-css-truth branch August 7, 2026 11:46
@bestax-release-bot

Copy link
Copy Markdown

🎉 This PR is included in version 5.8.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

@bestax-release-bot

Copy link
Copy Markdown

🎉 This PR is included in version 4.0.2 🎉

The release is available on:

Your semantic-release bot 📦🚀

@bestax-release-bot

Copy link
Copy Markdown

🎉 This PR is included in version 1.0.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@bestax-release-bot

Copy link
Copy Markdown

🎉 This PR is included in version 2.0.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] bulma-ui: color props typecheck values with no shipped CSS; Box color falls through to has-text-*

2 participants