Skip to content

Commit

Permalink
disable immediate and virtual feature for Combobox component in…
Browse files Browse the repository at this point in the history
… patch release
  • Loading branch information
RobinMalfait committed Jan 8, 2024
1 parent 279356b commit ac64a80
Show file tree
Hide file tree
Showing 4 changed files with 327 additions and 313 deletions.
282 changes: 141 additions & 141 deletions packages/@headlessui-react/src/components/combobox/combobox.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1832,7 +1832,7 @@ describe('Composition', () => {
)
})

describe.each([{ virtual: true }, { virtual: false }])(
describe.each([{ virtual: false }, { virtual: false }])(
'Keyboard interactions %s',
({ virtual }) => {
let data = ['Option A', 'Option B', 'Option C']
Expand Down Expand Up @@ -4309,7 +4309,7 @@ describe.each([{ virtual: true }, { virtual: false }])(
}
)

describe.each([{ virtual: true }, { virtual: false }])('Mouse interactions %s', ({ virtual }) => {
describe.each([{ virtual: false }, { virtual: false }])('Mouse interactions %s', ({ virtual }) => {
let data = ['Option A', 'Option B', 'Option C']
function MyCombobox<T>({
options = data.slice() as T[],
Expand Down Expand Up @@ -4411,126 +4411,126 @@ describe.each([{ virtual: true }, { virtual: false }])('Mouse interactions %s',
})
)

it(
'should be possible to open the combobox by focusing the input with immediate mode enabled',
suppressConsoleLogs(async () => {
render(<MyCombobox comboboxProps={{ immediate: true }} label={false} />)

assertComboboxButton({
state: ComboboxState.InvisibleUnmounted,
attributes: { id: 'headlessui-combobox-button-2' },
})
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })

// Focus the input
await focus(getComboboxInput())

// Verify it is visible
assertComboboxButton({ state: ComboboxState.Visible })
assertComboboxList({
state: ComboboxState.Visible,
attributes: { id: 'headlessui-combobox-options-3' },
})
assertActiveElement(getComboboxInput())
assertComboboxButtonLinkedWithCombobox()

// Verify we have combobox options
let options = getComboboxOptions()
expect(options).toHaveLength(3)
options.forEach((option) => assertComboboxOption(option))
})
)

it(
'should not be possible to open the combobox by focusing the input with immediate mode disabled',
suppressConsoleLogs(async () => {
render(<MyCombobox />)

assertComboboxButton({
state: ComboboxState.InvisibleUnmounted,
attributes: { id: 'headlessui-combobox-button-3' },
})
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })

// Focus the input
await focus(getComboboxInput())

// Verify it is invisible
assertComboboxButton({
state: ComboboxState.InvisibleUnmounted,
attributes: { id: 'headlessui-combobox-button-3' },
})
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
})
)

it(
'should not be possible to open the combobox by focusing the input with immediate mode enabled when button is disabled',
suppressConsoleLogs(async () => {
render(<MyCombobox comboboxProps={{ immediate: true, disabled: true }} />)

assertComboboxButton({
state: ComboboxState.InvisibleUnmounted,
attributes: { id: 'headlessui-combobox-button-3' },
})
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })

// Focus the input
await focus(getComboboxInput())

// Verify it is invisible
assertComboboxButton({
state: ComboboxState.InvisibleUnmounted,
attributes: { id: 'headlessui-combobox-button-3' },
})
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
})
)

it(
'should be possible to close a combobox on click with immediate mode enabled',
suppressConsoleLogs(async () => {
render(<MyCombobox comboboxProps={{ immediate: true }} />)

// Open combobox
await click(getComboboxButton())

// Verify it is visible
assertComboboxButton({ state: ComboboxState.Visible })

// Click to close
await click(getComboboxButton())

// Verify it is closed
assertComboboxButton({ state: ComboboxState.InvisibleUnmounted })
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
assertActiveElement(getComboboxInput())
})
)

it(
'should be possible to close a focused combobox on click with immediate mode enabled',
suppressConsoleLogs(async () => {
render(<MyCombobox comboboxProps={{ immediate: true }} />)
assertComboboxButton({ state: ComboboxState.InvisibleUnmounted })

// Open combobox by focusing input
await focus(getComboboxInput())
assertActiveElement(getComboboxInput())

// Verify it is visible
assertComboboxButton({ state: ComboboxState.Visible })

// Click to close
await click(getComboboxButton())

// Verify it is closed
assertComboboxButton({ state: ComboboxState.InvisibleUnmounted })
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
assertActiveElement(getComboboxInput())
})
)

// it(
// 'should be possible to open the combobox by focusing the input with immediate mode enabled',
// suppressConsoleLogs(async () => {
// render(<MyCombobox comboboxProps={{ immediate: true }} label={false} />)
//
// assertComboboxButton({
// state: ComboboxState.InvisibleUnmounted,
// attributes: { id: 'headlessui-combobox-button-2' },
// })
// assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
//
// // Focus the input
// await focus(getComboboxInput())
//
// // Verify it is visible
// assertComboboxButton({ state: ComboboxState.Visible })
// assertComboboxList({
// state: ComboboxState.Visible,
// attributes: { id: 'headlessui-combobox-options-3' },
// })
// assertActiveElement(getComboboxInput())
// assertComboboxButtonLinkedWithCombobox()
//
// // Verify we have combobox options
// let options = getComboboxOptions()
// expect(options).toHaveLength(3)
// options.forEach((option) => assertComboboxOption(option))
// })
// )
//
// it(
// 'should not be possible to open the combobox by focusing the input with immediate mode disabled',
// suppressConsoleLogs(async () => {
// render(<MyCombobox />)
//
// assertComboboxButton({
// state: ComboboxState.InvisibleUnmounted,
// attributes: { id: 'headlessui-combobox-button-3' },
// })
// assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
//
// // Focus the input
// await focus(getComboboxInput())
//
// // Verify it is invisible
// assertComboboxButton({
// state: ComboboxState.InvisibleUnmounted,
// attributes: { id: 'headlessui-combobox-button-3' },
// })
// assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
// })
// )
//
// it(
// 'should not be possible to open the combobox by focusing the input with immediate mode enabled when button is disabled',
// suppressConsoleLogs(async () => {
// render(<MyCombobox comboboxProps={{ immediate: true, disabled: true }} />)
//
// assertComboboxButton({
// state: ComboboxState.InvisibleUnmounted,
// attributes: { id: 'headlessui-combobox-button-3' },
// })
// assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
//
// // Focus the input
// await focus(getComboboxInput())
//
// // Verify it is invisible
// assertComboboxButton({
// state: ComboboxState.InvisibleUnmounted,
// attributes: { id: 'headlessui-combobox-button-3' },
// })
// assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
// })
// )
//
// it(
// 'should be possible to close a combobox on click with immediate mode enabled',
// suppressConsoleLogs(async () => {
// render(<MyCombobox comboboxProps={{ immediate: true }} />)
//
// // Open combobox
// await click(getComboboxButton())
//
// // Verify it is visible
// assertComboboxButton({ state: ComboboxState.Visible })
//
// // Click to close
// await click(getComboboxButton())
//
// // Verify it is closed
// assertComboboxButton({ state: ComboboxState.InvisibleUnmounted })
// assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
// assertActiveElement(getComboboxInput())
// })
// )
//
// it(
// 'should be possible to close a focused combobox on click with immediate mode enabled',
// suppressConsoleLogs(async () => {
// render(<MyCombobox comboboxProps={{ immediate: true }} />)
// assertComboboxButton({ state: ComboboxState.InvisibleUnmounted })
//
// // Open combobox by focusing input
// await focus(getComboboxInput())
// assertActiveElement(getComboboxInput())
//
// // Verify it is visible
// assertComboboxButton({ state: ComboboxState.Visible })
//
// // Click to close
// await click(getComboboxButton())
//
// // Verify it is closed
// assertComboboxButton({ state: ComboboxState.InvisibleUnmounted })
// assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
// assertActiveElement(getComboboxInput())
// })
// )
//
it(
'should be possible to open the combobox on click',
suppressConsoleLogs(async () => {
Expand Down Expand Up @@ -5031,25 +5031,25 @@ describe.each([{ virtual: true }, { virtual: false }])('Mouse interactions %s',
assertActiveComboboxOption(getComboboxOptions()[1])
})
)

it(
'should be possible to click a combobox option, which closes the combobox with immediate mode enabled',
suppressConsoleLogs(async () => {
render(<MyCombobox comboboxProps={{ immediate: true }} />)

// Open combobox by focusing input
await focus(getComboboxInput())
assertActiveElement(getComboboxInput())

assertComboboxList({ state: ComboboxState.Visible })

let options = getComboboxOptions()

// We should be able to click the first option
await click(options[1])
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
})
)
//
// it(
// 'should be possible to click a combobox option, which closes the combobox with immediate mode enabled',
// suppressConsoleLogs(async () => {
// render(<MyCombobox comboboxProps={{ immediate: true }} />)
//
// // Open combobox by focusing input
// await focus(getComboboxInput())
// assertActiveElement(getComboboxInput())
//
// assertComboboxList({ state: ComboboxState.Visible })
//
// let options = getComboboxOptions()
//
// // We should be able to click the first option
// await click(options[1])
// assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
// })
// )

it(
'should be possible to click a disabled combobox option, which is a no-op',
Expand Down
21 changes: 14 additions & 7 deletions packages/@headlessui-react/src/components/combobox/combobox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -605,11 +605,6 @@ export type ComboboxProps<
__demoMode?: boolean
form?: string
name?: string
immediate?: boolean
virtual?: {
options: TValue[]
disabled?: (value: TValue) => boolean
} | null
}

function ComboboxFn<TValue, TTag extends ElementType = typeof DEFAULT_COMBOBOX_TAG>(
Expand Down Expand Up @@ -644,10 +639,22 @@ function ComboboxFn<TValue, TTag extends ElementType = typeof DEFAULT_COMBOBOX_T
__demoMode = false,
nullable = false,
multiple = false,
immediate = false,
virtual = null,
// @ts-expect-error
immediate: _immediate = false,
// @ts-expect-error
virtual: _virtual = null,
...theirProps
} = props

// Disabling immediate mode feature for patch release v1.7.x
let immediate = false

// Disabling virtual feature for patch release v1.7.x
let virtual = null as {
options: TValue[]
disabled?: (value: TValue) => boolean
} | null

let [value = multiple ? [] : undefined, theirOnChange] = useControllable<any>(
controlledValue,
controlledOnChange,
Expand Down
Loading

0 comments on commit ac64a80

Please sign in to comment.