feat(components): serve all.css via CSS cascade layers#2626
Open
mfal wants to merge 3 commits into
Open
Conversation
Wrap the generated component stylesheet (all.css) in a `flow` cascade layer so consuming applications can override Flow with unlayered CSS without specificity battles. Sublayer order (low -> high): flow.reset, flow.base, flow.components, flow.components-override. Design tokens (CSS custom properties) and @font-face are intentionally left unlayered. - Split styles/globals.scss into globals-reset.scss (the hard reset) and globals-base.scss (typography, Josh-Comeau reset, color-scheme, reduced-motion), loaded into flow.reset / flow.base. - Add a Vite/PostCSS plugin (dev/vite/flowCssLayerPlugin.ts) that wraps every component CSS module in @layer flow.components and prepends the layer-order statement to all.css (after @charset). - Support an `@layer unlayered { ... }` escape hatch: the plugin hoists its rules out of any layer so components can still override third-party CSS injected unlayered at runtime. Applied to CodeEditor (CodeMirror) and ImageCropper (react-easy-crop). - Document for consumers (MIGRATION.md, docs stylesheet page) and contributors (CONTRIBUTE.md). Note: Flow's styles now live in a cascade layer, so unlayered CSS in a consuming app overrides Flow automatically. Apps that relied on Flow winning over their own unlayered global CSS can move those rules into a layer ordered before `flow` (see MIGRATION.md). Co-Authored-By: Claude Opus 4.8 <[email protected]>
…omponent overrides Move the rules where one Flow component overrides another (nested/composed) component into the `flow.components-override` sublayer, so they win via the cascade layer instead of via selector specificity, source order or `!important`. - CartesianChart: focus-outline suppression (drops `!important`) - CheckboxGroup, MarkdownEditor: FormField `display` override - CodeBlock: CodeEditor/CodeMirror border color - DateInput, DateRangeInput: embedded Button geometry - Message: sender Text alignment - LayoutCard: Tabs context-menu button corner radius - ListItemView: Avatar icon/initials sizing in tile view Behavior-preserving: selectors and declarations are unchanged; only the layer assignment changes. Co-Authored-By: Claude Opus 4.8 <[email protected]>
Contributor
Coverage Report for ./packages/components/
File Coverage
|
||||||||||||||||||||||||||||||||||||||
Contributor
🚀 Preview DeploymentPreview environments are ready:
Images:
|
Covers flowComponentsLayerPostcssPlugin (flow.components wrapping, @layer unlayered unwrap, flow.components-override passthrough, module-file gating) and flowLayerOrderPlugin (order-statement prepend after @charset, idempotency, target-asset gating). Co-Authored-By: Claude Opus 4.8 <[email protected]>
Member
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
Serve the generated component stylesheet (
all.css) via CSS cascade layers, so consuming applications can override Flow with unlayered CSS without specificity battles.Layer order (low → high priority):
flow.reset– the hard reset (all: initial+ display restoration).flow.base– base typography, Josh-Comeau reset,color-scheme, reduced-motion.flow.components– every component CSS module (wrapped automatically at build time).flow.components-override– inter-component overrides (one Flow component restyling another).@font-face.How it works
styles/globals.scssintoglobals-reset.scss/globals-base.scss, loaded intoflow.reset/flow.base.dev/vite/flowCssLayerPlugin.ts:*.module.(scss|css)in@layer flow.components;all.css(after@charset, via apostgenerateBundlehook).@layer unlayered { … }escape hatch: the plugin hoists such rules out of any layer, so components can still override third-party CSS injected unlayered at runtime. Applied to CodeEditor (CodeMirror) and ImageCropper (react-easy-crop).@layer flow.components-overrideapplied to the genuine inter-component overrides (CartesianChart, CheckboxGroup, MarkdownEditor, CodeBlock, DateInput, DateRangeInput, Message, LayoutCard, ListItemView) — replacing reliance on specificity/source-order and one!important.Behavior change (documented, not a forced major)
Flow's styles now live in a cascade layer, so unlayered CSS in a consuming app overrides Flow automatically. Apps that relied on Flow winning over their own unlayered global CSS can move those rules into a layer ordered before
flow. Documented in:packages/components/MIGRATION.md(consumer migration note)apps/docs/.../01-get-started/stylesheet/index.mdx)packages/components/CONTRIBUTE.md(the@layer unlayered/flow.components-overrideconventions)Verification
all.cssis emitted with the correct layer order (@charset→ order statement → layer blocks), tokens/@font-faceunlayered, all component modules inflow.components, and the CodeMirror / react-easy-crop overrides correctly unlayered.@layer unlayeredfix restored all three to green.backdrop-filterblur), not caused by this change.flow.components-overridemoves are behavior-preserving (selectors/values unchanged; only the layer assignment changes).Notes
MIGRATION.mduses a placeholder version (>=0.2.0-alpha.897) — adjust to the actual release version.main; rebase before merge if needed.🤖 Generated with Claude Code