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

在Next.js中使用Material UI:如何禁用Accordion但保留默认样式?

禁用Material UI Accordion但保留默认样式(无灰色禁用外观)

我在Next.js项目中使用Material UI,需要在song?.lyrics不存在时禁用Accordion组件,但不想让它显示灰色的禁用样式,保持正常状态的外观。当前代码设置了disabled={!song?.lyrics},但会触发MUI默认的禁用态样式,尝试过className、sx、createTheme等方式都没解决。


方案1:全局Theme覆盖禁用态样式

MUI的Accordion禁用时会自动添加.Mui-disabled类,我们需要在全局主题中覆盖这个类的样式,同时还要处理子组件(AccordionSummary、AccordionDetails)的禁用态样式——因为它们会继承父组件的禁用样式。

修正后的createTheme代码:

import { createTheme, ThemeProvider } from '@mui/material/styles';

const theme = createTheme({
  components: {
    MuiAccordion: {
      styleOverrides: {
        root: {
          '&.Mui-disabled': {
            // 重置为正常状态的背景色(比如默认透明/白色)
            backgroundColor: 'transparent',
            // 移除禁用态的透明度
            opacity: 1,
            cursor: 'default',
          },
        },
      },
    },
    MuiAccordionSummary: {
      styleOverrides: {
        root: {
          '&.Mui-disabled': {
            color: 'inherit', // 继承正常文本颜色
            '& .MuiAccordionSummary-content': { opacity: 1 },
            '& .MuiIconButton-root': { opacity: 1 }, // 重置图标的透明度
          },
        },
      },
    },
    MuiAccordionDetails: {
      styleOverrides: {
        root: {
          '&.Mui-disabled': {
            color: 'inherit',
            opacity: 1,
          },
        },
      },
    },
  },
});

// 在项目根组件中用ThemeProvider包裹
function MyApp({ Component, pageProps }) {
  return (
    <ThemeProvider theme={theme}>
      <Component {...pageProps} />
    </ThemeProvider>
  );
}

export default MyApp;

配置完成后,禁用的Accordion会保持正常外观,同时具备禁用的交互特性(无法展开)。


方案2:手动控制交互,不使用disabled属性

如果不想修改全局主题,可以跳过disabled属性,通过逻辑控制展开状态和点击事件,避免触发禁用态样式:

import { useState } from 'react';
import { Accordion, AccordionSummary, AccordionDetails } from '@mui/material';
import MdLyrics from '@mui/icons-material/Lyrics';

function ShowLyrics({ song }: Readonly<{ song: song }>) {
  const [expanded, setExpanded] = useState(false);

  const handleToggle = () => {
    // 仅当歌词存在时允许切换展开状态
    if (song?.lyrics) setExpanded(!expanded);
  };

  return (
    <Accordion expanded={expanded}>
      <AccordionSummary
        expandIcon={song?.lyrics ? <MdLyrics className='text-black' /> : null}
        onClick={handleToggle}
        sx={{ cursor: song?.lyrics ? 'pointer' : 'default' }}
      >
        {song.name}
      </AccordionSummary>
      <AccordionDetails>
        {song?.lyrics ? song.lyrics : 'Paroles non disponibles'}
      </AccordionDetails>
    </Accordion>
  );
}

这种方式下组件不会进入禁用状态,自然不会应用MUI的灰色禁用样式,同时通过逻辑实现了“无歌词时无法展开”的需求。


方案3:局部sx属性覆盖样式

如果只想针对当前组件修改,不影响全局,可以直接在Accordion上用sx属性覆盖禁用态样式:

<Accordion
  disabled={!song?.lyrics}
  sx={{
    '&.Mui-disabled': {
      backgroundColor: 'transparent',
      opacity: 1,
      '& .MuiAccordionSummary-root': {
        color: 'inherit',
        '& .MuiAccordionSummary-content': { opacity: 1 },
      },
      '& .MuiAccordionDetails-root': {
        color: 'inherit',
        opacity: 1,
      },
    },
  }}
>
  <AccordionSummary
    expandIcon={song?.lyrics ? <MdLyrics className='text-black' /> : null}
  >
    {song.name}
  </AccordionSummary>
  <AccordionDetails>
    {song?.lyrics ? song.lyrics : 'Paroles non disponibles'}
  </AccordionDetails>
</Accordion>

这种方式灵活度高,仅对当前Accordion生效。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 03:10:15