-
Notifications
You must be signed in to change notification settings - Fork 1
Implement CSS @layer cascade and color-mix features #82
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughAdds opt-in CSS Layers and CSS Relative Color Syntax; reorganizes and forwards SCSS mixins into modular mixin-modules; introduces color-mix/relative color utilities and conditional color maps; wraps most SCSS outputs in layer blocks; refactors theme application to spread-theme-component; updates auto-import typings and ESLint auto-import globals. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 9
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/settings/_effects.scss (1)
25-27: Invalid Sass function calls — missing module prefix.The functions
color-hue(),color-saturation(), andcolor-lightness()should use thecolormodule prefix since you're using@use 'sass:color'. The current syntax will fail to compile in modern Sass.🔎 Proposed fix
-$color-shadow-hue: color-hue(colors.$color-shadow); -$color-shadow-saturation: color-saturation(colors.$color-shadow); -$color-shadow-lightness: color-lightness(colors.$color-shadow); +$color-shadow-hue: color.hue(colors.$color-shadow); +$color-shadow-saturation: color.saturation(colors.$color-shadow); +$color-shadow-lightness: color.lightness(colors.$color-shadow);
🧹 Nitpick comments (15)
auto-imports.d.ts (1)
91-96: Inconsistent syntax on line 96.Line 96 (
resolveUnref) still uses bracket notation['resolveUnref']while the surrounding declarations (lines 9-95, 97-304) were updated to dot notation (.Name). Since this is a generated file, consider regenerating to ensure consistency, or verify this was intentional.🔎 Suggested fix for consistency
- const resolveUnref: typeof import('@vueuse/core')['resolveUnref'] + const resolveUnref: typeof import('@vueuse/core').resolveUnrefdocs/contents/get-started/configuration.md (1)
75-119: Excellent documentation for CSS Layers feature.The documentation clearly explains the CSS
@layerfeature, configuration options, layer order, and browser support requirements. The code examples are helpful and the structure is easy to follow.Optional enhancement: Document fallback behavior
Consider adding a brief note about what happens when
$use-css-layers: trueis used in older browsers. For example:#### Browser Support CSS `@layer` is supported in all modern browsers (Chrome 99+, Firefox 97+, Safari 15.4+, Edge 99+). **Note:** In browsers that don't support `@layer`, the styles will still work but the explicit cascade ordering will be ignored, falling back to standard CSS cascade rules. For older browsers, consider keeping `$use-css-layers: false` (the default).README.md (1)
86-94: Consider updating this example for consistency with the new default.This "Custom props" example still shows the legacy HSL variable approach (
--color-brand-hue,--color-brand-saturation,--color-brand-lightness). Since$use-color-mix: trueis now the default, users would typically just set--color-branddirectly. Consider either updating this example to reflect the new approach or adding a note clarifying this is for legacy mode.src/components/vv-skeleton.scss (1)
7-7: Remove unused variable$component-selector.The variable is defined on line 7 but is never used within vv-skeleton.scss. Unlike other component files that reference this variable, it serves no purpose here and can be safely removed.
src/settings/components/_vv-badge.scss (1)
70-76: Updated to usecolor-mix()for semi-transparent white/black backgrounds.The
color-mix(in srgb, var(--color-white), transparent 20%)syntax is valid CSS Color Level 5 with strong modern browser support (Chrome 111+, Edge 111+, Firefox 113+, Safari 16.2+). Consider adding a plain-color fallback or@supports()feature query if the project targets older browsers, as support is ~92% globally but not universal in legacy environments.src/tools/_breakpoints.scss (4)
20-24: LGTM! Improved code clarity.The refactoring from implicit returns to explicit
@if/@elseblocks makes the null-handling and boundary conditions clearer. The logic remains functionally identical—returning the next breakpoint name when it exists, or null for the last breakpoint.
37-41: LGTM! Clearer zero-value handling.The explicit conditional block makes it immediately clear that zero-valued breakpoints (typically for the smallest breakpoint like
xs: 0) are treated as having no minimum and return null. Functionally equivalent to the previous implementation.
59-63: LGTM! Explicit max boundary calculation.The refactoring makes the Safari rounding workaround (subtracting 0.02px from the next breakpoint's minimum) more explicit and easier to understand. The logic remains identical.
77-81: LGTM! Clear infix logic for responsive utilities.The explicit conditional makes it clear when an empty string is returned (smallest breakpoint) versus a dash-prefixed name (all other breakpoints). This is important for generating responsive utility class names. Logic is preserved.
src/tools/mixin-modules/_helpers.scss (1)
12-14: Consider edge case handling for selector coercion.The string interpolation
#{$selector}for map/list types may not handle complex nested structures or special characters consistently. For selectors containing commas (e.g., multiple selectors as a list), the interpolation could produce unexpected results.🔎 Consider adding validation or flattening logic
@if meta.type-of($selector) == 'map' or meta.type-of($selector) == 'list' { - $selector: #{$selector}; + // Convert list of selectors to comma-separated string + $selector: meta.inspect($selector); + $selector: string.slice($selector, 2, -2); // Remove parentheses if present }Alternatively, document the expected input format for list/map types to clarify usage.
docs/contents/settings/colors.md (1)
108-109: Minor: Comment could be more specific.The comment "Surface uses fixed steps (addition/subtraction)" is accurate but the example only shows subtraction. Consider adding an addition example for completeness, or update the comment to match the single example.
- /* Surface uses fixed steps (addition/subtraction) */ + /* Surface uses fixed steps (+12 for lighter, -12 for darker) */ --color-surface-6: hsl(from var(--color-surface) h s calc(l - 12));src/tools/mixin-modules/_utilities.scss (1)
33-37: Hardcoded backslash escaping may need configuration.Line 36 hardcodes the backslash escape for breakpoint prefixes (
$breakpoint + '\\:'), following Tailwind's convention. This works for CSS but assumes all consumers want this format.Consider making the separator configurable if different naming conventions are needed:
@mixin spread-map-into-utilities( $map: (), $class: '', $attribute: '', $prop: '', $name: '', $deep: true, $bps: (xxs: 0), $prefix: '', - $zero-specificity: false + $zero-specificity: false, + $bp-separator: '\\:' ) { @if (meta.type-of($map) == 'map' or meta.type-of($map) == 'list') and $attribute != '' { @each $breakpoint, $breakpoint-value in $bps { @if $breakpoint-value > 0 { - $prefix: $breakpoint + '\\:'; + $prefix: $breakpoint + $bp-separator; }src/tools/mixin-modules/_layers.scss (1)
25-41: Consider using Sass list interpolation for cleaner layer list generation.The manual string concatenation works, but Sass provides built-in list handling that could simplify this.
🔎 Optional refactor using list.join()
+@use 'sass:list'; + @mixin define-layers($enabled: false, $order: (reset, props, utilities, components, themes), $prefix: 'volver') { @if $enabled { - $layers: null; - - @each $name in $order { - $layer-name: $prefix + '.' + $name; - - @if $layers { - $layers: $layers + ', ' + $layer-name; - } @else { - $layers: $layer-name; - } - } + $layers: (); + @each $name in $order { + $layers: list.append($layers, #{$prefix}.#{$name}, comma); + } /* stylelint-disable-next-line layer-name-pattern */ @layer #{$layers}; } }src/tools/mixin-modules/_attrs.scss (2)
44-57: Consider consolidating vendor-prefixed pseudo-elements.The
$-pseudo-elementslist includes both unprefixed (progress-bar) and vendor-prefixed (-webkit-progress-bar,-moz-progress-bar) variants. Sincepseudo-element-placeholderalready handles vendor prefixing for the unprefixed names, the explicit vendor-prefixed entries may cause redundant selector generation when used elsewhere.
80-88: Variable shadowing:$originalis reassigned within the loop.Reassigning the parameter
$originalat line 84 shadows the outer value. While functional due to Sass scoping, this reduces clarity. Consider using a distinct variable name like$nested-original.🔎 Suggested improvement
@if meta.type-of($value) == 'map' and ($deep or $key == 'pseudo') { - $original: map.get($original, $key); + $nested-original: map.get($original, $key); - @if not $original { - $original: (); + @if not $nested-original { + $nested-original: (); }Then use
$nested-originalin subsequent lines within this block.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (107)
.eslintrc-auto-import.jsonCHANGELOG.mdREADME.mdauto-imports.d.tsdocs/App.vuedocs/components/ColorPalette.vuedocs/contents/get-started/configuration.mddocs/contents/settings/colors.mdpackage.jsonpostcss.config.cjssrc/_config.scsssrc/_layers.scsssrc/_preflight.scsssrc/components/vv-accordion-group.scsssrc/components/vv-accordion.scsssrc/components/vv-alert-group.scsssrc/components/vv-alert.scsssrc/components/vv-avatar-group.scsssrc/components/vv-avatar.scsssrc/components/vv-badge.scsssrc/components/vv-breadcrumb.scsssrc/components/vv-button-group.scsssrc/components/vv-button.scsssrc/components/vv-card.scsssrc/components/vv-checkbox-group.scsssrc/components/vv-checkbox.scsssrc/components/vv-dialog.scsssrc/components/vv-dropdown-action.scsssrc/components/vv-dropdown-optgroup.scsssrc/components/vv-dropdown-option.scsssrc/components/vv-dropdown.scsssrc/components/vv-input-file.scsssrc/components/vv-input-text.scsssrc/components/vv-nav.scsssrc/components/vv-progress.scsssrc/components/vv-radio-group.scsssrc/components/vv-radio.scsssrc/components/vv-select.scsssrc/components/vv-skeleton.scsssrc/components/vv-tab.scsssrc/components/vv-table.scsssrc/components/vv-text.scsssrc/components/vv-textarea.scsssrc/components/vv-tooltip.scsssrc/export.scsssrc/props/background.scsssrc/props/borders.scsssrc/props/breakpoints.scsssrc/props/colors.scsssrc/props/effects.scsssrc/props/filters.scsssrc/props/input.scsssrc/props/layout.scsssrc/props/sizing.scsssrc/props/spacing.scsssrc/props/transitions.scsssrc/props/typography.scsssrc/reset.scsssrc/settings/_colors.scsssrc/settings/_effects.scsssrc/settings/components/_vv-badge.scsssrc/settings/components/_vv-button.scsssrc/settings/components/_vv-card.scsssrc/settings/components/_vv-nav.scsssrc/settings/components/_vv-text.scsssrc/themes/dark/components/_vv-alert.scsssrc/themes/dark/components/_vv-avatar.scsssrc/themes/dark/components/_vv-badge.scsssrc/themes/dark/components/_vv-button.scsssrc/themes/dark/components/_vv-dropdown-action.scsssrc/themes/dark/components/_vv-dropdown-option.scsssrc/themes/dark/components/_vv-nav.scsssrc/themes/dark/components/_vv-select.scsssrc/themes/dark/props/_background.scsssrc/themes/dark/props/_colors.scsssrc/themes/dark/props/_input.scsssrc/themes/dark/settings/_colors.scsssrc/themes/dark/settings/components/_vv-alert.scsssrc/themes/dark/settings/components/_vv-avatar.scsssrc/themes/dark/settings/components/_vv-button.scsssrc/tools/_breakpoints.scsssrc/tools/_functions.scsssrc/tools/_mixins.scsssrc/tools/mixin-modules/_attrs.scsssrc/tools/mixin-modules/_bem.scsssrc/tools/mixin-modules/_helpers.scsssrc/tools/mixin-modules/_index.scsssrc/tools/mixin-modules/_layers.scsssrc/tools/mixin-modules/_props.scsssrc/tools/mixin-modules/_theme.scsssrc/tools/mixin-modules/_utilities.scsssrc/utilities/backgrounds.scsssrc/utilities/borders.scsssrc/utilities/colors.scsssrc/utilities/effects.scsssrc/utilities/filters.scsssrc/utilities/flexbox.scsssrc/utilities/grid.scsssrc/utilities/interactivity.scsssrc/utilities/layout.scsssrc/utilities/sizing.scsssrc/utilities/spacing.scsssrc/utilities/tables.scsssrc/utilities/transforms.scsssrc/utilities/transitions.scsssrc/utilities/typography.scsssrc/volver.scss
💤 Files with no reviewable changes (1)
- src/themes/dark/settings/components/_vv-button.scss
🔇 Additional comments (116)
auto-imports.d.ts (2)
400-400: LGTM!The
refManualResetaddition toComponentCustomPropertiesis correctly placed alphabetically and uses consistent bracket notation with the rest of this section.
1-7: Generated file committed — ensure regeneration process is documented.This file is auto-generated by
unplugin-auto-import. Verify that:
- The generation config has been updated to include
refManualReset- CI/build process regenerates this file to prevent manual drift
src/components/vv-textarea.scss (1)
5-5: LGTM - CSS layer wrapper applied correctly.The component is now properly scoped within the CSS layers system using the
layer()mixin. The internal component logic remains unchanged, and the implementation aligns with the broader PR pattern.Also applies to: 100-101
src/props/filters.scss (1)
3-9: LGTM - Props correctly scoped within CSS layer.The property definitions are now properly wrapped within the
propslayer context while preserving the existing:where(:host, :root, .theme)selector structure.CHANGELOG.md (1)
5-26: Comprehensive changelog entry.The version 0.1.24 entry thoroughly documents the new CSS Relative Color Syntax support, CSS layers, configuration options, and migration notes. The comparison link is properly formatted.
Also applies to: 298-298
src/props/effects.scss (1)
3-8: LGTM - Effects props correctly layered.The box-shadow and opacity properties are now properly scoped within the
propslayer, maintaining the existing property generation logic.src/components/vv-dropdown-optgroup.scss (1)
4-4: LGTM - Component properly wrapped in CSS layer.The dropdown optgroup component is now correctly scoped within the
componentslayer, consistent with the broader CSS layers implementation across the codebase.Also applies to: 15-16
postcss.config.cjs (1)
18-18: Browser support is determined by consuming projects, not this library.This is a CSS utility library with no explicit browserslist configuration. Browser support for
@layersyntax is not a concern for the library itself—consuming projects will apply their own PostCSS transformations based on their own browser targets. The setting'cascade-layers': falsepreserves@layerrules for downstream build tools to handle according to their own requirements.Likely an incorrect or invalid review comment.
src/settings/components/_vv-button.scss (1)
92-92: This change is an intentional part of the v0.1.24 color system refactor to semantic colors.The
--color-surfacevariable is properly defined insrc/settings/_colors.scssusing the new Relative Color Syntax system. In the light theme, it evaluates to white (matching the previousvar(--color-white)), ensuring backward-compatible visual appearance. In the dark theme,--color-surfaceintentionally uses a very dark background, which is the correct semantic choice for secondary buttons in that theme. This is documented in the CHANGELOG as part of the migration from literal color names to semantic color variables for improved theming flexibility.src/settings/_effects.scss (1)
6-22: LGTM! Clean migration tocolor-mix()for shadow transparency.The box-shadow definitions now use modern CSS
color-mix()with the--color-shadowvariable, aligning with the PR's goal to reduce CSS custom properties and leverage native CSS color functions.README.md (1)
111-139: Good documentation for the new Relative Color Syntax feature.The examples clearly illustrate the difference between proportional scaling for brand colors and fixed steps for surface/word colors.
src/themes/dark/settings/components/_vv-alert.scss (1)
60-109: LGTM! Consistent header text contrast for notification modifiers.Adding
color: var(--color-white)to all notification header variants ensures readable text on colored backgrounds in dark theme. The pattern is consistently applied across danger, brand, success, accent, warning, and info modifiers.src/tools/_mixins.scss (1)
1-6: LGTM! Clean refactoring to a façade pattern.Re-exporting all mixins via
@forward 'mixin-modules'maintains backward compatibility while consolidating implementations in the new module structure. Consumers can continue using@use '@volverjs/style/scss/mixins'without changes.package.json (1)
112-139: LGTM! Props export mappings properly added.The new export entries follow the established pattern and expand the public API to allow consumers to import individual props modules (typography, transitions, spacing, etc.) both as CSS and SCSS.
src/components/vv-dropdown-action.scss (1)
4-16: LGTM! Proper CSS layer scoping applied.The component styles are correctly wrapped with the
layer()mixin, enabling optional cascade layer support when$use-css-layersis true.src/components/vv-skeleton.scss (1)
4-17: LGTM! CSS layer scoping applied correctly.The layer wrapper follows the same pattern as other components.
src/settings/components/_vv-text.scss (1)
6-13: LGTM! Explicit color for headline modifier.Adding
color: var(--color-word)ensures headlines use the semantic text color variable, improving theme consistency and making the text color explicit rather than relying on inheritance.src/components/vv-alert-group.scss (1)
4-16: LGTM! CSS layer wrapper correctly applied.The component styles are now scoped under the
componentslayer when$use-css-layersis enabled. The internal logic remains unchanged, and the layer block is properly opened and closed.src/components/vv-input-text.scss (1)
5-101: LGTM! Layer wrapper correctly encompasses complex component logic.The entire vv-input-text component, including its state management logic for disabled and readonly states, is now properly scoped within the
componentslayer. All existing functionality is preserved.src/components/vv-radio-group.scss (1)
4-16: LGTM! Consistent layer implementation.The vv-radio-group component follows the same layer-scoping pattern as other components, correctly wrapping styles under the
componentslayer.src/components/vv-tab.scss (1)
4-16: LGTM! Layer wrapper correctly applied.The vv-tab component styles are properly scoped within the
componentslayer, maintaining consistency with other components in this PR.src/components/vv-accordion.scss (1)
4-16: LGTM! Layer wrapper correctly applied.The vv-accordion component is properly wrapped within the
componentslayer, following the consistent pattern applied across all components in this PR.src/components/vv-alert.scss (1)
4-16: LGTM! Consistent layer implementation.The vv-alert component correctly follows the layer-scoping pattern, wrapping all styles under the
componentslayer when$use-css-layersis enabled.src/utilities/typography.scss (1)
4-268: LGTM! Typography utilities correctly scoped under utilities layer.All typography utilities are now properly wrapped within the
utilitieslayer (note: correctly using 'utilities' rather than 'components'), which aligns with the CSS layer architecture for separating utility classes from component styles. The extensive typography utility definitions remain unchanged and intact.src/themes/dark/settings/components/_vv-avatar.scss (1)
24-26: New surface modifier follows color system conventions.The
surfacemodifier is correctly added to the ring modifiers group, usingvar(--color-word-2)which aligns with the new surface/word color palette introduced in this PR. The variable is properly defined through the color map generation system.src/components/vv-checkbox-group.scss (1)
4-4: LGTM: Consistent layer integration.The component correctly adopts the CSS layer pattern matching other components in this PR.
Also applies to: 15-16
src/utilities/layout.scss (1)
5-5: LGTM: Utilities correctly scoped to their layer.All layout utilities are now properly wrapped in the
utilitieslayer, maintaining the appropriate separation from component and prop layers.Also applies to: 208-209
src/components/vv-accordion-group.scss (1)
4-4: LGTM: Layer integration applied consistently.Also applies to: 15-16
src/components/vv-avatar.scss (1)
4-4: LGTM: Layer integration applied consistently.Also applies to: 15-16
src/props/background.scss (1)
3-8: LGTM: Props correctly scoped to their layer.The background and gradient property mappings are now properly wrapped in the
propslayer, with correct indentation maintained for the nested:where(:host, :root, .theme)selector.src/volver.scss (1)
1-2: LGTM: Layer order definition correctly positioned.The explicit layers import is properly placed at the top of the entry file with a clear comment explaining the requirement. CSS layer order must be established before any layered styles are defined, making this positioning critical for the cascade layer system to function correctly.
src/components/vv-input-file.scss (1)
5-5: LGTM: Layer integration applied consistently.The component, including its disabled/readonly state handling logic, is now properly scoped within the
componentslayer.Also applies to: 100-101
src/components/vv-button.scss (1)
4-4: CSS layer integration applied correctly.The component is properly scoped within the
componentslayer using the configuration-driven approach. Thelayermixin is defined insrc/tools/mixin-modules/_layers.scss, and both configuration variables ($use-css-layersand$layer-prefix) are defined insrc/_config.scssand exported via the imported context file. All dependencies are available in scope.src/themes/dark/props/_background.scss (1)
7-18: LGTM!The CSS layer wrapper is correctly applied around the dark theme background rules. The
themeslayer name is semantically appropriate, and the inner logic remains unchanged.src/utilities/flexbox.scss (1)
5-5: LGTM!The layer wrapper correctly scopes all flexbox utilities under the
utilitieslayer. The existing utility definitions remain functionally unchanged.Also applies to: 138-139
src/utilities/effects.scss (1)
3-3: LGTM!The layer wrapper correctly scopes all effect utilities (box-shadow, opacity, blend modes) under the
utilitieslayer, consistent with other utility files.Also applies to: 35-36
src/utilities/backgrounds.scss (1)
3-3: LGTM!Background utilities are correctly wrapped in the
utilitieslayer, following the consistent pattern established across all utility files.Also applies to: 69-70
src/components/vv-button-group.scss (1)
4-4: LGTM!The button group component is correctly wrapped in the
componentslayer. All the complex modifier logic (block, compact, vertical) remains intact within the layer scope.Also applies to: 114-115
src/components/vv-nav.scss (1)
4-4: LGTM!The nav component is correctly wrapped in the
componentslayer, following the established pattern for component files.Also applies to: 15-16
src/components/vv-text.scss (1)
4-4: LGTM!The text component is correctly wrapped in the
componentslayer, consistent with all other component files in this PR.Also applies to: 15-16
src/components/vv-progress.scss (1)
4-4: LGTM! Component layer wrapping applied correctly.The
vv-progresscomponent is now properly scoped under thecomponentslayer, consistent with the broader CSS layers architecture introduced in this PR.Also applies to: 15-16
src/utilities/grid.scss (1)
4-4: LGTM! Layer wrapping applied correctly.The grid utilities are now properly scoped under the
utilitieslayer, following the same pattern as other utility files.Also applies to: 86-87
src/utilities/tables.scss (1)
3-3: LGTM! Layer wrapping applied correctly.The table utilities are now properly scoped under the
utilitieslayer, consistent with other utility modules.Also applies to: 19-20
src/components/vv-table.scss (1)
4-4: LGTM! Component layer wrapping applied correctly.The
vv-tablecomponent is now properly scoped under thecomponentslayer.Also applies to: 15-16
src/components/vv-dropdown-option.scss (1)
4-4: LGTM! Component layer wrapping applied correctly.The
vv-dropdown-optioncomponent is now properly scoped under thecomponentslayer.Also applies to: 15-16
src/components/vv-breadcrumb.scss (1)
4-4: LGTM! Component layer wrapping applied correctly.The
vv-breadcrumbcomponent is now properly scoped under thecomponentslayer.Also applies to: 15-16
src/_preflight.scss (1)
12-12: LGTM! Preflight layer wrapping applied correctly.The preflight styles are now properly scoped under the
preflightlayer. This is an appropriate layer designation for base reset/normalization styles, allowing them to be positioned early in the cascade order.Also applies to: 452-452
src/utilities/spacing.scss (1)
5-5: Layer wrapping applied correctly.The spacing utilities are now properly scoped under the
utilitieslayer. Thelayer()mixin is correctly defined insrc/tools/mixin-modules/_layers.scss, and both required configuration variables ($use-css-layersand$layer-prefix) are defined insrc/_config.scss. The wrapping is clean with proper opening at line 5 and closing at line 121, and the internal logic remains unchanged.src/components/vv-checkbox.scss (1)
4-32: LGTM! Clean layer integration.The component is correctly wrapped in the CSS layer scope. The internal logic remains unchanged, and the opening/closing braces are properly balanced.
src/components/vv-select.scss (1)
5-101: LGTM! Consistent layer integration.The component follows the same layer-wrapping pattern as other components in this PR. Structure is sound and internal logic is preserved.
src/components/vv-dialog.scss (1)
4-16: LGTM! Proper layer scoping applied.The layer wrapper is correctly implemented with balanced braces and unchanged internal logic.
docs/App.vue (1)
20-22: LGTM! Good test configuration.Enabling
$use-css-layers: trueand$use-custom-props-for-components: falsein the documentation app provides an excellent test bed for the new CSS layer and performance optimization features.src/utilities/interactivity.scss (1)
4-29: LGTM! Utilities properly layered.The utilities are correctly scoped under the
utilitieslayer. Structure is sound and utility logic is preserved.src/utilities/sizing.scss (1)
4-89: LGTM! Consistent utility layer integration.The sizing utilities follow the same layer pattern as other utility files. All opening/closing braces are balanced, and the internal logic remains intact.
src/components/vv-dropdown.scss (1)
4-16: LGTM! Layer wrapping applied correctly.The dropdown component is properly scoped within the CSS layer with balanced braces and preserved internal logic.
src/components/vv-avatar-group.scss (1)
4-16: LGTM! Consistent layer implementation.The avatar group component follows the same mechanical pattern as all other components in this PR. Structure is correct and internal logic is unchanged.
src/themes/dark/props/_input.scss (1)
7-18: LGTM! CSS layer integration is correct.The layer wrapper appropriately scopes dark input theme styles under the
themeslayer, maintaining all existing selectors and media query logic while enabling cascade layer management.src/themes/dark/props/_colors.scss (1)
7-18: LGTM! Consistent layer integration for dark theme colors.The layer wrapper correctly scopes dark color theme styles under the
themeslayer, consistent with the pattern used across other theme files.src/props/colors.scss (1)
3-7: LGTM! Proper layer scoping for color properties.The layer wrapper correctly places color property definitions in the
propslayer, which appropriately precedes thethemeslayer in the cascade order.src/utilities/transitions.scss (1)
5-51: LGTM! Utilities correctly scoped to highest specificity layer.The layer wrapper places transition utilities in the
utilitieslayer, which appropriately comes last in the cascade order, allowing utilities to override component and theme styles as expected.src/components/vv-badge.scss (1)
4-16: LGTM! Component correctly scoped to components layer.The layer wrapper appropriately places the badge component in the
componentslayer, maintaining proper cascade order between base props and theme overrides.src/props/layout.scss (1)
3-8: LGTM! Layout properties correctly scoped to props layer.The layer wrapper maintains consistency with other property files by placing layout properties in the
propslayer, ensuring proper cascade order.src/_layers.scss (1)
1-4: No action needed—CSS layer initialization is already correctly positioned.The file is already imported first in the main entry point (
volver.scss) before any files that use@include layer(...). The dependency order is correct, and the layer order will be established before any styles are emitted to layers.src/settings/components/_vv-nav.scss (1)
125-125: Confirm that the project's target browser matrix supports color-mix() (Chrome 111+, Firefox 113+, Safari 16.2+), or add a fallback for older browser versions if required.The
color-mix()function is well-established in modern browsers (supported since late 2022–early 2023). Ensure your browser support policy explicitly includes these versions; if not, provide a fallback.src/props/input.scss (1)
3-7: LGTM! Clean layer integration.The input props are now properly scoped within the CSS
propslayer. The wrapping is consistent with the broader CSS Layers architecture introduced in this PR, and the inner logic remains unchanged.src/utilities/colors.scss (1)
3-40: LGTM! Utilities properly layered.All color utilities (background, text, decoration, border) are now consistently scoped within the
utilitieslayer, aligning with the CSS Layers architecture. The utility generation logic remains intact.src/utilities/borders.scss (1)
4-93: LGTM! Border utilities correctly layered.The border utilities (radius, width, style) and their directional variants are now properly scoped within the
utilitieslayer. The complex nested loops for generating directional utilities remain functionally unchanged.src/props/borders.scss (1)
3-8: LGTM! Border props layered correctly.Border-related CSS custom properties are now scoped within the
propslayer, consistent with other prop files in this PR. The property generation logic is preserved.src/props/spacing.scss (1)
4-29: LGTM! Spacing props with responsive logic properly layered.The spacing props, including both static and dynamic responsive variants, are now scoped within the
propslayer. The complex breakpoint-driven dynamic spacing logic and conditional handling remain functionally intact.src/utilities/filters.scss (1)
3-36: LGTM! Filter utilities layered consistently.Filter utilities (blur, brightness, saturate, backdrop-blur) are now properly scoped within the
utilitieslayer, maintaining consistency with the other utility files in this PR.src/reset.scss (2)
1-3: LGTM! Reset layer properly configured.The addition of the
contextmodule import enables access to thelayer()mixin, and the reset styles are now correctly scoped within theresetlayer. This aligns with CSS Layers best practices for managing cascade order.
4-101: LGTM! Reset styles preserved.All reset rules remain functionally unchanged while now being scoped within the CSS layer. The complex
:whereselectors and attribute-based rules are properly maintained.src/components/vv-card.scss (1)
4-16: LGTM! Clean layer encapsulation.The component styles are correctly wrapped in the CSS layer context using the
componentslayer, aligning with the PR's architecture for optional cascade layer management.src/props/breakpoints.scss (1)
4-18: LGTM! Breakpoint properties correctly layered.The breakpoint properties are properly encapsulated in the
propslayer, maintaining the existing logic while enabling optional layer-based specificity control.src/props/sizing.scss (1)
3-8: LGTM! Sizing properties correctly layered.The width and height properties are properly wrapped in the
propslayer, consistent with the broader layering strategy.src/components/vv-radio.scss (1)
4-24: LGTM! Radio component correctly layered.The vv-radio component styles are properly encapsulated in the
componentslayer without modifying the internal BEM structure or disabled state handling.src/tools/mixin-modules/_index.scss (1)
1-25: Excellent centralized mixin index.This index module provides a clean, single-import interface for all mixin utilities, improving developer experience and maintainability. The documentation comments clearly indicate what each forwarded module provides.
src/props/typography.scss (1)
4-41: LGTM! Typography properties correctly layered.The typography properties, including static and responsive font-size mappings, are properly encapsulated in the
propslayer. The breakpoint handling and dynamic font-size logic remain intact.src/themes/dark/components/_vv-avatar.scss (2)
7-13: LGTM! Updated to use spread-theme-component.The mixin correctly migrates to the new
spread-theme-componenthelper, consolidating theme component logic and aligning with the PR's refactored theme system.
16-26: LGTM! Dark theme correctly layered.The dark theme logic is properly wrapped in the
themeslayer while maintaining both automatic (prefers-color-scheme) and explicit (.theme--dark) dark mode paths.src/settings/components/_vv-card.scss (1)
48-56: Modern color-mix implementation for glass effects.The glass modifier correctly uses CSS
color-mix()with appropriate transparency levels (40% for main background, 70% for header/footer), creating the intended glass aesthetic. This syntax is widely supported in modern browsers (Chrome/Edge 111+, Firefox 113+, Safari 16.2+) and marked as baseline/widely available per MDN. If targeting older browsers, consider providing a fallback background color via a@supportsfeature query.src/tools/mixin-modules/_helpers.scss (1)
16-18: LGTM!The conditional
:where()wrapper correctly implements zero-specificity when enabled. Thestring.unquoteensures the selector string is properly formatted for CSS output.src/utilities/transforms.scss (1)
3-3: LGTM - Layer wrapper correctly applied.The utilities are properly wrapped in the CSS layer using the new configuration flags. This enables cascade management when
$use-css-layersis enabled.Also applies to: 127-127
src/props/transitions.scss (1)
51-169: LGTM - Keyframes definitions preserved.The
@keyframesdefinitions are correctly moved inside the layer wrapper while maintaining their functionality. The formatting changes improve readability without altering behavior.src/_config.scss (2)
12-14: Verify layer order priority matches intended cascade.The
$layer-orderdefines cascade priority where later layers have higher specificity. The current order(reset, preflight, props, components, themes, utilities)means:
- Utilities have highest priority (can override everything)
- Themes can override components/props/preflight/reset
- Components can override props/preflight/reset
Verify this matches the intended design system behavior, particularly:
- Should themes really override component defaults?
- Is utilities having the highest priority intentional (following Tailwind's model)?
Consider documenting this cascade order with examples in the configuration comments to help users understand the implications when
$use-css-layers: true.
4-7: LGTM - Well-documented color system toggle.The
$use-color-mixflag is clearly documented with the distinction between modern Relative Color Syntax and legacy HSL channel separation. Defaulting totrueis appropriate given browser support in Chrome 125+, Edge 125+, Firefox 128+, and Safari 18+. Ensure minimum browser requirements are documented at the project level (e.g., in README or contributing guide).src/themes/dark/components/_vv-dropdown-action.scss (2)
7-13: LGTM - Theme component refactored correctly.The mixin now uses
spread-theme-componentwith explicit base and theme maps, which provides better control over theme application and supports the new custom properties flag.
16-26: LGTM - Proper layer scoping for themes.The theme rules are correctly wrapped in the CSS layer, maintaining both the automatic dark mode detection via
prefers-color-schemeand explicit.theme--darkclass application.src/tools/mixin-modules/_utilities.scss (2)
44-54: LGTM - Recursive nested map handling.The recursive call for nested maps correctly passes through all necessary parameters and maintains the naming hierarchy with the
$nameparameter. This enables deep map traversal for complex utility definitions.
75-75: Thestr-replacefunction is properly imported and available. It is defined insrc/tools/_functions.scss(line 520) and imported via@use '../functions' as *at line 3 of the utilities file. No action required.src/themes/dark/components/_vv-alert.scss (1)
7-13: LGTM - Consistent theme component pattern.The file follows the same refactoring pattern as other theme components (e.g.,
_vv-dropdown-action.scss), usingspread-theme-componentand proper layer scoping. This consistency ensures predictable behavior across all themed components.Also applies to: 16-26
docs/contents/settings/colors.md (1)
97-114: The color algorithm values are mathematically correct but documentation could clarify the scale differences.The documentation examples are accurate:
- Brand-lighten-6:
calc(l * 1.6)is correct (6 steps × 10% scale = 1.6 multiplier)- Surface-6:
calc(l - 12)is correct (6 steps × 2% scale = 12)However, the general description stating "Fixed steps for surface/word colors:
calc(l + 12)" is imprecise. The implementation uses two different scales:
color-mix-lighten-mapuses 12% per step (for lighten variants)color-mix-darken-mapuses 2% per step (for darken variants)The documentation example demonstrates the 2% scale (step 6: 6 × 2 = 12), while the general description references the 12% scale. Clarify which function and scale applies to each color type to avoid confusion.
src/components/vv-tooltip.scss (1)
4-31: LGTM - Layer wrapper and consolidated selector look correct.The component is properly wrapped with the
layer()mixin for CSS cascade layer support. The consolidated selector on line 25 correctly handles all hover/focus-visible interaction states (both pseudo-classes and utility classes) in a single rule.src/themes/dark/components/_vv-select.scss (1)
6-26: LGTM - Consistent dark theme pattern with layer wrapping.The
spread-theme-componentmixin usage with explicit parameters and thelayer(themes, ...)wrapper follow the established pattern across dark theme components. The dual-path approach (media query for system preference + explicit.theme--darkclass) provides good flexibility for theme switching.src/themes/dark/components/_vv-badge.scss (1)
6-26: LGTM - Follows established dark theme component pattern.Structure is consistent with other dark theme components (
_vv-select.scss,_vv-button.scss, etc.) usingspread-theme-componentand layer wrapping.src/tools/mixin-modules/_layers.scss (1)
9-18: LGTM - Clean and functional layer wrapper mixin.The conditional layer wrapping based on
$enabledflag is well-implemented. The@contentpassthrough when disabled ensures no output overhead.src/themes/dark/components/_vv-button.scss (1)
6-26: LGTM - Consistent with the dark theme component pattern.Follows the same structure as other dark theme components with
spread-theme-componentand layer wrapping.src/themes/dark/components/_vv-nav.scss (1)
6-26: LGTM - Follows established dark theme component pattern.The implementation correctly uses
$vv-navand$dark-vv-navmaps with the standardized layer wrapping.Note: The AI summary references
_vv-alert.scsscontent, but this file is_vv-nav.scss. The code itself is correct.src/themes/dark/components/_vv-dropdown-option.scss (1)
6-26: LGTM - Consistent dark theme component implementation.Follows the standardized pattern with
spread-theme-componentand layer wrapping.src/tools/mixin-modules/_props.scss (1)
15-41: LGTM - Solid recursive map-to-CSS-props transformation.The mixin correctly handles:
- Nested map recursion with proper key concatenation
- Skip logic for internal keys (prefixed with
_,--, or[)- Escaped slash normalization via
str-replaceThe
meta.inspect()usage for key comparisons ensures consistent string handling regardless of the original key type. Thestr-replacefunction is properly imported and available from the functions module.src/tools/mixin-modules/_attrs.scss (2)
12-42: LGTM - Vendor prefix handling for pseudo-elements.The mixin correctly emits both
-webkit-and-moz-variants for form control pseudo-elements that require vendor prefixes.
134-174: Logic for attribute generation is well-structured.The conditional handling for CSS custom properties vs direct values, bracketed keys, and content properties is comprehensive. The use of
meta.inspectfor string operations is appropriate.src/themes/dark/settings/_colors.scss (2)
14-33: Conditional surface palette for color-mix mode is well-implemented.The dual-branch approach using CSS Relative Color Syntax (
hsl(from var(...) h s 10%)) when color-mix is enabled, with fallback to legacy HSL variable pattern, provides good backward compatibility.
36-55: Dark theme color inversion logic is correct.The dark theme appropriately uses
color-mix-darken-mapfor word colors (darkening bright text) andcolor-mix-lighten-mapfor surface colors (lightening dark backgrounds), which is the inverse of the light theme behavior.src/settings/_colors.scss (2)
58-103: Comprehensive color map with dual-mode support.The color map construction cleanly separates the color-mix-enabled path (using
color-base-map,color-mix-*-mapfunctions) from the legacy path (usinghsla-map,color-*-mapfunctions). The structure is consistent and maintainable.
89-93: Minor inconsistency: legacy surface map usescolor-darken-mapwith$fixed: true.In the color-mix branch (line 69), surface uses
color-mix-darken-mapwhich produces darkened shades. In the legacy branch (line 91), it also usescolor-darken-map. However, the word colors use opposite operations in each branch (lighten in color-mix, but line 89 showscolor-lighten-map). This appears intentional for the light theme, just confirming the logic is correct.src/tools/_functions.scss (3)
133-152: Verify proportional mode calculation for relative-color-value.In proportional mode (lines 147-150), the calculation
$multiplier: 1 + $scale-factormeans a 10% scale produces multiplier 1.1. For darkening (negative change), a -10% would produce multiplier 0.9. However, line 179 passes$scale * $i * -1for darken, socolor-mix-shades-mapuses negative values for darkening.The issue: when
$lightness-changeis negative (e.g., -10%), line 147 calculates$scale-factor: -0.1, then$multiplier: 0.9, which correctly darkens. The logic appears sound.
244-261: Alpha map percentage calculation may produce unexpected results at boundaries.At line 254,
$percentage: 100% - ($scale * $i * 100%)with default$scale: 0.1and$steps: 9:
- Step 1: 100% - (0.1 * 1 * 100%) = 90% transparent → 10% opaque
- Step 9: 100% - (0.1 * 9 * 100%) = 10% transparent → 90% opaque
This is correct for generating increasing opacity steps. The
color-mix(in srgb, var(...), transparent #{$percentage})syntax is valid.
117-121: LGTM - Simple and effective base map function.Clean implementation that returns the color under its CSS variable name.
docs/components/ColorPalette.vue (2)
72-75: Good simplification to single CSS variable.Consolidating from separate hue/saturation/lightness variables to a single
--color-{name}variable aligns with the new CSS Relative Color Syntax approach and reduces complexity.
256-259: Simplified color setter writes hex directly to CSS variable.Setting the hex value directly to
colorVarworks because modern browsers accept hex colors as CSS variable values, and the Relative Color Syntax can work with them.src/tools/mixin-modules/_theme.scss (3)
18-45: Well-designed recursive function for extracting light reset values.The
extract-light-valuesfunction correctly traverses the theme map and extracts corresponding values from the base map, enabling automatic light-mode reset generation. The null-safe handling and empty map check are good practices.
57-146: Comprehensive theme component mixin with dual-mode support.The
spread-theme-componentmixin cleanly handles both CSS custom properties mode and direct attributes mode. The automatic light reset generation from base-map is a thoughtful feature for theme toggling scenarios.
283-354: State spreading handles multiple selector variants comprehensively.The mixin generates BEM modifier style (
.block--state), class style (.block.state), and appropriate pseudo-class/attribute selectors for each state. The focus-visible selector at line 323 includes proper exclusions for disabled and inactive elements.src/tools/mixin-modules/_bem.scss (2)
41-170: Well-structured main BEM mixin with customization flags.The
spread-map-into-bemmixin provides a clean orchestration layer with individual$custom-*flags allowing selective generation. The:where(:host, :root, .theme)wrapper for CSS custom properties at line 66 is appropriate for low-specificity theming.
496-574: Comprehensive state selector helper function.The
-add-state-selectorsfunction handles various state types appropriately:
checked-withinwith:has(input:checked)open/closewith attribute selectorsdirtywith:not(:has(*:placeholder-shown))disabled/readonly/multiplewith attribute selectorspressed/selectedwith ARIA attributesThe alias support ensures consistent behavior across alternative selectors.
| "unplugin-auto-import": "^20.3.0", | ||
| "unplugin-vue-components": "^30.0.0", | ||
| "vite": "^7.1.11", | ||
| "vite": "^7.3.0", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🌐 Web query:
Vite 7 breaking changes migration guide
💡 Result:
Summary migration checklist for Vite 7 — key breaking changes and actions
-
Upgrade Node in dev/CI to >= 20.19 (or 22.12+) — Vite 7 is ESM-only and drops Node 18. Update Docker/CI runners. [2]
-
ESM-only distribution — Vite core is shipped as pure ESM; ensure any CJS consumers use supported Node require(esm) shims or migrate to ESM. [2]
-
Default build.target changed to "baseline-widely-available" (new baseline browser versions bumped) — verify your app against the new target and pin build.target if you need broader legacy support. [1][2]
-
Removed/deprecated APIs/features to address before upgrading:
- Legacy Sass API support removed. Migrate to supported Sass usage. [2]
- splitVendorChunkPlugin removed — adjust chunking strategy if you relied on it. [2]
- Other outdated config options / deprecated internals — run tests and review migration docs/changelog for project-specific items. [1][2]
-
Environment API and new hooks:
- New buildApp hook and other Environment API changes for framework integrations — plugin/framework authors should adapt. [1][2]
-
Rolldown integration (new Rust-based bundler):
- Rolldown/rolldown-vite is introduced as an alternative (path toward future default). Test with rolldown-vite if you rely on bundler internals or want to migrate early. Watch for minor Rolldown-specific edge cases documented in the migration notes. [1]
-
Testing/tooling:
- Upgrade Vitest to a compatible version (Vitest 3.2+ recommended). Update any test configs that interact with Vite internals. [2]
-
Practical upgrade steps
- Update package.json to vite@^7, update devDependencies (vitest, plugins). [2]
- Update Node versions in local/dev/CI to 20.19+ or 22.12+. [2]
- Run full test suite and dev server; fix plugin or config breakages reported. [1][3]
- If you need to preserve legacy behavior, pin build.target or keep using a Vite 6 branch until you’re ready to migrate. [1]
References
- Vite migration page / Migration from v7 (breaking notes & Rolldown notes). [1]
- Vite 7 release announcement (requirements, removed features, summary). [2]
- Vite breaking changes index (list of planned/past breaking changes). [3]
If you want, I can produce a tailored step-by-step upgrade plan for your repo—tell me your current Vite version, Node version, and any plugins you use.
🏁 Script executed:
# First, let's examine the package.json to see the current plugin versions
cat package.json | grep -A 20 -B 5 "vite"Repository: volverjs/style
Length of output: 2782
🏁 Script executed:
# Check if there's a vite config file
fd -t f "vite\.config\." -o "vitest\.config\."Repository: volverjs/style
Length of output: 209
🏁 Script executed:
# Find vite config files with correct syntax
fd "vite\.config" -t fRepository: volverjs/style
Length of output: 72
🏁 Script executed:
# Check for vitest config and vitest dependency
grep -i "vitest" package.jsonRepository: volverjs/style
Length of output: 40
🌐 Web query:
vite-plugin-css-export Vite 7 compatibility
💡 Result:
Short answer: Use vite-plugin-css-export v3.0.3 or later — v3.0.3+ is listed as compatible with Vite 7. [1][2]
Details: the plugin README and package pages show the compatibility table (3.x supports Vite 5–7; specifically >=3.0.3 adds Vite 7 support). If you need a specific install command: npm i -D vite-plugin-css-export@^3.0.3. [1][2]
Sources:
[1] GitHub README (vite-plugin-css-export).
[2] Package metadata / compatibility table (npm/socket view).
🌐 Web query:
vite-plugin-handlebars Vite 7 support
💡 Result:
Short answer: Most popular vite-plugin-handlebars packages are not officially updated for Vite 7; you’ll need to either use a maintained fork (e.g. @yoichiro / @vituum variants) or patch the plugin to the Vite 7 plugin API. See sources below for status and Vite 7 breaking changes.
- Vite 7 release notes (Node and ESM changes / plugin hook adjustments) — upgrade may require plugin changes. [1]
- The original vite-plugin-handlebars npm page states it was written for Vite 2 and hasn’t been updated for newer majors. [2]
- The GitHub repo for @yoichiro/vite-plugin-handlebars (active repo/fork) and @vituum package are available as alternatives you can try; check those repos for recent activity and compatibility. [3][4]
Recommendation: try one of the maintained forks (install and run with Vite 7); if you hit errors, update the plugin to use Vite 7’s ESM-only distribution and any changed transformIndexHtml / plugin-hook signatures (see Vite 7 docs). If you want, tell me which package/version you’re using and I’ll check compatibility or suggest exact code changes.
Sources:
[1] Vite 7 announcement.
[2] vite-plugin-handlebars — npm.
[3] yoichiro/vite-plugin-handlebars — GitHub.
[4] @vituum/vite-plugin-handlebars — npm / Vituum docs.
🌐 Web query:
vite-ssg Vite 7 compatibility
💡 Result:
Short answer: Possibly — but you should verify before upgrading.
- Vite 7 was released June 24, 2025 (Node 20.19+/22.12+ and ESM-only distribution). [1]
- The official vite-ssg README (antfu-collective/vite-ssg) does not explicitly list Vite 7 in its top-level compatibility note; it documents ESM-only from v27.0.0 and general Vite support but you should check the repo's issues/PRs for Vite‑7-specific fixes. [2]
Actionable steps:
- Check your installed vite-ssg version (use v27+ for ESM). [2]
- Search the vite-ssg GitHub issues/PRs for “vite 7” or open an issue if you hit breakage. [2]
- Confirm your Node version meets Vite 7’s requirements (Node 20.19+ or 22.12+). [1]
Sources:
- Vite 7 announcement (June 24, 2025). [1]
- vite-ssg README (antfu-collective/vite-ssg). [2]
🏁 Script executed:
cat -n vite.config.tsRepository: volverjs/style
Length of output: 3445
🌐 Web query:
vite-ssg v28 Vite 7 support compatibility
💡 Result:
Short answer: vite-ssg v28 (v27+ is ESM-only) is expected to work with Vite 7, but you must run on the Node versions Vite 7 requires (Node.js >= 20.19 or 22.12) and confirm any downstream plugin/adapter you use also supports Vite 7. Sources: vite-ssg README (ESM-only from v27) and the Vite 7 announcement (Node / ESM requirements). [1][2]
Sources
[1] antfu-collective/vite-ssg — README (notes ESM-only from v27.0.0).
[2] Vite — "Vite 7.0 is out!" (Vite 7 release notes: ESM-only distribution and Node.js 20.19+/22.12+ requirement).
Update Node.js requirement and vite-plugin-handlebars for Vite 7 compatibility.
Vite 7 requires Node ≥ 20.19 or 22.12+, but package.json specifies ">= 12.x" — update the engines.node field to at least ">= 20.19". Additionally, vite-plugin-handlebars v2.0.0 is not officially compatible with Vite 7; replace it with a maintained fork such as @yoichiro/vite-plugin-handlebars or @vituum/vite-plugin-handlebars. The other plugins (vite-plugin-css-export v3.0.3, vite-ssg v28.2.2, @vitejs/plugin-vue v6.0.3) support Vite 7. After these changes, test the build and consider pinning build.target if legacy browser support is required (Vite 7 changed the default baseline).
🤖 Prompt for AI Agents
In package.json around line 82, update the Node engine requirement and replace
the incompatible handlebars plugin: change the "engines.node" value to at least
">= 20.19" (Vite 7 requires Node ≥ 20.19 or 22.12+), remove
"vite-plugin-handlebars" v2.0.0 and add a maintained fork such as
"@yoichiro/vite-plugin-handlebars" or "@vituum/vite-plugin-handlebars" in
dependencies, run npm/yarn install to update lockfile, then run the build and
tests to verify compatibility and optionally pin Vite build.target if you need
legacy browser support.
src/export.scss
Outdated
|
|
||
| // Keep the escaped slash for CSS property names | ||
| $name: str-replace($name, '\\/', '\\/'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
Remove the redundant no-op str-replace operation.
The str-replace($name, '\\/', '\\/') operation replaces the escaped slash with itself, which is a no-op. If the intent is to preserve escaped slashes in translation keys (as indicated by the comment), simply remove the str-replace line entirely.
🔎 Proposed fix
@each $key, $value in $translate {
$name: meta.inspect($key);
-
- // Keep the escaped slash for CSS property names
- $name: str-replace($name, '\\/', '\\/');
#{'translate__' + $name}: $value;
}Alternatively, if you need to keep the comment for documentation purposes:
@each $key, $value in $translate {
+ // Keep the escaped slash for CSS property names
$name: meta.inspect($key);
-
- // Keep the escaped slash for CSS property names
- $name: str-replace($name, '\\/', '\\/');
#{'translate__' + $name}: $value;
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // Keep the escaped slash for CSS property names | |
| $name: str-replace($name, '\\/', '\\/'); | |
| @each $key, $value in $translate { | |
| $name: meta.inspect($key); | |
| #{'translate__' + $name}: $value; | |
| } |
🤖 Prompt for AI Agents
In src/export.scss around lines 544 to 546, the str-replace call
str-replace($name, '\\/', '\\/') is a redundant no-op (it replaces an escaped
slash with itself); remove that line and keep the existing comment so escaped
slashes are preserved without performing an unnecessary replacement.
| $default: null; | ||
| $class-name: $class; | ||
| $key: meta.inspect($key); | ||
| $var: $prop; | ||
|
|
||
| // fix class name | ||
| @if $class-name != $key and $prop != $key { | ||
| @if $class-name != '' { | ||
| $class-name: $class-name + '-'; | ||
| } | ||
|
|
||
| $class-name: $class-name + $key; | ||
| } | ||
|
|
||
| // fix variable name | ||
| @if $var != '' and $var != $key { | ||
| $var: $var + '-' + $key; | ||
| } | ||
|
|
||
| $var: str-replace($var, '\\/', '-'); | ||
|
|
||
| // check if value is not a map (spacing-dynamic) | ||
| @if meta.type-of($value) != 'map' { | ||
| $default: $value; | ||
| } | ||
|
|
||
| // check if map is a list | ||
| @if meta.type-of($map) == 'list' and (not $default or $default == '') { | ||
| $default: $key; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
Complex default value logic - verify edge cases.
The default value determination (lines 78-85) has multiple conditions:
- Use
$valueif not a map - Use
$keyif$mapis a list and no default - Unquote if string
This logic might not handle all edge cases correctly, particularly:
- What happens if
$valueisnullor0? Line 98 checks@if $defaultwhich would fail for falsy values. - List detection at line 83 happens after the map check, but lists were already handled recursively.
🔎 Strengthen default value handling
// check if value is not a map (spacing-dynamic)
@if meta.type-of($value) != 'map' {
$default: $value;
}
// check if map is a list
-@if meta.type-of($map) == 'list' and (not $default or $default == '') {
+@if meta.type-of($map) == 'list' and $default == null {
$default: $key;
}
@if meta.type-of($default) == 'string' {
$default: string.unquote($default);
}
%#{$prefix}#{$class-name} {
@include media-breakpoint-up($breakpoint, $bps) {
@if meta.type-of($attribute) != 'list' {
$attribute: ($attribute);
}
@each $attr in $attribute {
- @if $default {
+ @if $default != null {
@if $var != '' {
#{$attr}: var(--#{$var}, $default);
} @else {
#{$attr}: $default;
}This ensures falsy but valid values (like 0) are handled correctly.
Committable suggestion skipped: line range outside the PR's diff.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (2)
package.json (2)
28-30: Node version constraint is too loose for Vite 7.Vite 7 requires Node.js ≥ 20.19 or ≥ 22.12, but
">= 20.x"permits Node 20.0–20.18 which will fail. Tighten the constraint.🔎 Proposed fix
"engines": { - "node": ">= 20.x" + "node": ">= 20.19" },
82-84: vite-plugin-handlebars v2.0.0 is not officially compatible with Vite 7.With
vite@^7.3.0, the unchangedvite-plugin-handlebars@^2.0.0may cause build failures or runtime issues. Consider replacing it with a maintained fork such as@yoichiro/vite-plugin-handlebarsor@vituum/vite-plugin-handlebars.#!/bin/bash # Check if vite-plugin-handlebars is actually used in the vite config cat vite.config.ts | grep -i "handlebars"
🧹 Nitpick comments (1)
src/props/transitions.scss (1)
39-42: Consider removing redundant CSS variable definitions.The
$transition-propertymap (lines 39-42) and$transition-timing-functionmap (lines 51-54) are already spread outside the media query at lines 21-24 and 15-18 respectively. Since these values don't need to change based on motion preference, spreading them again inside the media query generates duplicate CSS output unnecessarily.The
--transition-property-*and--ease-*variables can be defined once outside the media query, reducing CSS output size. Only the duration, animation, and composite transition values need to be overridden insideprefers-reduced-motion: no-preference.🔎 Proposed optimization
Remove the redundant spreads from inside the media query:
@media (prefers-reduced-motion: no-preference) { - // transition-property - @include spread-map-into-props( - $transition-property, - $prefix: transition-property - ); - // duration @include spread-map-into-props( $transition-duration-delay, $prefix: duration ); - // ease - @include spread-map-into-props( - $transition-timing-function, - $prefix: ease - ); - // animation @include spread-map-into-props($animation, animation);Also applies to: 51-54
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
.eslintrc-auto-import.jsonauto-imports.d.tsdocs/components/ColorPalette.vuepackage.jsonsrc/export.scsssrc/props/transitions.scsssrc/tools/mixin-modules/_bem.scsssrc/utilities/transforms.scss
💤 Files with no reviewable changes (2)
- .eslintrc-auto-import.json
- src/export.scss
🚧 Files skipped from review as they are similar to previous changes (1)
- src/tools/mixin-modules/_bem.scss
🧰 Additional context used
🧬 Code graph analysis (1)
auto-imports.d.ts (1)
scripts/generateDesignTokens.js (1)
icssExports(15-17)
🔇 Additional comments (13)
package.json (3)
31-31: LGTM!The pnpm version bump to 10.26.2 is a routine maintenance update.
50-93: DevDependency updates look reasonable.The version bumps align with the Vite 7 migration. Key observations:
@vitejs/plugin-vue@^6.0.3andvite-plugin-css-export@^3.0.3support Vite 7sass-embedded@^1.97.1uses the modern Sass API (legacy API was removed in Vite 7)vite-ssg@^28.2.2is ESM-compatibleEnsure build and dev server are tested after these upgrades.
112-139: New props exports are well-structured and properly referenced.The export entries follow a consistent pattern and provide granular access to individual prop modules alongside the bundled
./propsentry. All 14 referenced SCSS source files exist insrc/props/, confirming the exports are correctly configured. This aligns with the PR's goal of modularizing props.src/props/transitions.scss (2)
6-34: Excellent fix for the critical accessibility issue!This change directly addresses the critical issue flagged in previous reviews where transition variables were undefined for users with
prefers-reduced-motionenabled. The default values ensure that:
- All
--duration-*variables are set to0s(no animation)- All
--transition-*variables are set tonone(no transitions)- All
--animation-*variables are set tonone(no animations)Components that reference these variables (e.g.,
var(--transition-all)) will now always receive valid values, preventing broken transition properties for reduced-motion users.
60-76: Transition building logic looks correct.The logic correctly constructs composite transition values by combining property names with duration and easing variables. The string manipulation properly handles comma-separated properties and removes the trailing delimiter.
The hardcoded defaults (
--duration-300and--ease-in-out) are reasonable choices for the composite transitions.src/utilities/transforms.scss (4)
3-3: LGTM! CSS layer wrapper added correctly.The layer wrapper correctly implements the new CSS @layer support introduced in this PR, using the utilities layer name with conditional activation via
$use-css-layers.
65-65: Excellent! Previous escaping issue resolved.All translate selectors now consistently use
$escaped-size, including the negative translate-xand-yvariants at lines 109 and 120 that were flagged in the previous review. This will correctly generate escaped class names like.-translate-x-1\/2instead of invalid.-translate-x-1/2.Also applies to: 76-76, 87-87, 98-98, 109-109, 120-120
127-127: LGTM! Layer wrapper properly closed.The closing brace correctly closes the CSS layer wrapper block opened at line 3, ensuring all transform utilities are properly scoped within the utilities layer.
58-59: Thestr-replacefunction is properly defined and available through the import chain. The custom Sass function is defined insrc/tools/_functions.scssand exported throughsrc/tools/_index.scss, which is forwarded bysrc/_context.scss. This makes it accessible intransforms.scssvia the@use '../context' as *;import statement. The implementation at lines 58-59 is correct.docs/components/ColorPalette.vue (4)
72-75: Clean refactor to single CSS variable.The consolidation from separate HSL variables to a single
colorVarbound to--color-${props.name}aligns well with the PR's CSS Relative Color Syntax objectives and simplifies the reactive state management.
100-160: Robust color parsing implementation.The enhanced
getComputedStyleRgbnow comprehensively handles multiple color formats with proper error handling:
- rgb/rgba parsing via regex
- color() format (sRGB) parsing
- Canvas-based fallback with OffscreenCanvas support
- Null checks for canvas context (addresses previous review concern)
- Try-catch wrapper with safe defaults
The implementation properly guards against all failure modes identified in the previous review.
162-162: Updated watcher dependencies align with refactor.The watchThrottled dependencies correctly reflect the new single-variable color model, watching
colorVarinstead of the previous separate HSL components.
279-280: The implementation is correct. CSS Relative Color Syntax accepts any color format (including hex) as the source color, so assigning hex directly tocolorVarworks as intended. This is the documented default approach in the library and requires no changes.
| const refWithControl: typeof import('@vueuse/core').refWithControl | ||
| const resolveComponent: typeof import('vue').resolveComponent | ||
| const resolveRef: typeof import('@vueuse/core').resolveRef | ||
| const resolveUnref: typeof import('@vueuse/core')['resolveUnref'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent type declaration syntax.
Line 95 uses bracket notation ['resolveUnref'] while all other global declarations (lines 9-94, 96-303) have been migrated to dot notation. This inconsistency likely indicates incomplete refactoring in the auto-generation configuration.
🔎 Proposed fix
- const resolveUnref: typeof import('@vueuse/core')['resolveUnref']
+ const resolveUnref: typeof import('@vueuse/core').resolveUnref📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const resolveUnref: typeof import('@vueuse/core')['resolveUnref'] | |
| const resolveUnref: typeof import('@vueuse/core').resolveUnref |
🤖 Prompt for AI Agents
In auto-imports.d.ts around line 95, the global declaration uses bracket
notation "typeof import('@vueuse/core')['resolveUnref']" which is inconsistent
with the rest of the file; change it to dot notation "typeof
import('@vueuse/core').resolveUnref" to match lines 9–94 and 96–303, ensuring
the auto-generated declaration uses the same syntax and saving the file so the
refactor is complete.



[0.1.24] - 2025-12-29
Added
hsl(from color h s calc(...)). Brand/accent colors use proportional scaling (l * 1.1), while surface/word colors use fixed steps (l + 12). This significantly reduces the number of CSS variables, improving Chrome DevTools inspector performance.@layersupport: Optional cascade layers for better CSS specificity management.$use-color-mix: true- Enable/disable Relative Color Syntax mode (default:true)$use-css-layers: false- Enable/disable CSS @layer cascade management (default:false)$layer-order- Define layer priority order$layer-prefix- Prefix for layer names (default:volver)$use-custom-props-for-components: true- Enable/disable CSS variables in components (default:true)relative-color-value(),color-mix-shades-map(),color-mix-darken-map(),color-mix-lighten-map(),color-mix-alpha-map()Changed
if()function calls to new Sass CSS-compatible syntax (if(sass($condition): $value; else: $fallback))--color-{name}variable with Relative Color Syntax instead of separate-hue,-saturation,-lightnessvariablesFixed
Summary by CodeRabbit
New Features
Changes
Documentation
Chores
✏️ Tip: You can customize this high-level summary in your review settings.