<div class="bux-progress-bar" aria-label="Progress">
    <div class="bux-progress-bar__track">
        <div class="bux-progress-bar__fill"></div>
    </div>

    <div class="bux-progress-bar__steps-container">
        <div class="bux-progress-bar__step bux-progress-bar__step--current">
            <span class="bux-progress-bar__icon">1</span>
        </div>
        <div class="bux-progress-bar__step bux-progress-bar__step--current">
            <span class="bux-progress-bar__icon">2</span>
        </div>
        <div class="bux-progress-bar__step bux-progress-bar__step--current">
            <span class="bux-progress-bar__icon">3</span>
        </div>
        <div class="bux-progress-bar__success">
            <span class="bux-progress-bar__success-icon"></span>
        </div>
    </div>
</div>
<div class="bux-progress-bar{{ modifier ? " bux-progress-bar--" ~ modifier : ""}}" aria-label="Progress">
  <div class="bux-progress-bar__track">
    <div class="bux-progress-bar__fill"></div>
  </div>

  <div class="bux-progress-bar__steps-container">
    {% for step in steps %}
      <div class="bux-progress-bar__step bux-progress-bar__step--current">
        <span class="bux-progress-bar__icon">{{ loop.index }}</span>
      </div>
    {% endfor %}
    <div class="bux-progress-bar__success">
      <span class="bux-progress-bar__success-icon"></span>
    </div>
  </div>
</div>
site_name_prefix: Office of
site_name: Learning Relations Excellence
site_slogan: Additional text or site slogan
address_1: 100 Building Name
address_2: 1 Oval Mall
city: Columbus
state: OH
zip: '43210'
contact_email: email@osu.edu
contact_phone: 614-292-OHIO
contact_tty: 614-688-8605
steps:
  one: null
  two: null
  three: null
  • Content:
    $progress-duration: 400ms;
    $progress-ease: ease-in;
    
    .bux-progress-bar {
      position: relative;
      width: 50%;
      margin: 0 auto;
    
      &__track {
        position: absolute;
        top: 50%;
        left: 0;
        width: 100%;
        height: 4px;
        background-color: $gray-light-60;
        z-index: 1;
        transform: translateY(-50%);
    
        .bux-progress-bar--gray & {
          background-color: $gray-dark-40;
        }
      }
    
      &__fill {
        height: 100%;
        background-color: $scarlet;
        width: 0%;
        transition: width $progress-duration $progress-ease;
      }
    
      &__steps-container {
        position: relative;
        z-index: 2;
        display: flex;
        justify-content: space-between;
        align-items: center;
        width: calc(100% + 5px);
    
        &--complete {
          .bux-progress-bar__step {
            opacity: 0;
            pointer-events: none;
          }
    
          .bux-progress-bar__success {
            transform: translate(-50%, -50%) scale(1);
            opacity: 1;
          }
        }
      }
    
      &__step {
        border-radius: 50%;
        transition:
          transform $progress-duration $progress-ease,
          opacity 0.2s;
        position: relative;
        z-index: 2;
    
        .bux-progress-bar__icon {
          display: flex;
          align-items: center;
          justify-content: center;
          font-size: 14px;
          width: 20px;
          height: 20px;
          border-radius: 50%;
          background-color: $gray-light-60;
          color: $black;
          transition: all $progress-duration $progress-ease;
          position: relative;
          z-index: 2;
    
          .bux-progress-bar--gray & {
            background-color: $gray-dark-40;
            color: $white;
          }
        }
    
        &--current,
        &--complete {
          .bux-progress-bar__icon {
            background-color: $scarlet;
            color: $white;
          }
    
          .bux-progress-bar--gray & .bux-progress-bar__icon {
            background-color: $scarlet;
            color: $white;
          }
        }
      }
    
      &__success {
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%) scale(0);
        opacity: 0;
        transition: transform 200ms $progress-ease;
        z-index: 10;
    
        .bux-progress-bar__success-icon {
          display: flex;
          font-family: $icon;
          align-items: center;
          justify-content: center;
          width: 20px;
          height: 20px;
          border-radius: 50%;
          background-color: $scarlet;
          color: $white;
    
          &::before {
            font-size: 11px;
            content: "\f101";
          }
        }
      }
    }
    
  • URL: /components/raw/progress-bar/_progress-bar.scss
  • Filesystem Path: src/components/forms/form_subcomponents/progress-bar/_progress-bar.scss
  • Size: 2.4 KB
  • Content:
    const PROG_BAR_SELECTORS = {
      fill: ".bux-progress-bar__fill",
      stepsContainer: ".bux-progress-bar__steps-container",
      step: ".bux-progress-bar__step",
      icon: ".bux-progress-bar__icon",
      complete: "bux-progress-bar__steps-container--complete",
      stepCurrent: "bux-progress-bar__step--current",
      stepComplete: "bux-progress-bar__step--complete",
    };
    
    export const createProgressBar = (container: HTMLElement) => {
      const fill = container.querySelector(PROG_BAR_SELECTORS.fill) as HTMLElement;
      const stepsContainer = container.querySelector(PROG_BAR_SELECTORS.stepsContainer) as HTMLElement;
      const steps = container.querySelectorAll(PROG_BAR_SELECTORS.step) as NodeListOf<HTMLElement>;
    
      if (!fill || !stepsContainer || steps.length === 0) {
        throw new TypeError(`Buckeye UX Progress Bar is missing required elements.`);
      }
    
      const totalSteps = steps.length - 1;
    
      let currentStep = 0;
    
      const initProgress = () => {
        currentStep = -1;
    
        updateFill();
        updateCircles();
      };
    
      const isValidStep = (): boolean => {
        return currentStep >= 0 && currentStep <= totalSteps;
      };
    
      const calculateProgress = (): number => {
        if (currentStep === totalSteps) {
          return 100;
        }
    
        const adjustedStepValue = currentStep + 0.5;
        const progressPercentage = (adjustedStepValue / totalSteps) * 100;
    
        return Math.min(progressPercentage, 100);
      };
    
      const getStepState = (stepIndex: number): "complete" | "current" | "inactive" => {
        if (stepIndex === currentStep) return "complete";
        if (stepIndex < currentStep) return "current";
        return "inactive";
      };
    
      const updateFill = () => {
        if (!isValidStep()) {
          fill.style.width = "0%";
          return;
        }
    
        const width = calculateProgress();
        fill.style.width = `${width}%`;
      };
    
      const updateCircles = () => {
        for (const [index, step] of steps.entries()) {
          step.classList.remove(PROG_BAR_SELECTORS.stepCurrent, PROG_BAR_SELECTORS.stepComplete);
    
          if (!isValidStep()) continue;
    
          const state = getStepState(index);
    
          if (state === "complete") {
            step.classList.add(PROG_BAR_SELECTORS.stepComplete);
          } else if (state === "current") {
            step.classList.add(PROG_BAR_SELECTORS.stepCurrent);
          }
        }
      };
    
      const set = (step: number) => {
        currentStep = step;
        if (!isValidStep()) return;
        updateFill();
        updateCircles();
      };
    
      const complete = () => {
        const containerWidth = stepsContainer.offsetWidth;
        const containerCenter = containerWidth / 2;
    
        for (const step of steps) {
          const stepCenter = step.offsetLeft + step.offsetWidth / 2;
          const deltaToCenter = containerCenter - stepCenter;
          step.style.transform = `translate(${deltaToCenter}px, 0)`;
        }
    
        setTimeout(() => {
          stepsContainer.classList.add(PROG_BAR_SELECTORS.complete);
        }, 300);
      };
    
      const reset = () => {
        stepsContainer.classList.remove(PROG_BAR_SELECTORS.complete);
    
        initProgress();
        for (const step of steps) {
          step.style.transform = "";
        }
      };
    
      initProgress();
    
      return {
        set,
        complete,
        reset,
      };
    };
    
  • URL: /components/raw/progress-bar/progress-bar.ts
  • Filesystem Path: src/components/forms/form_subcomponents/progress-bar/progress-bar.ts
  • Size: 3.1 KB

No notes defined.