<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
$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";
}
}
}
}
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,
};
};
No notes defined.