Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<script setup lang="ts">
const value = ref(5)
</script>

<template>
<UInputNumber
v-model="value"
:increment="false"
:decrement="false"
/>
</template>
10 changes: 10 additions & 0 deletions docs/content/docs/2.components/input-number.md
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,16 @@ name: 'input-number-currency-example'
---
::

### Without buttons

You can use the `increment` and `decrement` props to control visibility of the buttons.

::component-example
---
name: 'input-number-without-buttons-example'
---
::

### Within a FormField

You can use the InputNumber within a [FormField](/docs/components/form-field) component to display a label, help text, required indicator, etc.
Expand Down
2 changes: 1 addition & 1 deletion docs/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ export default defineNuxtConfig({
vite: {
optimizeDeps: {
// prevents reloading page when navigating between components
include: ['@internationalized/date', '@vueuse/shared', '@vueuse/integrations/useFuse', '@tanstack/vue-table', 'reka-ui', 'reka-ui/namespaced', 'embla-carousel-vue', 'embla-carousel-autoplay', 'embla-carousel-auto-scroll', 'embla-carousel-auto-height', 'embla-carousel-class-names', 'embla-carousel-fade', 'embla-carousel-wheel-gestures', 'colortranslator', 'tailwindcss/colors', 'tailwind-variants', 'ufo', 'zod', 'vaul-vue', 'scule', 'motion-v', 'json5', 'ohash', 'shiki-transformer-color-highlight']
include: ['@ai-sdk/vue', '@internationalized/date', '@nuxt/content/utils', '@tanstack/vue-table', '@vercel/analytics/nuxt', '@vercel/speed-insights/nuxt', '@vue/devtools-core', '@vue/devtools-kit', '@vueuse/integrations/useFuse', '@vueuse/shared', 'ai', 'colortranslator', 'embla-carousel-auto-height', 'embla-carousel-auto-scroll', 'embla-carousel-autoplay', 'embla-carousel-class-names', 'embla-carousel-fade', 'embla-carousel-vue', 'embla-carousel-wheel-gestures', 'json5', 'motion-v', 'ohash', 'ohash/utils', 'prettier', 'reka-ui', 'reka-ui/namespaced', 'scule', 'shiki', 'shiki-stream/vue', 'shiki-transformer-color-highlight', 'shiki/engine-javascript.mjs', 'tailwind-variants', 'tailwindcss/colors', 'ufo', 'vaul-vue', 'zod']
}
},

Expand Down
2 changes: 1 addition & 1 deletion playgrounds/nuxt/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default defineNuxtConfig({
vite: {
optimizeDeps: {
// prevents reloading page when navigating between components
include: ['@internationalized/date', '@vueuse/shared', '@vueuse/integrations/useFuse', '@tanstack/vue-table', 'reka-ui', 'reka-ui/namespaced', 'embla-carousel-vue', 'embla-carousel-autoplay', 'embla-carousel-auto-scroll', 'embla-carousel-auto-height', 'embla-carousel-class-names', 'embla-carousel-fade', 'embla-carousel-wheel-gestures', 'colortranslator', 'tailwindcss/colors', 'tailwind-variants', 'ufo', 'zod', 'vaul-vue']
include: ['@ai-sdk/vue', '@internationalized/date', '@tanstack/vue-table', '@tanstack/vue-virtual', '@vue/devtools-core', '@vue/devtools-kit', '@vueuse/core', '@vueuse/integrations/useFuse', '@vueuse/shared', 'colortranslator', 'embla-carousel-auto-height', 'embla-carousel-auto-scroll', 'embla-carousel-autoplay', 'embla-carousel-class-names', 'embla-carousel-fade', 'embla-carousel-vue', 'embla-carousel-wheel-gestures', 'ohash/utils', 'reka-ui', 'reka-ui/namespaced', 'scule', 'tailwind-variants', 'tailwindcss/colors', 'ufo', 'vaul-vue', 'zod']
}
}
})
16 changes: 9 additions & 7 deletions src/runtime/components/InputNumber.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export interface InputNumberProps extends Pick<NumberFieldRootProps, 'modelValue
* Configure the increment button. The `color` and `size` are inherited.
* @defaultValue { variant: 'link' }
*/
increment?: ButtonProps
increment?: boolean | ButtonProps
/**
* The icon displayed to increment the value.
* @defaultValue appConfig.ui.icons.plus
Expand All @@ -43,7 +43,7 @@ export interface InputNumberProps extends Pick<NumberFieldRootProps, 'modelValue
* Configure the decrement button. The `color` and `size` are inherited.
* @defaultValue { variant: 'link' }
*/
decrement?: ButtonProps
decrement?: boolean | ButtonProps
/**
* The icon displayed to decrement the value.
* @defaultValue appConfig.ui.icons.minus
Expand Down Expand Up @@ -91,8 +91,8 @@ defineOptions({ inheritAttrs: false })

const props = withDefaults(defineProps<InputNumberProps>(), {
orientation: 'horizontal',
disabledIncrement: false,
disabledDecrement: false
increment: true,
decrement: true
})
const emits = defineEmits<InputNumberEmits>()
defineSlots<InputNumberSlots>()
Expand All @@ -116,7 +116,9 @@ const ui = computed(() => tv({ extend: tv(theme), ...(appConfig.ui?.inputNumber
size: inputSize.value,
highlight: highlight.value,
orientation: props.orientation,
fieldGroup: orientation.value
fieldGroup: orientation.value,
increment: props.orientation === 'vertical' ? (!!props.increment || !!props.decrement) : !!props.increment,
decrement: props.orientation === 'vertical' ? false : !!props.decrement
}))

const incrementIcon = computed(() => props.incrementIcon || (props.orientation === 'horizontal' ? appConfig.ui.icons.plus : appConfig.ui.icons.chevronUp))
Expand Down Expand Up @@ -180,7 +182,7 @@ defineExpose({
@focus="emitFormFocus"
/>

<div :class="ui.increment({ class: props.ui?.increment })">
<div v-if="!!increment" :class="ui.increment({ class: props.ui?.increment })">
<NumberFieldIncrement as-child :disabled="disabled || incrementDisabled">
<slot name="increment">
<UButton
Expand All @@ -195,7 +197,7 @@ defineExpose({
</NumberFieldIncrement>
</div>

<div :class="ui.decrement({ class: props.ui?.decrement })">
<div v-if="!!decrement" :class="ui.decrement({ class: props.ui?.decrement })">
<NumberFieldDecrement as-child :disabled="disabled || decrementDisabled">
<slot name="decrement">
<UButton
Expand Down
38 changes: 24 additions & 14 deletions src/theme/input-number.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ export default (options: Required<ModuleOptions>) => {
},
highlight: {
true: ''
},
increment: {
false: ''
},
decrement: {
false: ''
}
},
compoundVariants: [...(options.theme.colors || []).map((color: string) => ({
Expand All @@ -67,42 +73,46 @@ export default (options: Required<ModuleOptions>) => {
class: 'ring ring-inset ring-inverted'
}, {
orientation: 'horizontal',
decrement: false,
class: 'text-start'
}, {
decrement: true,
size: 'xs',
class: 'px-7'
class: 'ps-7'
}, {
orientation: 'horizontal',
decrement: true,
size: 'sm',
class: 'px-8'
class: 'ps-8'
}, {
orientation: 'horizontal',
decrement: true,
size: 'md',
class: 'px-9'
class: 'ps-9'
}, {
orientation: 'horizontal',
decrement: true,
size: 'lg',
class: 'px-10'
class: 'ps-10'
}, {
orientation: 'horizontal',
decrement: true,
size: 'xl',
class: 'px-11'
class: 'ps-11'
}, {
orientation: 'vertical',
increment: true,
size: 'xs',
class: 'pe-7'
}, {
orientation: 'vertical',
increment: true,
size: 'sm',
class: 'pe-8'
}, {
orientation: 'vertical',
increment: true,
size: 'md',
class: 'pe-9'
}, {
orientation: 'vertical',
increment: true,
size: 'lg',
class: 'pe-10'
}, {
orientation: 'vertical',
increment: true,
size: 'xl',
class: 'pe-11'
}],
Expand Down
8 changes: 7 additions & 1 deletion test/components/InputNumber.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,20 @@ describe('InputNumber', () => {
['with orientation vertical', { props: { orientation: 'vertical' } }],
['with incrementIcon', { props: { incrementIcon: 'i-lucide-arrow-left' } }],
['with decrementIcon', { props: { decrementIcon: 'i-lucide-arrow-right' } }],
['without increment', { props: { increment: false } }],
['without increment vertical', { props: { increment: false, orientation: 'vertical' } }],
['without decrement', { props: { decrement: false } }],
['without decrement vertical', { props: { decrement: false, orientation: 'vertical' } }],
['without increment and decrement', { props: { increment: false, decrement: false } }],
['without increment and decrement vertical', { props: { increment: false, decrement: false, orientation: 'vertical' } }],
...sizes.map((size: string) => [`with size ${size}`, { props: { size } }]),
...variants.map((variant: string) => [`with primary variant ${variant}`, { props: { variant } }]),
...variants.map((variant: string) => [`with neutral variant ${variant}`, { props: { variant, color: 'neutral' } }]),
['with ariaLabel', { attrs: { 'aria-label': 'Aria label' } }],
['with .optional modifier', { props: { modelModifiers: { optional: true } } }, { input: '', expected: undefined }],
['with as', { props: { as: 'section' } }],
['with class', { props: { class: 'absolute' } }],
['with ui', { props: { ui: { base: 'rounded-full' } } }],
['with .optional modifier', { props: { modelModifiers: { optional: true } } }, { input: '', expected: undefined }],
// Slots
['with increment slot', { slots: { increment: () => '+' } }],
['with decrement slot', { slots: { decrement: () => '-' } }]
Expand Down
Loading
Loading