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

如何为垂直步进器添加符合状态的进度线条?

如何为垂直步进器添加符合状态的进度线条?

你好呀!我看了你的垂直步进器代码,已经帮你调整好了进度线条的实现,完全符合你要的状态对应颜色需求——已完成的步骤间线条是绿色,当前步骤到下一段的线条是蓝色,未触碰的是灰色,提交后所有线条都会变成绿色。具体改动和完整代码如下:

核心实现思路

  1. 布局调整:给步进器的列表添加左侧内边距,把圆形指示器定位到内边距区域,专门留出进度线条的位置,保证布局整齐。
  2. 伪元素实现线条:利用每个步骤项(除最后一个)的::after伪元素绘制垂直线条,默认设为灰色。
  3. 状态关联颜色:通过步骤的complete、active类,以及提交状态的全局类,分别设置线条的绿色、蓝色、全绿样式。

修改后的完整代码

React 组件代码

interface StepsProps {
  currentStep: number;
  isSubmitted: boolean;
  stepsData: { title: string }[];
}

const Steps: React.FC<StepsProps> = ({
  currentStep,
  isSubmitted,
  stepsData,
}) => (
  // 提交状态时添加submitted类,统一所有线条为绿色
  <nav className={`steps ${isSubmitted ? 'submitted' : ''}`}>
    <ul>
      {stepsData.map((step, index) => (
        <li
          key={index}
          className={`${
            index < currentStep ||
            (index === stepsData.length - 1 && isSubmitted)
              ? "complete"
              : ""
          } ${currentStep === index ? "active" : ""}`}
        >
          <span className="circle"></span>
          <span className="step-label">{step.title}</span>
        </li>
      ))}
    </ul>
  </nav>
);

interface BodyProps {
  currentStep: number;
  isSubmitted: boolean;
  stepsData: { title: string; content: string }[];
}

const Body: React.FC<BodyProps> = ({ currentStep, isSubmitted, stepsData }) => (
  <div className="body">
    <div className="left">
      <Steps
        currentStep={currentStep}
        isSubmitted={isSubmitted}
        stepsData={stepsData.map(s => ({ title: s.title }))}
      />
    </div>
    <div className="right">
      <StepContent currentStep={currentStep} stepsData={stepsData} />
    </div>
  </div>
);

const StepContent: React.FC<{ currentStep: number; stepsData: { title: string; content: string }[] }> = ({ currentStep, stepsData }) => (
  <div className="step-content">
    <p>{stepsData[currentStep].content}</p>
  </div>
);

const root = ReactDOM.createRoot(document.getElementById('root')!);
root.render(
  <Body
    currentStep={1}
    isSubmitted={false}
    stepsData={[
      { title: "Example 1", content: "Hello, world! This is step 1 content." },
      { title: "Example 2", content: "Hello, world! This is step 2 content." },
      { title: "Example 3", content: "Hello, world! This is step 3 content." },
    ]}
  />
);

CSS 样式代码

body {
  margin: 0;
  font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
  background-color: #f9f9f9;
  color: #333;
}

h1,
h2,
h3,
p {
  margin: 0;
}

.header {
  text-align: center;
  padding: 20px;
  background-color: #007bff;
  color: white;
}

.footer {
  display: flex;
  justify-content: center;
  gap: 15px;
  padding: 15px;
  background-color: #007bff;
}

.footer-button {
  padding: 10px 20px;
  font-size: 16px;
  color: white;
  background-color: #0056b3;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  transition: background-color 0.3s ease;
}

.footer-button:disabled {
  background-color: #ccc;
  cursor: not-allowed;
}

.footer-button:hover:not(:disabled) {
  background-color: #004085;
}

.footer-button.submit {
  background-color: #28a745;
}

.footer-button.submit:hover:not(:disabled) {
  background-color: #218838;
}

.body {
  display: flex;
  flex-direction: row;
}

.left {
  width: 30%;
  padding: 20px;
  background-color: #f4f4f4;
  border-right: 1px solid #ddd;
}

.steps {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  position: relative;
}

.steps ul {
  list-style: none;
  padding: 0 0 0 30px; /* 左侧留出线条和圆形的位置 */
  margin: 0;
  position: relative;
}

.steps li {
  display: flex;
  align-items: center;
  margin-bottom: 40px;
  cursor: pointer;
  position: relative;
}

.steps li .circle {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: 2px solid #ccc;
  background-color: #fff;
  position: absolute;
  left: -30px; /* 把圆形定位到ul的内边距区域 */
  z-index: 1;
  transition: background-color 0.3s, border-color 0.3s;
}

.steps li.complete .circle {
  background-color: #28a745;
  border-color: #28a745;
}

.steps li.active .circle {
  background-color: #007bff;
  border-color: #007bff;
}

/* 绘制垂直进度线条 */
.steps li:not(:last-child)::after {
  content: '';
  position: absolute;
  left: calc(-30px + 12px); /* 线条对齐圆形的中心 */
  top: 24px; /* 从圆形底部开始 */
  width: 2px;
  height: 40px; /* 对应li的margin-bottom,连接上下两个圆形 */
  background-color: #ccc; /* 默认灰色 */
  z-index: 0;
  transition: background-color 0.3s;
}

/* 已完成步骤的线条为绿色 */
.steps li.complete:not(:last-child)::after {
  background-color: #28a745;
}

/* 当前活跃步骤的下一段线条为蓝色 */
.steps li.active:not(:last-child)::after {
  background-color: #007bff;
}

/* 提交后所有线条统一为绿色 */
.steps.submitted li:not(:last-child)::after {
  background-color: #28a745;
}

.steps li .step-label {
  margin-left: 0; /* 因为圆形已经定位到左侧,不需要额外间距 */
  font-size: 16px;
  color: #333;
  transition: color 0.3s;
}

/* 可选:给已完成和活跃步骤的文字加颜色 */
.steps li.complete .step-label {
  color: #28a745;
}

.steps li.active .step-label {
  color: #007bff;
}

.right {
  flex: 1;
  padding: 20px;
}

.step-content {
  padding: 10px;
  background-color: #fff;
  border-radius: 4px;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

.step-content p {
  font-size: 16px;
  line-height: 1.6;
}

HTML 代码

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.3.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.3.1/umd/react-dom.production.min.js"></script>

<div id="root"></div>

效果说明

  • 当你在第1步时,第0步的进度条是绿色,第1步的下一段进度条是蓝色;
  • 完成所有步骤并提交后,所有进度条都会变成绿色;
  • 未触碰的步骤之间的进度条保持灰色。

备注:内容来源于stack exchange,提问作者lrr59

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 13:20:29