39 lines
1.3 KiB
Vue
39 lines
1.3 KiB
Vue
<script setup lang="ts">
|
||
const props = withDefaults(defineProps<{ modelValue: number; max?: number }>(), { max: 999 });
|
||
const emit = defineEmits<{ "update:modelValue": [v: number] }>();
|
||
|
||
function set(v: number): void {
|
||
const next = Math.min(props.max, Math.max(1, Math.floor(v) || 1));
|
||
emit("update:modelValue", next);
|
||
}
|
||
</script>
|
||
|
||
<template>
|
||
<div class="border-border inline-flex overflow-hidden rounded-md border">
|
||
<button
|
||
type="button"
|
||
class="bg-bg hover:text-primary h-8 w-[30px] border-0 text-sm transition-colors disabled:cursor-not-allowed disabled:opacity-40"
|
||
:disabled="modelValue <= 1"
|
||
@click="set(modelValue - 1)"
|
||
>
|
||
−
|
||
</button>
|
||
<input
|
||
:value="modelValue"
|
||
type="number"
|
||
:min="1"
|
||
:max="max"
|
||
class="border-border bg-surface text-text focus:border-primary h-8 w-12 [appearance:textfield] border-x text-center text-[13px] outline-none"
|
||
@change="set(Number(($event.target as HTMLInputElement).value))"
|
||
/>
|
||
<button
|
||
type="button"
|
||
class="bg-bg hover:text-primary h-8 w-[30px] border-0 text-sm transition-colors disabled:cursor-not-allowed disabled:opacity-40"
|
||
:disabled="modelValue >= max"
|
||
@click="set(modelValue + 1)"
|
||
>
|
||
+
|
||
</button>
|
||
</div>
|
||
</template>
|