如何为垂直步进器添加符合状态的进度线条?
如何为垂直步进器添加符合状态的进度线条?
你好呀!我看了你的垂直步进器代码,已经帮你调整好了进度线条的实现,完全符合你要的状态对应颜色需求——已完成的步骤间线条是绿色,当前步骤到下一段的线条是蓝色,未触碰的是灰色,提交后所有线条都会变成绿色。具体改动和完整代码如下:
核心实现思路
- 布局调整:给步进器的列表添加左侧内边距,把圆形指示器定位到内边距区域,专门留出进度线条的位置,保证布局整齐。
- 伪元素实现线条:利用每个步骤项(除最后一个)的
::after伪元素绘制垂直线条,默认设为灰色。 - 状态关联颜色:通过步骤的
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
相关产品推荐
相关产品推荐

