Files
tools/vue/primitives/src/stepper/StepperItem.vue
T
robonen 626fbc70d8 fix(primitives): eslint/tsconfig migration, asChild refactor, type fixes
- Migrate to eslint flat config + composite tsconfig.
- Complete the asChild→as="template" refactor (remove asChild prop + :as-child
  bindings across components, matching Primitive's slot model).
- Fix test type errors and source type-safety (useGraceArea hull/point math,
  FocusScope/util ref typing).

Note: ~53 vue-tsc errors remain (HTML attr/event passthrough typing on
transparent wrapper components + a couple of duplicate-export naming
collisions) — not gated by CI (build/lint/test green); pending a
component-attribute-typing design decision.
2026-06-07 16:29:56 +07:00

64 lines
1.9 KiB
Vue

<script lang="ts">
import type { PrimitiveProps } from '../primitive';
export interface StepperItemProps extends PrimitiveProps {
/** 1-based index associating this item with a step. */
step: number;
/** Disable this specific step. */
disabled?: boolean;
/** Mark the step as completed regardless of current `modelValue`. */
completed?: boolean;
}
</script>
<script setup lang="ts">
import { computed, toRef } from 'vue';
import { provideStepperItemContext, useStepperRootContext } from './context';
import { Primitive } from '../primitive';
import { useForwardExpose } from '@robonen/vue';
import { useId } from '../config-provider';
const { as = 'div', step, disabled = false, completed = false } = defineProps<StepperItemProps>();
const root = useStepperRootContext();
const { forwardRef } = useForwardExpose();
const state = computed(() => {
if (completed) return 'completed' as const;
if (root.value.value === step) return 'active' as const;
if (root.value.value > step) return 'completed' as const;
return 'inactive' as const;
});
const focusable = computed(() => {
if (disabled || root.disabled.value) return false;
if (!root.linear.value) return true;
return step <= root.value.value + 1;
});
const titleId = useId(undefined, 'stepper-item-title').value;
const descriptionId = useId(undefined, 'stepper-item-description').value;
provideStepperItemContext({
step: toRef(() => step),
state,
disabled: toRef(() => disabled || root.disabled.value),
focusable,
titleId,
descriptionId,
});
</script>
<template>
<Primitive
:ref="forwardRef"
:as="as"
:aria-current="state === 'active' ? 'step' : undefined"
:data-state="state"
:data-orientation="root.orientation.value"
:data-disabled="disabled || root.disabled.value || !focusable ? '' : undefined"
>
<slot :state="state" :step="step" />
</Primitive>
</template>