You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Theme-UI中使用disabled、active这类动态类名值?

在Theme-UI中实现动态状态样式(替代classNames的写法)

嘿,我刚上手Theme-UI的时候也纠结过这个问题——毕竟classNames的动态样式切换已经用得顺手了!其实Theme-UI里有几种很直观的方式实现同样的效果,完全能满足你根据props/状态切换disabled、active这类样式的需求,我给你一步步拆解:

方法1:用sx Prop直接写条件样式(最常用)

Theme-UI的sx prop是核心,它可以接受一个函数,函数参数是当前的theme对象,你可以在函数里根据组件的props/状态动态返回样式对象,就像你之前用classNames拼接类名那样。

示例:动态切换按钮的active/disabled状态

首先在你的theme.js里定义基础样式和状态样式(也可以直接写在sx里,但复用的话建议放主题里):

// theme.js
export default {
  colors: {
    text: '#333',
    background: '#fff',
    primary: '#0070f3',
    muted: '#e0e0e0',
    textMuted: '#999',
  },
  buttons: {
    plain: {
      padding: '8px 16px',
      borderRadius: '4px',
      border: 'none',
      cursor: 'pointer',
      transition: 'all 0.2s',
      color: 'text',
      backgroundColor: 'background',
    },
    active: {
      backgroundColor: 'primary',
      color: 'white',
    },
    disabled: {
      backgroundColor: 'muted',
      color: 'textMuted',
      cursor: 'not-allowed',
      opacity: 0.7,
    },
  },
};

然后在组件里,通过sx的函数形式叠加样式:

import { Button } from 'theme-ui';

function DynamicButton({ isActive, isDisabled, children }) {
  return (
    <Button
      // 用sx函数接收theme,根据状态合并样式
      sx={(theme) => ({
        // 先应用基础样式
        ...theme.buttons.plain,
        // 如果isActive为真,叠加active样式
        ...(isActive && theme.buttons.active),
        // 如果isDisabled为真,叠加disabled样式(注意disabled优先级要高于active)
        ...(isDisabled && theme.buttons.disabled),
      })}
      // 别忘了给原生按钮加上disabled属性
      disabled={isDisabled}
    >
      {children}
    </Button>
  );
}

如果是普通的div元素,不用Theme-UI的Button组件,写法类似:

function DynamicDiv({ isActive, isDisabled }) {
  return (
    <div
      sx={(theme) => ({
        padding: '12px',
        border: '1px solid',
        borderColor: isActive ? theme.colors.primary : theme.colors.muted,
        opacity: isDisabled ? 0.7 : 1,
        cursor: isDisabled ? 'not-allowed' : 'default',
      })}
    >
      我是动态样式的Div
    </div>
  );
}

方法2:动态切换Theme-UI的variant

如果你的主题里已经定义了不同状态的按钮变体,也可以直接根据状态切换variant属性,这种方式更适合样式复用性高的场景。

示例:基于状态切换按钮variant

import { Button } from 'theme-ui';

function VariantButton({ isActive, isDisabled, children }) {
  // 根据状态确定要使用的variant
  let buttonVariant = 'buttons.plain';
  if (isDisabled) {
    buttonVariant = 'buttons.disabled';
  } else if (isActive) {
    buttonVariant = 'buttons.active';
  }

  return (
    <Button variant={buttonVariant} disabled={isDisabled}>
      {children}
    </Button>
  );
}

关键注意点

  • 不需要额外在theme.js里声明主题类型(除非你用TypeScript,那可以定义类型来获得更好的提示);
  • sx prop会自动合并样式,后面的样式会覆盖前面的,所以要注意状态的优先级(比如disabled应该覆盖active);
  • 尽量复用主题里的tokens(比如theme.colors.primary),而不是硬写颜色值,这样后续修改主题会更方便。

其实核心就是把classNames里的条件类名拼接,转换成sx里的条件样式对象合并,或者用variant来管理不同状态的样式集合,比classNames更贴合Theme-UI的主题系统哦~

内容的提问来源于stack exchange,提问作者james emanon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 14:02:32