<svelte:options customElement={{ tag: 'm-stepper-stacked' }} />

<script lang="ts">
  import { Check24 } from '@mozaic-ds/icons-svelte';
  /**
   * A stepper is a navigation component that guides users through a sequence of steps in a structured process. It visually represents progress, completed steps, and upcoming steps, helping users understand their position within a workflow. Steppers are commonly used in multi-step forms, onboarding flows, checkout processes, and task completion sequences to improve clarity and reduce cognitive load.
   */

  interface Props {
    [key: string]: any;
    /**
     * Defines the currently active step.
     *
     * - If a `number` is provided, it represents the 1-based position of the step
     *   in the `steps` array (e.g. `1` for the first step).
     * - If a `string` is provided, it must match the `id` of one of the steps.
     */
    step?: string | number;

    /**
     * Steps of the stepper stacked.
     */
    steps?: Array<{
      /**
       * Unique identifier for the step.
       */
      id?: string;
      /**
       * Label of the step.
       */
      label: string;

      /**
       * Optional additional information under the label.
       */
      additionalinfo?: string;
    }>;
  }

  let { step = $bindable(1), steps = $bindable([]), class: className, ...attrs }: Props = $props();

  const activeStep = $derived.by(() => {
    if (typeof step === 'number') {
      return Math.min(Math.max(step, 1), steps.length) - 1;
    } else {
      const activeIndex = steps.findIndex((el) => el.id === step);
      return activeIndex === -1 ? 0 : activeIndex;
    }
  });

  const stepStates = $derived(() =>
    steps.map((_, i) => ({
      completed: i < activeStep,
      current: i === activeStep,
    })),
  );
</script>

<nav class={['mc-stepper-stacked', className]} aria-label="Stepper" {...attrs}>
  <ol class="mc-stepper-stacked__container">
    {#each steps as step, index (index)}
      {@const state = stepStates()[index]}
      <li
        class={{
          'mc-stepper-stacked__item': true,
          'has-additional': step.additionalinfo,
        }}
      >
        <div class="mc-stepper-stacked__indicator">
          {#if state.completed}
            <span class="mc-stepper-stacked__icon mc-stepper-stacked__icon--check">
              <Check24 />
            </span>
          {:else}
            <span
              class={{
                'mc-stepper-stacked__circle': true,
                'is-current': state.current,
              }}
            >
              {index + 1}
            </span>
          {/if}
        </div>
        <div class="mc-stepper-stacked__content">
          <span
            class={{
              'mc-stepper-stacked__label': true,
              'is-current': state.current,
            }}
          >
            {step.label}
          </span>
          <span class="mc-stepper-stacked__additional">
            {step.additionalinfo}
          </span>
        </div>
      </li>
    {/each}
  </ol>
</nav>

<style>/**
 * Do not edit directly, this file was auto-generated.
 */
.mc-stepper-stacked__container {
  display: flex;
  flex-direction: column;
  list-style: none;
  padding: 0;
  margin: 0;
}
.mc-stepper-stacked__indicator {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-right: 0.5rem;
  position: relative;
  min-height: 100%;
  padding-bottom: 2rem;
}
.mc-stepper-stacked__indicator::after {
  content: "";
  position: absolute;
  top: 1.5rem;
  bottom: 0;
  width: 0.125rem;
  background-color: var(--stepper-color-progress-bar-background, #c9d0de);
  left: 50%;
  transform: translateX(-50%);
}
.mc-stepper-stacked__circle {
  box-sizing: border-box;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 50%;
  border: 0.125rem solid var(--stepper-color-step-item-default-border, #333333);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--font-size-100, 0.875rem);
  font-weight: var(--font-weight-bold, 700);
  color: var(--stepper-color-information, #666666);
  background-color: var(--stepper-color-step-item-default-background, #ffffff);
  z-index: 1;
  flex-shrink: 0;
  transition: background-color 200ms ease, color 200ms ease, border-color 200ms ease;
}
.mc-stepper-stacked__circle.is-current {
  background-color: var(--stepper-color-step-item-active-background, #117f03);
  border-color: var(--stepper-color-step-item-active-background, #117f03);
  color: var(--stepper-color-step-item-active-text, #ffffff);
  animation: pop-in 300ms cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards;
}
.mc-stepper-stacked__icon--check {
  width: 1.5rem;
  height: 1.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--stepper-color-step-item-default-icon, #666666);
  fill: currentcolor;
  border: 0.125rem solid var(--stepper-color-step-item-default-border, #333333);
  border-radius: 50%;
  box-sizing: border-box;
  background-color: var(--stepper-color-step-item-default-background, #ffffff);
  z-index: 1;
}
.mc-stepper-stacked__content {
  display: flex;
  flex-direction: column;
  padding-top: 0.25rem;
}
.mc-stepper-stacked__label {
  font-size: var(--font-size-100, 0.875rem);
  color: var(--stepper-color-step-label-default, #666666);
  line-height: var(--line-height-s, 1.3);
  transition: color 200ms ease;
}
.mc-stepper-stacked__label.is-current {
  font-weight: var(--font-weight-medium, 600);
  color: var(--stepper-color-step-label-active, #000000);
}
.mc-stepper-stacked__additional {
  font-size: var(--font-size-50, 0.75rem);
  color: var(--stepper-color-information, #666666);
  margin-top: 0.25rem;
}
.mc-stepper-stacked__item {
  display: flex;
  position: relative;
}
.mc-stepper-stacked__item.has-additional .mc-stepper-stacked__indicator,
.mc-stepper-stacked__item.has-additional .mc-stepper-stacked__content {
  padding-bottom: 1rem;
}
.mc-stepper-stacked__item:last-child .mc-stepper-stacked__indicator,
.mc-stepper-stacked__item:last-child .mc-stepper-stacked__content {
  padding-bottom: 0;
}
.mc-stepper-stacked__item:last-child .mc-stepper-stacked__indicator::after {
  display: none;
}

@keyframes pop-in {
  0% {
    transform: scale(0.5);
    opacity: 0;
  }
  100% {
    transform: scale(1);
    opacity: 1;
  }
}</style>
