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

如何实现点击指定卡片的全屏打开(当前双卡片同时触发)

解决方案:实现单卡片独立全屏控制

当前问题的核心是所有卡片共享同一个布尔状态,导致点击任意按钮都会同时切换所有卡片的全屏状态。要实现单卡片独立控制,只需将全局布尔状态改为精准标识当前全屏卡片的状态,具体步骤如下:

1. 修改父组件状态管理

将原来的单个布尔值open,改为存储当前全屏卡片的唯一标识(比如卡片标题、自定义ID):

export const ChartsContainer: FC = () => {
  // 用字符串存储当前全屏的卡片标识,null表示无卡片全屏
  const [fullscreenCard, setFullscreenCard] = useState<string | null>(null);

  // 通用切换函数:点击时切换指定卡片的全屏状态
  const toggleFullscreen = (cardId: string) => {
    setFullscreenCard(prev => prev === cardId ? null : cardId);
  };

  return (
    <div className={styles.chartsContainer}>
      <Grid container className={styles.panelContainerWrapper} wrap="nowrap">
        <Grid item xs={6} className={styles.panelContainer}>
          <ChartContainer
            title="title1"
            // 判断当前卡片是否匹配全屏标识
            open={fullscreenCard === "title1"}
            feature={
              <div className={styles.featureWrapper}>
                <p className={styles.featureText}>
                  {data.chartRequestData.totalRequests.toLocaleString()}
                </p>
                <FullScreenButton onClick={() => toggleFullscreen("title1")}>
                  <IconOpenInFull />
                </FullScreenButton>
              </div>
            }
          >
            <>
              <LineBar data={data.chartRequestData.request} type="line" />
              <ChartLegend />
            </>
          </ChartContainer>
        </Grid>
        <Grid item xs={6} className={styles.panelContainer}>
          <ChartContainer
            title="title2"
            open={fullscreenCard === "title2"}
            feature={
              <div className={styles.featureWrapper}>
                <CustomSelect
                  variant="secondary"
                  options={chartSelectOptions}
                />
                <FullScreenButton onClick={() => toggleFullscreen("title2")}>
                  <IconOpenInFull />
                </FullScreenButton>
              </div>
            }
          >
            <LineBar
              data={data.chartFoivData.request.maxIndicators}
              type="bar"
            />
          </ChartContainer>
        </Grid>
      </Grid>
    </div>
  );
};

2. 子组件无需修改

ChartContainer组件保持原有逻辑即可,它仅通过接收的open属性判断是否应用全屏样式:

export const ChartContainer: FC<ChartContainerProps> = ({
  feature,
  title,
  children,
  className,
  open,
}) => {
  return (
    <div
      className={cn(styles.panelWrapper, className, {
        [styles.panelFull]: open,
      })}
    >
      <div className={styles.headerWrapper}>
        <h3 className={styles.title}>{title}</h3>
        {feature}
      </div>
      {children}
    </div>
  );
};

逻辑说明

  • 用fullscreenCard存储当前全屏的卡片标识(如title1),点击按钮时触发toggleFullscreen函数:
    • 如果当前全屏的就是该卡片,则清空标识(关闭全屏)
    • 如果不是,则设置为该卡片的标识(打开对应卡片全屏)
  • 每个ChartContainer的open属性通过对比自身标识和fullscreenCard的值,决定是否应用全屏样式

扩展:支持多卡片同时全屏

如果需要允许多个卡片同时全屏,可以将状态改为Set类型存储多个标识:

const [fullscreenCards, setFullscreenCards] = useState<Set<string>>(new Set());

const toggleFullscreen = (cardId: string) => {
  setFullscreenCards(prev => {
    const newSet = new Set(prev);
    newSet.has(cardId) ? newSet.delete(cardId) : newSet.add(cardId);
    return newSet;
  });
};

// 子组件open属性改为:
open={fullscreenCards.has("title1")}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 02:30:03