Fix XYZPropsWeControl and cleanup internal TypeScript types (#2329)

* cleanup `XYZPropsWeControl`

The idea behind the `PropsWeControl` is that we can omit all the fields
that we are controlling entirely. In this case, passing a prop like
`role`, but if we already set the role ourselves then the prop won't do
anything at all. This is why we want to alert the end user that it is an
"error".

It can also happen that we "control" the value by default, but keep
incoming props into account. For example we generate a unique ID for
most components, but you can provide your own to override it. In this
case we _don't_ want to include the ID in the `XYZPropsWeControl`.

Additionally, we introduced some functionality months ago where we call
event callbacks (`onClick`, ...) from the incoming props before our own
callbacks. This means that by definition all `onXYZ` callbacks can be
provided.

* improve defining types

Whenever we explicitly provide custom types for certain props, then we
make sure to omit those keys first from the original props (of let's say
an `input`). This is important so that TypeScript doesn't try to "merge"
those types together.

* cleanup: move `useEffect`

* add `defaultValue` explicitly

* ensure tests are not using `any` because of `onChange={console.log}`

The `console.log` is typed as `(...args: any[]) => void` which means
that it will incorrectly mark its incoming data as `any` as well.
Converting it to `x => console.log(x)` makes TypeScript happy. Or in
this case, angry since it found a bug.

This is required because it _can_ be that your value (e.g.: the value of
a Combobox) is an object (e.g.: a `User`), but it is also nullable.

Therefore we can provide the value `null`. This would mean that
eventually this resolves to `keyof null` which is `never`, but we just
want a string in this case.

```diff
-export type ByComparator<T> = (keyof T & string) | ((a: T, b: T) => boolean)
+export type ByComparator<T> =
+  | (T extends null ? string : keyof T & string)
+  | ((a: T, b: T) => boolean)
```

* improve the internal types of the `Combobox` component

* improve the internal types of the `Disclosure` component

* improve the internal types of the `Listbox` component

* improve the internal types of the `Menu` component

* improve the internal types of the `Popover` component

* improve the internal types of the `Tabs` component

* improve the internal types of the `Transition` component

* use `Override` in `Hidden` as well

* cleanup unused code

* don't check the `useSyncExternalStoreShimClient`

* don't check the `useSyncExternalStoreShimServer`

* improve types in the render tests

* fix `Ref<TTag>` to be `Ref<HTMLElement>`

* improve internal types of the `Transition` component (Vue)

+ add `attrs.class` as well

* use different type for `AnyComponent`

* update changelog
This commit is contained in:
Robin Malfait
2023-03-02 22:50:41 +01:00
committed by GitHub
parent 948ae73608
commit 989cd6b040
23 changed files with 386 additions and 400 deletions
+1
View File
@@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Ensure `Transition` component completes if nothing is transitioning ([#2318](https://github.com/tailwindlabs/headlessui/pull/2318))
- Enable native label behavior for `<Switch>` where possible ([#2265](https://github.com/tailwindlabs/headlessui/pull/2265))
- Allow root containers from the `Dialog` component in the `FocusTrap` component ([#2322](https://github.com/tailwindlabs/headlessui/pull/2322))
- Fix `XYZPropsWeControl` and cleanup internal TypeScript types ([#2329](https://github.com/tailwindlabs/headlessui/pull/2329))
## [1.7.12] - 2023-02-24
@@ -74,7 +74,7 @@ describe('safeguards', () => {
'should be possible to render a Combobox without crashing',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -100,7 +100,7 @@ describe('Rendering', () => {
'should be possible to render a Combobox using a render prop',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
{({ open }) => (
<>
<Combobox.Input onChange={NOOP} />
@@ -137,7 +137,7 @@ describe('Rendering', () => {
'should be possible to disable a Combobox',
suppressConsoleLogs(async () => {
render(
<Combobox value={undefined} onChange={console.log} disabled>
<Combobox value={undefined} onChange={(x) => console.log(x)} disabled>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -206,7 +206,7 @@ describe('Rendering', () => {
'should use object equality by default',
suppressConsoleLogs(async () => {
render(
<Combobox value={options[1]} onChange={console.log}>
<Combobox value={options[1]} onChange={(x) => console.log(x)}>
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
{options.map((option) => (
@@ -236,7 +236,7 @@ describe('Rendering', () => {
'should be possible to compare null values by a field',
suppressConsoleLogs(async () => {
render(
<Combobox value={null} onChange={console.log} by="id">
<Combobox value={null} onChange={(x) => console.log(x)} by="id">
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
{options.map((option) => (
@@ -274,7 +274,7 @@ describe('Rendering', () => {
'should be possible to compare objects by a field',
suppressConsoleLogs(async () => {
render(
<Combobox value={{ id: 2, name: 'Bob' }} onChange={console.log} by="id">
<Combobox value={{ id: 2, name: 'Bob' }} onChange={(x) => console.log(x)} by="id">
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
{options.map((option) => (
@@ -306,7 +306,7 @@ describe('Rendering', () => {
render(
<Combobox
value={{ id: 2, name: 'Bob' }}
onChange={console.log}
onChange={(x) => console.log(x)}
by={(a, z) => a.id === z.id}
>
<Combobox.Button>Trigger</Combobox.Button>
@@ -687,7 +687,7 @@ describe('Rendering', () => {
'should be possible to render a Combobox.Label using a render prop',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Label>{JSON.stringify}</Combobox.Label>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
@@ -725,7 +725,7 @@ describe('Rendering', () => {
'should be possible to link Input/Button and Label if Label is rendered last',
suppressConsoleLogs(async () => {
render(
<Combobox value="Test" onChange={console.log}>
<Combobox value="Test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button />
<Combobox.Label>Label</Combobox.Label>
@@ -741,7 +741,7 @@ describe('Rendering', () => {
'should be possible to render a Combobox.Label using a render prop and an `as` prop',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Label as="p">{JSON.stringify}</Combobox.Label>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
@@ -776,7 +776,7 @@ describe('Rendering', () => {
'should be possible to render a Combobox.Button using a render prop',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>{JSON.stringify}</Combobox.Button>
<Combobox.Options>
@@ -809,7 +809,7 @@ describe('Rendering', () => {
'should be possible to render a Combobox.Button using a render prop and an `as` prop',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button as="div" role="button">
{JSON.stringify}
@@ -844,7 +844,7 @@ describe('Rendering', () => {
'should be possible to render a Combobox.Button and a Combobox.Label and see them linked together',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Label>Label</Combobox.Label>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
@@ -871,7 +871,7 @@ describe('Rendering', () => {
describe('`type` attribute', () => {
it('should set the `type` to "button" by default', async () => {
render(
<Combobox value={null} onChange={console.log}>
<Combobox value={null} onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
</Combobox>
@@ -882,7 +882,7 @@ describe('Rendering', () => {
it('should not set the `type` to "button" if it already contains a `type`', async () => {
render(
<Combobox value={null} onChange={console.log}>
<Combobox value={null} onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button type="submit">Trigger</Combobox.Button>
</Combobox>
@@ -897,7 +897,7 @@ describe('Rendering', () => {
))
render(
<Combobox value={null} onChange={console.log}>
<Combobox value={null} onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button as={CustomButton}>Trigger</Combobox.Button>
</Combobox>
@@ -908,7 +908,7 @@ describe('Rendering', () => {
it('should not set the type if the "as" prop is not a "button"', async () => {
render(
<Combobox value={null} onChange={console.log}>
<Combobox value={null} onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button as="div">Trigger</Combobox.Button>
</Combobox>
@@ -923,7 +923,7 @@ describe('Rendering', () => {
))
render(
<Combobox value={null} onChange={console.log}>
<Combobox value={null} onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button as={CustomButton}>Trigger</Combobox.Button>
</Combobox>
@@ -939,7 +939,7 @@ describe('Rendering', () => {
'should be possible to render Combobox.Options using a render prop',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -974,7 +974,7 @@ describe('Rendering', () => {
it('should be possible to always render the Combobox.Options if we provide it a `static` prop', () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options static>
@@ -991,7 +991,7 @@ describe('Rendering', () => {
it('should be possible to use a different render strategy for the Combobox.Options', async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options unmount={false}>
@@ -1016,7 +1016,7 @@ describe('Rendering', () => {
'should be possible to render a Combobox.Option using a render prop',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -1049,7 +1049,7 @@ describe('Rendering', () => {
function Example({ hide = false }) {
return (
<>
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -1405,7 +1405,7 @@ describe('Rendering composition', () => {
'should be possible to conditionally render classNames (aka className can be a function?!)',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -1466,7 +1466,7 @@ describe('Rendering composition', () => {
'should be possible to swap the Combobox option with a button for example',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -1501,7 +1501,7 @@ describe('Rendering composition', () => {
'should mark all the elements between Combobox.Options and Combobox.Option with role none',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button />
<div className="outer">
@@ -1560,7 +1560,7 @@ describe('Composition', () => {
suppressConsoleLogs(async () => {
let orderFn = jest.fn()
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Debug name="Combobox" fn={orderFn} />
@@ -1618,7 +1618,7 @@ describe('Keyboard interactions', () => {
'should be possible to open the combobox with Enter',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -1667,7 +1667,7 @@ describe('Keyboard interactions', () => {
'should not be possible to open the combobox with Enter when the button is disabled',
suppressConsoleLogs(async () => {
render(
<Combobox value={undefined} onChange={console.log} disabled>
<Combobox value={undefined} onChange={(x) => console.log(x)} disabled>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -1703,7 +1703,7 @@ describe('Keyboard interactions', () => {
'should be possible to open the combobox with Enter, and focus the selected option',
suppressConsoleLogs(async () => {
render(
<Combobox value="b" onChange={console.log}>
<Combobox value="b" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -1752,7 +1752,7 @@ describe('Keyboard interactions', () => {
'should be possible to open the combobox with Enter, and focus the selected option (when using the `hidden` render strategy)',
suppressConsoleLogs(async () => {
render(
<Combobox value="b" onChange={console.log}>
<Combobox value="b" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options unmount={false}>
@@ -1823,7 +1823,7 @@ describe('Keyboard interactions', () => {
]
let selectedOption = myOptions[1]
render(
<Combobox value={selectedOption} onChange={console.log}>
<Combobox value={selectedOption} onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -1874,7 +1874,7 @@ describe('Keyboard interactions', () => {
'should have no active combobox option when there are no combobox options at all',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options />
@@ -1905,7 +1905,7 @@ describe('Keyboard interactions', () => {
'should be possible to open the combobox with Space',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -1952,7 +1952,7 @@ describe('Keyboard interactions', () => {
'should not be possible to open the combobox with Space when the button is disabled',
suppressConsoleLogs(async () => {
render(
<Combobox value={undefined} onChange={console.log} disabled>
<Combobox value={undefined} onChange={(x) => console.log(x)} disabled>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -1988,7 +1988,7 @@ describe('Keyboard interactions', () => {
'should be possible to open the combobox with Space, and focus the selected option',
suppressConsoleLogs(async () => {
render(
<Combobox value="b" onChange={console.log}>
<Combobox value="b" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -2036,7 +2036,7 @@ describe('Keyboard interactions', () => {
'should have no active combobox option when there are no combobox options at all',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options />
@@ -2063,7 +2063,7 @@ describe('Keyboard interactions', () => {
'should have no active combobox option upon Space key press, when there are no non-disabled combobox options',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -2104,7 +2104,7 @@ describe('Keyboard interactions', () => {
'should be possible to close an open combobox with Escape',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -2149,7 +2149,7 @@ describe('Keyboard interactions', () => {
let handleKeyDown = jest.fn()
render(
<div onKeyDown={handleKeyDown}>
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -2178,7 +2178,7 @@ describe('Keyboard interactions', () => {
let handleKeyDown = jest.fn()
render(
<div onKeyDown={handleKeyDown}>
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -2207,7 +2207,7 @@ describe('Keyboard interactions', () => {
'should be possible to open the combobox with ArrowDown',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -2253,7 +2253,7 @@ describe('Keyboard interactions', () => {
'should not be possible to open the combobox with ArrowDown when the button is disabled',
suppressConsoleLogs(async () => {
render(
<Combobox value={undefined} onChange={console.log} disabled>
<Combobox value={undefined} onChange={(x) => console.log(x)} disabled>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -2289,7 +2289,7 @@ describe('Keyboard interactions', () => {
'should be possible to open the combobox with ArrowDown, and focus the selected option',
suppressConsoleLogs(async () => {
render(
<Combobox value="b" onChange={console.log}>
<Combobox value="b" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -2335,7 +2335,7 @@ describe('Keyboard interactions', () => {
'should have no active combobox option when there are no combobox options at all',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options />
@@ -2362,7 +2362,7 @@ describe('Keyboard interactions', () => {
'should be possible to open the combobox with ArrowUp and the last option should be active',
suppressConsoleLogs(async () => {
render(
<Combobox value={undefined} onChange={console.log}>
<Combobox value={undefined} onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -2408,7 +2408,7 @@ describe('Keyboard interactions', () => {
'should not be possible to open the combobox with ArrowUp and the last option should be active when the button is disabled',
suppressConsoleLogs(async () => {
render(
<Combobox value={undefined} onChange={console.log} disabled>
<Combobox value={undefined} onChange={(x) => console.log(x)} disabled>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -2444,7 +2444,7 @@ describe('Keyboard interactions', () => {
'should be possible to open the combobox with ArrowUp, and focus the selected option',
suppressConsoleLogs(async () => {
render(
<Combobox value="b" onChange={console.log}>
<Combobox value="b" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -2490,7 +2490,7 @@ describe('Keyboard interactions', () => {
'should have no active combobox option when there are no combobox options at all',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options />
@@ -2515,7 +2515,7 @@ describe('Keyboard interactions', () => {
'should be possible to use ArrowUp to navigate the combobox options and jump to the first non-disabled one',
suppressConsoleLogs(async () => {
render(
<Combobox value={undefined} onChange={console.log}>
<Combobox value={undefined} onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -2851,7 +2851,7 @@ describe('Keyboard interactions', () => {
'should be possible to close an open combobox with Escape',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -2890,7 +2890,7 @@ describe('Keyboard interactions', () => {
'should bubble escape when using `static` on Combobox.Options',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options static>
@@ -2941,7 +2941,7 @@ describe('Keyboard interactions', () => {
'should bubble escape when not using Combobox.Options at all',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
</Combobox>
@@ -2987,7 +2987,7 @@ describe('Keyboard interactions', () => {
'should sync the input field correctly and reset it when pressing Escape',
suppressConsoleLogs(async () => {
render(
<Combobox value="option-b" onChange={console.log}>
<Combobox value="option-b" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -3022,7 +3022,7 @@ describe('Keyboard interactions', () => {
'should be possible to open the combobox with ArrowDown',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -3068,7 +3068,7 @@ describe('Keyboard interactions', () => {
'should not be possible to open the combobox with ArrowDown when the button is disabled',
suppressConsoleLogs(async () => {
render(
<Combobox value={undefined} onChange={console.log} disabled>
<Combobox value={undefined} onChange={(x) => console.log(x)} disabled>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -3104,7 +3104,7 @@ describe('Keyboard interactions', () => {
'should be possible to open the combobox with ArrowDown, and focus the selected option',
suppressConsoleLogs(async () => {
render(
<Combobox value="b" onChange={console.log}>
<Combobox value="b" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -3150,7 +3150,7 @@ describe('Keyboard interactions', () => {
'should have no active combobox option when there are no combobox options at all',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options />
@@ -3175,7 +3175,7 @@ describe('Keyboard interactions', () => {
'should be possible to use ArrowDown to navigate the combobox options',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -3220,7 +3220,7 @@ describe('Keyboard interactions', () => {
'should be possible to use ArrowDown to navigate the combobox options and skip the first disabled one',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -3258,7 +3258,7 @@ describe('Keyboard interactions', () => {
'should be possible to use ArrowDown to navigate the combobox options and jump to the first non-disabled one',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -3298,7 +3298,7 @@ describe('Keyboard interactions', () => {
'should be possible to go to the next item if no value is set',
suppressConsoleLogs(async () => {
render(
<Combobox value={null} onChange={console.log}>
<Combobox value={null} onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -3337,7 +3337,7 @@ describe('Keyboard interactions', () => {
'should be possible to open the combobox with ArrowUp and the last option should be active',
suppressConsoleLogs(async () => {
render(
<Combobox value={undefined} onChange={console.log}>
<Combobox value={undefined} onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -3383,7 +3383,7 @@ describe('Keyboard interactions', () => {
'should not be possible to open the combobox with ArrowUp and the last option should be active when the button is disabled',
suppressConsoleLogs(async () => {
render(
<Combobox value={undefined} onChange={console.log} disabled>
<Combobox value={undefined} onChange={(x) => console.log(x)} disabled>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -3419,7 +3419,7 @@ describe('Keyboard interactions', () => {
'should be possible to open the combobox with ArrowUp, and focus the selected option',
suppressConsoleLogs(async () => {
render(
<Combobox value="b" onChange={console.log}>
<Combobox value="b" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -3465,7 +3465,7 @@ describe('Keyboard interactions', () => {
'should have no active combobox option when there are no combobox options at all',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options />
@@ -3490,7 +3490,7 @@ describe('Keyboard interactions', () => {
'should be possible to use ArrowUp to navigate the combobox options and jump to the first non-disabled one',
suppressConsoleLogs(async () => {
render(
<Combobox value={undefined} onChange={console.log}>
<Combobox value={undefined} onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -3529,7 +3529,7 @@ describe('Keyboard interactions', () => {
'should not be possible to navigate up or down if there is only a single non-disabled option',
suppressConsoleLogs(async () => {
render(
<Combobox value={undefined} onChange={console.log}>
<Combobox value={undefined} onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -3576,7 +3576,7 @@ describe('Keyboard interactions', () => {
'should be possible to use ArrowUp to navigate the combobox options',
suppressConsoleLogs(async () => {
render(
<Combobox value={undefined} onChange={console.log}>
<Combobox value={undefined} onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -3634,7 +3634,7 @@ describe('Keyboard interactions', () => {
'should be possible to use the End key to go to the last combobox option',
suppressConsoleLogs(async () => {
render(
<Combobox value={undefined} onChange={console.log}>
<Combobox value={undefined} onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -3663,7 +3663,7 @@ describe('Keyboard interactions', () => {
'should be possible to use the End key to go to the last non disabled combobox option',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -3697,7 +3697,7 @@ describe('Keyboard interactions', () => {
'should be possible to use the End key to go to the first combobox option if that is the only non-disabled combobox option',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -3734,7 +3734,7 @@ describe('Keyboard interactions', () => {
'should have no active combobox option upon End key press, when there are no non-disabled combobox options',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -3773,7 +3773,7 @@ describe('Keyboard interactions', () => {
'should be possible to use the PageDown key to go to the last combobox option',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -3802,7 +3802,7 @@ describe('Keyboard interactions', () => {
'should be possible to use the PageDown key to go to the last non disabled combobox option',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -3839,7 +3839,7 @@ describe('Keyboard interactions', () => {
'should be possible to use the PageDown key to go to the first combobox option if that is the only non-disabled combobox option',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -3876,7 +3876,7 @@ describe('Keyboard interactions', () => {
'should have no active combobox option upon PageDown key press, when there are no non-disabled combobox options',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -3915,7 +3915,7 @@ describe('Keyboard interactions', () => {
'should be possible to use the Home key to go to the first combobox option',
suppressConsoleLogs(async () => {
render(
<Combobox value={undefined} onChange={console.log}>
<Combobox value={undefined} onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -3947,7 +3947,7 @@ describe('Keyboard interactions', () => {
'should be possible to use the Home key to go to the first non disabled combobox option',
suppressConsoleLogs(async () => {
render(
<Combobox value={undefined} onChange={console.log}>
<Combobox value={undefined} onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -3983,7 +3983,7 @@ describe('Keyboard interactions', () => {
'should be possible to use the Home key to go to the last combobox option if that is the only non-disabled combobox option',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -4020,7 +4020,7 @@ describe('Keyboard interactions', () => {
'should have no active combobox option upon Home key press, when there are no non-disabled combobox options',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -4059,7 +4059,7 @@ describe('Keyboard interactions', () => {
'should be possible to use the PageUp key to go to the first combobox option',
suppressConsoleLogs(async () => {
render(
<Combobox value={undefined} onChange={console.log}>
<Combobox value={undefined} onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -4091,7 +4091,7 @@ describe('Keyboard interactions', () => {
'should be possible to use the PageUp key to go to the first non disabled combobox option',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -4126,7 +4126,7 @@ describe('Keyboard interactions', () => {
'should be possible to use the PageUp key to go to the last combobox option if that is the only non-disabled combobox option',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -4163,7 +4163,7 @@ describe('Keyboard interactions', () => {
'should have no active combobox option upon PageUp key press, when there are no non-disabled combobox options',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -4436,7 +4436,7 @@ describe('Mouse interactions', () => {
'should focus the Combobox.Input when we click the Combobox.Label',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Label>Label</Combobox.Label>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
@@ -4463,7 +4463,7 @@ describe('Mouse interactions', () => {
'should not focus the Combobox.Input when we right click the Combobox.Label',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Label>Label</Combobox.Label>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
@@ -4490,7 +4490,7 @@ describe('Mouse interactions', () => {
'should be possible to open the combobox on click',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -4530,7 +4530,7 @@ describe('Mouse interactions', () => {
'should not be possible to open the combobox on right click',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -4559,7 +4559,7 @@ describe('Mouse interactions', () => {
'should not be possible to open the combobox on click when the button is disabled',
suppressConsoleLogs(async () => {
render(
<Combobox value={undefined} onChange={console.log} disabled>
<Combobox value={undefined} onChange={(x) => console.log(x)} disabled>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -4592,7 +4592,7 @@ describe('Mouse interactions', () => {
'should be possible to open the combobox on click, and focus the selected option',
suppressConsoleLogs(async () => {
render(
<Combobox value="b" onChange={console.log}>
<Combobox value="b" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -4635,7 +4635,7 @@ describe('Mouse interactions', () => {
'should be possible to close a combobox on click',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -4665,7 +4665,7 @@ describe('Mouse interactions', () => {
'should be a no-op when we click outside of a closed combobox',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -4694,7 +4694,7 @@ describe('Mouse interactions', () => {
suppressConsoleLogs(async () => {
render(
<>
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -4730,7 +4730,7 @@ describe('Mouse interactions', () => {
suppressConsoleLogs(async () => {
render(
<div>
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -4740,7 +4740,7 @@ describe('Mouse interactions', () => {
</Combobox.Options>
</Combobox>
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -4775,7 +4775,7 @@ describe('Mouse interactions', () => {
'should be possible to click outside of the combobox which should close the combobox (even if we press the combobox button)',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -4808,7 +4808,7 @@ describe('Mouse interactions', () => {
let focusFn = jest.fn()
render(
<div>
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} onFocus={focusFn} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -4848,7 +4848,7 @@ describe('Mouse interactions', () => {
'should be possible to hover an option and make it active',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -4881,7 +4881,7 @@ describe('Mouse interactions', () => {
'should be possible to hover an option and make it active when using `static`',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options static>
@@ -4911,7 +4911,7 @@ describe('Mouse interactions', () => {
'should make a combobox option active when you move the mouse over it',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -4936,7 +4936,7 @@ describe('Mouse interactions', () => {
'should be a no-op when we move the mouse and the combobox option is already active',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -4967,7 +4967,7 @@ describe('Mouse interactions', () => {
'should be a no-op when we move the mouse and the combobox option is disabled',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -4994,7 +4994,7 @@ describe('Mouse interactions', () => {
'should not be possible to hover an option that is disabled',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -5024,7 +5024,7 @@ describe('Mouse interactions', () => {
'should be possible to mouse leave an option and make it inactive',
suppressConsoleLogs(async () => {
render(
<Combobox value="bob" onChange={console.log}>
<Combobox value="bob" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -5067,7 +5067,7 @@ describe('Mouse interactions', () => {
'should be possible to mouse leave a disabled option and be a no-op',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -5244,7 +5244,7 @@ describe('Mouse interactions', () => {
'should not be possible to focus a combobox option which is disabled',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
@@ -5274,7 +5274,7 @@ describe('Mouse interactions', () => {
'should be possible to hold the last active option',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log}>
<Combobox value="test" onChange={(x) => console.log(x)}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options hold>
@@ -5797,7 +5797,7 @@ describe('Form compatibility', () => {
}}
>
<Combobox value={value} onChange={setValue} name="delivery">
<Combobox.Input onChange={console.log} />
<Combobox.Input onChange={(x) => console.log(x)} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Label>Pizza Delivery</Combobox.Label>
<Combobox.Options>
@@ -4,6 +4,7 @@ import React, {
createRef,
useCallback,
useContext,
useEffect,
useMemo,
useReducer,
useRef,
@@ -14,7 +15,6 @@ import React, {
MouseEvent as ReactMouseEvent,
MutableRefObject,
Ref,
useEffect,
} from 'react'
import { ByComparator, EnsureArray, Expand, Props } from '../../types'
@@ -385,31 +385,31 @@ export type ComboboxProps<
function ComboboxFn<TValue, TTag extends ElementType = typeof DEFAULT_COMBOBOX_TAG>(
props: ComboboxProps<TValue, true, true, TTag>,
ref: Ref<TTag>
ref: Ref<HTMLElement>
): JSX.Element
function ComboboxFn<TValue, TTag extends ElementType = typeof DEFAULT_COMBOBOX_TAG>(
props: ComboboxProps<TValue, true, false, TTag>,
ref: Ref<TTag>
ref: Ref<HTMLElement>
): JSX.Element
function ComboboxFn<TValue, TTag extends ElementType = typeof DEFAULT_COMBOBOX_TAG>(
props: ComboboxProps<TValue, false, false, TTag>,
ref: Ref<TTag>
ref: Ref<HTMLElement>
): JSX.Element
function ComboboxFn<TValue, TTag extends ElementType = typeof DEFAULT_COMBOBOX_TAG>(
props: ComboboxProps<TValue, false, true, TTag>,
ref: Ref<TTag>
ref: Ref<HTMLElement>
): JSX.Element
function ComboboxFn<TValue, TTag extends ElementType = typeof DEFAULT_COMBOBOX_TAG>(
props: ComboboxProps<TValue, boolean | undefined, boolean | undefined, TTag>,
ref: Ref<TTag>
ref: Ref<HTMLElement>
) {
let {
value: controlledValue,
defaultValue,
onChange: controlledOnChange,
name,
by = (a: any, z: any) => a === z,
by = (a: TValue, z: TValue) => a === z,
disabled = false,
__demoMode = false,
nullable = false,
@@ -440,16 +440,18 @@ function ComboboxFn<TValue, TTag extends ElementType = typeof DEFAULT_COMBOBOX_T
let buttonRef = useRef<_Data['buttonRef']['current']>(null)
let optionsRef = useRef<_Data['optionsRef']['current']>(null)
type TActualValue = true extends typeof multiple ? EnsureArray<TValue>[number] : TValue
let compare = useEvent(
// @ts-expect-error Eventually we'll want to tackle this, but for now this will do.
typeof by === 'string'
? (a, z) => {
let property = by as unknown as keyof TValue
? (a: TActualValue, z: TActualValue) => {
let property = by as unknown as keyof TActualValue
return a?.[property] === z?.[property]
}
: by
)
let isSelected: (value: unknown) => boolean = useCallback(
let isSelected: (value: TValue) => boolean = useCallback(
(compareValue) =>
match(data.mode, {
[ValueMode.Multi]: () =>
@@ -695,23 +697,24 @@ interface InputRenderPropArg {
disabled: boolean
}
type InputPropsWeControl =
| 'role'
| 'aria-labelledby'
| 'aria-expanded'
| 'aria-activedescendant'
| 'aria-autocomplete'
| 'onKeyDown'
| 'onChange'
| 'displayValue'
| 'aria-controls'
| 'aria-expanded'
| 'aria-labelledby'
| 'disabled'
| 'role'
export type ComboboxInputProps<TTag extends ElementType, TType> = Props<
TTag,
InputRenderPropArg,
InputPropsWeControl
> & {
displayValue?(item: TType): string
onChange?(event: React.ChangeEvent<HTMLInputElement>): void
}
InputPropsWeControl,
{
defaultValue?: TType
displayValue?(item: TType): string
onChange?(event: React.ChangeEvent<HTMLInputElement>): void
}
>
function InputFn<
TTag extends ElementType = typeof DEFAULT_INPUT_TAG,
@@ -1010,15 +1013,12 @@ interface ButtonRenderPropArg {
value: any
}
type ButtonPropsWeControl =
// | 'type' // While we do "control" this prop we allow it to be overridden
| 'tabIndex'
| 'aria-haspopup'
| 'aria-controls'
| 'aria-expanded'
| 'aria-haspopup'
| 'aria-labelledby'
| 'disabled'
| 'onClick'
| 'onKeyDown'
| 'tabIndex'
export type ComboboxButtonProps<TTag extends ElementType> = Props<
TTag,
@@ -1131,13 +1131,8 @@ interface LabelRenderPropArg {
open: boolean
disabled: boolean
}
type LabelPropsWeControl = 'ref' | 'onClick'
export type ComboboxLabelProps<TTag extends ElementType> = Props<
TTag,
LabelRenderPropArg,
LabelPropsWeControl
>
export type ComboboxLabelProps<TTag extends ElementType> = Props<TTag, LabelRenderPropArg>
function LabelFn<TTag extends ElementType = typeof DEFAULT_LABEL_TAG>(
props: ComboboxLabelProps<TTag>,
@@ -1175,18 +1170,18 @@ let DEFAULT_OPTIONS_TAG = 'ul' as const
interface OptionsRenderPropArg {
open: boolean
}
type OptionsPropsWeControl = 'aria-labelledby' | 'hold' | 'onKeyDown' | 'role' | 'tabIndex'
type OptionsPropsWeControl = 'aria-labelledby' | 'aria-multiselectable' | 'role' | 'tabIndex'
let OptionsRenderFeatures = Features.RenderStrategy | Features.Static
export type ComboboxOptionsProps<TTag extends ElementType> = Props<
TTag,
OptionsRenderPropArg,
OptionsPropsWeControl
> &
OptionsPropsWeControl,
PropsForFeatures<typeof OptionsRenderFeatures> & {
hold?: boolean
}
>
function OptionsFn<TTag extends ElementType = typeof DEFAULT_OPTIONS_TAG>(
props: ComboboxOptionsProps<TTag>,
@@ -1263,16 +1258,17 @@ interface OptionRenderPropArg {
selected: boolean
disabled: boolean
}
type ComboboxOptionPropsWeControl = 'role' | 'tabIndex' | 'aria-disabled' | 'aria-selected'
type OptionPropsWeControl = 'role' | 'tabIndex' | 'aria-disabled' | 'aria-selected'
export type ComboboxOptionProps<TTag extends ElementType, TType> = Props<
TTag,
OptionRenderPropArg,
ComboboxOptionPropsWeControl | 'value'
> & {
disabled?: boolean
value: TType
}
OptionPropsWeControl,
{
disabled?: boolean
value: TType
}
>
function OptionFn<
TTag extends ElementType = typeof DEFAULT_OPTION_TAG,
@@ -118,21 +118,21 @@ let DEFAULT_DIALOG_TAG = 'div' as const
interface DialogRenderPropArg {
open: boolean
}
type DialogPropsWeControl = 'role' | 'aria-modal' | 'aria-describedby' | 'aria-labelledby'
type DialogPropsWeControl = 'role' | 'aria-describedby' | 'aria-labelledby' | 'aria-modal'
let DialogRenderFeatures = Features.RenderStrategy | Features.Static
export type DialogProps<TTag extends ElementType> = Props<
TTag,
DialogRenderPropArg,
DialogPropsWeControl
> &
DialogPropsWeControl,
PropsForFeatures<typeof DialogRenderFeatures> & {
open?: boolean
onClose(value: boolean): void
initialFocus?: MutableRefObject<HTMLElement | null>
__demoMode?: boolean
}
>
function DialogFn<TTag extends ElementType = typeof DEFAULT_DIALOG_TAG>(
props: DialogProps<TTag>,
@@ -402,7 +402,7 @@ let DEFAULT_OVERLAY_TAG = 'div' as const
interface OverlayRenderPropArg {
open: boolean
}
type OverlayPropsWeControl = 'aria-hidden' | 'onClick'
type OverlayPropsWeControl = 'aria-hidden'
export type DialogOverlayProps<TTag extends ElementType> = Props<
TTag,
@@ -454,7 +454,7 @@ let DEFAULT_BACKDROP_TAG = 'div' as const
interface BackdropRenderPropArg {
open: boolean
}
type BackdropPropsWeControl = 'aria-hidden' | 'onClick'
type BackdropPropsWeControl = 'aria-hidden'
export type DialogBackdropProps<TTag extends ElementType> = Props<
TTag,
@@ -162,7 +162,7 @@ export type DisclosureProps<TTag extends ElementType> = Props<TTag, DisclosureRe
function DisclosureFn<TTag extends ElementType = typeof DEFAULT_DISCLOSURE_TAG>(
props: DisclosureProps<TTag>,
ref: Ref<TTag>
ref: Ref<HTMLElement>
) {
let { defaultOpen = false, ...theirProps } = props
let internalDisclosureRef = useRef<HTMLElement | null>(null)
@@ -247,14 +247,15 @@ let DEFAULT_BUTTON_TAG = 'button' as const
interface ButtonRenderPropArg {
open: boolean
}
type ButtonPropsWeControl =
// | 'type' // We allow this to be overridden
'aria-expanded' | 'aria-controls' | 'onKeyDown' | 'onClick'
type ButtonPropsWeControl = 'aria-controls' | 'aria-expanded'
export type DisclosureButtonProps<TTag extends ElementType> = Props<
TTag,
ButtonRenderPropArg,
ButtonPropsWeControl
ButtonPropsWeControl,
{
disabled?: boolean
}
>
function ButtonFn<TTag extends ElementType = typeof DEFAULT_BUTTON_TAG>(
@@ -68,7 +68,7 @@ describe('safeguards', () => {
'should be possible to render a Listbox without crashing',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a">Option A</Listbox.Option>
@@ -93,7 +93,7 @@ describe('Rendering', () => {
'should be possible to render a Listbox using a render prop',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
{({ open }) => (
<>
<Listbox.Button>Trigger</Listbox.Button>
@@ -129,7 +129,7 @@ describe('Rendering', () => {
'should be possible to disable a Listbox',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log} disabled>
<Listbox value={undefined} onChange={(x) => console.log(x)} disabled>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a">Option A</Listbox.Option>
@@ -197,7 +197,7 @@ describe('Rendering', () => {
'should use object equality by default',
suppressConsoleLogs(async () => {
render(
<Listbox value={options[1]} onChange={console.log}>
<Listbox value={options[1]} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
{options.map((option) => (
@@ -227,7 +227,7 @@ describe('Rendering', () => {
'should be possible to compare objects by a field',
suppressConsoleLogs(async () => {
render(
<Listbox value={{ id: 2, name: 'Bob' }} onChange={console.log} by="id">
<Listbox value={{ id: 2, name: 'Bob' }} onChange={(x) => console.log(x)} by="id">
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
{options.map((option) => (
@@ -259,7 +259,7 @@ describe('Rendering', () => {
render(
<Listbox
value={{ id: 2, name: 'Bob' }}
onChange={console.log}
onChange={(x) => console.log(x)}
by={(a, z) => a.id === z.id}
>
<Listbox.Button>Trigger</Listbox.Button>
@@ -461,7 +461,7 @@ describe('Rendering', () => {
'null should be a valid value for the Listbox',
suppressConsoleLogs(async () => {
render(
<Listbox value={null} onChange={console.log}>
<Listbox value={null} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a">Option A</Listbox.Option>
@@ -487,7 +487,7 @@ describe('Rendering', () => {
'should be possible to render a Listbox.Label using a render prop',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Label>{JSON.stringify}</Listbox.Label>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
@@ -524,7 +524,7 @@ describe('Rendering', () => {
'should be possible to render a Listbox.Label using a render prop and an `as` prop',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Label as="p">{JSON.stringify}</Listbox.Label>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
@@ -558,7 +558,7 @@ describe('Rendering', () => {
'should be possible to render a Listbox.Button using a render prop',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>{JSON.stringify}</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a">Option A</Listbox.Option>
@@ -590,7 +590,7 @@ describe('Rendering', () => {
'should be possible to render a Listbox.Button using a render prop and an `as` prop',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button as="div" role="button">
{JSON.stringify}
</Listbox.Button>
@@ -624,7 +624,7 @@ describe('Rendering', () => {
'should be possible to render a Listbox.Button and a Listbox.Label and see them linked together',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Label>Label</Listbox.Label>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
@@ -650,7 +650,7 @@ describe('Rendering', () => {
describe('`type` attribute', () => {
it('should set the `type` to "button" by default', async () => {
render(
<Listbox value={null} onChange={console.log}>
<Listbox value={null} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
</Listbox>
)
@@ -660,7 +660,7 @@ describe('Rendering', () => {
it('should not set the `type` to "button" if it already contains a `type`', async () => {
render(
<Listbox value={null} onChange={console.log}>
<Listbox value={null} onChange={(x) => console.log(x)}>
<Listbox.Button type="submit">Trigger</Listbox.Button>
</Listbox>
)
@@ -674,7 +674,7 @@ describe('Rendering', () => {
))
render(
<Listbox value={null} onChange={console.log}>
<Listbox value={null} onChange={(x) => console.log(x)}>
<Listbox.Button as={CustomButton}>Trigger</Listbox.Button>
</Listbox>
)
@@ -684,7 +684,7 @@ describe('Rendering', () => {
it('should not set the type if the "as" prop is not a "button"', async () => {
render(
<Listbox value={null} onChange={console.log}>
<Listbox value={null} onChange={(x) => console.log(x)}>
<Listbox.Button as="div">Trigger</Listbox.Button>
</Listbox>
)
@@ -698,7 +698,7 @@ describe('Rendering', () => {
))
render(
<Listbox value={null} onChange={console.log}>
<Listbox value={null} onChange={(x) => console.log(x)}>
<Listbox.Button as={CustomButton}>Trigger</Listbox.Button>
</Listbox>
)
@@ -713,7 +713,7 @@ describe('Rendering', () => {
'should be possible to render Listbox.Options using a render prop',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
{(data) => (
@@ -747,7 +747,7 @@ describe('Rendering', () => {
it('should be possible to always render the Listbox.Options if we provide it a `static` prop', () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options static>
<Listbox.Option value="a">Option A</Listbox.Option>
@@ -763,7 +763,7 @@ describe('Rendering', () => {
it('should be possible to use a different render strategy for the Listbox.Options', async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options unmount={false}>
<Listbox.Option value="a">Option A</Listbox.Option>
@@ -787,7 +787,7 @@ describe('Rendering', () => {
'should be possible to render a Listbox.Option using a render prop',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a">{JSON.stringify}</Listbox.Option>
@@ -819,7 +819,7 @@ describe('Rendering', () => {
function Example({ hide = false }) {
return (
<>
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a">Option 1</Listbox.Option>
@@ -1163,7 +1163,7 @@ describe('Rendering composition', () => {
'should be possible to conditionally render classNames (aka className can be a function?!)',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a" className={(bag) => JSON.stringify(bag)}>
@@ -1238,7 +1238,7 @@ describe('Rendering composition', () => {
'should be possible to swap the Listbox option with a button for example',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option as="button" value="a">
@@ -1285,7 +1285,7 @@ describe('Composition', () => {
suppressConsoleLogs(async () => {
let orderFn = jest.fn()
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Debug name="Listbox" fn={orderFn} />
<Transition>
@@ -1341,7 +1341,7 @@ describe('Keyboard interactions', () => {
'should be possible to open the listbox with Enter',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a">Option A</Listbox.Option>
@@ -1387,7 +1387,7 @@ describe('Keyboard interactions', () => {
'should not be possible to open the listbox with Enter when the button is disabled',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log} disabled>
<Listbox value={undefined} onChange={(x) => console.log(x)} disabled>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a">Option A</Listbox.Option>
@@ -1422,7 +1422,7 @@ describe('Keyboard interactions', () => {
'should be possible to open the listbox with Enter, and focus the selected option',
suppressConsoleLogs(async () => {
render(
<Listbox value="b" onChange={console.log}>
<Listbox value="b" onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a">Option A</Listbox.Option>
@@ -1467,7 +1467,7 @@ describe('Keyboard interactions', () => {
'should be possible to open the listbox with Enter, and focus the selected option (when using the `hidden` render strategy)',
suppressConsoleLogs(async () => {
render(
<Listbox value="b" onChange={console.log}>
<Listbox value="b" onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options unmount={false}>
<Listbox.Option value="a">Option A</Listbox.Option>
@@ -1534,7 +1534,7 @@ describe('Keyboard interactions', () => {
]
let selectedOption = myOptions[1]
render(
<Listbox value={selectedOption} onChange={console.log}>
<Listbox value={selectedOption} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
{myOptions.map((myOption) => (
@@ -1581,7 +1581,7 @@ describe('Keyboard interactions', () => {
'should have no active listbox option when there are no listbox options at all',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options />
</Listbox>
@@ -1605,7 +1605,7 @@ describe('Keyboard interactions', () => {
'should focus the first non disabled listbox option when opening with Enter',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option disabled value="a">
@@ -1640,7 +1640,7 @@ describe('Keyboard interactions', () => {
'should focus the first non disabled listbox option when opening with Enter (jump over multiple disabled ones)',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option disabled value="a">
@@ -1677,7 +1677,7 @@ describe('Keyboard interactions', () => {
'should have no active listbox option upon Enter key press, when there are no non-disabled listbox options',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option disabled value="a">
@@ -1713,7 +1713,7 @@ describe('Keyboard interactions', () => {
'should be possible to close the listbox with Enter when there is no active listboxoption',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a">Option A</Listbox.Option>
@@ -1819,7 +1819,7 @@ describe('Keyboard interactions', () => {
'should be possible to open the listbox with Space',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a">Option A</Listbox.Option>
@@ -1862,7 +1862,7 @@ describe('Keyboard interactions', () => {
'should not be possible to open the listbox with Space when the button is disabled',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log} disabled>
<Listbox value={undefined} onChange={(x) => console.log(x)} disabled>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a">Option A</Listbox.Option>
@@ -1897,7 +1897,7 @@ describe('Keyboard interactions', () => {
'should be possible to open the listbox with Space, and focus the selected option',
suppressConsoleLogs(async () => {
render(
<Listbox value="b" onChange={console.log}>
<Listbox value="b" onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a">Option A</Listbox.Option>
@@ -1942,7 +1942,7 @@ describe('Keyboard interactions', () => {
'should have no active listbox option when there are no listbox options at all',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options />
</Listbox>
@@ -1966,7 +1966,7 @@ describe('Keyboard interactions', () => {
'should focus the first non disabled listbox option when opening with Space',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option disabled value="a">
@@ -2001,7 +2001,7 @@ describe('Keyboard interactions', () => {
'should focus the first non disabled listbox option when opening with Space (jump over multiple disabled ones)',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option disabled value="a">
@@ -2038,7 +2038,7 @@ describe('Keyboard interactions', () => {
'should have no active listbox option upon Space key press, when there are no non-disabled listbox options',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option disabled value="a">
@@ -2142,7 +2142,7 @@ describe('Keyboard interactions', () => {
'should be possible to close an open listbox with Escape',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a">Option A</Listbox.Option>
@@ -2185,7 +2185,7 @@ describe('Keyboard interactions', () => {
'should focus trap when we use Tab',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a">Option A</Listbox.Option>
@@ -2236,7 +2236,7 @@ describe('Keyboard interactions', () => {
'should focus trap when we use Shift+Tab',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a">Option A</Listbox.Option>
@@ -2289,7 +2289,7 @@ describe('Keyboard interactions', () => {
'should be possible to open the listbox with ArrowDown',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a">Option A</Listbox.Option>
@@ -2334,7 +2334,7 @@ describe('Keyboard interactions', () => {
'should not be possible to open the listbox with ArrowDown when the button is disabled',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log} disabled>
<Listbox value={undefined} onChange={(x) => console.log(x)} disabled>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a">Option A</Listbox.Option>
@@ -2369,7 +2369,7 @@ describe('Keyboard interactions', () => {
'should be possible to open the listbox with ArrowDown, and focus the selected option',
suppressConsoleLogs(async () => {
render(
<Listbox value="b" onChange={console.log}>
<Listbox value="b" onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a">Option A</Listbox.Option>
@@ -2414,7 +2414,7 @@ describe('Keyboard interactions', () => {
'should have no active listbox option when there are no listbox options at all',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options />
</Listbox>
@@ -2438,7 +2438,7 @@ describe('Keyboard interactions', () => {
'should be possible to use ArrowDown to navigate the listbox options',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a">Option A</Listbox.Option>
@@ -2484,7 +2484,7 @@ describe('Keyboard interactions', () => {
'should be possible to use ArrowDown to navigate the listbox options and skip the first disabled one',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option disabled value="a">
@@ -2524,7 +2524,7 @@ describe('Keyboard interactions', () => {
'should be possible to use ArrowDown to navigate the listbox options and jump to the first non-disabled one',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option disabled value="a">
@@ -2564,7 +2564,7 @@ describe('Keyboard interactions', () => {
'should be possible to use ArrowRight to navigate the listbox options',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log} horizontal>
<Listbox value={undefined} onChange={(x) => console.log(x)} horizontal>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a">Option A</Listbox.Option>
@@ -2612,7 +2612,7 @@ describe('Keyboard interactions', () => {
'should be possible to open the listbox with ArrowUp and the last option should be active',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a">Option A</Listbox.Option>
@@ -2657,7 +2657,7 @@ describe('Keyboard interactions', () => {
'should not be possible to open the listbox with ArrowUp and the last option should be active when the button is disabled',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log} disabled>
<Listbox value={undefined} onChange={(x) => console.log(x)} disabled>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a">Option A</Listbox.Option>
@@ -2692,7 +2692,7 @@ describe('Keyboard interactions', () => {
'should be possible to open the listbox with ArrowUp, and focus the selected option',
suppressConsoleLogs(async () => {
render(
<Listbox value="b" onChange={console.log}>
<Listbox value="b" onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a">Option A</Listbox.Option>
@@ -2737,7 +2737,7 @@ describe('Keyboard interactions', () => {
'should have no active listbox option when there are no listbox options at all',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options />
</Listbox>
@@ -2761,7 +2761,7 @@ describe('Keyboard interactions', () => {
'should be possible to use ArrowUp to navigate the listbox options and jump to the first non-disabled one',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a">Option A</Listbox.Option>
@@ -2799,7 +2799,7 @@ describe('Keyboard interactions', () => {
'should not be possible to navigate up or down if there is only a single non-disabled option',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option disabled value="a">
@@ -2845,7 +2845,7 @@ describe('Keyboard interactions', () => {
'should be possible to use ArrowUp to navigate the listbox options',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a">Option A</Listbox.Option>
@@ -2902,7 +2902,7 @@ describe('Keyboard interactions', () => {
'should be possible to use ArrowLeft to navigate the listbox options',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log} horizontal>
<Listbox value={undefined} onChange={(x) => console.log(x)} horizontal>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a">Option A</Listbox.Option>
@@ -2960,7 +2960,7 @@ describe('Keyboard interactions', () => {
'should be possible to use the End key to go to the last listbox option',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a">Option A</Listbox.Option>
@@ -2991,7 +2991,7 @@ describe('Keyboard interactions', () => {
'should be possible to use the End key to go to the last non disabled listbox option',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a">Option A</Listbox.Option>
@@ -3027,7 +3027,7 @@ describe('Keyboard interactions', () => {
'should be possible to use the End key to go to the first listbox option if that is the only non-disabled listbox option',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a">Option A</Listbox.Option>
@@ -3062,7 +3062,7 @@ describe('Keyboard interactions', () => {
'should have no active listbox option upon End key press, when there are no non-disabled listbox options',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option disabled value="a">
@@ -3100,7 +3100,7 @@ describe('Keyboard interactions', () => {
'should be possible to use the PageDown key to go to the last listbox option',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a">Option A</Listbox.Option>
@@ -3131,7 +3131,7 @@ describe('Keyboard interactions', () => {
'should be possible to use the PageDown key to go to the last non disabled listbox option',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a">Option A</Listbox.Option>
@@ -3167,7 +3167,7 @@ describe('Keyboard interactions', () => {
'should be possible to use the PageDown key to go to the first listbox option if that is the only non-disabled listbox option',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a">Option A</Listbox.Option>
@@ -3202,7 +3202,7 @@ describe('Keyboard interactions', () => {
'should have no active listbox option upon PageDown key press, when there are no non-disabled listbox options',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option disabled value="a">
@@ -3240,7 +3240,7 @@ describe('Keyboard interactions', () => {
'should be possible to use the Home key to go to the first listbox option',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a">Option A</Listbox.Option>
@@ -3271,7 +3271,7 @@ describe('Keyboard interactions', () => {
'should be possible to use the Home key to go to the first non disabled listbox option',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option disabled value="a">
@@ -3306,7 +3306,7 @@ describe('Keyboard interactions', () => {
'should be possible to use the Home key to go to the last listbox option if that is the only non-disabled listbox option',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option disabled value="a">
@@ -3341,7 +3341,7 @@ describe('Keyboard interactions', () => {
'should have no active listbox option upon Home key press, when there are no non-disabled listbox options',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option disabled value="a">
@@ -3379,7 +3379,7 @@ describe('Keyboard interactions', () => {
'should be possible to use the PageUp key to go to the first listbox option',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a">Option A</Listbox.Option>
@@ -3410,7 +3410,7 @@ describe('Keyboard interactions', () => {
'should be possible to use the PageUp key to go to the first non disabled listbox option',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option disabled value="a">
@@ -3445,7 +3445,7 @@ describe('Keyboard interactions', () => {
'should be possible to use the PageUp key to go to the last listbox option if that is the only non-disabled listbox option',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option disabled value="a">
@@ -3480,7 +3480,7 @@ describe('Keyboard interactions', () => {
'should have no active listbox option upon PageUp key press, when there are no non-disabled listbox options',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option disabled value="a">
@@ -3518,7 +3518,7 @@ describe('Keyboard interactions', () => {
'should be possible to type a full word that has a perfect match',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="alice">alice</Listbox.Option>
@@ -3551,7 +3551,7 @@ describe('Keyboard interactions', () => {
'should be possible to type a partial of a word',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="alice">alice</Listbox.Option>
@@ -3590,7 +3590,7 @@ describe('Keyboard interactions', () => {
'should be possible to type words with spaces',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a">value a</Listbox.Option>
@@ -3629,7 +3629,7 @@ describe('Keyboard interactions', () => {
'should not be possible to search for a disabled option',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="alice">alice</Listbox.Option>
@@ -3664,7 +3664,7 @@ describe('Keyboard interactions', () => {
'should be possible to search for a word (case insensitive)',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="alice">alice</Listbox.Option>
@@ -3697,7 +3697,7 @@ describe('Keyboard interactions', () => {
'should be possible to search for the next occurence',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a">alice</Listbox.Option>
@@ -3731,7 +3731,7 @@ describe('Keyboard interactions', () => {
'should stay on the same item while keystrokes still match',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a">alice</Listbox.Option>
@@ -3807,7 +3807,7 @@ describe('Mouse interactions', () => {
'should focus the Listbox.Button when we click the Listbox.Label',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Label>Label</Listbox.Label>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
@@ -3833,7 +3833,7 @@ describe('Mouse interactions', () => {
'should not focus the Listbox.Button when we right click the Listbox.Label',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Label>Label</Listbox.Label>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
@@ -3859,7 +3859,7 @@ describe('Mouse interactions', () => {
'should be possible to open the listbox on click',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a">Option A</Listbox.Option>
@@ -3898,7 +3898,7 @@ describe('Mouse interactions', () => {
'should not be possible to open the listbox on right click',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a">Item A</Listbox.Option>
@@ -3926,7 +3926,7 @@ describe('Mouse interactions', () => {
'should not be possible to open the listbox on click when the button is disabled',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log} disabled>
<Listbox value={undefined} onChange={(x) => console.log(x)} disabled>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a">Option A</Listbox.Option>
@@ -3958,7 +3958,7 @@ describe('Mouse interactions', () => {
'should be possible to open the listbox on click, and focus the selected option',
suppressConsoleLogs(async () => {
render(
<Listbox value="b" onChange={console.log}>
<Listbox value="b" onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a">Option A</Listbox.Option>
@@ -4000,7 +4000,7 @@ describe('Mouse interactions', () => {
'should be possible to close a listbox on click',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="a">Option A</Listbox.Option>
@@ -4029,7 +4029,7 @@ describe('Mouse interactions', () => {
'should be a no-op when we click outside of a closed listbox',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="alice">alice</Listbox.Option>
@@ -4054,7 +4054,7 @@ describe('Mouse interactions', () => {
'should be possible to click outside of the listbox which should close the listbox',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="alice">alice</Listbox.Option>
@@ -4085,7 +4085,7 @@ describe('Mouse interactions', () => {
suppressConsoleLogs(async () => {
render(
<div>
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="alice">alice</Listbox.Option>
@@ -4094,7 +4094,7 @@ describe('Mouse interactions', () => {
</Listbox.Options>
</Listbox>
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="alice">alice</Listbox.Option>
@@ -4128,7 +4128,7 @@ describe('Mouse interactions', () => {
'should be possible to click outside of the listbox which should close the listbox (even if we press the listbox button)',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="alice">alice</Listbox.Option>
@@ -4160,7 +4160,7 @@ describe('Mouse interactions', () => {
let focusFn = jest.fn()
render(
<div>
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button onFocus={focusFn}>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="alice">alice</Listbox.Option>
@@ -4199,7 +4199,7 @@ describe('Mouse interactions', () => {
'should be possible to hover an option and make it active',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="alice">alice</Listbox.Option>
@@ -4231,7 +4231,7 @@ describe('Mouse interactions', () => {
'should make a listbox option active when you move the mouse over it',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="alice">alice</Listbox.Option>
@@ -4255,7 +4255,7 @@ describe('Mouse interactions', () => {
'should be a no-op when we move the mouse and the listbox option is already active',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="alice">alice</Listbox.Option>
@@ -4285,7 +4285,7 @@ describe('Mouse interactions', () => {
'should be a no-op when we move the mouse and the listbox option is disabled',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="alice">alice</Listbox.Option>
@@ -4311,7 +4311,7 @@ describe('Mouse interactions', () => {
'should not be possible to hover an option that is disabled',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="alice">alice</Listbox.Option>
@@ -4340,7 +4340,7 @@ describe('Mouse interactions', () => {
'should be possible to mouse leave an option and make it inactive',
suppressConsoleLogs(async () => {
render(
<Listbox value="bob" onChange={console.log}>
<Listbox value="bob" onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="alice">alice</Listbox.Option>
@@ -4382,7 +4382,7 @@ describe('Mouse interactions', () => {
'should be possible to mouse leave a disabled option and be a no-op',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="alice">alice</Listbox.Option>
@@ -4516,7 +4516,7 @@ describe('Mouse interactions', () => {
'should be possible focus a listbox option, so that it becomes active',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="alice">alice</Listbox.Option>
@@ -4546,7 +4546,7 @@ describe('Mouse interactions', () => {
'should not be possible to focus a listbox option which is disabled',
suppressConsoleLogs(async () => {
render(
<Listbox value={undefined} onChange={console.log}>
<Listbox value={undefined} onChange={(x) => console.log(x)}>
<Listbox.Button>Trigger</Listbox.Button>
<Listbox.Options>
<Listbox.Option value="alice">alice</Listbox.Option>
@@ -351,13 +351,13 @@ function ListboxFn<
TTag extends ElementType = typeof DEFAULT_LISTBOX_TAG,
TType = string,
TActualType = TType extends (infer U)[] ? U : TType
>(props: ListboxProps<TTag, TType, TActualType>, ref: Ref<TTag>) {
>(props: ListboxProps<TTag, TType, TActualType>, ref: Ref<HTMLElement>) {
let {
value: controlledValue,
defaultValue,
name,
onChange: controlledOnChange,
by = (a, z) => a === z,
by = (a: TActualType, z: TActualType) => a === z,
disabled = false,
horizontal = false,
multiple = false,
@@ -366,7 +366,7 @@ function ListboxFn<
const orientation = horizontal ? 'horizontal' : 'vertical'
let listboxRef = useSyncRefs(ref)
let [value = multiple ? [] : undefined, theirOnChange] = useControllable(
let [value = multiple ? [] : undefined, theirOnChange] = useControllable<any>(
controlledValue,
controlledOnChange,
defaultValue
@@ -397,12 +397,12 @@ function ListboxFn<
: by
)
let isSelected: (value: unknown) => boolean = useCallback(
let isSelected: (value: TActualType) => boolean = useCallback(
(compareValue) =>
match(data.mode, {
[ValueMode.Multi]: () =>
(value as unknown as EnsureArray<TType>).some((option) => compare(option, compareValue)),
[ValueMode.Single]: () => compare(value as TType, compareValue),
[ValueMode.Single]: () => compare(value as TActualType, compareValue),
}),
[value]
)
@@ -586,14 +586,11 @@ interface ButtonRenderPropArg {
value: any
}
type ButtonPropsWeControl =
// | 'type' // We allow this to be overridden
| 'aria-haspopup'
| 'aria-controls'
| 'aria-expanded'
| 'aria-haspopup'
| 'aria-labelledby'
| 'disabled'
| 'onKeyDown'
| 'onClick'
export type ListboxButtonProps<TTag extends ElementType> = Props<
TTag,
@@ -703,13 +700,8 @@ interface LabelRenderPropArg {
open: boolean
disabled: boolean
}
type LabelPropsWeControl = 'ref' | 'onClick'
export type ListboxLabelProps<TTag extends ElementType> = Props<
TTag,
LabelRenderPropArg,
LabelPropsWeControl
>
export type ListboxLabelProps<TTag extends ElementType> = Props<TTag, LabelRenderPropArg>
function LabelFn<TTag extends ElementType = typeof DEFAULT_LABEL_TAG>(
props: ListboxLabelProps<TTag>,
@@ -749,8 +741,8 @@ interface OptionsRenderPropArg {
type OptionsPropsWeControl =
| 'aria-activedescendant'
| 'aria-labelledby'
| 'aria-multiselectable'
| 'aria-orientation'
| 'onKeyDown'
| 'role'
| 'tabIndex'
@@ -906,25 +898,17 @@ interface OptionRenderPropArg {
selected: boolean
disabled: boolean
}
type ListboxOptionPropsWeControl =
| 'role'
| 'tabIndex'
| 'aria-disabled'
| 'aria-selected'
| 'onPointerLeave'
| 'onMouseLeave'
| 'onPointerMove'
| 'onMouseMove'
| 'onFocus'
type OptionPropsWeControl = 'aria-disabled' | 'aria-selected' | 'role' | 'tabIndex'
export type ListboxOptionProps<TTag extends ElementType, TType> = Props<
TTag,
OptionRenderPropArg,
ListboxOptionPropsWeControl | 'value'
> & {
disabled?: boolean
value: TType
}
OptionPropsWeControl,
{
disabled?: boolean
value: TType
}
>
function OptionFn<
TTag extends ElementType = typeof DEFAULT_OPTION_TAG,
@@ -308,14 +308,15 @@ let DEFAULT_BUTTON_TAG = 'button' as const
interface ButtonRenderPropArg {
open: boolean
}
type ButtonPropsWeControl =
// | 'type' // We allow this to be overridden
'aria-haspopup' | 'aria-controls' | 'aria-expanded' | 'onKeyDown' | 'onClick'
type ButtonPropsWeControl = 'aria-controls' | 'aria-expanded' | 'aria-haspopup'
export type MenuButtonProps<TTag extends ElementType> = Props<
TTag,
ButtonRenderPropArg,
ButtonPropsWeControl
ButtonPropsWeControl,
{
disabled?: boolean
}
>
function ButtonFn<TTag extends ElementType = typeof DEFAULT_BUTTON_TAG>(
@@ -405,12 +406,7 @@ let DEFAULT_ITEMS_TAG = 'div' as const
interface ItemsRenderPropArg {
open: boolean
}
type ItemsPropsWeControl =
| 'aria-activedescendant'
| 'aria-labelledby'
| 'onKeyDown'
| 'role'
| 'tabIndex'
type ItemsPropsWeControl = 'aria-activedescendant' | 'aria-labelledby' | 'role' | 'tabIndex'
let ItemsRenderFeatures = Features.RenderStrategy | Features.Static
@@ -586,20 +582,12 @@ interface ItemRenderPropArg {
disabled: boolean
close: () => void
}
type MenuItemPropsWeControl =
| 'role'
| 'tabIndex'
| 'aria-disabled'
| 'onPointerLeave'
| 'onPointerMove'
| 'onMouseLeave'
| 'onMouseMove'
| 'onFocus'
type ItemPropsWeControl = 'aria-disabled' | 'role' | 'tabIndex'
export type MenuItemProps<TTag extends ElementType> = Props<
TTag,
ItemRenderPropArg,
MenuItemPropsWeControl
ItemPropsWeControl
> & {
disabled?: boolean
}
@@ -385,14 +385,15 @@ let DEFAULT_BUTTON_TAG = 'button' as const
interface ButtonRenderPropArg {
open: boolean
}
type ButtonPropsWeControl =
// | 'type' // We allow this to be overridden
'aria-expanded' | 'aria-controls' | 'onKeyDown' | 'onClick'
type ButtonPropsWeControl = 'aria-controls' | 'aria-expanded'
export type PopoverButtonProps<TTag extends ElementType> = Props<
TTag,
ButtonRenderPropArg,
ButtonPropsWeControl
ButtonPropsWeControl,
{
disabled?: boolean
}
>
function ButtonFn<TTag extends ElementType = typeof DEFAULT_BUTTON_TAG>(
@@ -620,7 +621,7 @@ let DEFAULT_OVERLAY_TAG = 'div' as const
interface OverlayRenderPropArg {
open: boolean
}
type OverlayPropsWeControl = 'aria-hidden' | 'onClick'
type OverlayPropsWeControl = 'aria-hidden'
let OverlayRenderFeatures = Features.RenderStrategy | Features.Static
@@ -684,18 +685,19 @@ interface PanelRenderPropArg {
open: boolean
close: (focusableElement?: HTMLElement | MutableRefObject<HTMLElement | null>) => void
}
type PanelPropsWeControl = 'onKeyDown'
let PanelRenderFeatures = Features.RenderStrategy | Features.Static
type PanelPropsWeControl = 'tabIndex'
export type PopoverPanelProps<TTag extends ElementType> = Props<
TTag,
PanelRenderPropArg,
PanelPropsWeControl
> &
PanelPropsWeControl,
PropsForFeatures<typeof PanelRenderFeatures> & {
focus?: boolean
}
>
function PanelFn<TTag extends ElementType = typeof DEFAULT_PANEL_TAG>(
props: PopoverPanelProps<TTag>,
@@ -140,15 +140,16 @@ type RadioGroupPropsWeControl = 'role' | 'aria-labelledby' | 'aria-describedby'
export type RadioGroupProps<TTag extends ElementType, TType> = Props<
TTag,
RadioGroupRenderPropArg<TType>,
RadioGroupPropsWeControl | 'value' | 'defaultValue' | 'onChange' | 'disabled' | 'name' | 'by'
> & {
value?: TType
defaultValue?: TType
onChange?(value: TType): void
by?: (keyof TType & string) | ((a: TType, z: TType) => boolean)
disabled?: boolean
name?: string
}
RadioGroupPropsWeControl,
{
value?: TType
defaultValue?: TType
onChange?(value: TType): void
by?: (keyof TType & string) | ((a: TType, z: TType) => boolean)
disabled?: boolean
name?: string
}
>
function RadioGroupFn<TTag extends ElementType = typeof DEFAULT_RADIO_GROUP_TAG, TType = string>(
props: RadioGroupProps<TTag, TType>,
@@ -161,7 +162,7 @@ function RadioGroupFn<TTag extends ElementType = typeof DEFAULT_RADIO_GROUP_TAG,
defaultValue,
name,
onChange: controlledOnChange,
by = (a, z) => a === z,
by = (a: TType, z: TType) => a === z,
disabled = false,
...theirProps
} = props
@@ -374,23 +375,22 @@ interface OptionRenderPropArg {
active: boolean
disabled: boolean
}
type RadioPropsWeControl =
type OptionPropsWeControl =
| 'aria-checked'
| 'onBlur'
| 'onClick'
| 'onFocus'
| 'ref'
| 'aria-describedby'
| 'aria-lablledby'
| 'role'
| 'tabIndex'
export type RadioOptionProps<TTag extends ElementType, TType> = Props<
TTag,
OptionRenderPropArg,
RadioPropsWeControl | 'value' | 'disabled'
> & {
value: TType
disabled?: boolean
}
OptionPropsWeControl,
{
value: TType
disabled?: boolean
}
>
function OptionFn<
TTag extends ElementType = typeof DEFAULT_OPTION_TAG,
@@ -96,26 +96,24 @@ interface SwitchRenderPropArg {
checked: boolean
}
type SwitchPropsWeControl =
| 'aria-checked'
| 'aria-describedby'
| 'aria-labelledby'
| 'role'
| 'tabIndex'
| 'aria-checked'
| 'aria-labelledby'
| 'aria-describedby'
| 'onClick'
| 'onKeyUp'
| 'onKeyPress'
export type SwitchProps<TTag extends ElementType> = Props<
TTag,
SwitchRenderPropArg,
SwitchPropsWeControl | 'checked' | 'defaultChecked' | 'onChange' | 'name' | 'value'
> & {
checked?: boolean
defaultChecked?: boolean
onChange?(checked: boolean): void
name?: string
value?: string
}
SwitchPropsWeControl,
{
checked?: boolean
defaultChecked?: boolean
onChange?(checked: boolean): void
name?: string
value?: string
}
>
function SwitchFn<TTag extends ElementType = typeof DEFAULT_SWITCH_TAG>(
props: SwitchProps<TTag>,
@@ -209,13 +209,18 @@ interface TabsRenderPropArg {
selectedIndex: number
}
export type TabGroupProps<TTag extends ElementType> = Props<TTag, TabsRenderPropArg> & {
defaultIndex?: number
onChange?: (index: number) => void
selectedIndex?: number
vertical?: boolean
manual?: boolean
}
export type TabGroupProps<TTag extends ElementType> = Props<
TTag,
TabsRenderPropArg,
never,
{
defaultIndex?: number
onChange?: (index: number) => void
selectedIndex?: number
vertical?: boolean
manual?: boolean
}
>
function GroupFn<TTag extends ElementType = typeof DEFAULT_TABS_TAG>(
props: TabGroupProps<TTag>,
@@ -329,15 +334,16 @@ let DEFAULT_LIST_TAG = 'div' as const
interface ListRenderPropArg {
selectedIndex: number
}
type ListPropsWeControl = 'role' | 'aria-orientation'
type ListPropsWeControl = 'aria-orientation' | 'role'
export type TabListProps<TTag extends ElementType> = Props<
TTag,
ListRenderPropArg,
ListPropsWeControl
> & {
//
}
ListPropsWeControl,
{
//
}
>
function ListFn<TTag extends ElementType = typeof DEFAULT_LIST_TAG>(
props: TabListProps<TTag>,
@@ -370,9 +376,7 @@ let DEFAULT_TAB_TAG = 'button' as const
interface TabRenderPropArg {
selected: boolean
}
type TabPropsWeControl =
// | 'type' // We allow this to be overridden
'role' | 'aria-controls' | 'aria-selected' | 'tabIndex'
type TabPropsWeControl = 'aria-controls' | 'aria-selected' | 'role' | 'tabIndex'
export type TabProps<TTag extends ElementType> = Props<
TTag,
@@ -547,9 +551,9 @@ let PanelRenderFeatures = Features.RenderStrategy | Features.Static
export type TabPanelProps<TTag extends ElementType> = Props<
TTag,
PanelRenderPropArg,
PanelPropsWeControl
> &
PropsForFeatures<typeof PanelRenderFeatures>
PanelPropsWeControl,
PropsForFeatures<typeof PanelRenderFeatures> & { id?: string; tabIndex?: number }
>
function PanelFn<TTag extends ElementType = typeof DEFAULT_PANEL_TAG>(
props: TabPanelProps<TTag>,
@@ -74,13 +74,14 @@ export interface TransitionEvents {
afterLeave?: () => void
}
export type TransitionChildProps<TTag extends ReactTag> = Omit<
Props<TTag, TransitionChildRenderPropArg>,
'ref'
> &
export type TransitionChildProps<TTag extends ReactTag> = Props<
TTag,
TransitionChildRenderPropArg,
never,
PropsForFeatures<typeof TransitionChildRenderFeatures> &
TransitionClasses &
TransitionEvents & { appear?: boolean }
TransitionClasses &
TransitionEvents & { appear?: boolean }
>
function useTransitionContext() {
let context = useContext(TransitionContext)
@@ -573,8 +574,10 @@ function ChildFn<TTag extends ElementType = typeof DEFAULT_TRANSITION_CHILD_TAG>
return (
<>
{!hasTransitionContext && hasOpenClosedContext ? (
// @ts-expect-error This is an object
<TransitionRoot ref={ref} {...props} />
) : (
// @ts-expect-error This is an object
<TransitionChild ref={ref} {...props} />
)}
</>
@@ -15,9 +15,7 @@ export enum Features {
Hidden = 1 << 2,
}
export type HiddenProps<TTag extends ElementType> = Props<TTag> & {
features?: Features
}
export type HiddenProps<TTag extends ElementType> = Props<TTag, {}, never, { features?: Features }>
function VisuallyHidden<TTag extends ElementType = typeof DEFAULT_VISUALLY_HIDDEN_TAG>(
props: HiddenProps<TTag>,
@@ -1,9 +1,6 @@
import { fireEvent } from '@testing-library/react'
import { disposables } from '../utils/disposables'
import { pointer } from './fake-pointer'
let d = disposables()
function nextFrame(cb: Function): void {
setImmediate(() => {
setImmediate(() => {
+9 -3
View File
@@ -48,8 +48,12 @@ type ClassNameOverride<TTag extends ReactTag, TSlot = {}> =
export type Props<
TTag extends ReactTag,
TSlot = {},
TOmitableProps extends PropertyKey = never
> = CleanProps<TTag, TOmitableProps> & OurProps<TTag, TSlot> & ClassNameOverride<TTag, TSlot>
TOmitableProps extends PropertyKey = never,
Overrides = {}
> = CleanProps<TTag, TOmitableProps | keyof Overrides> &
OurProps<TTag, TSlot> &
ClassNameOverride<TTag, TSlot> &
Overrides
type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never }
export type XOR<T, U> = T | U extends __
@@ -62,5 +66,7 @@ export type XOR<T, U> = T | U extends __
? (Without<T, U> & U) | (Without<U, T> & T)
: T | U
export type ByComparator<T> = (keyof T & string) | ((a: T, b: T) => boolean)
export type ByComparator<T> =
| (T extends null ? string : keyof T & string)
| ((a: T, b: T) => boolean)
export type EnsureArray<T> = T extends any[] ? T : Expand<T>[]
@@ -1,3 +1,5 @@
// @ts-nocheck
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
@@ -1,3 +1,5 @@
// @ts-nocheck
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
@@ -68,12 +68,12 @@ describe('Default functionality', () => {
})
it('should be possible to add a ref with a different name', () => {
let ref = createRef()
let ref = createRef<HTMLDivElement>()
function MyComponent<T extends ElementType = 'div'>({
innerRef,
...props
}: Props<T> & { innerRef: Ref<HTMLDivElement> }) {
}: Props<T, {}, never, { innerRef?: Ref<HTMLDivElement> }>) {
return <div ref={innerRef} {...props} />
}
+1
View File
@@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Enable native label behavior for `<Switch>` where possible ([#2265](https://github.com/tailwindlabs/headlessui/pull/2265))
- Allow root containers from the `Dialog` component in the `FocusTrap` component ([#2322](https://github.com/tailwindlabs/headlessui/pull/2322))
- Cleanup internal TypeScript types ([#2329](https://github.com/tailwindlabs/headlessui/pull/2329))
## [1.7.11] - 2023-02-24
@@ -357,7 +357,13 @@ export let TransitionChild = defineComponent({
...(appear && show && env.isServer
? {
// Already apply the `enter` and `enterFrom` on the server if required
class: normalizeClass([rest.class, ...enterClasses, ...enterFromClasses]),
class: normalizeClass([
attrs.class,
// @ts-expect-error not explicitly defined
rest.class,
...enterClasses,
...enterFromClasses,
]),
}
: {}),
}
@@ -1,9 +1,6 @@
import { fireEvent } from '@testing-library/dom'
import { disposables } from '../utils/disposables'
import { pointer } from './fake-pointer'
let d = disposables()
function nextFrame(cb: Function): void {
setImmediate(() =>
setImmediate(() => {
@@ -1,6 +1,6 @@
import { mount } from '@vue/test-utils'
import { logDOM, fireEvent, screen } from '@testing-library/dom'
import { DefineComponent, ComponentOptionsWithoutProps, defineComponent } from 'vue'
import { ComponentOptionsWithoutProps, defineComponent } from 'vue'
let mountedWrappers = new Set()
@@ -16,7 +16,7 @@ function resolveContainer(): HTMLElement {
// It's not the most elegant type
// but Props and Emits need to be typed as any and not `{}`
type AnyComponent = DefineComponent<any, any, any, any, any, any, any, any>
type AnyComponent = ReturnType<typeof defineComponent>
export function createRenderTemplate(defaultComponents: Record<string, AnyComponent>) {
return (input: string | ComponentOptionsWithoutProps) => {