Skip to content

Commit

Permalink
fix(VNumberInput): disable keyboard up/down for readonly state
Browse files Browse the repository at this point in the history
  • Loading branch information
jsek committed May 27, 2024
1 parent 2877f4f commit 4998955
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 0 deletions.
10 changes: 10 additions & 0 deletions packages/vuetify/src/labs/VNumberInput/VNumberInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { VDivider } from '../../components/VDivider'
import { makeVTextFieldProps, VTextField } from '@/components/VTextField/VTextField'

// Composables
import { useForm } from '@/composables/form'
import { useProxiedModel } from '@/composables/proxiedModel'

// Utilities
Expand Down Expand Up @@ -71,16 +72,24 @@ export const VNumberInput = genericComponent<VNumberInputSlots>()({
const stepDecimals = computed(() => getDecimals(props.step))
const modelDecimals = computed(() => model.value != null ? getDecimals(model.value) : 0)

const form = useForm()
const controlsDisabled = computed(() => (
props.disabled || props.readonly || form?.isReadonly.value
))

const canIncrease = computed(() => {
if (controlsDisabled.value) return false
if (model.value == null) return true
return model.value + props.step <= props.max
})
const canDecrease = computed(() => {
if (controlsDisabled.value) return false
if (model.value == null) return true
return model.value - props.step >= props.min
})

watchEffect(() => {
if (controlsDisabled.value) return
if (model.value != null && (model.value < props.min || model.value > props.max)) {
model.value = clamp(model.value, props.min, props.max)
}
Expand All @@ -95,6 +104,7 @@ export const VNumberInput = genericComponent<VNumberInputSlots>()({
const decrementSlotProps = computed(() => ({ click: onClickDown }))

function toggleUpDown (increment = true) {
if (controlsDisabled.value) return
if (model.value == null) {
model.value = 0
return
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,98 @@
/// <reference types="../../../../types/cypress" />

// Components
import { VDivider } from '@/components'
import { VNumberInput } from '../VNumberInput'
import { VForm } from '@/components/VForm'

// Utilities
import { ref } from 'vue'

describe('VNumberInput', () => {

it('should prevent mutation when readonly', () => {
const value1 = ref(1)
const value2 = ref(1)

cy.mount(() => (
<>
<VNumberInput
class='standalone-input'
v-model={ value1.value }
readonly
/>
<VForm readonly>
<VNumberInput
class='input-in-form'
v-model={ value2.value }
/>
</VForm>
</>
))

const selectors = ['.standalone-input', '.input-in-form']
selectors.forEach((selector: string) => {
cy.get(selector)
.first()
.within(() => {
cy.get('.v-field input').as('input')
cy.get('.v-number-input__control .v-btn:first-child').click({ force: true })
cy.get('@input').should('have.value', '1')

cy.get('.v-number-input__control .v-btn:last-child').click({ force: true })
cy.get('@input').should('have.value', '1')

cy.get('@input')
.focus()
.type('{uparrow}', { force: true })
.should('have.value', '1')
.type('{downarrow}', { force: true })
.should('have.value', '1')
})
})
})

it('should keep original value when readonly or disabled', () => {
const value1 = ref(120)
const value2 = ref(-15)
const value3 = ref(40.4)
const value4 = ref(-8.6)

cy.mount(() => (
<>
<VNumberInput
class='readonly-input-1'
v-model={ value1.value }
min={0} max={50}
readonly
/>
<VNumberInput
class='readonly-input-2'
v-model={ value2.value }
min={0} max={50}
readonly
/>
<VNumberInput
class='disabled-input-1'
v-model={ value3.value }
min={0} max={10}
disabled
/>
<VNumberInput
class='disabled-input-2'
v-model={ value4.value }
min={0} max={10}
disabled
/>
</>
))

cy.get('.readonly-input-1 input').should('have.value', '120')
cy.get('.readonly-input-2 input').should('have.value', '-15')
cy.get('.disabled-input-1 input').should('have.value', '40.4')
cy.get('.disabled-input-2 input').should('have.value', '-8.6')
})

describe('native number input quirks', () => {
it('should not bypass min', () => {
const numberInputValue = ref(1)
Expand Down

0 comments on commit 4998955

Please sign in to comment.