admin管理员组

文章数量:1124381

I have a created a dummy stepper application, functionality wise the app works fine . I am trying to add a progress line right below the circle and between all circles. The circles indicating the steps have three states

  1. Green, when the step is completed
  2. Blue, when on the current step
  3. White, when its untouched.

In the similar lines, I want green line when the current step is completed and the line directed towards the next step should be blue, else case it should be grey in color.

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

const Steps: React.FC<StepsProps> = ({
  currentStep,
  isSubmitted,
  stepsData,
}) => (
  <nav className="steps">
    <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}
      />
    </div>
    <div className="right">
      <StepContent currentStep={currentStep} stepsData={stepsData} />
    </div>
  </div>
);

const StepContent = () => { return null }

const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
  <Body
    currentStep={1}
    isSubmitted={false}
    stepsData={[
      { title: "Example 1", content: "Hello, world!" },
      { title: "Example 2", content: "Hello, world!" },
    ]}
  />
)
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;
  margin: 0;
}

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

.steps li .circle {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: 2px solid #ccc;
  background-color: #fff;
  position: relative;
  z-index: 1;
  transition: background-color 0.3s, border-color 0.3s;
}

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

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

.steps li .step-label {
  margin-left: 15px;
  font-size: 16px;
  color: #333;
}

.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;
}
<script src=".3.1/umd/react.production.min.js"></script>
<script src=".3.1/umd/react-dom.production.min.js"></script>

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

I have a created a dummy stepper application, functionality wise the app works fine . I am trying to add a progress line right below the circle and between all circles. The circles indicating the steps have three states

  1. Green, when the step is completed
  2. Blue, when on the current step
  3. White, when its untouched.

In the similar lines, I want green line when the current step is completed and the line directed towards the next step should be blue, else case it should be grey in color.

https://codesandbox.io/p/sandbox/stepper-ppnqgc

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

const Steps: React.FC<StepsProps> = ({
  currentStep,
  isSubmitted,
  stepsData,
}) => (
  <nav className="steps">
    <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}
      />
    </div>
    <div className="right">
      <StepContent currentStep={currentStep} stepsData={stepsData} />
    </div>
  </div>
);

const StepContent = () => { return null }

const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
  <Body
    currentStep={1}
    isSubmitted={false}
    stepsData={[
      { title: "Example 1", content: "Hello, world!" },
      { title: "Example 2", content: "Hello, world!" },
    ]}
  />
)
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;
  margin: 0;
}

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

.steps li .circle {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: 2px solid #ccc;
  background-color: #fff;
  position: relative;
  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 .step-label {
  margin-left: 15px;
  font-size: 16px;
  color: #333;
}

.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;
}
<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>

Share Improve this question edited yesterday Drew Reese 202k17 gold badges228 silver badges264 bronze badges asked 2 days ago lrr59lrr59 2011 silver badge6 bronze badges 5
  • It's not clear what you're looking for and your CodeSandbox link is broken. I reformatted your code to use the snippets functionality and added a couple example "steps", but even so it's not clear what result you are looking for. Perhaps an illustration would help? – coreyward Commented 2 days ago
  • @coreyward I have attached a picture of what is expected. In my case, I want green line towards step2 when step 1 is completed and the line directed towards step3 should be blue as it's currently active , by default the line should be grey. Sandbox is now made accessible – lrr59 Commented 2 days ago
  • @lrr59 Are you asking only for the lines in between? Or do you want all to be done? – Developer Commented 2 days ago
  • @Developer yes lines and the interactions – lrr59 Commented 2 days ago
  • @lrr59 Oky let me check. – Developer Commented 2 days ago
Add a comment  | 

1 Answer 1

Reset to default 1

I checked the sandbox, I think the missing part are the lines. Please use this CSS:

.steps li:not(:last-child) .circle::after {
  content: "";
  width: 1.25px;
  height: 35px;
  position: absolute;
  top: 110%;
  left: 40%;
  background-color: grey;
}

.steps li.complete:not(:last-child) .circle::after {
  content: "";
  width: 1.5px;
  height: 35px;
  position: absolute;
  top: 110%;
  left: 40%;
  background-color: blue;
}

Hope it will be helpful. Sandbox Link

本文标签: javascriptLogic to add vertical stepper linesStack Overflow