{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "stepper",
  "title": "Stepper",
  "type": "registry:ui",
  "files": [
    {
      "path": "packages/registry-angular/components/stepper/stepper.component.ts",
      "content": "import {\n  AfterViewInit,\n  Component,\n  ContentChild,\n  Directive,\n  ElementRef,\n  EmbeddedViewRef,\n  EventEmitter,\n  Input,\n  OnChanges,\n  OnDestroy,\n  Output,\n  TemplateRef,\n  ViewChild,\n  ViewContainerRef,\n  ViewEncapsulation,\n  booleanAttribute,\n  forwardRef,\n  inject,\n  signal,\n  ChangeDetectionStrategy,\n} from '@angular/core'\nimport { cn } from '@/lib/utils'\nimport { stepperIndicatorVariants } from './stepper.variants'\n\nexport type StepperOrientation = 'horizontal' | 'vertical'\nexport type StepperStatus = 'active' | 'completed' | 'pending' | 'error'\nexport type StepperSize = 'sm' | 'default' | 'lg'\n\nexport interface StepperStep {\n  id: string | number\n  title: string\n  description?: string\n  /** Icon template (React passes a LucideIcon component). */\n  icon?: TemplateRef<unknown>\n  disabled?: boolean\n  error?: boolean\n}\n/** React exports the step config type under this alias too. */\nexport type StepperStepConfig = StepperStep\n\nexport interface StepperContentContext {\n  $implicit: number\n  activeStep: number\n  steps: StepperStep[]\n}\n\n/* Motion styles, verbatim from the React / Vue source. */\nconst STEPPER_STYLE_CONTENT = `\n@keyframes stepper-indicator-pop {\n  0% { transform: scale(0.92); }\n  55% { transform: scale(1.06); }\n  100% { transform: scale(1); }\n}\n@keyframes stepper-indicator-fill {\n  0% { transform: scale(0.92); }\n  55% { transform: scale(1.06); }\n  100% { transform: scale(1); }\n}\n@keyframes stepper-indicator-error {\n  0% { transform: scale(0.92); }\n  55% { transform: scale(1.06); }\n  100% { transform: scale(1); }\n}\n@keyframes stepper-icon-in {\n  from { opacity: 0; transform: scale(0.6); }\n  to { opacity: 1; transform: scale(1); }\n}\n/* Distinct names so active→completed restarts the pop. */\n[data-slot='stepper-indicator'][data-status='active'] {\n  animation: stepper-indicator-pop 280ms cubic-bezier(0.22, 1.4, 0.36, 1) both;\n}\n[data-slot='stepper-indicator'][data-status='completed'] {\n  animation: stepper-indicator-fill 280ms cubic-bezier(0.22, 1.4, 0.36, 1) both;\n}\n[data-slot='stepper-indicator'][data-status='error'] {\n  animation: stepper-indicator-error 280ms cubic-bezier(0.22, 1.4, 0.36, 1) both;\n}\n[data-slot='stepper-indicator'][data-status='completed'] [data-slot='stepper-indicator-icon'],\n[data-slot='stepper-indicator'][data-status='error'] [data-slot='stepper-indicator-icon'],\n[data-slot='stepper-indicator'][data-status='active'] [data-slot='stepper-indicator-icon'] {\n  animation: stepper-icon-in 220ms cubic-bezier(0.22, 1.2, 0.36, 1) both;\n}\n[data-slot='stepper-connector-fill'] {\n  transition: transform 320ms cubic-bezier(0.22, 1, 0.36, 1);\n}\n[data-slot='stepper-connector-fill'][data-orientation='horizontal'] {\n  transform-origin: left center;\n  transform: scaleX(0);\n}\n[data-slot='stepper-connector-fill'][data-orientation='horizontal'][data-completed='true'] {\n  transform: scaleX(1);\n}\n[data-slot='stepper-connector-fill'][data-orientation='vertical'] {\n  transform-origin: center top;\n  transform: scaleY(0);\n}\n[data-slot='stepper-connector-fill'][data-orientation='vertical'][data-completed='true'] {\n  transform: scaleY(1);\n}\n@media (prefers-reduced-motion: reduce) {\n  [data-slot='stepper-indicator'],\n  [data-slot='stepper-indicator'] [data-slot='stepper-indicator-icon'],\n  [data-slot='stepper-indicator'] [data-slot='stepper-indicator-label'],\n  [data-slot='stepper-connector-fill'] {\n    animation: none !important;\n    transition: none !important;\n  }\n}\n`\n\n/**\n * Renders a template with a context (UiRenderTemplateDirective has none). With `iconClass`\n * set it also decorates the rendered root <svg>s the way React passes props to an icon\n * component: `class`, `data-slot=\"stepper-indicator-icon\"` and `aria-hidden`.\n */\n@Directive({ selector: '[uiStepperOutlet]', standalone: true })\nexport class UiStepperOutletDirective implements OnChanges, OnDestroy {\n  @Input('uiStepperOutlet') template: TemplateRef<unknown> | null | undefined = null\n  @Input('uiStepperOutletContext') context: unknown = null\n  @Input('uiStepperOutletIconClass') iconClass?: string\n  private readonly vcr = inject(ViewContainerRef)\n  private view: EmbeddedViewRef<unknown> | null = null\n\n  ngOnChanges(): void {\n    this.vcr.clear()\n    this.view = null\n    if (!this.template) return\n    this.view = this.vcr.createEmbeddedView(this.template, this.context ?? {})\n    if (this.iconClass === undefined) return\n    for (const node of this.view.rootNodes) {\n      if (!(node instanceof Element) || node.tagName.toLowerCase() !== 'svg') continue\n      if (this.iconClass) node.classList.add(...this.iconClass.split(' '))\n      node.setAttribute('data-slot', 'stepper-indicator-icon')\n      node.setAttribute('aria-hidden', 'true')\n    }\n  }\n\n  ngOnDestroy(): void {\n    this.vcr.clear()\n  }\n}\n\n/** Marks `<ng-template uiStepperContent let-activeStep=\"activeStep\">` as the render-prop content (React children fn). */\n@Directive({ selector: 'ng-template[uiStepperContent]', standalone: true })\nexport class UiStepperContentTemplateDirective {\n  readonly template = inject<TemplateRef<StepperContentContext>>(TemplateRef)\n}\n\n/* ------------------------------------------------------------------ */\n/* StepperIndicator                                                    */\n/* ------------------------------------------------------------------ */\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-stepper-indicator, [ui-stepper-indicator]',\n  standalone: true,\n  imports: [UiStepperOutletDirective],\n  host: {\n    '[attr.type]': '\"button\"',\n    '[attr.data-slot]': '\"stepper-indicator\"',\n    '[attr.data-status]': 'status',\n    '[attr.disabled]': 'clickable ? null : \"\"',\n    '[attr.aria-current]': 'status === \"active\" ? \"step\" : null',\n    '[class]': 'hostClass',\n  },\n  template: `<ng-content>\n    @if (icon) {\n      <ng-container [uiStepperOutlet]=\"icon\" uiStepperOutletIconClass=\"size-4\" />\n    } @else if (status === 'completed') {\n      <svg\n        xmlns=\"http://www.w3.org/2000/svg\"\n        width=\"24\"\n        height=\"24\"\n        viewBox=\"0 0 24 24\"\n        fill=\"none\"\n        stroke=\"currentColor\"\n        stroke-width=\"2\"\n        stroke-linecap=\"round\"\n        stroke-linejoin=\"round\"\n        class=\"lucide lucide-check size-4\"\n        data-slot=\"stepper-indicator-icon\"\n        aria-hidden=\"true\"\n      >\n        <path d=\"M20 6 9 17l-5-5\" />\n      </svg>\n    } @else if (status === 'error') {\n      <svg\n        xmlns=\"http://www.w3.org/2000/svg\"\n        width=\"24\"\n        height=\"24\"\n        viewBox=\"0 0 24 24\"\n        fill=\"none\"\n        stroke=\"currentColor\"\n        stroke-width=\"2\"\n        stroke-linecap=\"round\"\n        stroke-linejoin=\"round\"\n        class=\"lucide lucide-x size-4\"\n        data-slot=\"stepper-indicator-icon\"\n        aria-hidden=\"true\"\n      >\n        <path d=\"M18 6 6 18\" />\n        <path d=\"m6 6 12 12\" />\n      </svg>\n    } @else if (index !== undefined) {\n      <span class=\"font-medium\" data-slot=\"stepper-indicator-label\">{{ index }}</span>\n    }\n  </ng-content>`,\n})\nexport class UiStepperIndicatorComponent {\n  @Input() status: StepperStatus = 'pending'\n  @Input() size: StepperSize = 'default'\n  @Input() index?: number\n  @Input() icon?: TemplateRef<unknown>\n  @Input({ transform: booleanAttribute }) clickable = false\n  @Input('class') className?: string\n\n  get hostClass(): string {\n    return cn(\n      stepperIndicatorVariants({ status: this.status, size: this.size }),\n      'ring-background relative z-10 ring-4 transition-[color,background-color,box-shadow,transform] duration-200 outline-none',\n      this.clickable && 'focus-visible:ring-ring cursor-pointer focus-visible:ring-2 focus-visible:outline-none',\n      !this.clickable && 'cursor-default',\n      this.className,\n    )\n  }\n}\n\n/* ------------------------------------------------------------------ */\n/* Stepper (root)                                                      */\n/* ------------------------------------------------------------------ */\n\n/**\n * Angular port of UIPKGE Stepper (React parity). Controlled like React: `value` (1-based\n * active step, default 1) + `valueChange`; clicking a completed step's indicator or title\n * navigates back to it, disabled steps can't be reached. Renders an `<ol>` of StepperItems\n * from `steps` unless a `[slot=steps]` element is projected; any other projected content (or\n * an `<ng-template uiStepperContent>` render prop) goes in the content area below.\n */\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-stepper, [ui-stepper]',\n  standalone: true,\n  encapsulation: ViewEncapsulation.None,\n  styles: [STEPPER_STYLE_CONTENT],\n  imports: [UiStepperOutletDirective, forwardRef(() => UiStepperItemComponent)],\n  host: {\n    '[class]': 'hostClass',\n    role: 'tablist',\n    '[attr.aria-orientation]': 'orientation',\n    '[attr.data-orientation]': 'orientation',\n  },\n  template: `<ng-content select=\"[slot=steps]\">\n      @if (steps.length > 0) {\n        <ol [class]=\"listClass\">\n          @for (step of steps; track step.id; let index = $index) {\n            <li ui-stepper-item [step]=\"step\" [index]=\"index\"></li>\n          }\n        </ol>\n      }\n    </ng-content>\n    <div #contentWrap [class]=\"hasContent() ? 'mt-6 flex-1' : 'hidden'\">\n      <ng-content />\n      @if (contentTemplate) {\n        <ng-container\n          [uiStepperOutlet]=\"contentTemplate.template\"\n          [uiStepperOutletContext]=\"{ $implicit: value, activeStep: value, steps: steps }\"\n        />\n      }\n    </div>`,\n})\nexport class UiStepperComponent implements AfterViewInit, OnDestroy {\n  @Input() steps: StepperStep[] = []\n  /** Active step, 1-based (React `value`). */\n  @Input() value = 1\n  @Input() orientation: StepperOrientation = 'horizontal'\n  @Input() size: StepperSize = 'default'\n  @Input('class') className?: string\n  @Output() valueChange = new EventEmitter<number>()\n\n  @ContentChild(UiStepperContentTemplateDirective) contentTemplate?: UiStepperContentTemplateDirective\n  @ViewChild('contentWrap', { static: true }) contentWrap!: ElementRef<HTMLElement>\n  /** React renders the content wrapper only when children exist. */\n  readonly hasContent = signal(false)\n  private observer?: MutationObserver\n\n  get activeStep(): number {\n    return this.value\n  }\n\n  get hostClass(): string {\n    return cn('block w-full', this.className)\n  }\n\n  get listClass(): string {\n    return cn('flex', this.orientation === 'horizontal' ? 'flex-row items-start' : 'flex-col items-stretch')\n  }\n\n  getStatus(index: number): StepperStatus {\n    const step = this.steps[index]\n    if (step?.error) return 'error'\n    if (index + 1 === this.activeStep) return 'active'\n    if (index + 1 < this.activeStep) return 'completed'\n    return 'pending'\n  }\n\n  isClickable(index: number): boolean {\n    return index + 1 < this.activeStep\n  }\n\n  goToStep(stepIndex: number): void {\n    if (stepIndex < 1 || stepIndex > this.steps.length) return\n    if (this.steps[stepIndex - 1]?.disabled) return\n    this.valueChange.emit(stepIndex)\n  }\n\n  ngAfterViewInit(): void {\n    const el = this.contentWrap.nativeElement\n    const check = () => this.hasContent.set(Array.from(el.childNodes).some((n) => n.nodeType !== Node.COMMENT_NODE))\n    check()\n    if (typeof MutationObserver !== 'undefined') {\n      this.observer = new MutationObserver(check)\n      this.observer.observe(el, { childList: true })\n    }\n  }\n\n  ngOnDestroy(): void {\n    this.observer?.disconnect()\n  }\n}\n\n/* ------------------------------------------------------------------ */\n/* StepperItem                                                         */\n/* ------------------------------------------------------------------ */\n\nconst INDICATOR_AXIS = {\n  horizontal: {\n    sm: 'h-7 w-full items-center justify-center',\n    default: 'h-9 w-full items-center justify-center',\n    lg: 'h-11 w-full items-center justify-center',\n  },\n  vertical: {\n    sm: 'w-7 flex-col items-center justify-start self-stretch',\n    default: 'w-9 flex-col items-center justify-start self-stretch',\n    lg: 'w-11 flex-col items-center justify-start self-stretch',\n  },\n} as const\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-stepper-item, [ui-stepper-item]',\n  standalone: true,\n  imports: [UiStepperIndicatorComponent],\n  host: {\n    '[attr.data-slot]': '\"stepper-item\"',\n    '[class]': 'hostClass',\n    role: 'tab',\n    '[attr.aria-selected]': 'status === \"active\"',\n    '[attr.aria-disabled]': 'step.disabled || null',\n    '[attr.data-status]': 'status',\n  },\n  template: `\n    <div [class]=\"axisClass\">\n      @if (!isFirst) {\n        <span\n          aria-hidden=\"true\"\n          data-slot=\"stepper-connector\"\n          [attr.data-orientation]=\"orientation\"\n          [attr.data-edge]=\"orientation === 'horizontal' ? 'left' : 'top'\"\n          [class]=\"\n            orientation === 'horizontal'\n              ? 'bg-border pointer-events-none absolute top-1/2 right-1/2 left-0 h-px -translate-y-1/2 overflow-hidden'\n              : 'bg-border pointer-events-none absolute top-0 bottom-1/2 left-1/2 w-px -translate-x-1/2 overflow-hidden'\n          \"\n        >\n          <span\n            data-slot=\"stepper-connector-fill\"\n            [attr.data-completed]=\"index < stepper.activeStep ? 'true' : 'false'\"\n            [attr.data-orientation]=\"orientation\"\n            class=\"bg-primary absolute inset-0\"\n          ></span>\n        </span>\n      }\n      @if (!isLast) {\n        <span\n          aria-hidden=\"true\"\n          data-slot=\"stepper-connector\"\n          [attr.data-orientation]=\"orientation\"\n          [attr.data-edge]=\"orientation === 'horizontal' ? 'right' : 'bottom'\"\n          [class]=\"\n            orientation === 'horizontal'\n              ? 'bg-border pointer-events-none absolute top-1/2 right-0 left-1/2 h-px -translate-y-1/2 overflow-hidden'\n              : 'bg-border pointer-events-none absolute top-1/2 bottom-0 left-1/2 w-px -translate-x-1/2 overflow-hidden'\n          \"\n        >\n          <span\n            data-slot=\"stepper-connector-fill\"\n            [attr.data-completed]=\"index < stepper.activeStep - 1 ? 'true' : 'false'\"\n            [attr.data-orientation]=\"orientation\"\n            class=\"bg-primary absolute inset-0\"\n          ></span>\n        </span>\n      }\n      <button\n        ui-stepper-indicator\n        [status]=\"status\"\n        [size]=\"stepper.size\"\n        [index]=\"index + 1\"\n        [icon]=\"step.icon\"\n        [clickable]=\"clickable\"\n        class=\"focus-visible:ring-ring focus-visible:ring-2 focus-visible:outline-none\"\n        (click)=\"navigate()\"\n      ></button>\n    </div>\n    <div data-slot=\"stepper-item-content\" [class]=\"contentClass\">\n      <button type=\"button\" [class]=\"titleClass\" [disabled]=\"!clickable\" (click)=\"navigate()\">{{ step.title }}</button>\n      @if (step.description) {\n        <p class=\"text-muted-foreground mt-0.5 text-xs text-balance\">{{ step.description }}</p>\n      }\n    </div>\n  `,\n})\nexport class UiStepperItemComponent {\n  readonly stepper = inject(UiStepperComponent)\n  @Input({ required: true }) step!: StepperStep\n  @Input({ required: true }) index!: number\n  @Input('class') className?: string\n\n  get orientation(): StepperOrientation {\n    return this.stepper.orientation\n  }\n  get status(): StepperStatus {\n    return this.stepper.getStatus(this.index)\n  }\n  get isFirst(): boolean {\n    return this.index === 0\n  }\n  get isLast(): boolean {\n    return this.index === this.stepper.steps.length - 1\n  }\n  get clickable(): boolean {\n    return this.stepper.isClickable(this.index) && !this.step.disabled\n  }\n\n  get hostClass(): string {\n    return cn(\n      'group/stepper-item relative min-w-0',\n      this.orientation === 'horizontal'\n        ? 'flex flex-1 flex-col items-center gap-2'\n        : 'flex flex-row items-start gap-3 pb-6 last:pb-0',\n      this.step.disabled && 'opacity-50',\n      this.className,\n    )\n  }\n\n  get axisClass(): string {\n    return cn('relative flex shrink-0', INDICATOR_AXIS[this.orientation][this.stepper.size])\n  }\n\n  get contentClass(): string {\n    return cn('min-w-0', this.orientation === 'horizontal' ? 'max-w-[12rem] text-center' : 'flex-1 pt-1.5')\n  }\n\n  get titleClass(): string {\n    const status = this.status\n    return cn(\n      'text-foreground text-sm font-medium text-balance transition-colors duration-200 outline-none',\n      this.clickable &&\n        'hover:text-primary focus-visible:text-primary focus-visible:ring-ring cursor-pointer focus-visible:ring-2 focus-visible:outline-none',\n      !this.clickable && 'cursor-default',\n      status === 'pending' && 'text-muted-foreground',\n      status === 'error' && 'text-destructive',\n    )\n  }\n\n  navigate(): void {\n    if (this.clickable) this.stepper.goToStep(this.index + 1)\n  }\n}\n\n/* ------------------------------------------------------------------ */\n/* StepperHeader / Content / Title / Description                       */\n/* ------------------------------------------------------------------ */\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-stepper-header, [ui-stepper-header]',\n  standalone: true,\n  host: { '[class]': 'hostClass' },\n  template: `<ng-content />`,\n})\nexport class UiStepperHeaderComponent {\n  @Input('class') className?: string\n  get hostClass(): string {\n    return cn('stepper-header flex items-center gap-0', this.className)\n  }\n}\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-stepper-content, [ui-stepper-content]',\n  standalone: true,\n  host: {\n    '[attr.data-slot]': '\"stepper-content\"',\n    '[class]': 'hostClass',\n    '[style.display]': 'isActive ? null : \"none\"',\n    role: 'tabpanel',\n    '[attr.aria-hidden]': '!isActive',\n  },\n  template: `<ng-content />`,\n})\nexport class UiStepperContentComponent {\n  @Input() step = 1\n  @Input() activeStep = 1\n  @Input('class') className?: string\n\n  get isActive(): boolean {\n    return this.step === this.activeStep\n  }\n\n  get hostClass(): string {\n    return cn(\n      'block stepper-content motion-safe:animate-in motion-safe:fade-in-0 motion-safe:slide-in-from-bottom-1 motion-safe:duration-200 motion-safe:ease-out',\n      this.className,\n    )\n  }\n}\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-stepper-title, [ui-stepper-title]',\n  standalone: true,\n  host: { '[class]': 'hostClass' },\n  template: `<ng-content />`,\n})\nexport class UiStepperTitleComponent {\n  @Input('class') className?: string\n  get hostClass(): string {\n    return cn('text-foreground text-sm font-medium', this.className)\n  }\n}\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-stepper-description, [ui-stepper-description]',\n  standalone: true,\n  host: { '[class]': 'hostClass' },\n  template: `<ng-content />`,\n})\nexport class UiStepperDescriptionComponent {\n  @Input('class') className?: string\n  get hostClass(): string {\n    return cn('text-muted-foreground text-xs', this.className)\n  }\n}\n\n/* ------------------------------------------------------------------ */\n/* StepperStep (standalone, slot-driven)                               */\n/* ------------------------------------------------------------------ */\n\n/**\n * Standalone step row. Slots (React `iconSlot` / `titleSlot` / `descriptionSlot`):\n * project `[slot=icon]`, `[slot=title]`, `[slot=description]` to replace the defaults.\n */\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-stepper-step, [ui-stepper-step]',\n  standalone: true,\n  host: {\n    '[class]': 'hostClass',\n    role: 'tab',\n    '[attr.aria-selected]': 'active',\n    '[attr.aria-disabled]': 'disabled',\n  },\n  template: `\n    <div data-slot=\"stepper-indicator\" [attr.data-status]=\"computedStatus\" [class]=\"indicatorClass\">\n      <ng-content select=\"[slot=icon]\">\n        @if (computedStatus === 'completed') {\n          <svg\n            xmlns=\"http://www.w3.org/2000/svg\"\n            width=\"24\"\n            height=\"24\"\n            viewBox=\"0 0 24 24\"\n            fill=\"none\"\n            stroke=\"currentColor\"\n            stroke-width=\"2\"\n            stroke-linecap=\"round\"\n            stroke-linejoin=\"round\"\n            class=\"lucide lucide-check size-4\"\n            data-slot=\"stepper-indicator-icon\"\n            aria-hidden=\"true\"\n          >\n            <path d=\"M20 6 9 17l-5-5\" />\n          </svg>\n        } @else if (index) {\n          <span data-slot=\"stepper-indicator-label\">{{ index }}</span>\n        }\n      </ng-content>\n    </div>\n    <div class=\"flex flex-col gap-0.5 pt-1\">\n      <ng-content select=\"[slot=title]\"\n        ><span class=\"text-sm font-medium\">{{ title }}</span></ng-content\n      >\n      <ng-content select=\"[slot=description]\">\n        @if (description) {\n          <span class=\"text-muted-foreground text-xs\">{{ description }}</span>\n        }\n      </ng-content>\n    </div>\n  `,\n})\nexport class UiStepperStepComponent {\n  @Input() title = ''\n  @Input() description?: string\n  @Input({ transform: booleanAttribute }) completed = false\n  @Input({ transform: booleanAttribute }) active = false\n  @Input({ transform: booleanAttribute }) error = false\n  @Input({ transform: booleanAttribute }) disabled = false\n  @Input() status?: StepperStatus\n  @Input() index?: number\n  @Input('class') className?: string\n\n  get computedStatus(): StepperStatus {\n    if (this.status) return this.status\n    if (this.error) return 'error'\n    if (this.active) return 'active'\n    if (this.completed) return 'completed'\n    return 'pending'\n  }\n\n  get hostClass(): string {\n    return cn('stepper-step flex gap-3', this.className)\n  }\n\n  get indicatorClass(): string {\n    return cn(stepperIndicatorVariants({ status: this.computedStatus, size: 'default' }))\n  }\n}\n\nexport { stepperIndicatorVariants, type StepperIndicatorVariants } from './stepper.variants'\n",
      "type": "registry:ui",
      "target": "~/src/app/components/ui/stepper/stepper.component.ts"
    },
    {
      "path": "packages/registry-angular/components/stepper/stepper.variants.ts",
      "content": "import type { VariantProps } from 'class-variance-authority'\nimport { cva } from 'class-variance-authority'\n\n/**\n * Variant definitions live in their own file (rather than the package\n * `index.ts`) so `StepperIndicator.vue` / `StepperStep.vue` can import\n * them without creating a circular dependency back through the index.\n * Sibling pattern to `card/card.variants.ts`.\n */\nexport const stepperIndicatorVariants = cva('flex items-center justify-center rounded-full font-semibold shrink-0', {\n  variants: {\n    status: {\n      pending: 'bg-muted text-muted-foreground',\n      active: 'bg-primary text-primary-foreground shadow-sm',\n      completed: 'bg-primary text-primary-foreground',\n      error: 'bg-destructive text-destructive-foreground',\n    },\n    size: {\n      sm: 'size-7 text-xs [&>svg]:size-3.5',\n      default: 'size-9 text-sm [&>svg]:size-4',\n      lg: 'size-11 text-base [&>svg]:size-5',\n    },\n  },\n  defaultVariants: {\n    status: 'pending',\n    size: 'default',\n  },\n})\n\nexport type StepperIndicatorVariants = VariantProps<typeof stepperIndicatorVariants>\n",
      "type": "registry:ui",
      "target": "~/src/app/components/ui/stepper/stepper.variants.ts"
    },
    {
      "path": "packages/registry-angular/components/stepper/index.ts",
      "content": "export {\n  UiStepperComponent,\n  UiStepperHeaderComponent,\n  UiStepperItemComponent,\n  UiStepperIndicatorComponent,\n  UiStepperContentComponent,\n  UiStepperTitleComponent,\n  UiStepperDescriptionComponent,\n  UiStepperStepComponent,\n  UiStepperContentTemplateDirective,\n  UiStepperOutletDirective,\n  type StepperStep,\n  type StepperStepConfig,\n  type StepperContentContext,\n  type StepperOrientation,\n  type StepperSize,\n  type StepperStatus,\n} from './stepper.component'\nexport { stepperIndicatorVariants, type StepperIndicatorVariants } from './stepper.variants'\n",
      "type": "registry:ui",
      "target": "~/src/app/components/ui/stepper/index.ts"
    }
  ],
  "dependencies": [
    "class-variance-authority"
  ],
  "devDependencies": [],
  "registryDependencies": [],
  "description": "Multi-step indicator — horizontal or vertical, with completed / active / pending / error states, animated connectors, click-back navigation, disabled steps, icon templates and optional descriptions. Use for onboarding wizards and checkout flows.",
  "categories": [
    "navigation"
  ]
}