Stepper 步进器

用于输入或调整数值的组件,支持自定义步长、精度、格式化以及不同的布局。

组件特性

  • 🔢 数值控制:支持自定义最小值、最大值、步长和精度。
  • 🎨 布局多样:支持控制按钮在两侧、在右侧,或者仅显示按钮。
  • 🔤 格式化:支持自定义数值格式化和解析(例如货币格式)。
  • 📏 多尺寸:提供小、中、大三种尺寸。
  • 🖱️ 长按支持:支持长按按钮连续增减数值。
  • 📋 表单集成:与 BrForm 无缝集成,支持验证状态显示。

基础用法

最基础的步进器,通过 v-model 绑定数值。

<script setup lang="ts">
import { ref } from 'vue'
import { BrStepper } from '@breezeui/vue'

const value = ref(1)
</script>

<template>
  <div class="flex items-center gap-4">
    <BrStepper v-model="value" />
    <span class="text-sm text-muted-foreground">Current Value: {{ value }}</span>
  </div>
</template>

精度与步长

通过 step 属性设置步长,precision 属性设置小数精度。

<script setup lang="ts">
import { ref } from 'vue'
import { BrStepper } from '@breezeui/vue'

const value = ref(0.5)
</script>

<template>
  <div class="flex items-center gap-4">
    <BrStepper v-model="value" :step="0.1" :precision="1" :min="0" :max="10" />
    <span class="text-sm text-muted-foreground">Current Value: {{ value }}</span>
  </div>
</template>

格式化

通过 formatterparser 属性可以自定义输入框中数值的显示格式。

<script setup lang="ts">
import { ref } from 'vue'
import { BrStepper } from '@breezeui/vue'

const value = ref(1000)

const formatCurrency = (val: number | null) => {
  if (val === null) return ''
  return `$ ${val}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')
}

const parseCurrency = (val: string) => {
  return parseFloat(val.replace(/\$\s?|(,*)/g, ''))
}
</script>

<template>
  <BrStepper 
    v-model="value" 
    :step="100" 
    :formatter="formatCurrency" 
    :parser="parseCurrency" 
    class="w-48"
  />
</template>

按钮位置与模式

通过 controls-position 可以改变按钮的位置,通过 button-only 可以隐藏输入框仅保留控制按钮。

<script setup lang="ts">
import { ref } from 'vue'
import { BrStepper } from '@breezeui/vue'

const value1 = ref(1)
const value2 = ref(5)
</script>

<template>
  <div class="flex flex-col gap-6">
    <div class="space-y-2">
      <label class="text-sm font-medium">Controls on the right</label>
      <div>
        <BrStepper v-model="value1" controls-position="right" class="w-32" />
      </div>
    </div>
    
    <div class="space-y-2">
      <label class="text-sm font-medium">Buttons Only Mode</label>
      <div class="flex items-center gap-4">
        <BrStepper v-model="value2" button-only />
        <span class="font-mono text-lg w-8 text-center">{{ value2 }}</span>
      </div>
    </div>
  </div>
</template>

尺寸

支持 smmdlg 三种不同尺寸。

<script setup lang="ts">
import { ref } from 'vue'
import { BrStepper } from '@breezeui/vue'

const value1 = ref(1)
const value2 = ref(2)
const value3 = ref(3)
const value4 = ref(4)
const value5 = ref(5)
const value6 = ref(6)
</script>

<template>
  <div class="flex flex-col gap-4">
    <div class="flex items-center gap-4">
      <BrStepper v-model="value1" size="xs" />
      <span class="text-sm text-muted-foreground">xs (Extra Small Size)</span>
    </div>
    <div class="flex items-center gap-4">
      <BrStepper v-model="value2" size="sm" />
      <span class="text-sm text-muted-foreground">sm (Small Size)</span>
    </div>
    <div class="flex items-center gap-4">
      <BrStepper v-model="value3" size="md" />
      <span class="text-sm text-muted-foreground">md (Medium Size,Default)</span>
    </div>
    <div class="flex items-center gap-4">
      <BrStepper v-model="value4" size="lg" />
      <span class="text-sm text-muted-foreground">lg (Large Size)</span>
    </div>
    <div class="flex items-center gap-4">
      <BrStepper v-model="value5" size="xl" />
      <span class="text-sm text-muted-foreground">xl (Extra Large Size)</span>
    </div>
    <div class="flex items-center gap-4">
      <BrStepper v-model="value6" size="2xl" />
      <span class="text-sm text-muted-foreground">2xl (Massive Size)</span>
    </div>
  </div>
</template>

与表单集成

在表单中的典型应用,支持与 BrFormItem 配合展示验证状态和禁用状态。

<script setup lang="ts">
import { ref } from 'vue'
import { BrStepper, BrForm, BrFormItem, BrFormLabel, BrFormControl, BrFormMessage, BrButton, useToast } from '@breezeui/vue'

const formData = ref({
  amount: 5,
})

const rules = {
  amount: (value: any) => {
    if (!value) return 'Please enter quantity'
    if (value < 1 || value > 10) return 'Quantity must be between 1-10 between'
    return true
  }
}

const { toast } = useToast()

const onSubmit = (values: any) => {
  toast({
    title: 'Submit successful!',
    description: `Current quantity is: ${values.amount}`,
    variant: 'success'
  })
}

const onInvalidSubmit = () => {
  toast({
    title: 'Validation Failed',
    description: 'Please check if the form is filled out correctly',
    variant: 'error'
  })
}
</script>

<template>
  <div class="w-80">
    <BrForm 
      layout="vertical" 
      @submit="onSubmit"
      @invalid-submit="onInvalidSubmit"
    >
      <BrFormItem name="amount" :rules="rules.amount">
        <BrFormLabel>Purchase Quantity (Limits 1-10)</BrFormLabel>
        <BrFormControl>
          <BrStepper v-model="formData.amount" :min="0" :max="15" class="w-full" />
        </BrFormControl>
        <BrFormMessage />
      </BrFormItem>
      
      <BrFormItem name="disabled">
        <BrFormLabel>Disabled State</BrFormLabel>
        <BrFormControl>
          <BrStepper v-model="formData.amount" disabled class="w-full" />
        </BrFormControl>
      </BrFormItem>
      
      <BrButton type="submit" class="mt-4">
        Submit Validation
      </BrButton>
    </BrForm>
  </div>
</template>

主题定制

结合 BrConfigProvider,可以全局覆盖组件默认样式。同时可以通过 TailwindCSS 局部覆盖样式。

<script setup lang="ts">
import { ref } from 'vue'
import { BrStepper, BrConfigProvider } from '@breezeui/vue'

const value = ref(1)

const themeConfig = {
  radius: 1, // Full rounding
  primary: '220 90% 56%',
}
</script>

<template>
  <BrConfigProvider :theme="themeConfig">
    <div class="space-y-4">
      <div class="space-y-2">
        <label class="text-sm font-medium">Use global config to change border radius</label>
        <div>
          <BrStepper v-model="value" />
        </div>
      </div>
      
      <div class="space-y-2">
        <label class="text-sm font-medium">Use TailwindCSS Local override style</label>
        <div>
          <BrStepper 
            v-model="value" 
            class="border-blue-500 rounded-full [&_button]:text-blue-600 [&_button:hover]:bg-blue-50" 
          />
        </div>
      </div>
    </div>
  </BrConfigProvider>
</template>

API 说明

BrStepper

属性类型默认值说明
modelValue / v-modelnumber | null-绑定值
defaultValuenumber | null-默认值(非受控模式)
minnumberNumber.MIN_SAFE_INTEGER最小值
maxnumberNumber.MAX_SAFE_INTEGER最大值
stepnumber1每次改变的步数
precisionnumber-数值精度
disabledbooleanfalse是否禁用
readonlybooleanfalse是否只读
size'sm' | 'md' | 'lg''md'步进器尺寸
formatter(value: number | null) => string-指定输入框展示值的格式
parser(value: string) => number | null-指定从输入框提取数字的方式
debounceDelaynumber300输入框变更防抖延迟(ms)
longPressbooleantrue是否启用长按连续改变数值
buttonOnlybooleanfalse是否仅显示按钮(不显示输入框)
controlsPosition'both' | 'right''both'控制按钮位置
placeholderstring-占位符文本

事件

事件名说明回调参数
update:modelValue绑定值发生改变时触发(value: number | null)
change绑定值发生改变时触发(value: number | null)
blur输入框失去焦点时触发(event: FocusEvent)
focus输入框获得焦点时触发(event: FocusEvent)