从Emotion迁移到Stitches:如何在变体与断点中处理双属性?
将Emotion的可见性组件转换为Stitches实现
首先明确原Emotion代码的核心逻辑:
- 默认状态:
onlyShowOnDesktop为true时隐藏,为false时显示 - 在指定断点宽度以上:反转显示逻辑——
onlyShowOnDesktop为true时显示,为false时隐藏 - 断点值仅为600px(对应原
m断点)或1280px(对应原xl断点)
推荐实现方式:基于Stitches主题断点(最佳实践)
Stitches的设计理念是通过主题统一管理断点,所以我们先把断点配置到Stitches主题中,再结合变体(variants)实现逻辑:
1. 配置Stitches主题
import { createStitches } from '@stitches/react'; const { styled } = createStitches({ theme: { breakpoints: { m: '600px', xl: '1280px', }, }, });
2. 创建Visible组件
利用Stitches支持在媒体查询中嵌套变体的特性,直接对应原逻辑:
export const Visible = styled('div', { // 默认样式:根据onlyShowOnDesktop控制初始显示 variants: { onlyShowOnDesktop: { true: { display: 'none' }, false: { display: 'unset' }, }, // 根据断点名称,在对应媒体查询下反转显示逻辑 breakpoint: { xl: { '@xl': { variants: { onlyShowOnDesktop: { true: { display: 'unset' }, false: { display: 'none' }, }, }, }, }, m: { '@m': { variants: { onlyShowOnDesktop: { true: { display: 'unset' }, false: { display: 'none' }, }, }, }, }, }, // 原组件的selected属性,可按需添加样式 selected: { true: { // 示例:添加选中状态样式 // border: '1px solid blue' }, false: {}, }, }, });
3. 使用组件
先根据isTopNavigationBreakPoint确定断点名称,再传入组件:
const breakpointName = isTopNavigationBreakPoint ? 'xl' : 'm'; <Visible onlyShowOnDesktop={true} breakpoint={breakpointName} selected={false} />
备选实现:支持动态数值断点
如果需要保留原组件传入数值断点的逻辑,可以通过styles函数直接生成动态媒体查询:
export const Visible = styled('div', { props: { onlyShowOnDesktop: Boolean, breakpoint: Number, selected: Boolean, }, defaultVariants: { onlyShowOnDesktop: false, }, styles: ({ props }) => ({ // 默认显示逻辑 display: props.onlyShowOnDesktop ? 'none' : 'unset', // 动态生成媒体查询 [`@media(min-width: ${props.breakpoint}px)`]: { display: props.onlyShowOnDesktop ? 'unset' : 'none', }, // 选中状态样式(按需添加) ...(props.selected && { // 示例样式 // backgroundColor: 'rgba(0,0,255,0.1)' }), }), });
对你思路的验证
你之前考虑的「在媒体查询中嵌套变体」是完全可行的,也是Stitches推荐的写法——第一种实现方式就是这么做的。这种写法能清晰对应不同断点与onlyShowOnDesktop组合的样式逻辑,符合Stitches的组件设计思路。
内容的提问来源于stack exchange,提问作者Stefan
相关产品推荐
相关产品推荐

