Skip to content

Commit

Permalink
feat: add inputAutoFocus param (#2581)
Browse files Browse the repository at this point in the history
  • Loading branch information
limonte committed Jan 11, 2023
1 parent 48dadd0 commit bcdb60c
Show file tree
Hide file tree
Showing 6 changed files with 184 additions and 139 deletions.
176 changes: 170 additions & 6 deletions cypress/e2e/methods/input.cy.js → cypress/e2e/inputs.cy.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { isVisible } from '../../../src/utils/dom'
import { $, Swal, SwalWithoutAnimation, TIMEOUT, dispatchCustomEvent, isHidden, triggerKeydownEvent } from '../../utils'
import defaultInputValidators from '../../../src/utils/defaultInputValidators'
import { isVisible } from '../../src/utils/dom'
import { $, Swal, SwalWithoutAnimation, TIMEOUT, dispatchCustomEvent, isHidden, triggerKeydownEvent } from '../utils'
import defaultInputValidators from '../../src/utils/defaultInputValidators'

describe('Input', () => {
describe('Inputs', () => {
it('should throw console error about unexpected input type', () => {
const spy = cy.spy(console, 'error')
Swal.fire({ input: 'invalid-input-type' })
Expand All @@ -27,7 +27,6 @@ describe('Input', () => {
it('input textarea', (done) => {
Swal.fire({
input: 'textarea',
inputAutoTrim: false,
}).then((result) => {
expect(result.value).to.equal('hola!')
done()
Expand All @@ -36,10 +35,47 @@ describe('Input', () => {
// Enter should not submit but put a newline to the textarea
triggerKeydownEvent(Swal.getInput(), 'Enter')

Swal.getInput().value = 'hola!'
Swal.getInput().value = ' hola! '
Swal.clickConfirm()
})

it('input textarea + inputAutoTrim: false', (done) => {
Swal.fire({
input: 'textarea',
inputAutoTrim: false,
}).then((result) => {
expect(result.value).to.equal(' hola! ')
done()
})

// Enter should not submit but put a newline to the textarea
triggerKeydownEvent(Swal.getInput(), 'Enter')

Swal.getInput().value = ' hola! '
Swal.clickConfirm()
})

it('inputAutoFocus: true (default)', (done) => {
Swal.fire({
input: 'textarea',
})
setTimeout(() => {
expect(document.activeElement).to.equal(Swal.getInput())
done()
})
})

it('inputAutoFocus: false', (done) => {
Swal.fire({
input: 'textarea',
inputAutoFocus: false,
})
setTimeout(() => {
expect(document.activeElement).to.equal(Swal.getConfirmButton())
done()
})
})

it('input email + built-in email validation', (done) => {
const invalidEmailAddress = 'blah-blah@zzz'
const validEmailAddress = 'team+support+a.b@example.com'
Expand Down Expand Up @@ -521,3 +557,131 @@ describe('Validation', () => {
})
})
})

describe('inputAttributes', () => {
it('input text w/ placeholder', () => {
Swal.fire({
input: 'text',
inputAttributes: {
placeholder: 'placeholder text',
},
})
expect(Swal.getInput().value).to.equal('')
expect(Swal.getInput().placeholder).to.equal('placeholder text')
})

it('input file w/ placeholder', () => {
Swal.fire({
input: 'file',
inputAttributes: {
placeholder: 'placeholder text',
},
})
expect(Swal.getInput().value).to.equal('')
expect(Swal.getInput().placeholder).to.equal('placeholder text')
})

it('input textarea w/ placeholder', () => {
Swal.fire({
input: 'textarea',
inputAttributes: {
placeholder: 'Provide your input here',
},
})
expect(Swal.getInput().value).to.equal('')
expect(Swal.getInput().placeholder).to.equal('Provide your input here')
})
})

describe('inputValue', () => {
it('inputValue number', () => {
Swal.fire({ input: 'text', inputValue: 333 })
expect(Swal.getInput().value).to.equal('333')
})

it('inputValue with object containing toPromise', (done) => {
Swal.fire({
input: 'text',
inputValue: {
toPromise: () => Promise.resolve('test'),
},
didOpen: () => {
setTimeout(() => {
expect(Swal.getInput().value).to.equal('test')
done()
}, TIMEOUT)
},
})
})

it('inputValue as a Promise', (done) => {
const spy = cy.spy(console, 'warn')
const inputTypes = ['text', 'email', 'number', 'tel', 'textarea']
const value = '1.1 input value'
const inputValue = new Promise((resolve) => {
resolve('1.1 input value')
})

function showPopupWithInput() {
const input = inputTypes.pop()
SwalWithoutAnimation.fire({
input,
inputValue,
didOpen: () => {
setTimeout(() => {
expect(Swal.getInput().value).to.equal(input === 'number' ? parseFloat(value).toString() : value)
if (inputTypes.length) {
showPopupWithInput()
} else {
done()
}
}, TIMEOUT)
},
})
}
showPopupWithInput()
expect(spy.notCalled).to.be.true
})

it('should throw console error when inputValue as a Promise rejects', (done) => {
const spy = cy.spy(console, 'error')
SwalWithoutAnimation.fire({
input: 'text',
inputValue: new Promise((resolve, reject) => {
reject(new Error('input promise rejected'))
}),
didOpen: () => {
setTimeout(() => {
expect(spy.calledWith('SweetAlert2: Error in inputValue promise: Error: input promise rejected')).to.be.true
done()
}, TIMEOUT)
},
})
})

it('should throw console warning about unexpected type of inputValue for input: text', () => {
const spy = cy.spy(console, 'warn')
Swal.fire({ input: 'text', inputValue: undefined })
expect(
spy.calledWith(
'SweetAlert2: Unexpected type of inputValue! Expected "string", "number" or "Promise", got "undefined"'
)
).to.be.true
})

it('should throw console warning about unexpected type of inputValue for input: textarea', () => {
const spy = cy.spy(console, 'warn')
Swal.fire({ input: 'textarea', inputValue: {} })
expect(
spy.calledWith(
'SweetAlert2: Unexpected type of inputValue! Expected "string", "number" or "Promise", got "object"'
)
).to.be.true
})

it('inputValue can be null', () => {
const spy = cy.spy(console, 'error')
Swal.fire({ input: 'select', inputOptions: { a: 'a' }, inputValue: null })
expect(spy.notCalled).to.be.true
})
})
36 changes: 0 additions & 36 deletions cypress/e2e/params/inputAttributes.cy.js

This file was deleted.

94 changes: 0 additions & 94 deletions cypress/e2e/params/inputValue.cy.js

This file was deleted.

8 changes: 5 additions & 3 deletions src/utils/dom/renderers/renderInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,11 @@ const showInput = (params) => {
dom.show(inputContainer)

// input autofocus
setTimeout(() => {
dom.focusInput(input)
})
if (params.inputAutoFocus) {
setTimeout(() => {
dom.focusInput(input)
})
}
}

/**
Expand Down
1 change: 1 addition & 0 deletions src/utils/params.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export const defaultParams = {
inputLabel: '',
inputValue: '',
inputOptions: {},
inputAutoFocus: true,
inputAutoTrim: true,
inputAttributes: {},
inputValidator: undefined,
Expand Down
8 changes: 8 additions & 0 deletions sweetalert2.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1020,6 +1020,14 @@ declare module 'sweetalert2' {
*/
inputOptions?: SyncOrAsync<ReadonlyMap<string, string> | Record<string, any>>

/**
* Automatically focus the input when popup is shown.
* Set this parameter to `false` to disable auto-focusing.
*
* @default true
*/
inputAutoFocus?: boolean

/**
* Automatically remove whitespaces from both ends of a result string.
* Set this parameter to `false` to disable auto-trimming.
Expand Down

0 comments on commit bcdb60c

Please sign in to comment.