This release brings deeper composition and sharper ergonomics to the css
engine. css.mix
and css.use
now apply a union-style deep merge, preserving media queries and nested overrides across layers — perfect for atom/molecule composition in JSX.
Selector normalization gets even smarter: combinators, HTML tags, and pseudo-prefixed selectors now auto-space with better contextual awareness. If you’ve used the spacing behavior before, this update makes it even more intelligent, reducing friction in complex nesting scenarios.
We're also bumping the valkyrie utils to 12.40.0 (valkyrie utils is also created by the creator of TriFrost), this version brings meaningful performance improvements for omit/merge/formdata conversion, all of which are used in core parts of TriFrost.
Improved
- feat: Further enhanced selector normalization with intelligent auto-spacing. Selectors that begin with combinators (
>
,+
,~
), known HTML tags (e.g.div
,section
) or known HTML tags followed by:
(pseudo),.
(class), or space
css({
section: {padding: '1rem'}, // auto-space => ' section'
div:hover: {color: 'red'}, // auto-space => ' div:hover'
'a.active' {textDecoration: 'underline'}, // auto-space => ' a.active'
'ul li': {fontSize: '1.6rem'}, // auto-space => ' ul li'
'#hero': {fontWeight: 'bold'}, // NOT auto-spaced => '#hero'
});
- feat: Enhanced
css.mix
andcss.use
to support union-style deep merges. This change enables more powerful style composition patterns, particularly beneficial for JSX-based atomic/molecular components. Nested structures like responsive breakpoints or selector-based overrides are now preserved during merging. For example:
import {css} from './css'; /* Your css factory instance */
type ButtonProps = {
title: string;
style?: Record<string, unknown>;
};
export function Button({title, style = {}}: ButtonProps) {
return (<button
type="button"
className={css.use(
css.mix({
padding: '1rem 1.5rem',
borderRadius: css.$v.rad_m,
fontSize: css.$v.font_s_button,
border: 'none',
[css.media.mobile]: {
padding: '.5rem 1rem',
borderRadius: css.$v.rad_s,
},
},
style
))}
>{title}</button>);
}
export function SmallButton({title, style = {}}: ButtonProps) {
return (<Button
title={title}
style={css.mix({
fontSize: `calc(${css.$v.font_s_button} - .2rem)`,
[css.media.mobile]: {
padding: '.5rem',
},
}, style)}
/>);
}
export function BlueSmallButton({title, style = {}}: ButtonProps) {
/**
* Eventual Styles
* {
* padding: '1rem 1.5rem',
* borderRadius: '12px',
* fontSize: 'calc(1rem - .2rem)',
* border: 'none',
* background: 'blue',
* color: 'white',
* [css.media.mobile]: {
* padding: '.5rem',
* borderRadius: '8px',
* },
* }
*/
return (<SmallButton
title={title}
style={css.mix({
background: 'blue',
color: 'white',
}, style)}
/>);
}
export function RedSmallButton({title, style = {}}: ButtonProps) {
/**
* Eventual Styles
* {
* padding: '1rem 1.5rem',
* borderRadius: '12px',
* fontSize: 'calc(1rem - .2rem)',
* border: 'none',
* background: 'red',
* color: 'white',
* [css.media.mobile]: {
* padding: '.5rem',
* borderRadius: '8px',
* },
* }
*/
return (<SmallButton
title={title}
style={css.mix({
background: 'red',
color: 'white',
}, style)}
/>);
}
- deps: Upgrade @cloudflare/workers-types to 4.20250605.0
- deps: Upgrade @valkyriestudios/utils to 12.40.0
Smarter styles. Still frosty. ❄️