add React 18 compatibility (#1326)
* bump dev dependencies to React 18 * setup Jest to include `IS_REACT_ACT_ENVIRONMENT` * prefer `useId` from React 18 if it exists In React 16 & 17, where `useId` doesn't exist, we will fallback to our implementation we have been using up until now. The `useId` exposed by React 18, ensures stable references even in SSR environments. * update expected events React 18 now uses the proper events: - `blur` -> `focusout` - `focus` -> `focusin` * ensure to wait a bit longer This is a bit unfortunate, but since React 18 now does an extra unmount/remount in `StrictMode` to ensure that your code is ConcurrentMode ready, it takes a bit longer to settle what the DOM sees. That said, this is a temporary "hack". We are going to experiment with using tools like Puppeteer/Playwright to run our tests in an actual browser instead to eliminate all the weird details that we have to keep in mind. * prefer `.focus()` over `fireEvent.focus(el)` * abstract `microTask` polyfill code * prefer our `focus(el)` function over `el.focus()` Internally we would still use `el.focus()`, but this allows us to have more control over that `focus` function. * add React 18 to the React Playground * improve hooks for React 18 - Improving the cleanup of useEffect hooks - useIsoMorphicEffect instead of normal useEffect, so that we can use useLayoutEffect to be a bit quicker. * improve disposables - This allows us to add event listeners on a node, and get automatic cleanup once `dispose` gets called. - We also return all the `d.add` calls, so that we can cleanup specific parts only instead of everything or nothing. * reimplement the Transition component to be React 18 ready * wait an additional frame for everything to settle * update playground examples * suppressConsoleLogs for RadioGroup components * update changelog * keep the `to` classes for a smoother transition In the next transition we will remove _all_ classes provided and re-add the once we need. --- Some extra special thanks: - Thanks @silvenon for your initial work on the `transition` events in #926 - Thanks @thecrypticace for doing late-night debugging sessions Co-authored-by: =?UTF-8?q?Matija=20Marohni=C4=87?= <matija.marohnic@gmail.com> Co-authored-by: Jordan Pittman <jordan@cryptica.me>
This commit is contained in:
@@ -35,6 +35,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Mimic browser select on focus when navigating via `Tab` ([#1272](https://github.com/tailwindlabs/headlessui/pull/1272))
|
||||
- Ensure that there is always an active option in the `Combobox` ([#1279](https://github.com/tailwindlabs/headlessui/pull/1279), [#1281](https://github.com/tailwindlabs/headlessui/pull/1281))
|
||||
- Allow `Enter` for form submit in `RadioGroup`, `Switch` and `Combobox` improvements ([#1285](https://github.com/tailwindlabs/headlessui/pull/1285))
|
||||
- add React 18 compatibility ([#1326](https://github.com/tailwindlabs/headlessui/pull/1326))
|
||||
|
||||
### Added
|
||||
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
module.exports = function createJestConfig(root, options) {
|
||||
let { setupFilesAfterEnv = [], transform = {}, ...rest } = options
|
||||
return Object.assign(
|
||||
{
|
||||
rootDir: root,
|
||||
setupFilesAfterEnv: ['<rootDir>../../jest/custom-matchers.ts'],
|
||||
setupFilesAfterEnv: ['<rootDir>../../jest/custom-matchers.ts', ...setupFilesAfterEnv],
|
||||
transform: {
|
||||
'^.+\\.(t|j)sx?$': '@swc/jest',
|
||||
...transform,
|
||||
},
|
||||
},
|
||||
options
|
||||
rest
|
||||
)
|
||||
}
|
||||
|
||||
+1
-1
@@ -39,7 +39,7 @@
|
||||
"devDependencies": {
|
||||
"@swc/core": "^1.2.131",
|
||||
"@swc/jest": "^0.2.17",
|
||||
"@testing-library/jest-dom": "^5.11.9",
|
||||
"@testing-library/jest-dom": "^5.16.4",
|
||||
"@types/node": "^14.14.22",
|
||||
"esbuild": "^0.14.11",
|
||||
"fast-glob": "^3.2.11",
|
||||
|
||||
@@ -1,2 +1,5 @@
|
||||
let create = require('../../jest/create-jest-config.cjs')
|
||||
module.exports = create(__dirname, { displayName: 'React' })
|
||||
module.exports = create(__dirname, {
|
||||
displayName: 'React',
|
||||
setupFilesAfterEnv: ['./jest.setup.js'],
|
||||
})
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
globalThis.IS_REACT_ACT_ENVIRONMENT = true
|
||||
@@ -42,12 +42,12 @@
|
||||
"react-dom": "^16 || ^17 || ^18"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@testing-library/react": "^11.2.3",
|
||||
"@types/react": "16.14.21",
|
||||
"@types/react-dom": "^16.9.0",
|
||||
"@testing-library/react": "^13.0.0",
|
||||
"@types/react": "^17.0.43",
|
||||
"@types/react-dom": "^17.0.14",
|
||||
"esbuild": "^0.11.18",
|
||||
"react": "^16.14.0",
|
||||
"react-dom": "^16.14.0",
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0",
|
||||
"snapshot-diff": "^0.8.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -866,7 +866,7 @@ describe('Keyboard interactions', () => {
|
||||
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getComboboxButton()?.focus()
|
||||
await focus(getComboboxButton())
|
||||
|
||||
// Open combobox
|
||||
await press(Keys.Enter)
|
||||
@@ -915,7 +915,7 @@ describe('Keyboard interactions', () => {
|
||||
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
|
||||
|
||||
// Try to focus the button
|
||||
getComboboxButton()?.focus()
|
||||
await focus(getComboboxButton())
|
||||
|
||||
// Try to open the combobox
|
||||
await press(Keys.Enter)
|
||||
@@ -951,7 +951,7 @@ describe('Keyboard interactions', () => {
|
||||
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getComboboxButton()?.focus()
|
||||
await focus(getComboboxButton())
|
||||
|
||||
// Open combobox
|
||||
await press(Keys.Enter)
|
||||
@@ -1000,7 +1000,7 @@ describe('Keyboard interactions', () => {
|
||||
assertComboboxList({ state: ComboboxState.InvisibleHidden })
|
||||
|
||||
// Focus the button
|
||||
getComboboxButton()?.focus()
|
||||
await focus(getComboboxButton())
|
||||
|
||||
// Open combobox
|
||||
await press(Keys.Enter)
|
||||
@@ -1073,7 +1073,7 @@ describe('Keyboard interactions', () => {
|
||||
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getComboboxButton()?.focus()
|
||||
await focus(getComboboxButton())
|
||||
|
||||
// Open combobox
|
||||
await press(Keys.Enter)
|
||||
@@ -1114,7 +1114,7 @@ describe('Keyboard interactions', () => {
|
||||
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getComboboxButton()?.focus()
|
||||
await focus(getComboboxButton())
|
||||
|
||||
// Open combobox
|
||||
await press(Keys.Enter)
|
||||
@@ -1153,7 +1153,7 @@ describe('Keyboard interactions', () => {
|
||||
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getComboboxButton()?.focus()
|
||||
await focus(getComboboxButton())
|
||||
|
||||
// Open combobox
|
||||
await press(Keys.Space)
|
||||
@@ -1200,7 +1200,7 @@ describe('Keyboard interactions', () => {
|
||||
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getComboboxButton()?.focus()
|
||||
await focus(getComboboxButton())
|
||||
|
||||
// Try to open the combobox
|
||||
await press(Keys.Space)
|
||||
@@ -1238,7 +1238,7 @@ describe('Keyboard interactions', () => {
|
||||
})
|
||||
|
||||
// Focus the button
|
||||
getComboboxButton()?.focus()
|
||||
await focus(getComboboxButton())
|
||||
|
||||
// Open combobox
|
||||
await press(Keys.Space)
|
||||
@@ -1278,7 +1278,7 @@ describe('Keyboard interactions', () => {
|
||||
})
|
||||
|
||||
// Focus the button
|
||||
getComboboxButton()?.focus()
|
||||
await focus(getComboboxButton())
|
||||
|
||||
// Open combobox
|
||||
await press(Keys.Space)
|
||||
@@ -1319,7 +1319,7 @@ describe('Keyboard interactions', () => {
|
||||
})
|
||||
|
||||
// Focus the button
|
||||
getComboboxButton()?.focus()
|
||||
await focus(getComboboxButton())
|
||||
|
||||
// Open combobox
|
||||
await press(Keys.Space)
|
||||
@@ -1358,7 +1358,7 @@ describe('Keyboard interactions', () => {
|
||||
assertComboboxButtonLinkedWithCombobox()
|
||||
|
||||
// Re-focus the button
|
||||
getComboboxButton()?.focus()
|
||||
await focus(getComboboxButton())
|
||||
assertActiveElement(getComboboxButton())
|
||||
|
||||
// Close combobox
|
||||
@@ -1397,7 +1397,7 @@ describe('Keyboard interactions', () => {
|
||||
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getComboboxButton()?.focus()
|
||||
await focus(getComboboxButton())
|
||||
|
||||
// Open combobox
|
||||
await press(Keys.ArrowDown)
|
||||
@@ -1443,7 +1443,7 @@ describe('Keyboard interactions', () => {
|
||||
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getComboboxButton()?.focus()
|
||||
await focus(getComboboxButton())
|
||||
|
||||
// Try to open the combobox
|
||||
await press(Keys.ArrowDown)
|
||||
@@ -1479,7 +1479,7 @@ describe('Keyboard interactions', () => {
|
||||
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getComboboxButton()?.focus()
|
||||
await focus(getComboboxButton())
|
||||
|
||||
// Open combobox
|
||||
await press(Keys.ArrowDown)
|
||||
@@ -1517,7 +1517,7 @@ describe('Keyboard interactions', () => {
|
||||
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getComboboxButton()?.focus()
|
||||
await focus(getComboboxButton())
|
||||
|
||||
// Open combobox
|
||||
await press(Keys.ArrowDown)
|
||||
@@ -1552,7 +1552,7 @@ describe('Keyboard interactions', () => {
|
||||
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getComboboxButton()?.focus()
|
||||
await focus(getComboboxButton())
|
||||
|
||||
// Open combobox
|
||||
await press(Keys.ArrowUp)
|
||||
@@ -1598,7 +1598,7 @@ describe('Keyboard interactions', () => {
|
||||
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getComboboxButton()?.focus()
|
||||
await focus(getComboboxButton())
|
||||
|
||||
// Try to open the combobox
|
||||
await press(Keys.ArrowUp)
|
||||
@@ -1634,7 +1634,7 @@ describe('Keyboard interactions', () => {
|
||||
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getComboboxButton()?.focus()
|
||||
await focus(getComboboxButton())
|
||||
|
||||
// Open combobox
|
||||
await press(Keys.ArrowUp)
|
||||
@@ -1672,7 +1672,7 @@ describe('Keyboard interactions', () => {
|
||||
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getComboboxButton()?.focus()
|
||||
await focus(getComboboxButton())
|
||||
|
||||
// Open combobox
|
||||
await press(Keys.ArrowUp)
|
||||
@@ -1709,7 +1709,7 @@ describe('Keyboard interactions', () => {
|
||||
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getComboboxButton()?.focus()
|
||||
await focus(getComboboxButton())
|
||||
|
||||
// Open combobox
|
||||
await press(Keys.ArrowUp)
|
||||
@@ -1899,7 +1899,7 @@ describe('Keyboard interactions', () => {
|
||||
render(<Example />)
|
||||
|
||||
// Focus the input field
|
||||
getComboboxInput()?.focus()
|
||||
await focus(getComboboxInput())
|
||||
assertActiveElement(getComboboxInput())
|
||||
|
||||
// Press enter (which should submit the form)
|
||||
@@ -2212,7 +2212,7 @@ describe('Keyboard interactions', () => {
|
||||
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the input
|
||||
getComboboxInput()?.focus()
|
||||
await focus(getComboboxInput())
|
||||
|
||||
// Open combobox
|
||||
await press(Keys.ArrowDown)
|
||||
@@ -2258,7 +2258,7 @@ describe('Keyboard interactions', () => {
|
||||
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the input
|
||||
getComboboxInput()?.focus()
|
||||
await focus(getComboboxInput())
|
||||
|
||||
// Try to open the combobox
|
||||
await press(Keys.ArrowDown)
|
||||
@@ -2294,7 +2294,7 @@ describe('Keyboard interactions', () => {
|
||||
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the input
|
||||
getComboboxInput()?.focus()
|
||||
await focus(getComboboxInput())
|
||||
|
||||
// Open combobox
|
||||
await press(Keys.ArrowDown)
|
||||
@@ -2332,7 +2332,7 @@ describe('Keyboard interactions', () => {
|
||||
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the input
|
||||
getComboboxInput()?.focus()
|
||||
await focus(getComboboxInput())
|
||||
|
||||
// Open combobox
|
||||
await press(Keys.ArrowDown)
|
||||
@@ -2527,7 +2527,7 @@ describe('Keyboard interactions', () => {
|
||||
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the input
|
||||
getComboboxInput()?.focus()
|
||||
await focus(getComboboxInput())
|
||||
|
||||
// Open combobox
|
||||
await press(Keys.ArrowUp)
|
||||
@@ -2573,7 +2573,7 @@ describe('Keyboard interactions', () => {
|
||||
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the input
|
||||
getComboboxInput()?.focus()
|
||||
await focus(getComboboxInput())
|
||||
|
||||
// Try to open the combobox
|
||||
await press(Keys.ArrowUp)
|
||||
@@ -2609,7 +2609,7 @@ describe('Keyboard interactions', () => {
|
||||
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the input
|
||||
getComboboxInput()?.focus()
|
||||
await focus(getComboboxInput())
|
||||
|
||||
// Open combobox
|
||||
await press(Keys.ArrowUp)
|
||||
@@ -2647,7 +2647,7 @@ describe('Keyboard interactions', () => {
|
||||
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the input
|
||||
getComboboxInput()?.focus()
|
||||
await focus(getComboboxInput())
|
||||
|
||||
// Open combobox
|
||||
await press(Keys.ArrowUp)
|
||||
@@ -2684,7 +2684,7 @@ describe('Keyboard interactions', () => {
|
||||
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the input
|
||||
getComboboxInput()?.focus()
|
||||
await focus(getComboboxInput())
|
||||
|
||||
// Open combobox
|
||||
await press(Keys.ArrowUp)
|
||||
@@ -2766,7 +2766,7 @@ describe('Keyboard interactions', () => {
|
||||
assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the input
|
||||
getComboboxInput()?.focus()
|
||||
await focus(getComboboxInput())
|
||||
|
||||
// Open combobox
|
||||
await press(Keys.ArrowUp)
|
||||
@@ -3099,7 +3099,7 @@ describe('Keyboard interactions', () => {
|
||||
)
|
||||
|
||||
// Focus the input
|
||||
getComboboxInput()?.focus()
|
||||
await focus(getComboboxInput())
|
||||
|
||||
// Open combobox
|
||||
await press(Keys.ArrowUp)
|
||||
@@ -3243,7 +3243,7 @@ describe('Keyboard interactions', () => {
|
||||
)
|
||||
|
||||
// Focus the input
|
||||
getComboboxInput()?.focus()
|
||||
await focus(getComboboxInput())
|
||||
|
||||
// Open combobox
|
||||
await press(Keys.ArrowUp)
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
assertActiveElement,
|
||||
getByText,
|
||||
} from '../../test-utils/accessibility-assertions'
|
||||
import { click, press, Keys, MouseButton } from '../../test-utils/interactions'
|
||||
import { click, press, focus, Keys, MouseButton } from '../../test-utils/interactions'
|
||||
import { Transition } from '../transitions/transition'
|
||||
|
||||
jest.mock('../../hooks/use-id')
|
||||
@@ -133,7 +133,7 @@ describe('Rendering', () => {
|
||||
)
|
||||
|
||||
// Focus the button
|
||||
getDisclosureButton()?.focus()
|
||||
await focus(getDisclosureButton())
|
||||
|
||||
// Ensure the button is focused
|
||||
assertActiveElement(getDisclosureButton())
|
||||
@@ -174,7 +174,7 @@ describe('Rendering', () => {
|
||||
)
|
||||
|
||||
// Focus the button
|
||||
getDisclosureButton()?.focus()
|
||||
await focus(getDisclosureButton())
|
||||
|
||||
// Ensure the button is focused
|
||||
assertActiveElement(getDisclosureButton())
|
||||
@@ -218,7 +218,7 @@ describe('Rendering', () => {
|
||||
render(<Example />)
|
||||
|
||||
// Focus the button
|
||||
getDisclosureButton()?.focus()
|
||||
await focus(getDisclosureButton())
|
||||
|
||||
// Ensure the button is focused
|
||||
assertActiveElement(getDisclosureButton())
|
||||
@@ -437,7 +437,7 @@ describe('Rendering', () => {
|
||||
)
|
||||
|
||||
// Focus the button
|
||||
getDisclosureButton()?.focus()
|
||||
await focus(getDisclosureButton())
|
||||
|
||||
// Ensure the button is focused
|
||||
assertActiveElement(getDisclosureButton())
|
||||
@@ -474,7 +474,7 @@ describe('Rendering', () => {
|
||||
)
|
||||
|
||||
// Focus the button
|
||||
getDisclosureButton()?.focus()
|
||||
await focus(getDisclosureButton())
|
||||
|
||||
// Ensure the button is focused
|
||||
assertActiveElement(getDisclosureButton())
|
||||
@@ -514,7 +514,7 @@ describe('Rendering', () => {
|
||||
render(<Example />)
|
||||
|
||||
// Focus the button
|
||||
getDisclosureButton()?.focus()
|
||||
await focus(getDisclosureButton())
|
||||
|
||||
// Ensure the button is focused
|
||||
assertActiveElement(getDisclosureButton())
|
||||
@@ -579,14 +579,15 @@ describe('Composition', () => {
|
||||
|
||||
// Wait for all transitions to finish
|
||||
await nextFrame()
|
||||
await nextFrame()
|
||||
|
||||
// Verify that we tracked the `mounts` and `unmounts` in the correct order
|
||||
expect(orderFn.mock.calls).toEqual([
|
||||
['Mounting - Disclosure'],
|
||||
['Mounting - Transition'],
|
||||
['Mounting - Transition.Child'],
|
||||
['Unmounting - Transition.Child'],
|
||||
['Unmounting - Transition'],
|
||||
['Unmounting - Transition.Child'],
|
||||
])
|
||||
})
|
||||
)
|
||||
@@ -611,7 +612,7 @@ describe('Keyboard interactions', () => {
|
||||
assertDisclosurePanel({ state: DisclosureState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getDisclosureButton()?.focus()
|
||||
await focus(getDisclosureButton())
|
||||
|
||||
// Open disclosure
|
||||
await press(Keys.Enter)
|
||||
@@ -646,7 +647,7 @@ describe('Keyboard interactions', () => {
|
||||
assertDisclosurePanel({ state: DisclosureState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getDisclosureButton()?.focus()
|
||||
await focus(getDisclosureButton())
|
||||
|
||||
// Try to open the disclosure
|
||||
await press(Keys.Enter)
|
||||
@@ -677,7 +678,7 @@ describe('Keyboard interactions', () => {
|
||||
assertDisclosurePanel({ state: DisclosureState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getDisclosureButton()?.focus()
|
||||
await focus(getDisclosureButton())
|
||||
|
||||
// Open disclosure
|
||||
await press(Keys.Enter)
|
||||
@@ -717,7 +718,7 @@ describe('Keyboard interactions', () => {
|
||||
assertDisclosurePanel({ state: DisclosureState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getDisclosureButton()?.focus()
|
||||
await focus(getDisclosureButton())
|
||||
|
||||
// Open disclosure
|
||||
await press(Keys.Space)
|
||||
@@ -748,7 +749,7 @@ describe('Keyboard interactions', () => {
|
||||
assertDisclosurePanel({ state: DisclosureState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getDisclosureButton()?.focus()
|
||||
await focus(getDisclosureButton())
|
||||
|
||||
// Try to open the disclosure
|
||||
await press(Keys.Space)
|
||||
@@ -779,7 +780,7 @@ describe('Keyboard interactions', () => {
|
||||
assertDisclosurePanel({ state: DisclosureState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getDisclosureButton()?.focus()
|
||||
await focus(getDisclosureButton())
|
||||
|
||||
// Open disclosure
|
||||
await press(Keys.Space)
|
||||
|
||||
@@ -741,7 +741,7 @@ describe('Keyboard interactions', () => {
|
||||
assertListbox({ state: ListboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Open listbox
|
||||
await press(Keys.Enter)
|
||||
@@ -787,7 +787,7 @@ describe('Keyboard interactions', () => {
|
||||
assertListbox({ state: ListboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Try to open the listbox
|
||||
await press(Keys.Enter)
|
||||
@@ -822,7 +822,7 @@ describe('Keyboard interactions', () => {
|
||||
assertListbox({ state: ListboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Open listbox
|
||||
await press(Keys.Enter)
|
||||
@@ -867,7 +867,7 @@ describe('Keyboard interactions', () => {
|
||||
assertListbox({ state: ListboxState.InvisibleHidden })
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Open listbox
|
||||
await press(Keys.Enter)
|
||||
@@ -936,7 +936,7 @@ describe('Keyboard interactions', () => {
|
||||
assertListbox({ state: ListboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Open listbox
|
||||
await press(Keys.Enter)
|
||||
@@ -973,7 +973,7 @@ describe('Keyboard interactions', () => {
|
||||
assertListbox({ state: ListboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Open listbox
|
||||
await press(Keys.Enter)
|
||||
@@ -1007,7 +1007,7 @@ describe('Keyboard interactions', () => {
|
||||
assertListbox({ state: ListboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Open listbox
|
||||
await press(Keys.Enter)
|
||||
@@ -1044,7 +1044,7 @@ describe('Keyboard interactions', () => {
|
||||
assertListbox({ state: ListboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Open listbox
|
||||
await press(Keys.Enter)
|
||||
@@ -1083,7 +1083,7 @@ describe('Keyboard interactions', () => {
|
||||
assertListbox({ state: ListboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Open listbox
|
||||
await press(Keys.Enter)
|
||||
@@ -1219,7 +1219,7 @@ describe('Keyboard interactions', () => {
|
||||
assertListbox({ state: ListboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Open listbox
|
||||
await press(Keys.Space)
|
||||
@@ -1262,7 +1262,7 @@ describe('Keyboard interactions', () => {
|
||||
assertListbox({ state: ListboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Try to open the listbox
|
||||
await press(Keys.Space)
|
||||
@@ -1297,7 +1297,7 @@ describe('Keyboard interactions', () => {
|
||||
assertListbox({ state: ListboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Open listbox
|
||||
await press(Keys.Space)
|
||||
@@ -1334,7 +1334,7 @@ describe('Keyboard interactions', () => {
|
||||
assertListbox({ state: ListboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Open listbox
|
||||
await press(Keys.Space)
|
||||
@@ -1368,7 +1368,7 @@ describe('Keyboard interactions', () => {
|
||||
assertListbox({ state: ListboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Open listbox
|
||||
await press(Keys.Space)
|
||||
@@ -1405,7 +1405,7 @@ describe('Keyboard interactions', () => {
|
||||
assertListbox({ state: ListboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Open listbox
|
||||
await press(Keys.Space)
|
||||
@@ -1444,7 +1444,7 @@ describe('Keyboard interactions', () => {
|
||||
assertListbox({ state: ListboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Open listbox
|
||||
await press(Keys.Space)
|
||||
@@ -1536,7 +1536,7 @@ describe('Keyboard interactions', () => {
|
||||
)
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Open listbox
|
||||
await press(Keys.Space)
|
||||
@@ -1585,7 +1585,7 @@ describe('Keyboard interactions', () => {
|
||||
assertListbox({ state: ListboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Open listbox
|
||||
await press(Keys.Enter)
|
||||
@@ -1636,7 +1636,7 @@ describe('Keyboard interactions', () => {
|
||||
assertListbox({ state: ListboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Open listbox
|
||||
await press(Keys.Enter)
|
||||
@@ -1689,7 +1689,7 @@ describe('Keyboard interactions', () => {
|
||||
assertListbox({ state: ListboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Open listbox
|
||||
await press(Keys.ArrowDown)
|
||||
@@ -1734,7 +1734,7 @@ describe('Keyboard interactions', () => {
|
||||
assertListbox({ state: ListboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Try to open the listbox
|
||||
await press(Keys.ArrowDown)
|
||||
@@ -1769,7 +1769,7 @@ describe('Keyboard interactions', () => {
|
||||
assertListbox({ state: ListboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Open listbox
|
||||
await press(Keys.ArrowDown)
|
||||
@@ -1806,7 +1806,7 @@ describe('Keyboard interactions', () => {
|
||||
assertListbox({ state: ListboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Open listbox
|
||||
await press(Keys.ArrowDown)
|
||||
@@ -1838,7 +1838,7 @@ describe('Keyboard interactions', () => {
|
||||
assertListbox({ state: ListboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Open listbox
|
||||
await press(Keys.Enter)
|
||||
@@ -1886,7 +1886,7 @@ describe('Keyboard interactions', () => {
|
||||
assertListbox({ state: ListboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Open listbox
|
||||
await press(Keys.Enter)
|
||||
@@ -1928,7 +1928,7 @@ describe('Keyboard interactions', () => {
|
||||
assertListbox({ state: ListboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Open listbox
|
||||
await press(Keys.Enter)
|
||||
@@ -1964,7 +1964,7 @@ describe('Keyboard interactions', () => {
|
||||
assertListbox({ state: ListboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Open listbox
|
||||
await press(Keys.Enter)
|
||||
@@ -2012,7 +2012,7 @@ describe('Keyboard interactions', () => {
|
||||
assertListbox({ state: ListboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Open listbox
|
||||
await press(Keys.ArrowUp)
|
||||
@@ -2057,7 +2057,7 @@ describe('Keyboard interactions', () => {
|
||||
assertListbox({ state: ListboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Try to open the listbox
|
||||
await press(Keys.ArrowUp)
|
||||
@@ -2092,7 +2092,7 @@ describe('Keyboard interactions', () => {
|
||||
assertListbox({ state: ListboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Open listbox
|
||||
await press(Keys.ArrowUp)
|
||||
@@ -2129,7 +2129,7 @@ describe('Keyboard interactions', () => {
|
||||
assertListbox({ state: ListboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Open listbox
|
||||
await press(Keys.ArrowUp)
|
||||
@@ -2165,7 +2165,7 @@ describe('Keyboard interactions', () => {
|
||||
assertListbox({ state: ListboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Open listbox
|
||||
await press(Keys.ArrowUp)
|
||||
@@ -2203,7 +2203,7 @@ describe('Keyboard interactions', () => {
|
||||
assertListbox({ state: ListboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Open listbox
|
||||
await press(Keys.Enter)
|
||||
@@ -2245,7 +2245,7 @@ describe('Keyboard interactions', () => {
|
||||
assertListbox({ state: ListboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Open listbox
|
||||
await press(Keys.ArrowUp)
|
||||
@@ -2302,7 +2302,7 @@ describe('Keyboard interactions', () => {
|
||||
assertListbox({ state: ListboxState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Open listbox
|
||||
await press(Keys.ArrowUp)
|
||||
@@ -2354,7 +2354,7 @@ describe('Keyboard interactions', () => {
|
||||
)
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Open listbox
|
||||
await press(Keys.Enter)
|
||||
@@ -2390,7 +2390,7 @@ describe('Keyboard interactions', () => {
|
||||
)
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Open listbox
|
||||
await press(Keys.Enter)
|
||||
@@ -2494,7 +2494,7 @@ describe('Keyboard interactions', () => {
|
||||
)
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Open listbox
|
||||
await press(Keys.Enter)
|
||||
@@ -2530,7 +2530,7 @@ describe('Keyboard interactions', () => {
|
||||
)
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Open listbox
|
||||
await press(Keys.Enter)
|
||||
@@ -2634,7 +2634,7 @@ describe('Keyboard interactions', () => {
|
||||
)
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Open listbox
|
||||
await press(Keys.ArrowUp)
|
||||
@@ -2773,7 +2773,7 @@ describe('Keyboard interactions', () => {
|
||||
)
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Open listbox
|
||||
await press(Keys.ArrowUp)
|
||||
@@ -2945,7 +2945,7 @@ describe('Keyboard interactions', () => {
|
||||
)
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Open listbox
|
||||
await press(Keys.ArrowUp)
|
||||
@@ -2984,7 +2984,7 @@ describe('Keyboard interactions', () => {
|
||||
)
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Open listbox
|
||||
await press(Keys.ArrowUp)
|
||||
@@ -3025,7 +3025,7 @@ describe('Keyboard interactions', () => {
|
||||
)
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Open listbox
|
||||
await press(Keys.ArrowUp)
|
||||
@@ -3058,7 +3058,7 @@ describe('Keyboard interactions', () => {
|
||||
)
|
||||
|
||||
// Focus the button
|
||||
getListboxButton()?.focus()
|
||||
await focus(getListboxButton())
|
||||
|
||||
// Open listbox
|
||||
await press(Keys.ArrowUp)
|
||||
|
||||
@@ -677,7 +677,7 @@ describe('Keyboard interactions', () => {
|
||||
assertMenu({ state: MenuState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getMenuButton()?.focus()
|
||||
await focus(getMenuButton())
|
||||
|
||||
// Open menu
|
||||
await press(Keys.Enter)
|
||||
@@ -721,7 +721,7 @@ describe('Keyboard interactions', () => {
|
||||
assertMenu({ state: MenuState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getMenuButton()?.focus()
|
||||
await focus(getMenuButton())
|
||||
|
||||
// Try to open the menu
|
||||
await press(Keys.Enter)
|
||||
@@ -748,7 +748,7 @@ describe('Keyboard interactions', () => {
|
||||
assertMenu({ state: MenuState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getMenuButton()?.focus()
|
||||
await focus(getMenuButton())
|
||||
|
||||
// Open menu
|
||||
await press(Keys.Enter)
|
||||
@@ -781,7 +781,7 @@ describe('Keyboard interactions', () => {
|
||||
assertMenu({ state: MenuState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getMenuButton()?.focus()
|
||||
await focus(getMenuButton())
|
||||
|
||||
// Open menu
|
||||
await press(Keys.Enter)
|
||||
@@ -818,7 +818,7 @@ describe('Keyboard interactions', () => {
|
||||
assertMenu({ state: MenuState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getMenuButton()?.focus()
|
||||
await focus(getMenuButton())
|
||||
|
||||
// Open menu
|
||||
await press(Keys.Enter)
|
||||
@@ -857,7 +857,7 @@ describe('Keyboard interactions', () => {
|
||||
assertMenu({ state: MenuState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getMenuButton()?.focus()
|
||||
await focus(getMenuButton())
|
||||
|
||||
// Open menu
|
||||
await press(Keys.Enter)
|
||||
@@ -1041,7 +1041,7 @@ describe('Keyboard interactions', () => {
|
||||
assertMenu({ state: MenuState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getMenuButton()?.focus()
|
||||
await focus(getMenuButton())
|
||||
|
||||
// Open menu
|
||||
await press(Keys.Space)
|
||||
@@ -1083,7 +1083,7 @@ describe('Keyboard interactions', () => {
|
||||
assertMenu({ state: MenuState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getMenuButton()?.focus()
|
||||
await focus(getMenuButton())
|
||||
|
||||
// Try to open the menu
|
||||
await press(Keys.Space)
|
||||
@@ -1110,7 +1110,7 @@ describe('Keyboard interactions', () => {
|
||||
assertMenu({ state: MenuState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getMenuButton()?.focus()
|
||||
await focus(getMenuButton())
|
||||
|
||||
// Open menu
|
||||
await press(Keys.Space)
|
||||
@@ -1143,7 +1143,7 @@ describe('Keyboard interactions', () => {
|
||||
assertMenu({ state: MenuState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getMenuButton()?.focus()
|
||||
await focus(getMenuButton())
|
||||
|
||||
// Open menu
|
||||
await press(Keys.Space)
|
||||
@@ -1180,7 +1180,7 @@ describe('Keyboard interactions', () => {
|
||||
assertMenu({ state: MenuState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getMenuButton()?.focus()
|
||||
await focus(getMenuButton())
|
||||
|
||||
// Open menu
|
||||
await press(Keys.Space)
|
||||
@@ -1219,7 +1219,7 @@ describe('Keyboard interactions', () => {
|
||||
assertMenu({ state: MenuState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getMenuButton()?.focus()
|
||||
await focus(getMenuButton())
|
||||
|
||||
// Open menu
|
||||
await press(Keys.Space)
|
||||
@@ -1331,7 +1331,7 @@ describe('Keyboard interactions', () => {
|
||||
)
|
||||
|
||||
// Focus the button
|
||||
getMenuButton()?.focus()
|
||||
await focus(getMenuButton())
|
||||
|
||||
// Open menu
|
||||
await press(Keys.Space)
|
||||
@@ -1379,7 +1379,7 @@ describe('Keyboard interactions', () => {
|
||||
assertMenu({ state: MenuState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getMenuButton()?.focus()
|
||||
await focus(getMenuButton())
|
||||
|
||||
// Open menu
|
||||
await press(Keys.Enter)
|
||||
@@ -1428,7 +1428,7 @@ describe('Keyboard interactions', () => {
|
||||
assertMenu({ state: MenuState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getMenuButton()?.focus()
|
||||
await focus(getMenuButton())
|
||||
|
||||
// Open menu
|
||||
await press(Keys.Enter)
|
||||
@@ -1479,7 +1479,7 @@ describe('Keyboard interactions', () => {
|
||||
assertMenu({ state: MenuState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getMenuButton()?.focus()
|
||||
await focus(getMenuButton())
|
||||
|
||||
// Open menu
|
||||
await press(Keys.ArrowDown)
|
||||
@@ -1523,7 +1523,7 @@ describe('Keyboard interactions', () => {
|
||||
assertMenu({ state: MenuState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getMenuButton()?.focus()
|
||||
await focus(getMenuButton())
|
||||
|
||||
// Try to open the menu
|
||||
await press(Keys.ArrowDown)
|
||||
@@ -1550,7 +1550,7 @@ describe('Keyboard interactions', () => {
|
||||
assertMenu({ state: MenuState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getMenuButton()?.focus()
|
||||
await focus(getMenuButton())
|
||||
|
||||
// Open menu
|
||||
await press(Keys.ArrowDown)
|
||||
@@ -1581,7 +1581,7 @@ describe('Keyboard interactions', () => {
|
||||
assertMenu({ state: MenuState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getMenuButton()?.focus()
|
||||
await focus(getMenuButton())
|
||||
|
||||
// Open menu
|
||||
await press(Keys.Enter)
|
||||
@@ -1629,7 +1629,7 @@ describe('Keyboard interactions', () => {
|
||||
assertMenu({ state: MenuState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getMenuButton()?.focus()
|
||||
await focus(getMenuButton())
|
||||
|
||||
// Open menu
|
||||
await press(Keys.Enter)
|
||||
@@ -1671,7 +1671,7 @@ describe('Keyboard interactions', () => {
|
||||
assertMenu({ state: MenuState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getMenuButton()?.focus()
|
||||
await focus(getMenuButton())
|
||||
|
||||
// Open menu
|
||||
await press(Keys.Enter)
|
||||
@@ -1707,7 +1707,7 @@ describe('Keyboard interactions', () => {
|
||||
assertMenu({ state: MenuState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getMenuButton()?.focus()
|
||||
await focus(getMenuButton())
|
||||
|
||||
// Open menu
|
||||
await press(Keys.ArrowUp)
|
||||
@@ -1751,7 +1751,7 @@ describe('Keyboard interactions', () => {
|
||||
assertMenu({ state: MenuState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getMenuButton()?.focus()
|
||||
await focus(getMenuButton())
|
||||
|
||||
// Try to open the menu
|
||||
await press(Keys.ArrowUp)
|
||||
@@ -1778,7 +1778,7 @@ describe('Keyboard interactions', () => {
|
||||
assertMenu({ state: MenuState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getMenuButton()?.focus()
|
||||
await focus(getMenuButton())
|
||||
|
||||
// Open menu
|
||||
await press(Keys.ArrowUp)
|
||||
@@ -1813,7 +1813,7 @@ describe('Keyboard interactions', () => {
|
||||
assertMenu({ state: MenuState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getMenuButton()?.focus()
|
||||
await focus(getMenuButton())
|
||||
|
||||
// Open menu
|
||||
await press(Keys.ArrowUp)
|
||||
@@ -1851,7 +1851,7 @@ describe('Keyboard interactions', () => {
|
||||
assertMenu({ state: MenuState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getMenuButton()?.focus()
|
||||
await focus(getMenuButton())
|
||||
|
||||
// Open menu
|
||||
await press(Keys.Enter)
|
||||
@@ -1893,7 +1893,7 @@ describe('Keyboard interactions', () => {
|
||||
assertMenu({ state: MenuState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getMenuButton()?.focus()
|
||||
await focus(getMenuButton())
|
||||
|
||||
// Open menu
|
||||
await press(Keys.ArrowUp)
|
||||
@@ -1943,7 +1943,7 @@ describe('Keyboard interactions', () => {
|
||||
)
|
||||
|
||||
// Focus the button
|
||||
getMenuButton()?.focus()
|
||||
await focus(getMenuButton())
|
||||
|
||||
// Open menu
|
||||
await press(Keys.Enter)
|
||||
@@ -1979,7 +1979,7 @@ describe('Keyboard interactions', () => {
|
||||
)
|
||||
|
||||
// Focus the button
|
||||
getMenuButton()?.focus()
|
||||
await focus(getMenuButton())
|
||||
|
||||
// Open menu
|
||||
await press(Keys.Enter)
|
||||
@@ -2083,7 +2083,7 @@ describe('Keyboard interactions', () => {
|
||||
)
|
||||
|
||||
// Focus the button
|
||||
getMenuButton()?.focus()
|
||||
await focus(getMenuButton())
|
||||
|
||||
// Open menu
|
||||
await press(Keys.Enter)
|
||||
@@ -2119,7 +2119,7 @@ describe('Keyboard interactions', () => {
|
||||
)
|
||||
|
||||
// Focus the button
|
||||
getMenuButton()?.focus()
|
||||
await focus(getMenuButton())
|
||||
|
||||
// Open menu
|
||||
await press(Keys.Enter)
|
||||
@@ -2223,7 +2223,7 @@ describe('Keyboard interactions', () => {
|
||||
)
|
||||
|
||||
// Focus the button
|
||||
getMenuButton()?.focus()
|
||||
await focus(getMenuButton())
|
||||
|
||||
// Open menu
|
||||
await press(Keys.ArrowUp)
|
||||
@@ -2362,7 +2362,7 @@ describe('Keyboard interactions', () => {
|
||||
)
|
||||
|
||||
// Focus the button
|
||||
getMenuButton()?.focus()
|
||||
await focus(getMenuButton())
|
||||
|
||||
// Open menu
|
||||
await press(Keys.ArrowUp)
|
||||
@@ -2534,7 +2534,7 @@ describe('Keyboard interactions', () => {
|
||||
)
|
||||
|
||||
// Focus the button
|
||||
getMenuButton()?.focus()
|
||||
await focus(getMenuButton())
|
||||
|
||||
// Open menu
|
||||
await press(Keys.ArrowUp)
|
||||
@@ -2573,7 +2573,7 @@ describe('Keyboard interactions', () => {
|
||||
)
|
||||
|
||||
// Focus the button
|
||||
getMenuButton()?.focus()
|
||||
await focus(getMenuButton())
|
||||
|
||||
// Open menu
|
||||
await press(Keys.ArrowUp)
|
||||
@@ -2614,7 +2614,7 @@ describe('Keyboard interactions', () => {
|
||||
)
|
||||
|
||||
// Focus the button
|
||||
getMenuButton()?.focus()
|
||||
await focus(getMenuButton())
|
||||
|
||||
// Open menu
|
||||
await press(Keys.ArrowUp)
|
||||
@@ -2647,7 +2647,7 @@ describe('Keyboard interactions', () => {
|
||||
)
|
||||
|
||||
// Focus the button
|
||||
getMenuButton()?.focus()
|
||||
await focus(getMenuButton())
|
||||
|
||||
// Open menu
|
||||
await press(Keys.ArrowUp)
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
assertContainsActiveElement,
|
||||
getPopoverOverlay,
|
||||
} from '../../test-utils/accessibility-assertions'
|
||||
import { click, press, Keys, MouseButton, shift } from '../../test-utils/interactions'
|
||||
import { click, press, focus, Keys, MouseButton, shift } from '../../test-utils/interactions'
|
||||
import { Portal } from '../portal/portal'
|
||||
import { Transition } from '../transitions/transition'
|
||||
|
||||
@@ -156,7 +156,7 @@ describe('Rendering', () => {
|
||||
)
|
||||
|
||||
// Focus the button
|
||||
getPopoverButton()?.focus()
|
||||
await focus(getPopoverButton())
|
||||
|
||||
// Ensure the button is focused
|
||||
assertActiveElement(getPopoverButton())
|
||||
@@ -197,7 +197,7 @@ describe('Rendering', () => {
|
||||
)
|
||||
|
||||
// Focus the button
|
||||
getPopoverButton()?.focus()
|
||||
await focus(getPopoverButton())
|
||||
|
||||
// Ensure the button is focused
|
||||
assertActiveElement(getPopoverButton())
|
||||
@@ -241,7 +241,7 @@ describe('Rendering', () => {
|
||||
render(<Example />)
|
||||
|
||||
// Focus the button
|
||||
getPopoverButton()?.focus()
|
||||
await focus(getPopoverButton())
|
||||
|
||||
// Ensure the button is focused
|
||||
assertActiveElement(getPopoverButton())
|
||||
@@ -431,7 +431,7 @@ describe('Rendering', () => {
|
||||
</Popover>
|
||||
)
|
||||
|
||||
getPopoverButton()?.focus()
|
||||
await focus(getPopoverButton())
|
||||
|
||||
assertPopoverButton({ state: PopoverState.InvisibleHidden })
|
||||
assertPopoverPanel({ state: PopoverState.InvisibleHidden })
|
||||
@@ -462,7 +462,7 @@ describe('Rendering', () => {
|
||||
)
|
||||
|
||||
// Focus the button
|
||||
getPopoverButton()?.focus()
|
||||
await focus(getPopoverButton())
|
||||
|
||||
// Ensure the button is focused
|
||||
assertActiveElement(getPopoverButton())
|
||||
@@ -489,7 +489,7 @@ describe('Rendering', () => {
|
||||
)
|
||||
|
||||
// Focus the button
|
||||
getPopoverButton()?.focus()
|
||||
await focus(getPopoverButton())
|
||||
|
||||
// Ensure the button is focused
|
||||
assertActiveElement(getPopoverButton())
|
||||
@@ -502,7 +502,7 @@ describe('Rendering', () => {
|
||||
assertActiveElement(getByText('Link 1'))
|
||||
|
||||
// Focus the button again
|
||||
getPopoverButton()?.focus()
|
||||
await focus(getPopoverButton())
|
||||
|
||||
// Ensure the Popover is closed again
|
||||
assertPopoverPanel({ state: PopoverState.InvisibleUnmounted })
|
||||
@@ -525,7 +525,7 @@ describe('Rendering', () => {
|
||||
)
|
||||
|
||||
// Focus the button
|
||||
getPopoverButton()?.focus()
|
||||
await focus(getPopoverButton())
|
||||
|
||||
// Ensure the button is focused
|
||||
assertActiveElement(getPopoverButton())
|
||||
@@ -552,7 +552,7 @@ describe('Rendering', () => {
|
||||
)
|
||||
|
||||
// Focus the button
|
||||
getPopoverButton()?.focus()
|
||||
await focus(getPopoverButton())
|
||||
|
||||
// Ensure the button is focused
|
||||
assertActiveElement(getPopoverButton())
|
||||
@@ -579,7 +579,7 @@ describe('Rendering', () => {
|
||||
)
|
||||
|
||||
// Focus the button
|
||||
getPopoverButton()?.focus()
|
||||
await focus(getPopoverButton())
|
||||
|
||||
// Ensure the button is focused
|
||||
assertActiveElement(getPopoverButton())
|
||||
@@ -616,7 +616,7 @@ describe('Rendering', () => {
|
||||
)
|
||||
|
||||
// Focus the button
|
||||
getPopoverButton()?.focus()
|
||||
await focus(getPopoverButton())
|
||||
|
||||
// Ensure the button is focused
|
||||
assertActiveElement(getPopoverButton())
|
||||
@@ -656,7 +656,7 @@ describe('Rendering', () => {
|
||||
render(<Example />)
|
||||
|
||||
// Focus the button
|
||||
getPopoverButton()?.focus()
|
||||
await focus(getPopoverButton())
|
||||
|
||||
// Ensure the button is focused
|
||||
assertActiveElement(getPopoverButton())
|
||||
@@ -715,14 +715,15 @@ describe('Composition', () => {
|
||||
|
||||
// Wait for all transitions to finish
|
||||
await nextFrame()
|
||||
await nextFrame()
|
||||
|
||||
// Verify that we tracked the `mounts` and `unmounts` in the correct order
|
||||
expect(orderFn.mock.calls).toEqual([
|
||||
['Mounting - Popover'],
|
||||
['Mounting - Transition'],
|
||||
['Mounting - Transition.Child'],
|
||||
['Unmounting - Transition.Child'],
|
||||
['Unmounting - Transition'],
|
||||
['Unmounting - Transition.Child'],
|
||||
])
|
||||
})
|
||||
)
|
||||
@@ -747,7 +748,7 @@ describe('Keyboard interactions', () => {
|
||||
assertPopoverPanel({ state: PopoverState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getPopoverButton()?.focus()
|
||||
await focus(getPopoverButton())
|
||||
|
||||
// Open popover
|
||||
await press(Keys.Enter)
|
||||
@@ -782,7 +783,7 @@ describe('Keyboard interactions', () => {
|
||||
assertPopoverPanel({ state: PopoverState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getPopoverButton()?.focus()
|
||||
await focus(getPopoverButton())
|
||||
|
||||
// Try to open the popover
|
||||
await press(Keys.Enter)
|
||||
@@ -813,7 +814,7 @@ describe('Keyboard interactions', () => {
|
||||
assertPopoverPanel({ state: PopoverState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getPopoverButton()?.focus()
|
||||
await focus(getPopoverButton())
|
||||
|
||||
// Open popover
|
||||
await press(Keys.Enter)
|
||||
@@ -918,7 +919,7 @@ describe('Keyboard interactions', () => {
|
||||
)
|
||||
|
||||
// Focus the button
|
||||
getPopoverButton()?.focus()
|
||||
await focus(getPopoverButton())
|
||||
|
||||
// Verify popover is closed
|
||||
assertPopoverButton({ state: PopoverState.InvisibleUnmounted })
|
||||
@@ -953,7 +954,7 @@ describe('Keyboard interactions', () => {
|
||||
)
|
||||
|
||||
// Focus the button
|
||||
getPopoverButton()?.focus()
|
||||
await focus(getPopoverButton())
|
||||
|
||||
// Verify popover is closed
|
||||
assertPopoverButton({ state: PopoverState.InvisibleUnmounted })
|
||||
@@ -1425,7 +1426,7 @@ describe('Keyboard interactions', () => {
|
||||
)
|
||||
|
||||
// Focus the button of the Popover
|
||||
getPopoverButton()?.focus()
|
||||
await focus(getPopoverButton())
|
||||
|
||||
// Open popover
|
||||
await click(getPopoverButton())
|
||||
@@ -1675,7 +1676,7 @@ describe('Keyboard interactions', () => {
|
||||
assertPopoverPanel({ state: PopoverState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getPopoverButton()?.focus()
|
||||
await focus(getPopoverButton())
|
||||
|
||||
// Open popover
|
||||
await press(Keys.Space)
|
||||
@@ -1706,7 +1707,7 @@ describe('Keyboard interactions', () => {
|
||||
assertPopoverPanel({ state: PopoverState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getPopoverButton()?.focus()
|
||||
await focus(getPopoverButton())
|
||||
|
||||
// Try to open the popover
|
||||
await press(Keys.Space)
|
||||
@@ -1737,7 +1738,7 @@ describe('Keyboard interactions', () => {
|
||||
assertPopoverPanel({ state: PopoverState.InvisibleUnmounted })
|
||||
|
||||
// Focus the button
|
||||
getPopoverButton()?.focus()
|
||||
await focus(getPopoverButton())
|
||||
|
||||
// Open popover
|
||||
await press(Keys.Space)
|
||||
@@ -1963,7 +1964,7 @@ describe('Mouse interactions', () => {
|
||||
</Popover>
|
||||
)
|
||||
|
||||
getPopoverButton()?.focus()
|
||||
await focus(getPopoverButton())
|
||||
|
||||
// Open popover
|
||||
await click(getPopoverButton())
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -10,7 +10,7 @@ import {
|
||||
getSwitchLabel,
|
||||
getByText,
|
||||
} from '../../test-utils/accessibility-assertions'
|
||||
import { press, click, Keys } from '../../test-utils/interactions'
|
||||
import { press, click, focus, Keys } from '../../test-utils/interactions'
|
||||
|
||||
jest.mock('../../hooks/use-id')
|
||||
|
||||
@@ -229,7 +229,7 @@ describe('Keyboard interactions', () => {
|
||||
assertSwitch({ state: SwitchState.Off })
|
||||
|
||||
// Focus the switch
|
||||
getSwitch()?.focus()
|
||||
await focus(getSwitch())
|
||||
|
||||
// Toggle
|
||||
await press(Keys.Space)
|
||||
@@ -254,7 +254,7 @@ describe('Keyboard interactions', () => {
|
||||
assertSwitch({ state: SwitchState.Off })
|
||||
|
||||
// Focus the switch
|
||||
getSwitch()?.focus()
|
||||
await focus(getSwitch())
|
||||
|
||||
// Try to toggle
|
||||
await press(Keys.Enter)
|
||||
@@ -284,7 +284,7 @@ describe('Keyboard interactions', () => {
|
||||
render(<Example />)
|
||||
|
||||
// Focus the input field
|
||||
getSwitch()?.focus()
|
||||
await focus(getSwitch())
|
||||
assertActiveElement(getSwitch())
|
||||
|
||||
// Press enter (which should submit the form)
|
||||
@@ -309,7 +309,7 @@ describe('Keyboard interactions', () => {
|
||||
assertSwitch({ state: SwitchState.Off })
|
||||
|
||||
// Focus the switch
|
||||
getSwitch()?.focus()
|
||||
await focus(getSwitch())
|
||||
|
||||
// Expect the switch to be active
|
||||
assertActiveElement(getSwitch())
|
||||
|
||||
@@ -474,7 +474,7 @@ describe('Transitions', () => {
|
||||
|
||||
Render 3: Transition took at least 50ms (yes)
|
||||
- class=\\"enter to\\"
|
||||
+ class=\\"\\""
|
||||
+ class=\\"to\\""
|
||||
`)
|
||||
})
|
||||
|
||||
@@ -525,7 +525,7 @@ describe('Transitions', () => {
|
||||
|
||||
Render 3: Transition took at least 50ms (yes)
|
||||
- class=\\"enter to\\"
|
||||
+ class=\\"\\""
|
||||
+ class=\\"to\\""
|
||||
`)
|
||||
})
|
||||
|
||||
@@ -573,7 +573,7 @@ describe('Transitions', () => {
|
||||
|
||||
Render 3: Transition took at least 50ms (yes)
|
||||
- class=\\"enter to\\"
|
||||
+ class=\\"\\""
|
||||
+ class=\\"to\\""
|
||||
`)
|
||||
})
|
||||
|
||||
@@ -622,7 +622,7 @@ describe('Transitions', () => {
|
||||
|
||||
Render 3: Transition took at least 50ms (yes)
|
||||
- class=\\"enter to\\"
|
||||
+ class=\\"\\""
|
||||
+ class=\\"to\\""
|
||||
`)
|
||||
})
|
||||
|
||||
@@ -724,7 +724,7 @@ describe('Transitions', () => {
|
||||
|
||||
Render 3: Transition took at least 50ms (yes)
|
||||
- class=\\"leave to\\"
|
||||
+ class=\\"\\"
|
||||
+ class=\\"to\\"
|
||||
+ hidden=\\"\\"
|
||||
+ style=\\"display: none;\\""
|
||||
`)
|
||||
@@ -794,10 +794,10 @@ describe('Transitions', () => {
|
||||
|
||||
Render 3: Transition took at least 50ms (yes)
|
||||
- class=\\"enter enter-to\\"
|
||||
+ class=\\"\\"
|
||||
+ class=\\"enter-to\\"
|
||||
|
||||
Render 4:
|
||||
- class=\\"\\"
|
||||
- class=\\"enter-to\\"
|
||||
+ class=\\"leave leave-from\\"
|
||||
|
||||
Render 5:
|
||||
@@ -883,10 +883,10 @@ describe('Transitions', () => {
|
||||
|
||||
Render 3: Transition took at least 50ms (yes)
|
||||
- class=\\"enter enter-to\\"
|
||||
+ class=\\"\\"
|
||||
+ class=\\"enter-to\\"
|
||||
|
||||
Render 4:
|
||||
- class=\\"\\"
|
||||
- class=\\"enter-to\\"
|
||||
+ class=\\"leave leave-from\\"
|
||||
|
||||
Render 5:
|
||||
@@ -896,12 +896,12 @@ describe('Transitions', () => {
|
||||
Render 6: Transition took at least 75ms (yes)
|
||||
- class=\\"leave leave-to\\"
|
||||
- style=\\"\\"
|
||||
+ class=\\"\\"
|
||||
+ class=\\"leave-to\\"
|
||||
+ hidden=\\"\\"
|
||||
+ style=\\"display: none;\\"
|
||||
|
||||
Render 7:
|
||||
- class=\\"\\"
|
||||
- class=\\"leave-to\\"
|
||||
- hidden=\\"\\"
|
||||
- style=\\"display: none;\\"
|
||||
+ class=\\"enter enter-from\\"
|
||||
@@ -913,7 +913,7 @@ describe('Transitions', () => {
|
||||
|
||||
Render 9: Transition took at least 75ms (yes)
|
||||
- class=\\"enter enter-to\\"
|
||||
+ class=\\"\\""
|
||||
+ class=\\"enter-to\\""
|
||||
`)
|
||||
})
|
||||
)
|
||||
@@ -1174,10 +1174,10 @@ describe('Events', () => {
|
||||
|
||||
Render 3: Transition took at least 50ms (yes)
|
||||
- class=\\"enter enter-to\\"
|
||||
+ class=\\"\\"
|
||||
+ class=\\"enter-to\\"
|
||||
|
||||
Render 4:
|
||||
- class=\\"\\"
|
||||
- class=\\"enter-to\\"
|
||||
+ class=\\"leave leave-from\\"
|
||||
|
||||
Render 5:
|
||||
|
||||
@@ -13,13 +13,6 @@ import React, {
|
||||
Ref,
|
||||
} from 'react'
|
||||
import { Props } from '../../types'
|
||||
|
||||
import { useId } from '../../hooks/use-id'
|
||||
import { useIsInitialRender } from '../../hooks/use-is-initial-render'
|
||||
import { match } from '../../utils/match'
|
||||
import { useIsMounted } from '../../hooks/use-is-mounted'
|
||||
import { useIsoMorphicEffect } from '../../hooks/use-iso-morphic-effect'
|
||||
|
||||
import {
|
||||
Features,
|
||||
forwardRefWithAs,
|
||||
@@ -27,19 +20,21 @@ import {
|
||||
render,
|
||||
RenderStrategy,
|
||||
} from '../../utils/render'
|
||||
import { Reason, transition } from './utils/transition'
|
||||
import { OpenClosedProvider, State, useOpenClosed } from '../../internal/open-closed'
|
||||
import { match } from '../../utils/match'
|
||||
import { microTask } from '../../utils/micro-task'
|
||||
import { useId } from '../../hooks/use-id'
|
||||
import { useIsMounted } from '../../hooks/use-is-mounted'
|
||||
import { useIsoMorphicEffect } from '../../hooks/use-iso-morphic-effect'
|
||||
import { useLatestValue } from '../../hooks/use-latest-value'
|
||||
import { useServerHandoffComplete } from '../../hooks/use-server-handoff-complete'
|
||||
import { useSyncRefs } from '../../hooks/use-sync-refs'
|
||||
import { useLatestValue } from '../../hooks/use-latest-value'
|
||||
import { useTransition } from '../../hooks/use-transition'
|
||||
|
||||
type ID = ReturnType<typeof useId>
|
||||
|
||||
function useSplitClasses(classes: string = '') {
|
||||
return useMemo(
|
||||
() => classes.split(' ').filter((className) => className.trim().length > 1),
|
||||
[classes]
|
||||
)
|
||||
function splitClasses(classes: string = '') {
|
||||
return classes.split(' ').filter((className) => className.trim().length > 1)
|
||||
}
|
||||
|
||||
interface TransitionContextValues {
|
||||
@@ -135,9 +130,11 @@ function useNesting(done?: () => void) {
|
||||
},
|
||||
})
|
||||
|
||||
if (!hasChildren(transitionableChildren) && mounted.current) {
|
||||
doneRef.current?.()
|
||||
}
|
||||
microTask(() => {
|
||||
if (!hasChildren(transitionableChildren) && mounted.current) {
|
||||
doneRef.current?.()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
let register = useLatestValue((childId: ID) => {
|
||||
@@ -220,23 +217,23 @@ let TransitionChild = forwardRefWithAs(function TransitionChild<
|
||||
|
||||
let id = useId()
|
||||
|
||||
let isTransitioning = useRef(false)
|
||||
let transitionInFlight = useRef(false)
|
||||
|
||||
let nesting = useNesting(() => {
|
||||
// When all children have been unmounted we can only hide ourselves if and only if we are not
|
||||
// transitioning ourselves. Otherwise we would unmount before the transitions are finished.
|
||||
if (!isTransitioning.current) {
|
||||
if (!transitionInFlight.current) {
|
||||
setState(TreeStates.Hidden)
|
||||
unregister.current(id)
|
||||
}
|
||||
})
|
||||
|
||||
useIsoMorphicEffect(() => {
|
||||
useEffect(() => {
|
||||
if (!id) return
|
||||
return register.current(id)
|
||||
}, [register, id])
|
||||
|
||||
useIsoMorphicEffect(() => {
|
||||
useEffect(() => {
|
||||
// If we are in another mode than the Hidden mode then ignore
|
||||
if (strategy !== RenderStrategy.Hidden) return
|
||||
if (!id) return
|
||||
@@ -253,16 +250,15 @@ let TransitionChild = forwardRefWithAs(function TransitionChild<
|
||||
})
|
||||
}, [state, id, register, unregister, show, strategy])
|
||||
|
||||
let enterClasses = useSplitClasses(enter)
|
||||
let enterFromClasses = useSplitClasses(enterFrom)
|
||||
let enterToClasses = useSplitClasses(enterTo)
|
||||
|
||||
let enteredClasses = useSplitClasses(entered)
|
||||
|
||||
let leaveClasses = useSplitClasses(leave)
|
||||
let leaveFromClasses = useSplitClasses(leaveFrom)
|
||||
let leaveToClasses = useSplitClasses(leaveTo)
|
||||
|
||||
let classes = useLatestValue({
|
||||
enter: splitClasses(enter),
|
||||
enterFrom: splitClasses(enterFrom),
|
||||
enterTo: splitClasses(enterTo),
|
||||
entered: splitClasses(entered),
|
||||
leave: splitClasses(leave),
|
||||
leaveFrom: splitClasses(leaveFrom),
|
||||
leaveTo: splitClasses(leaveTo),
|
||||
})
|
||||
let events = useEvents({ beforeEnter, afterEnter, beforeLeave, afterLeave })
|
||||
|
||||
let ready = useServerHandoffComplete()
|
||||
@@ -276,69 +272,30 @@ let TransitionChild = forwardRefWithAs(function TransitionChild<
|
||||
// Skipping initial transition
|
||||
let skip = initial && !appear
|
||||
|
||||
useIsoMorphicEffect(() => {
|
||||
let node = container.current
|
||||
if (!node) return
|
||||
if (!ready) return
|
||||
if (skip) return
|
||||
if (show === prevShow.current) return
|
||||
let transitionDirection = (() => {
|
||||
if (!ready) return 'idle'
|
||||
if (skip) return 'idle'
|
||||
if (prevShow.current === show) return 'idle'
|
||||
return show ? 'enter' : 'leave'
|
||||
})() as 'enter' | 'leave' | 'idle'
|
||||
|
||||
isTransitioning.current = true
|
||||
|
||||
if (show) events.current.beforeEnter()
|
||||
if (!show) events.current.beforeLeave()
|
||||
|
||||
return show
|
||||
? transition(
|
||||
node,
|
||||
enterClasses,
|
||||
enterFromClasses,
|
||||
enterToClasses,
|
||||
enteredClasses,
|
||||
(reason) => {
|
||||
isTransitioning.current = false
|
||||
if (reason === Reason.Finished) events.current.afterEnter()
|
||||
}
|
||||
)
|
||||
: transition(
|
||||
node,
|
||||
leaveClasses,
|
||||
leaveFromClasses,
|
||||
leaveToClasses,
|
||||
enteredClasses,
|
||||
(reason) => {
|
||||
isTransitioning.current = false
|
||||
|
||||
if (reason !== Reason.Finished) return
|
||||
|
||||
// When we don't have children anymore we can safely unregister from the parent and hide
|
||||
// ourselves.
|
||||
if (!hasChildren(nesting)) {
|
||||
setState(TreeStates.Hidden)
|
||||
unregister.current(id)
|
||||
events.current.afterLeave()
|
||||
}
|
||||
}
|
||||
)
|
||||
}, [
|
||||
events,
|
||||
id,
|
||||
isTransitioning,
|
||||
unregister,
|
||||
nesting,
|
||||
useTransition({
|
||||
container,
|
||||
skip,
|
||||
show,
|
||||
ready,
|
||||
enterClasses,
|
||||
enterFromClasses,
|
||||
enterToClasses,
|
||||
leaveClasses,
|
||||
leaveFromClasses,
|
||||
leaveToClasses,
|
||||
])
|
||||
classes,
|
||||
events,
|
||||
direction: transitionDirection,
|
||||
onStart: useLatestValue(() => {}),
|
||||
onStop: useLatestValue((direction) => {
|
||||
if (direction === 'leave' && !hasChildren(nesting)) {
|
||||
// When we don't have children anymore we can safely unregister from the parent and hide
|
||||
// ourselves.
|
||||
setState(TreeStates.Hidden)
|
||||
unregister.current(id)
|
||||
}
|
||||
}),
|
||||
})
|
||||
|
||||
useIsoMorphicEffect(() => {
|
||||
useEffect(() => {
|
||||
if (!skip) return
|
||||
|
||||
if (strategy === RenderStrategy.Hidden) {
|
||||
@@ -379,6 +336,9 @@ let TransitionRoot = forwardRefWithAs(function Transition<
|
||||
let { show, appear = false, unmount, ...theirProps } = props as typeof props
|
||||
let transitionRef = useSyncRefs(ref)
|
||||
|
||||
// The TransitionChild will also call this hook, and we have to make sure that we are ready.
|
||||
useServerHandoffComplete()
|
||||
|
||||
let usesOpenClosedState = useOpenClosed()
|
||||
|
||||
if (show === undefined && usesOpenClosedState !== null) {
|
||||
@@ -398,7 +358,23 @@ let TransitionRoot = forwardRefWithAs(function Transition<
|
||||
setState(TreeStates.Hidden)
|
||||
})
|
||||
|
||||
let initial = useIsInitialRender()
|
||||
let [initial, setInitial] = useState(true)
|
||||
|
||||
// Change the `initial` value
|
||||
let changes = useRef([show])
|
||||
useIsoMorphicEffect(() => {
|
||||
// We can skip this effect
|
||||
if (initial === false) {
|
||||
return
|
||||
}
|
||||
|
||||
// Track the changes
|
||||
if (changes.current.at(-1) !== show) {
|
||||
changes.current.push(show)
|
||||
setInitial(false)
|
||||
}
|
||||
}, [changes, show])
|
||||
|
||||
let transitionBag = useMemo<TransitionContextValues>(
|
||||
() => ({ show: show as boolean, appear, initial }),
|
||||
[show, appear, initial]
|
||||
@@ -440,10 +416,14 @@ function Child<TTag extends ElementType = typeof DEFAULT_TRANSITION_CHILD_TAG>(
|
||||
let hasTransitionContext = useContext(TransitionContext) !== null
|
||||
let hasOpenClosedContext = useOpenClosed() !== null
|
||||
|
||||
return !hasTransitionContext && hasOpenClosedContext ? (
|
||||
<TransitionRoot {...props} />
|
||||
) : (
|
||||
<TransitionChild {...props} />
|
||||
return (
|
||||
<>
|
||||
{!hasTransitionContext && hasOpenClosedContext ? (
|
||||
<TransitionRoot {...props} />
|
||||
) : (
|
||||
<TransitionChild {...props} />
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,20 @@ it('should be possible to transition', async () => {
|
||||
)
|
||||
|
||||
await new Promise((resolve) => {
|
||||
transition(element, ['enter'], ['enterFrom'], ['enterTo'], ['entered'], resolve)
|
||||
transition(
|
||||
element,
|
||||
{
|
||||
enter: ['enter'],
|
||||
enterFrom: ['enterFrom'],
|
||||
enterTo: ['enterTo'],
|
||||
leave: [],
|
||||
leaveFrom: [],
|
||||
leaveTo: [],
|
||||
entered: ['entered'],
|
||||
},
|
||||
true, // Show
|
||||
resolve
|
||||
)
|
||||
})
|
||||
|
||||
await new Promise((resolve) => d.nextFrame(resolve))
|
||||
@@ -42,7 +55,7 @@ it('should be possible to transition', async () => {
|
||||
// necessary to put the classes on the element and immediately remove them.
|
||||
|
||||
// Cleanup phase
|
||||
expect(snapshots[2].content).toEqual('<div class="entered"></div>')
|
||||
expect(snapshots[2].content).toEqual('<div class="enterTo entered"></div>')
|
||||
|
||||
d.dispose()
|
||||
})
|
||||
@@ -71,11 +84,24 @@ it('should wait the correct amount of time to finish a transition', async () =>
|
||||
)
|
||||
|
||||
let reason = await new Promise((resolve) => {
|
||||
transition(element, ['enter'], ['enterFrom'], ['enterTo'], ['entered'], resolve)
|
||||
transition(
|
||||
element,
|
||||
{
|
||||
enter: ['enter'],
|
||||
enterFrom: ['enterFrom'],
|
||||
enterTo: ['enterTo'],
|
||||
leave: [],
|
||||
leaveFrom: [],
|
||||
leaveTo: [],
|
||||
entered: ['entered'],
|
||||
},
|
||||
true, // Show
|
||||
resolve
|
||||
)
|
||||
})
|
||||
|
||||
await new Promise((resolve) => d.nextFrame(resolve))
|
||||
expect(reason).toBe(Reason.Finished)
|
||||
expect(reason).toBe(Reason.Ended)
|
||||
|
||||
// Initial render:
|
||||
expect(snapshots[0].content).toEqual(`<div style="transition-duration: ${duration}ms;"></div>`)
|
||||
@@ -98,7 +124,7 @@ it('should wait the correct amount of time to finish a transition', async () =>
|
||||
|
||||
// Cleanup phase
|
||||
expect(snapshots[3].content).toEqual(
|
||||
`<div style="transition-duration: ${duration}ms;" class="entered"></div>`
|
||||
`<div style="transition-duration: ${duration}ms;" class="enterTo entered"></div>`
|
||||
)
|
||||
})
|
||||
|
||||
@@ -128,11 +154,24 @@ it('should keep the delay time into account', async () => {
|
||||
)
|
||||
|
||||
let reason = await new Promise((resolve) => {
|
||||
transition(element, ['enter'], ['enterFrom'], ['enterTo'], ['entered'], resolve)
|
||||
transition(
|
||||
element,
|
||||
{
|
||||
enter: ['enter'],
|
||||
enterFrom: ['enterFrom'],
|
||||
enterTo: ['enterTo'],
|
||||
leave: [],
|
||||
leaveFrom: [],
|
||||
leaveTo: [],
|
||||
entered: ['entered'],
|
||||
},
|
||||
true, // Show
|
||||
resolve
|
||||
)
|
||||
})
|
||||
|
||||
await new Promise((resolve) => d.nextFrame(resolve))
|
||||
expect(reason).toBe(Reason.Finished)
|
||||
expect(reason).toBe(Reason.Ended)
|
||||
|
||||
let estimatedDuration = Number(
|
||||
(snapshots[snapshots.length - 1].recordedAt - snapshots[snapshots.length - 2].recordedAt) /
|
||||
@@ -141,53 +180,3 @@ it('should keep the delay time into account', async () => {
|
||||
|
||||
expect(estimatedDuration).toBeWithinRenderFrame(duration + delayDuration)
|
||||
})
|
||||
|
||||
it('should be possible to cancel a transition at any time', async () => {
|
||||
let d = disposables()
|
||||
|
||||
let snapshots: {
|
||||
content: string
|
||||
recordedAt: bigint
|
||||
relativeTime: number
|
||||
}[] = []
|
||||
let element = document.createElement('div')
|
||||
document.body.appendChild(element)
|
||||
|
||||
// This duration is so overkill, however it will demonstrate that we can cancel transitions.
|
||||
let duration = 5000
|
||||
|
||||
element.style.transitionDuration = `${duration}ms`
|
||||
|
||||
d.add(
|
||||
reportChanges(
|
||||
() => document.body.innerHTML,
|
||||
(content) => {
|
||||
let recordedAt = process.hrtime.bigint()
|
||||
let total = snapshots.length
|
||||
|
||||
snapshots.push({
|
||||
content,
|
||||
recordedAt,
|
||||
relativeTime:
|
||||
total === 0 ? 0 : Number((recordedAt - snapshots[total - 1].recordedAt) / BigInt(1e6)),
|
||||
})
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
expect.assertions(2)
|
||||
|
||||
// Setup the transition
|
||||
let cancel = transition(element, ['enter'], ['enterFrom'], ['enterTo'], ['entered'], (reason) => {
|
||||
expect(reason).toBe(Reason.Cancelled)
|
||||
})
|
||||
|
||||
// Wait for a bit
|
||||
await new Promise((resolve) => setTimeout(resolve, 20))
|
||||
|
||||
// Cancel the transition
|
||||
cancel()
|
||||
await new Promise((resolve) => d.nextFrame(resolve))
|
||||
|
||||
expect(snapshots.map((snapshot) => snapshot.content).join('\n')).not.toContain('enterTo')
|
||||
})
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { once } from '../../../utils/once'
|
||||
import { disposables } from '../../../utils/disposables'
|
||||
import { match } from '../../../utils/match'
|
||||
|
||||
function addClasses(node: HTMLElement, ...classes: string[]) {
|
||||
node && classes.length > 0 && node.classList.add(...classes)
|
||||
@@ -10,7 +11,10 @@ function removeClasses(node: HTMLElement, ...classes: string[]) {
|
||||
}
|
||||
|
||||
export enum Reason {
|
||||
Finished = 'finished',
|
||||
// Transition succesfully ended
|
||||
Ended = 'ended',
|
||||
|
||||
// Transition was cancelled
|
||||
Cancelled = 'cancelled',
|
||||
}
|
||||
|
||||
@@ -22,7 +26,7 @@ function waitForTransition(node: HTMLElement, done: (reason: Reason) => void) {
|
||||
// Safari returns a comma separated list of values, so let's sort them and take the highest value.
|
||||
let { transitionDuration, transitionDelay } = getComputedStyle(node)
|
||||
|
||||
let [durationMs, delaysMs] = [transitionDuration, transitionDelay].map((value) => {
|
||||
let [durationMs, delayMs] = [transitionDuration, transitionDelay].map((value) => {
|
||||
let [resolvedValue = 0] = value
|
||||
.split(',')
|
||||
// Remove falsy we can't work with
|
||||
@@ -34,22 +38,60 @@ function waitForTransition(node: HTMLElement, done: (reason: Reason) => void) {
|
||||
return resolvedValue
|
||||
})
|
||||
|
||||
// Waiting for the transition to end. We could use the `transitionend` event, however when no
|
||||
// actual transition/duration is defined then the `transitionend` event is not fired.
|
||||
//
|
||||
// TODO: Downside is, when you slow down transitions via devtools this timeout is still using the
|
||||
// full 100% speed instead of the 25% or 10%.
|
||||
if (durationMs !== 0) {
|
||||
d.setTimeout(() => {
|
||||
done(Reason.Finished)
|
||||
}, durationMs + delaysMs)
|
||||
let totalDuration = durationMs + delayMs
|
||||
|
||||
if (totalDuration !== 0) {
|
||||
let listeners: (() => void)[] = []
|
||||
|
||||
if (process.env.NODE_ENV === 'test') {
|
||||
listeners.push(
|
||||
d.setTimeout(() => {
|
||||
done(Reason.Ended)
|
||||
listeners.splice(0).forEach((dispose) => dispose())
|
||||
}, totalDuration)
|
||||
)
|
||||
} else {
|
||||
listeners.push(
|
||||
d.addEventListener(
|
||||
node,
|
||||
'transitionrun',
|
||||
() => {
|
||||
// Cleanup "old" listeners
|
||||
listeners.splice(0).forEach((dispose) => dispose())
|
||||
|
||||
// Register new listeners
|
||||
listeners.push(
|
||||
d.addEventListener(
|
||||
node,
|
||||
'transitionend',
|
||||
() => {
|
||||
done(Reason.Ended)
|
||||
listeners.splice(0).forEach((dispose) => dispose())
|
||||
},
|
||||
{ once: true }
|
||||
),
|
||||
d.addEventListener(
|
||||
node,
|
||||
'transitioncancel',
|
||||
() => {
|
||||
done(Reason.Cancelled)
|
||||
listeners.splice(0).forEach((dispose) => dispose())
|
||||
},
|
||||
{ once: true }
|
||||
)
|
||||
)
|
||||
},
|
||||
{ once: true }
|
||||
)
|
||||
)
|
||||
}
|
||||
} else {
|
||||
// No transition is happening, so we should cleanup already. Otherwise we have to wait until we
|
||||
// get disposed.
|
||||
done(Reason.Finished)
|
||||
done(Reason.Ended)
|
||||
}
|
||||
|
||||
// If we get disposed before the timeout runs we should cleanup anyway
|
||||
// If we get disposed before the transition finishes, we should cleanup anyway.
|
||||
d.add(() => done(Reason.Cancelled))
|
||||
|
||||
return d.dispose
|
||||
@@ -57,39 +99,60 @@ function waitForTransition(node: HTMLElement, done: (reason: Reason) => void) {
|
||||
|
||||
export function transition(
|
||||
node: HTMLElement,
|
||||
base: string[],
|
||||
from: string[],
|
||||
to: string[],
|
||||
entered: string[],
|
||||
classes: {
|
||||
enter: string[]
|
||||
enterFrom: string[]
|
||||
enterTo: string[]
|
||||
leave: string[]
|
||||
leaveFrom: string[]
|
||||
leaveTo: string[]
|
||||
entered: string[]
|
||||
},
|
||||
show: boolean,
|
||||
done?: (reason: Reason) => void
|
||||
) {
|
||||
let direction = show ? 'enter' : 'leave'
|
||||
let d = disposables()
|
||||
let _done = done !== undefined ? once(done) : () => {}
|
||||
|
||||
removeClasses(node, ...entered)
|
||||
let base = match(direction, {
|
||||
enter: () => classes.enter,
|
||||
leave: () => classes.leave,
|
||||
})
|
||||
let to = match(direction, {
|
||||
enter: () => classes.enterTo,
|
||||
leave: () => classes.leaveTo,
|
||||
})
|
||||
let from = match(direction, {
|
||||
enter: () => classes.enterFrom,
|
||||
leave: () => classes.leaveFrom,
|
||||
})
|
||||
|
||||
removeClasses(
|
||||
node,
|
||||
...classes.enter,
|
||||
...classes.enterTo,
|
||||
...classes.enterFrom,
|
||||
...classes.leave,
|
||||
...classes.leaveFrom,
|
||||
...classes.leaveTo,
|
||||
...classes.entered
|
||||
)
|
||||
addClasses(node, ...base, ...from)
|
||||
|
||||
d.nextFrame(() => {
|
||||
removeClasses(node, ...from)
|
||||
addClasses(node, ...to)
|
||||
|
||||
d.add(
|
||||
waitForTransition(node, (reason) => {
|
||||
removeClasses(node, ...to, ...base)
|
||||
addClasses(node, ...entered)
|
||||
return _done(reason)
|
||||
})
|
||||
)
|
||||
waitForTransition(node, (reason) => {
|
||||
if (reason === Reason.Ended) {
|
||||
removeClasses(node, ...base)
|
||||
addClasses(node, ...classes.entered)
|
||||
}
|
||||
|
||||
return _done(reason)
|
||||
})
|
||||
})
|
||||
|
||||
// Once we get disposed, we should ensure that we cleanup after ourselves. In case of an unmount,
|
||||
// the node itself will be nullified and will be a no-op. In case of a full transition the classes
|
||||
// are already removed which is also a no-op. However if you go from enter -> leave mid-transition
|
||||
// then we have some leftovers that should be cleaned.
|
||||
d.add(() => removeClasses(node, ...base, ...from, ...to, ...entered))
|
||||
|
||||
// When we get disposed early, than we should also call the done method but switch the reason.
|
||||
d.add(() => _done(Reason.Cancelled))
|
||||
|
||||
return d.dispose
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useState } from 'react'
|
||||
import React from 'react'
|
||||
import { useIsoMorphicEffect } from './use-iso-morphic-effect'
|
||||
import { useServerHandoffComplete } from './use-server-handoff-complete'
|
||||
|
||||
@@ -13,13 +13,17 @@ function generateId() {
|
||||
return ++id
|
||||
}
|
||||
|
||||
export function useId() {
|
||||
let ready = useServerHandoffComplete()
|
||||
let [id, setId] = useState(ready ? generateId : null)
|
||||
export let useId =
|
||||
// Prefer React's `useId` if it's available.
|
||||
// @ts-expect-error - `useId` doesn't exist in React < 18.
|
||||
React.useId ??
|
||||
function useId() {
|
||||
let ready = useServerHandoffComplete()
|
||||
let [id, setId] = React.useState(ready ? generateId : null)
|
||||
|
||||
useIsoMorphicEffect(() => {
|
||||
if (id === null) setId(generateId())
|
||||
}, [id])
|
||||
useIsoMorphicEffect(() => {
|
||||
if (id === null) setId(generateId())
|
||||
}, [id])
|
||||
|
||||
return id != null ? '' + id : undefined
|
||||
}
|
||||
return id != null ? '' + id : undefined
|
||||
}
|
||||
|
||||
@@ -5,6 +5,10 @@ export function useIsInitialRender() {
|
||||
|
||||
useEffect(() => {
|
||||
initial.current = false
|
||||
|
||||
return () => {
|
||||
initial.current = true
|
||||
}
|
||||
}, [])
|
||||
|
||||
return initial.current
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { useRef, useEffect } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { useIsoMorphicEffect } from './use-iso-morphic-effect'
|
||||
|
||||
export function useIsMounted() {
|
||||
let mounted = useRef(false)
|
||||
|
||||
useEffect(() => {
|
||||
useIsoMorphicEffect(() => {
|
||||
mounted.current = true
|
||||
|
||||
return () => {
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { useRef, useEffect } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { useIsoMorphicEffect } from './use-iso-morphic-effect'
|
||||
|
||||
export function useLatestValue<T>(value: T) {
|
||||
let cache = useRef(value)
|
||||
|
||||
useEffect(() => {
|
||||
useIsoMorphicEffect(() => {
|
||||
cache.current = value
|
||||
}, [value])
|
||||
|
||||
|
||||
@@ -1,22 +1,8 @@
|
||||
import { MutableRefObject, useMemo, useRef } from 'react'
|
||||
import { microTask } from '../utils/micro-task'
|
||||
import { useLatestValue } from './use-latest-value'
|
||||
import { useWindowEvent } from './use-window-event'
|
||||
|
||||
// Polyfill
|
||||
function microTask(cb: () => void) {
|
||||
if (typeof queueMicrotask === 'function') {
|
||||
queueMicrotask(cb)
|
||||
} else {
|
||||
Promise.resolve()
|
||||
.then(cb)
|
||||
.catch((e) =>
|
||||
setTimeout(() => {
|
||||
throw e
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
type Container = MutableRefObject<HTMLElement | null> | HTMLElement | null
|
||||
type ContainerCollection = Container[] | Set<Container>
|
||||
type ContainerInput = Container | ContainerCollection
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
import { MutableRefObject, useRef } from 'react'
|
||||
|
||||
import { Reason, transition } from '../components/transitions/utils/transition'
|
||||
import { disposables } from '../utils/disposables'
|
||||
import { match } from '../utils/match'
|
||||
|
||||
import { useDisposables } from './use-disposables'
|
||||
import { useIsMounted } from './use-is-mounted'
|
||||
import { useIsoMorphicEffect } from './use-iso-morphic-effect'
|
||||
import { useLatestValue } from './use-latest-value'
|
||||
|
||||
interface TransitionArgs {
|
||||
container: MutableRefObject<HTMLElement | null>
|
||||
classes: MutableRefObject<{
|
||||
enter: string[]
|
||||
enterFrom: string[]
|
||||
enterTo: string[]
|
||||
|
||||
leave: string[]
|
||||
leaveFrom: string[]
|
||||
leaveTo: string[]
|
||||
|
||||
entered: string[]
|
||||
}>
|
||||
events: MutableRefObject<{
|
||||
beforeEnter: () => void
|
||||
afterEnter: () => void
|
||||
beforeLeave: () => void
|
||||
afterLeave: () => void
|
||||
}>
|
||||
direction: 'enter' | 'leave' | 'idle'
|
||||
onStart: MutableRefObject<(direction: TransitionArgs['direction']) => void>
|
||||
onStop: MutableRefObject<(direction: TransitionArgs['direction']) => void>
|
||||
}
|
||||
|
||||
export function useTransition({
|
||||
container,
|
||||
direction,
|
||||
classes,
|
||||
events,
|
||||
onStart,
|
||||
onStop,
|
||||
}: TransitionArgs) {
|
||||
let mounted = useIsMounted()
|
||||
let d = useDisposables()
|
||||
|
||||
let latestDirection = useLatestValue(direction)
|
||||
|
||||
let beforeEvent = useLatestValue(() => {
|
||||
return match(latestDirection.current, {
|
||||
enter: () => events.current.beforeEnter(),
|
||||
leave: () => events.current.beforeLeave(),
|
||||
idle: () => {},
|
||||
})
|
||||
})
|
||||
|
||||
let afterEvent = useLatestValue(() => {
|
||||
return match(latestDirection.current, {
|
||||
enter: () => events.current.afterEnter(),
|
||||
leave: () => events.current.afterLeave(),
|
||||
idle: () => {},
|
||||
})
|
||||
})
|
||||
|
||||
useIsoMorphicEffect(() => {
|
||||
let dd = disposables()
|
||||
d.add(dd.dispose)
|
||||
|
||||
let node = container.current
|
||||
if (!node) return // We don't have a DOM node (yet)
|
||||
if (latestDirection.current === 'idle') return // We don't need to transition
|
||||
if (!mounted.current) return
|
||||
|
||||
dd.dispose()
|
||||
|
||||
beforeEvent.current()
|
||||
|
||||
onStart.current(latestDirection.current)
|
||||
|
||||
dd.add(
|
||||
transition(node, classes.current, latestDirection.current === 'enter', (reason) => {
|
||||
dd.dispose()
|
||||
|
||||
match(reason, {
|
||||
[Reason.Ended]() {
|
||||
afterEvent.current()
|
||||
onStop.current(latestDirection.current)
|
||||
},
|
||||
[Reason.Cancelled]: () => {},
|
||||
})
|
||||
})
|
||||
)
|
||||
|
||||
return dd.dispose
|
||||
}, [direction])
|
||||
}
|
||||
@@ -47,8 +47,8 @@ describe('Keyboard', () => {
|
||||
Keys.Tab,
|
||||
[
|
||||
event('keydown', 'trigger'),
|
||||
event('blur', 'trigger'),
|
||||
event('focus', 'after'),
|
||||
event('focusout', 'trigger'),
|
||||
event('focusin', 'after'),
|
||||
event('keyup', 'after'),
|
||||
],
|
||||
new Set(),
|
||||
@@ -57,8 +57,8 @@ describe('Keyboard', () => {
|
||||
shift(Keys.Tab),
|
||||
[
|
||||
event('keydown', 'trigger'),
|
||||
event('blur', 'trigger'),
|
||||
event('focus', 'before'),
|
||||
event('focusout', 'trigger'),
|
||||
event('focusin', 'before'),
|
||||
event('keyup', 'before'),
|
||||
],
|
||||
new Set(),
|
||||
@@ -79,8 +79,8 @@ describe('Keyboard', () => {
|
||||
Keys.Tab,
|
||||
[
|
||||
event('keydown', 'trigger'),
|
||||
event('blur', 'trigger'),
|
||||
event('focus', 'after'),
|
||||
event('focusout', 'trigger'),
|
||||
event('focusin', 'after'),
|
||||
event('keyup', 'after'),
|
||||
],
|
||||
new Set<Events>(['onKeyPress']),
|
||||
@@ -89,8 +89,8 @@ describe('Keyboard', () => {
|
||||
shift(Keys.Tab),
|
||||
[
|
||||
event('keydown', 'trigger'),
|
||||
event('blur', 'trigger'),
|
||||
event('focus', 'before'),
|
||||
event('focusout', 'trigger'),
|
||||
event('focusin', 'before'),
|
||||
event('keyup', 'before'),
|
||||
],
|
||||
new Set<Events>(['onKeyPress']),
|
||||
@@ -104,8 +104,8 @@ describe('Keyboard', () => {
|
||||
Keys.Tab,
|
||||
[
|
||||
event('keydown', 'trigger'),
|
||||
event('blur', 'trigger'),
|
||||
event('focus', 'after'),
|
||||
event('focusout', 'trigger'),
|
||||
event('focusin', 'after'),
|
||||
event('keyup', 'after'),
|
||||
],
|
||||
new Set<Events>(['onKeyUp']),
|
||||
@@ -114,8 +114,8 @@ describe('Keyboard', () => {
|
||||
shift(Keys.Tab),
|
||||
[
|
||||
event('keydown', 'trigger'),
|
||||
event('blur', 'trigger'),
|
||||
event('focus', 'before'),
|
||||
event('focusout', 'trigger'),
|
||||
event('focusin', 'before'),
|
||||
event('keyup', 'before'),
|
||||
],
|
||||
new Set<Events>(['onKeyUp']),
|
||||
@@ -126,8 +126,8 @@ describe('Keyboard', () => {
|
||||
Keys.Tab,
|
||||
[
|
||||
event('keydown', 'trigger'),
|
||||
event('blur', 'trigger'),
|
||||
event('focus', 'after'),
|
||||
event('focusout', 'trigger'),
|
||||
event('focusin', 'after'),
|
||||
event('keyup', 'after'),
|
||||
],
|
||||
new Set<Events>(['onBlur']),
|
||||
@@ -136,8 +136,8 @@ describe('Keyboard', () => {
|
||||
shift(Keys.Tab),
|
||||
[
|
||||
event('keydown', 'trigger'),
|
||||
event('blur', 'trigger'),
|
||||
event('focus', 'before'),
|
||||
event('focusout', 'trigger'),
|
||||
event('focusin', 'before'),
|
||||
event('keyup', 'before'),
|
||||
],
|
||||
new Set<Events>(['onBlur']),
|
||||
|
||||
@@ -4,11 +4,13 @@ import { disposables } from '../utils/disposables'
|
||||
let d = disposables()
|
||||
|
||||
function nextFrame(cb: Function): void {
|
||||
setImmediate(() =>
|
||||
setImmediate(() => {
|
||||
setImmediate(() => {
|
||||
cb()
|
||||
setImmediate(() => {
|
||||
cb()
|
||||
})
|
||||
})
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
export let Keys: Record<string, Partial<KeyboardEvent>> = {
|
||||
@@ -282,7 +284,11 @@ export async function focus(element: Document | Element | Window | Node | null)
|
||||
try {
|
||||
if (element === null) return expect(element).not.toBe(null)
|
||||
|
||||
fireEvent.focus(element)
|
||||
if (element instanceof HTMLElement) {
|
||||
element.focus()
|
||||
} else {
|
||||
fireEvent.focus(element)
|
||||
}
|
||||
|
||||
await new Promise(nextFrame)
|
||||
} catch (err) {
|
||||
|
||||
@@ -7,24 +7,41 @@ export function disposables() {
|
||||
queue.push(fn)
|
||||
},
|
||||
|
||||
addEventListener<TEventName extends keyof WindowEventMap>(
|
||||
element: HTMLElement,
|
||||
name: TEventName,
|
||||
listener: (event: WindowEventMap[TEventName]) => any,
|
||||
options?: boolean | AddEventListenerOptions
|
||||
) {
|
||||
element.addEventListener(name, listener as any, options)
|
||||
return api.add(() => element.removeEventListener(name, listener as any, options))
|
||||
},
|
||||
|
||||
requestAnimationFrame(...args: Parameters<typeof requestAnimationFrame>) {
|
||||
let raf = requestAnimationFrame(...args)
|
||||
api.add(() => cancelAnimationFrame(raf))
|
||||
return api.add(() => cancelAnimationFrame(raf))
|
||||
},
|
||||
|
||||
nextFrame(...args: Parameters<typeof requestAnimationFrame>) {
|
||||
api.requestAnimationFrame(() => {
|
||||
api.requestAnimationFrame(...args)
|
||||
return api.requestAnimationFrame(() => {
|
||||
return api.requestAnimationFrame(...args)
|
||||
})
|
||||
},
|
||||
|
||||
setTimeout(...args: Parameters<typeof setTimeout>) {
|
||||
let timer = setTimeout(...args)
|
||||
api.add(() => clearTimeout(timer))
|
||||
return api.add(() => clearTimeout(timer))
|
||||
},
|
||||
|
||||
add(cb: () => void) {
|
||||
disposables.push(cb)
|
||||
return () => {
|
||||
let idx = disposables.indexOf(cb)
|
||||
if (idx >= 0) {
|
||||
let [dispose] = disposables.splice(idx, 1)
|
||||
dispose()
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
dispose() {
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
// Polyfill
|
||||
export function microTask(cb: () => void) {
|
||||
if (typeof queueMicrotask === 'function') {
|
||||
queueMicrotask(cb)
|
||||
} else {
|
||||
Promise.resolve()
|
||||
.then(cb)
|
||||
.catch((e) =>
|
||||
setTimeout(() => {
|
||||
throw e
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
module.exports = {
|
||||
reactStrictMode: true,
|
||||
devIndicators: {
|
||||
autoPrerender: false,
|
||||
},
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
"@headlessui/react": "*",
|
||||
"@popperjs/core": "^2.6.0",
|
||||
"framer-motion": "^6.0.0",
|
||||
"next": "^12.0.8",
|
||||
"react": "16.14.0",
|
||||
"react-dom": "16.14.0",
|
||||
"next": "^12.1.4",
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0",
|
||||
"react-flatpickr": "^3.10.9"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +71,20 @@ export default function Home() {
|
||||
<button onClick={() => setNested(true)}>Show nested</button>
|
||||
{nested && <Nested onClose={() => setNested(false)} />}
|
||||
|
||||
<Transition show={isOpen} as={Fragment} afterLeave={() => console.log('done')}>
|
||||
<div
|
||||
data-preload
|
||||
className="translate-y-4 translate-y-0 translate-y-0 translate-y-4 scale-95 scale-100 scale-100 scale-95 transform transform transform transform transform transform opacity-0 opacity-75 opacity-75 opacity-0 opacity-75 opacity-0 opacity-100 opacity-100 opacity-0 opacity-0 opacity-100 opacity-100 opacity-0 transition transition duration-1000 duration-300 duration-200 duration-300 duration-200 duration-300 duration-75 ease-out ease-in ease-out ease-in ease-out ease-out sm:translate-y-0 sm:translate-y-0 sm:scale-95 sm:scale-100 sm:scale-100 sm:scale-95"
|
||||
/>
|
||||
|
||||
<Transition
|
||||
data-debug="Dialog"
|
||||
show={isOpen}
|
||||
as={Fragment}
|
||||
beforeEnter={() => console.log('[Transition] Before enter')}
|
||||
afterEnter={() => console.log('[Transition] After enter')}
|
||||
beforeLeave={() => console.log('[Transition] Before leave')}
|
||||
afterLeave={() => console.log('[Transition] After leave')}
|
||||
>
|
||||
<Dialog onClose={setIsOpen}>
|
||||
<div className="fixed inset-0 z-10 overflow-y-auto">
|
||||
<div className="flex min-h-screen items-end justify-center px-4 pt-4 pb-20 text-center sm:block sm:p-0">
|
||||
@@ -84,6 +97,10 @@ export default function Home() {
|
||||
leaveFrom="opacity-75"
|
||||
leaveTo="opacity-0"
|
||||
entered="opacity-75"
|
||||
beforeEnter={() => console.log('[Transition.Child] [Overlay] Before enter')}
|
||||
afterEnter={() => console.log('[Transition.Child] [Overlay] After enter')}
|
||||
beforeLeave={() => console.log('[Transition.Child] [Overlay] Before leave')}
|
||||
afterLeave={() => console.log('[Transition.Child] [Overlay] After leave')}
|
||||
>
|
||||
<Dialog.Overlay className="fixed inset-0 bg-gray-500 transition-opacity" />
|
||||
</Transition.Child>
|
||||
@@ -95,6 +112,10 @@ export default function Home() {
|
||||
leave="ease-in transform duration-200"
|
||||
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
|
||||
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
beforeEnter={() => console.log('[Transition.Child] [Panel] Before enter')}
|
||||
afterEnter={() => console.log('[Transition.Child] [Panel] After enter')}
|
||||
beforeLeave={() => console.log('[Transition.Child] [Panel] Before leave')}
|
||||
afterLeave={() => console.log('[Transition.Child] [Panel] After leave')}
|
||||
>
|
||||
{/* This element is to trick the browser into centering the modal contents. */}
|
||||
<span
|
||||
|
||||
@@ -14,6 +14,10 @@ export default function Home() {
|
||||
return (
|
||||
<div className="flex h-full w-screen justify-center bg-gray-50 p-12">
|
||||
<div className="relative inline-block text-left">
|
||||
<div
|
||||
data-preload
|
||||
className="scale-95 scale-100 scale-100 scale-95 transform transform transform transform opacity-0 opacity-100 opacity-100 opacity-0 transition transition duration-1000 duration-1000 ease-out ease-out"
|
||||
/>
|
||||
<Menu>
|
||||
<span className="rounded-md shadow-sm">
|
||||
<Menu.Button className="focus:shadow-outline-blue inline-flex w-full justify-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium leading-5 text-gray-700 transition duration-150 ease-in-out hover:text-gray-500 focus:border-blue-300 focus:outline-none active:bg-gray-50 active:text-gray-800">
|
||||
@@ -35,6 +39,10 @@ export default function Home() {
|
||||
leave="transition duration-1000 ease-out"
|
||||
leaveFrom="transform scale-100 opacity-100"
|
||||
leaveTo="transform scale-95 opacity-0"
|
||||
beforeEnter={() => console.log('Before enter')}
|
||||
afterEnter={() => console.log('After enter')}
|
||||
beforeLeave={() => console.log('Before leave')}
|
||||
afterLeave={() => console.log('After leave')}
|
||||
>
|
||||
<Menu.Items className="absolute right-0 mt-2 w-56 origin-top-right divide-y divide-gray-100 rounded-md border border-gray-200 bg-white shadow-lg outline-none">
|
||||
<div className="px-4 py-3">
|
||||
|
||||
@@ -17,6 +17,10 @@ export default function Home() {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div
|
||||
data-preload
|
||||
className="translate-y-4 translate-y-0 translate-y-0 translate-y-4 opacity-0 opacity-100 opacity-100 opacity-0 opacity-0 opacity-100 opacity-100 opacity-0 duration-300 duration-200 duration-300 duration-200 ease-out ease-in ease-out ease-in sm:translate-y-0 sm:translate-y-0 sm:scale-95 sm:scale-100 sm:scale-100 sm:scale-95"
|
||||
/>
|
||||
<div className="flex space-x-4 p-12">
|
||||
<div className="inline-block p-12">
|
||||
<span className="mt-3 flex w-full rounded-md shadow-sm sm:mt-0 sm:w-auto">
|
||||
@@ -44,21 +48,17 @@ export default function Home() {
|
||||
show={isOpen}
|
||||
className="fixed inset-0 z-10 overflow-y-auto"
|
||||
beforeEnter={() => {
|
||||
addEvent('Before enter')
|
||||
addEvent('[Root] Before enter')
|
||||
}}
|
||||
afterEnter={() => {
|
||||
inputRef.current.focus()
|
||||
addEvent('After enter')
|
||||
inputRef.current?.focus()
|
||||
addEvent('[Root] After enter')
|
||||
}}
|
||||
beforeLeave={() => {
|
||||
addEvent('Before leave (before confirm)')
|
||||
window.confirm('Are you sure?')
|
||||
addEvent('Before leave (after confirm)')
|
||||
addEvent('[Root] Before leave')
|
||||
}}
|
||||
afterLeave={() => {
|
||||
addEvent('After leave (before alert)')
|
||||
window.alert('Consider it done!')
|
||||
addEvent('After leave (after alert)')
|
||||
addEvent('[Root] After leave')
|
||||
setEmail('')
|
||||
}}
|
||||
>
|
||||
@@ -70,6 +70,10 @@ export default function Home() {
|
||||
leave="ease-in duration-200"
|
||||
leaveFrom="opacity-100"
|
||||
leaveTo="opacity-0"
|
||||
beforeEnter={() => addEvent('[Overlay] Before enter')}
|
||||
afterEnter={() => addEvent('[Overlay] After enter')}
|
||||
beforeLeave={() => addEvent('[Overlay] Before leave')}
|
||||
afterLeave={() => addEvent('[Overlay] After leave')}
|
||||
>
|
||||
<div className="fixed inset-0 transition-opacity">
|
||||
<div className="absolute inset-0 bg-gray-500 opacity-75"></div>
|
||||
@@ -88,6 +92,10 @@ export default function Home() {
|
||||
leave="ease-in duration-200"
|
||||
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
|
||||
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
beforeEnter={() => addEvent('[Panel] Before enter')}
|
||||
afterEnter={() => addEvent('[Panel] After enter')}
|
||||
beforeLeave={() => addEvent('[Panel] Before leave')}
|
||||
afterLeave={() => addEvent('[Panel] After leave')}
|
||||
>
|
||||
<div className="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
|
||||
<div className="sm:flex sm:items-start">
|
||||
@@ -131,6 +139,7 @@ export default function Home() {
|
||||
ref={inputRef}
|
||||
value={email}
|
||||
onChange={(event) => setEmail(event.target.value)}
|
||||
type="email"
|
||||
id="email"
|
||||
className="form-input block w-full px-3 sm:text-sm sm:leading-5"
|
||||
placeholder="name@example.com"
|
||||
|
||||
@@ -18,16 +18,27 @@ export default function Home() {
|
||||
</button>
|
||||
</span>
|
||||
|
||||
<div
|
||||
hidden
|
||||
data-preload
|
||||
className="transform transform transform transform rounded-md rounded-md bg-red-500 bg-blue-500 bg-red-500 bg-green-500 bg-green-500 bg-blue-500 bg-white p-4 p-4 opacity-0 opacity-100 opacity-100 opacity-0 shadow shadow transition-colors transition-colors transition-colors transition transition duration-[5s] duration-1000 duration-1000 duration-1000 duration-1000 ease-out ease-in ease-out ease-in"
|
||||
/>
|
||||
|
||||
<Transition
|
||||
show={isOpen}
|
||||
unmount={false}
|
||||
enter="transition ease-out duration-300"
|
||||
enterFrom="transform opacity-0"
|
||||
enterTo="transform opacity-100"
|
||||
leave="transition ease-in duration-300"
|
||||
leaveFrom="transform opacity-100"
|
||||
leaveTo="transform opacity-0"
|
||||
className="rounded-md bg-white p-4 shadow"
|
||||
appear={false}
|
||||
beforeEnter={() => console.log('beforeEnter')}
|
||||
afterEnter={() => console.log('afterEnter')}
|
||||
beforeLeave={() => console.log('beforeLeave')}
|
||||
afterLeave={() => console.log('afterLeave')}
|
||||
enter="transition-colors ease-out duration-[5s]"
|
||||
enterFrom="transform bg-red-500"
|
||||
enterTo="transform bg-blue-500"
|
||||
leave="transition-colors ease-in duration-[5s]"
|
||||
leaveFrom="transform bg-blue-500"
|
||||
leaveTo="transform bg-red-500"
|
||||
entered="bg-blue-500"
|
||||
className="h-64 rounded-md p-4 shadow"
|
||||
>
|
||||
Contents to show and hide
|
||||
</Transition>
|
||||
|
||||
@@ -531,65 +531,70 @@
|
||||
"@types/yargs" "^16.0.0"
|
||||
chalk "^4.0.0"
|
||||
|
||||
"@next/env@12.1.0":
|
||||
version "12.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/env/-/env-12.1.0.tgz#73713399399b34aa5a01771fb73272b55b22c314"
|
||||
integrity sha512-nrIgY6t17FQ9xxwH3jj0a6EOiQ/WDHUos35Hghtr+SWN/ntHIQ7UpuvSi0vaLzZVHQWaDupKI+liO5vANcDeTQ==
|
||||
"@next/env@12.1.4":
|
||||
version "12.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@next/env/-/env-12.1.4.tgz#5af629b43075281ecd7f87938802b7cf5b67e94b"
|
||||
integrity sha512-7gQwotJDKnfMxxXd8xJ2vsX5AzyDxO3zou0+QOXX8/unypA6icw5+wf6A62yKZ6qQ4UZHHxS68pb6UV+wNneXg==
|
||||
|
||||
"@next/swc-android-arm64@12.1.0":
|
||||
version "12.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-android-arm64/-/swc-android-arm64-12.1.0.tgz#865ba3a9afc204ff2bdeea49dd64d58705007a39"
|
||||
integrity sha512-/280MLdZe0W03stA69iL+v6I+J1ascrQ6FrXBlXGCsGzrfMaGr7fskMa0T5AhQIVQD4nA/46QQWxG//DYuFBcA==
|
||||
"@next/swc-android-arm-eabi@12.1.4":
|
||||
version "12.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-12.1.4.tgz#c3dae178b7c15ad627d2e9b8dfb38caecb5c4ac7"
|
||||
integrity sha512-FJg/6a3s2YrUaqZ+/DJZzeZqfxbbWrynQMT1C5wlIEq9aDLXCFpPM/PiOyJh0ahxc0XPmi6uo38Poq+GJTuKWw==
|
||||
|
||||
"@next/swc-darwin-arm64@12.1.0":
|
||||
version "12.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-12.1.0.tgz#08e8b411b8accd095009ed12efbc2f1d4d547135"
|
||||
integrity sha512-R8vcXE2/iONJ1Unf5Ptqjk6LRW3bggH+8drNkkzH4FLEQkHtELhvcmJwkXcuipyQCsIakldAXhRbZmm3YN1vXg==
|
||||
"@next/swc-android-arm64@12.1.4":
|
||||
version "12.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-android-arm64/-/swc-android-arm64-12.1.4.tgz#f320d60639e19ecffa1f9034829f2d95502a9a51"
|
||||
integrity sha512-LXraazvQQFBgxIg3Htny6G5V5he9EK7oS4jWtMdTGIikmD/OGByOv8ZjLuVLZLtVm3UIvaAiGtlQSLecxJoJDw==
|
||||
|
||||
"@next/swc-darwin-x64@12.1.0":
|
||||
version "12.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-12.1.0.tgz#fcd684497a76e8feaca88db3c394480ff0b007cd"
|
||||
integrity sha512-ieAz0/J0PhmbZBB8+EA/JGdhRHBogF8BWaeqR7hwveb6SYEIJaDNQy0I+ZN8gF8hLj63bEDxJAs/cEhdnTq+ug==
|
||||
"@next/swc-darwin-arm64@12.1.4":
|
||||
version "12.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-12.1.4.tgz#fd578278312613eddcf3aee26910100509941b63"
|
||||
integrity sha512-SSST/dBymecllZxcqTCcSTCu5o1NKk9I+xcvhn/O9nH6GWjgvGgGkNqLbCarCa0jJ1ukvlBA138FagyrmZ/4rQ==
|
||||
|
||||
"@next/swc-linux-arm-gnueabihf@12.1.0":
|
||||
version "12.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-12.1.0.tgz#9ec6380a27938a5799aaa6035c205b3c478468a7"
|
||||
integrity sha512-njUd9hpl6o6A5d08dC0cKAgXKCzm5fFtgGe6i0eko8IAdtAPbtHxtpre3VeSxdZvuGFh+hb0REySQP9T1ttkog==
|
||||
"@next/swc-darwin-x64@12.1.4":
|
||||
version "12.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-12.1.4.tgz#ace5f80d8c8348efe194f6d7074c6213c52b3944"
|
||||
integrity sha512-p1lwdX0TVjaoDXQVuAkjtxVBbCL/urgxiMCBwuPDO7TikpXtSRivi+mIzBj5q7ypgICFmIAOW3TyupXeoPRAnA==
|
||||
|
||||
"@next/swc-linux-arm64-gnu@12.1.0":
|
||||
version "12.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-12.1.0.tgz#7f4196dff1049cea479607c75b81033ae2dbd093"
|
||||
integrity sha512-OqangJLkRxVxMhDtcb7Qn1xjzFA3s50EIxY7mljbSCLybU+sByPaWAHY4px97ieOlr2y4S0xdPKkQ3BCAwyo6Q==
|
||||
"@next/swc-linux-arm-gnueabihf@12.1.4":
|
||||
version "12.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-12.1.4.tgz#2bf2c83863635f19c71c226a2df936e001cce29c"
|
||||
integrity sha512-67PZlgkCn3TDxacdVft0xqDCL7Io1/C4xbAs0+oSQ0xzp6OzN2RNpuKjHJrJgKd0DsE1XZ9sCP27Qv0591yfyg==
|
||||
|
||||
"@next/swc-linux-arm64-musl@12.1.0":
|
||||
version "12.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-12.1.0.tgz#b445f767569cdc2dddee785ca495e1a88c025566"
|
||||
integrity sha512-hB8cLSt4GdmOpcwRe2UzI5UWn6HHO/vLkr5OTuNvCJ5xGDwpPXelVkYW/0+C3g5axbDW2Tym4S+MQCkkH9QfWA==
|
||||
"@next/swc-linux-arm64-gnu@12.1.4":
|
||||
version "12.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-12.1.4.tgz#d577190f641c9b4b463719dd6b8953b6ba9be8d9"
|
||||
integrity sha512-OnOWixhhw7aU22TQdQLYrgpgFq0oA1wGgnjAiHJ+St7MLj82KTDyM9UcymAMbGYy6nG/TFOOHdTmRMtCRNOw0g==
|
||||
|
||||
"@next/swc-linux-x64-gnu@12.1.0":
|
||||
version "12.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-12.1.0.tgz#67610e9be4fbc987de7535f1bcb17e45fe12f90e"
|
||||
integrity sha512-OKO4R/digvrVuweSw/uBM4nSdyzsBV5EwkUeeG4KVpkIZEe64ZwRpnFB65bC6hGwxIBnTv5NMSnJ+0K/WmG78A==
|
||||
"@next/swc-linux-arm64-musl@12.1.4":
|
||||
version "12.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-12.1.4.tgz#e70ffe70393d8f9242deecdb282ce5a8fd588b14"
|
||||
integrity sha512-UoRMzPZnsAavdWtVylYxH8DNC7Uy0i6RrvNwT4PyQVdfANBn2omsUkcH5lgS2O7oaz0nAYLk1vqyZDO7+tJotA==
|
||||
|
||||
"@next/swc-linux-x64-musl@12.1.0":
|
||||
version "12.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-12.1.0.tgz#ea19a23db08a9f2e34ac30401f774cf7d1669d31"
|
||||
integrity sha512-JohhgAHZvOD3rQY7tlp7NlmvtvYHBYgY0x5ZCecUT6eCCcl9lv6iV3nfu82ErkxNk1H893fqH0FUpznZ/H3pSw==
|
||||
"@next/swc-linux-x64-gnu@12.1.4":
|
||||
version "12.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-12.1.4.tgz#91498a130387fb1961902f2bee55863f8e910cff"
|
||||
integrity sha512-nM+MA/frxlTLUKLJKorctdI20/ugfHRjVEEkcLp/58LGG7slNaP1E5d5dRA1yX6ISjPcQAkywas5VlGCg+uTvA==
|
||||
|
||||
"@next/swc-win32-arm64-msvc@12.1.0":
|
||||
version "12.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-12.1.0.tgz#eadf054fc412085659b98e145435bbba200b5283"
|
||||
integrity sha512-T/3gIE6QEfKIJ4dmJk75v9hhNiYZhQYAoYm4iVo1TgcsuaKLFa+zMPh4056AHiG6n9tn2UQ1CFE8EoybEsqsSw==
|
||||
"@next/swc-linux-x64-musl@12.1.4":
|
||||
version "12.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-12.1.4.tgz#78057b03c148c121553d41521ad38f6c732762ff"
|
||||
integrity sha512-GoRHxkuW4u4yKw734B9SzxJwVdyEJosaZ62P7ifOwcujTxhgBt3y76V2nNUrsSuopcKI2ZTDjaa+2wd5zyeXbA==
|
||||
|
||||
"@next/swc-win32-ia32-msvc@12.1.0":
|
||||
version "12.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-12.1.0.tgz#68faeae10c89f698bf9d28759172b74c9c21bda1"
|
||||
integrity sha512-iwnKgHJdqhIW19H9PRPM9j55V6RdcOo6rX+5imx832BCWzkDbyomWnlzBfr6ByUYfhohb8QuH4hSGEikpPqI0Q==
|
||||
"@next/swc-win32-arm64-msvc@12.1.4":
|
||||
version "12.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-12.1.4.tgz#05bbaabacac23b8edf6caa99eb86b17550a09051"
|
||||
integrity sha512-6TQkQze0ievXwHJcVUrIULwCYVe3ccX6T0JgZ1SiMeXpHxISN7VJF/O8uSCw1JvXZYZ6ud0CJ7nfC5HXivgfPg==
|
||||
|
||||
"@next/swc-win32-x64-msvc@12.1.0":
|
||||
version "12.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-12.1.0.tgz#d27e7e76c87a460a4da99c5bfdb1618dcd6cd064"
|
||||
integrity sha512-aBvcbMwuanDH4EMrL2TthNJy+4nP59Bimn8egqv6GHMVj0a44cU6Au4PjOhLNqEh9l+IpRGBqMTzec94UdC5xg==
|
||||
"@next/swc-win32-ia32-msvc@12.1.4":
|
||||
version "12.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-12.1.4.tgz#8fd2fb48f04a2802e51fc320878bf6b411c1c866"
|
||||
integrity sha512-CsbX/IXuZ5VSmWCpSetG2HD6VO5FTsO39WNp2IR2Ut/uom9XtLDJAZqjQEnbUTLGHuwDKFjrIO3LkhtROXLE/g==
|
||||
|
||||
"@next/swc-win32-x64-msvc@12.1.4":
|
||||
version "12.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-12.1.4.tgz#a72ed44c9b1f850986a30fe36c59e01f8a79b5f3"
|
||||
integrity sha512-JtYuWzKXKLDMgE/xTcFtCm1MiCIRaAc5XYZfYX3n/ZWSI1SJS/GMm+Su0SAHJgRFavJh6U/p998YwO/iGTIgqQ==
|
||||
|
||||
"@nodelib/fs.scandir@2.1.5":
|
||||
version "2.1.5"
|
||||
@@ -722,7 +727,7 @@
|
||||
dependencies:
|
||||
"@jest/create-cache-key-function" "^27.4.2"
|
||||
|
||||
"@testing-library/dom@^7.26.6", "@testing-library/dom@^7.28.1":
|
||||
"@testing-library/dom@^7.26.6":
|
||||
version "7.31.2"
|
||||
resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-7.31.2.tgz#df361db38f5212b88555068ab8119f5d841a8c4a"
|
||||
integrity sha512-3UqjCpey6HiTZT92vODYLPxTBWlM8ZOOjr3LX5F37/VRipW2M1kX6I/Cm4VXzteZqfGfagg8yXywpcOgQBlNsQ==
|
||||
@@ -736,10 +741,24 @@
|
||||
lz-string "^1.4.4"
|
||||
pretty-format "^26.6.2"
|
||||
|
||||
"@testing-library/jest-dom@^5.11.9":
|
||||
version "5.16.2"
|
||||
resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-5.16.2.tgz#f329b36b44aa6149cd6ced9adf567f8b6aa1c959"
|
||||
integrity sha512-6ewxs1MXWwsBFZXIk4nKKskWANelkdUehchEOokHsN8X7c2eKXGw+77aRV63UU8f/DTSVUPLaGxdrj4lN7D/ug==
|
||||
"@testing-library/dom@^8.5.0":
|
||||
version "8.12.0"
|
||||
resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-8.12.0.tgz#fef5e545533fb084175dda6509ee71d7d2f72e23"
|
||||
integrity sha512-rBrJk5WjI02X1edtiUcZhgyhgBhiut96r5Jp8J5qktKdcvLcZpKDW8i2hkGMMItxrghjXuQ5AM6aE0imnFawaw==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.10.4"
|
||||
"@babel/runtime" "^7.12.5"
|
||||
"@types/aria-query" "^4.2.0"
|
||||
aria-query "^5.0.0"
|
||||
chalk "^4.1.0"
|
||||
dom-accessibility-api "^0.5.9"
|
||||
lz-string "^1.4.4"
|
||||
pretty-format "^27.0.2"
|
||||
|
||||
"@testing-library/jest-dom@^5.16.4":
|
||||
version "5.16.4"
|
||||
resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-5.16.4.tgz#938302d7b8b483963a3ae821f1c0808f872245cd"
|
||||
integrity sha512-Gy+IoFutbMQcky0k+bqqumXZ1cTGswLsFqmNLzNdSKkU9KGV2u9oXhukCbbJ9/LRPKiqwxEE8VpV/+YZlfkPUA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.9.2"
|
||||
"@types/testing-library__jest-dom" "^5.9.1"
|
||||
@@ -751,13 +770,14 @@
|
||||
lodash "^4.17.15"
|
||||
redent "^3.0.0"
|
||||
|
||||
"@testing-library/react@^11.2.3":
|
||||
version "11.2.7"
|
||||
resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-11.2.7.tgz#b29e2e95c6765c815786c0bc1d5aed9cb2bf7818"
|
||||
integrity sha512-tzRNp7pzd5QmbtXNG/mhdcl7Awfu/Iz1RaVHY75zTdOkmHCuzMhRL83gWHSgOAcjS3CCbyfwUHMZgRJb4kAfpA==
|
||||
"@testing-library/react@^13.0.0":
|
||||
version "13.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-13.0.0.tgz#8cdaf4667c6c2b082eb0513731551e9db784e8bc"
|
||||
integrity sha512-p0lYA1M7uoEmk2LnCbZLGmHJHyH59sAaZVXChTXlyhV/PRW9LoIh4mdf7tiXsO8BoNG+vN8UnFJff1hbZeXv+w==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.12.5"
|
||||
"@testing-library/dom" "^7.28.1"
|
||||
"@testing-library/dom" "^8.5.0"
|
||||
"@types/react-dom" "*"
|
||||
|
||||
"@testing-library/vue@^5.8.2":
|
||||
version "5.8.2"
|
||||
@@ -875,17 +895,17 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.4.tgz#fcf7205c25dff795ee79af1e30da2c9790808f11"
|
||||
integrity sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==
|
||||
|
||||
"@types/react-dom@^16.9.0":
|
||||
version "16.9.14"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.9.14.tgz#674b8f116645fe5266b40b525777fc6bb8eb3bcd"
|
||||
integrity sha512-FIX2AVmPTGP30OUJ+0vadeIFJJ07Mh1m+U0rxfgyW34p3rTlXI+nlenvAxNn4BP36YyI9IJ/+UJ7Wu22N1pI7A==
|
||||
"@types/react-dom@*", "@types/react-dom@^17.0.14":
|
||||
version "17.0.14"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.14.tgz#c8f917156b652ddf807711f5becbd2ab018dea9f"
|
||||
integrity sha512-H03xwEP1oXmSfl3iobtmQ/2dHF5aBHr8aUMwyGZya6OW45G+xtdzmq6HkncefiBt5JU8DVyaWl/nWZbjZCnzAQ==
|
||||
dependencies:
|
||||
"@types/react" "^16"
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react@16.14.21", "@types/react@^16":
|
||||
version "16.14.21"
|
||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.14.21.tgz#35199b21a278355ec7a3c40003bd6a334bd4ae4a"
|
||||
integrity sha512-rY4DzPKK/4aohyWiDRHS2fotN5rhBSK6/rz1X37KzNna9HJyqtaGAbq9fVttrEPWF5ywpfIP1ITL8Xi2QZn6Eg==
|
||||
"@types/react@*", "@types/react@^17.0.43":
|
||||
version "17.0.43"
|
||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.43.tgz#4adc142887dd4a2601ce730bc56c3436fdb07a55"
|
||||
integrity sha512-8Q+LNpdxf057brvPu1lMtC5Vn7J119xrP1aq4qiaefNioQUYANF/CYeK4NsKorSZyUGJ66g0IM+4bbjwx45o2A==
|
||||
dependencies:
|
||||
"@types/prop-types" "*"
|
||||
"@types/scheduler" "*"
|
||||
@@ -1768,7 +1788,7 @@ diff-sequences@^27.5.1:
|
||||
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.5.1.tgz#eaecc0d327fd68c8d9672a1e64ab8dccb2ef5327"
|
||||
integrity sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==
|
||||
|
||||
dom-accessibility-api@^0.5.6:
|
||||
dom-accessibility-api@^0.5.6, dom-accessibility-api@^0.5.9:
|
||||
version "0.5.13"
|
||||
resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.13.tgz#102ee5f25eacce09bdf1cfa5a298f86da473be4b"
|
||||
integrity sha512-R305kwb5CcMDIpSHUnLyIAp7SrSPBx6F0VfQFB3M75xVMHhXJJIdePYgbPPh1o57vCHNu5QztokWUPsLjWzFqw==
|
||||
@@ -3668,28 +3688,28 @@ natural-compare@^1.4.0:
|
||||
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
|
||||
integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
|
||||
|
||||
next@^12.0.8:
|
||||
version "12.1.0"
|
||||
resolved "https://registry.yarnpkg.com/next/-/next-12.1.0.tgz#c33d753b644be92fc58e06e5a214f143da61dd5d"
|
||||
integrity sha512-s885kWvnIlxsUFHq9UGyIyLiuD0G3BUC/xrH0CEnH5lHEWkwQcHOORgbDF0hbrW9vr/7am4ETfX4A7M6DjrE7Q==
|
||||
next@^12.1.4:
|
||||
version "12.1.4"
|
||||
resolved "https://registry.yarnpkg.com/next/-/next-12.1.4.tgz#597a9bdec7aec778b442c4f6d41afd2c64a54b23"
|
||||
integrity sha512-DA4g97BM4Z0nKtDvCTm58RxdvoQyYzeg0AeVbh0N4Y/D8ELrNu47lQeEgRGF8hV4eQ+Sal90zxrJQQG/mPQ8CQ==
|
||||
dependencies:
|
||||
"@next/env" "12.1.0"
|
||||
"@next/env" "12.1.4"
|
||||
caniuse-lite "^1.0.30001283"
|
||||
postcss "8.4.5"
|
||||
styled-jsx "5.0.0"
|
||||
use-subscription "1.5.1"
|
||||
styled-jsx "5.0.1"
|
||||
optionalDependencies:
|
||||
"@next/swc-android-arm64" "12.1.0"
|
||||
"@next/swc-darwin-arm64" "12.1.0"
|
||||
"@next/swc-darwin-x64" "12.1.0"
|
||||
"@next/swc-linux-arm-gnueabihf" "12.1.0"
|
||||
"@next/swc-linux-arm64-gnu" "12.1.0"
|
||||
"@next/swc-linux-arm64-musl" "12.1.0"
|
||||
"@next/swc-linux-x64-gnu" "12.1.0"
|
||||
"@next/swc-linux-x64-musl" "12.1.0"
|
||||
"@next/swc-win32-arm64-msvc" "12.1.0"
|
||||
"@next/swc-win32-ia32-msvc" "12.1.0"
|
||||
"@next/swc-win32-x64-msvc" "12.1.0"
|
||||
"@next/swc-android-arm-eabi" "12.1.4"
|
||||
"@next/swc-android-arm64" "12.1.4"
|
||||
"@next/swc-darwin-arm64" "12.1.4"
|
||||
"@next/swc-darwin-x64" "12.1.4"
|
||||
"@next/swc-linux-arm-gnueabihf" "12.1.4"
|
||||
"@next/swc-linux-arm64-gnu" "12.1.4"
|
||||
"@next/swc-linux-arm64-musl" "12.1.4"
|
||||
"@next/swc-linux-x64-gnu" "12.1.4"
|
||||
"@next/swc-linux-x64-musl" "12.1.4"
|
||||
"@next/swc-win32-arm64-msvc" "12.1.4"
|
||||
"@next/swc-win32-ia32-msvc" "12.1.4"
|
||||
"@next/swc-win32-x64-msvc" "12.1.4"
|
||||
|
||||
nice-try@^1.0.4:
|
||||
version "1.0.5"
|
||||
@@ -4086,7 +4106,7 @@ pretty-format@^26.1.0, pretty-format@^26.6.2:
|
||||
ansi-styles "^4.0.0"
|
||||
react-is "^17.0.1"
|
||||
|
||||
pretty-format@^27.0.0, pretty-format@^27.5.1:
|
||||
pretty-format@^27.0.0, pretty-format@^27.0.2, pretty-format@^27.5.1:
|
||||
version "27.5.1"
|
||||
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e"
|
||||
integrity sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==
|
||||
@@ -4112,7 +4132,7 @@ prompts@^2.0.1:
|
||||
kleur "^3.0.3"
|
||||
sisteransi "^1.0.5"
|
||||
|
||||
prop-types@^15.5.10, prop-types@^15.6.2:
|
||||
prop-types@^15.5.10:
|
||||
version "15.8.1"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
|
||||
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
|
||||
@@ -4154,15 +4174,13 @@ queue-microtask@^1.2.2:
|
||||
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
|
||||
integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
|
||||
|
||||
react-dom@16.14.0, react-dom@^16.14.0:
|
||||
version "16.14.0"
|
||||
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.14.0.tgz#7ad838ec29a777fb3c75c3a190f661cf92ab8b89"
|
||||
integrity sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==
|
||||
react-dom@^18.0.0:
|
||||
version "18.0.0"
|
||||
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.0.0.tgz#26b88534f8f1dbb80853e1eabe752f24100d8023"
|
||||
integrity sha512-XqX7uzmFo0pUceWFCt7Gff6IyIMzFUn7QMZrbrQfGxtaxXZIcGQzoNpRLE3fQLnS4XzLLPMZX2T9TRcSrasicw==
|
||||
dependencies:
|
||||
loose-envify "^1.1.0"
|
||||
object-assign "^4.1.1"
|
||||
prop-types "^15.6.2"
|
||||
scheduler "^0.19.1"
|
||||
scheduler "^0.21.0"
|
||||
|
||||
react-flatpickr@^3.10.9:
|
||||
version "3.10.9"
|
||||
@@ -4182,14 +4200,12 @@ react-is@^17.0.1:
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
|
||||
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
|
||||
|
||||
react@16.14.0, react@^16.14.0:
|
||||
version "16.14.0"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-16.14.0.tgz#94d776ddd0aaa37da3eda8fc5b6b18a4c9a3114d"
|
||||
integrity sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==
|
||||
react@^18.0.0:
|
||||
version "18.0.0"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-18.0.0.tgz#b468736d1f4a5891f38585ba8e8fb29f91c3cb96"
|
||||
integrity sha512-x+VL6wbT4JRVPm7EGxXhZ8w8LTROaxPXOqhlGyVSrv0sB1jkyFGgXxJ8LVoPRLvPR6/CIZGFmfzqUa2NYeMr2A==
|
||||
dependencies:
|
||||
loose-envify "^1.1.0"
|
||||
object-assign "^4.1.1"
|
||||
prop-types "^15.6.2"
|
||||
|
||||
read-pkg-up@^7.0.1:
|
||||
version "7.0.1"
|
||||
@@ -4400,13 +4416,12 @@ saxes@^5.0.1:
|
||||
dependencies:
|
||||
xmlchars "^2.2.0"
|
||||
|
||||
scheduler@^0.19.1:
|
||||
version "0.19.1"
|
||||
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.19.1.tgz#4f3e2ed2c1a7d65681f4c854fa8c5a1ccb40f196"
|
||||
integrity sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==
|
||||
scheduler@^0.21.0:
|
||||
version "0.21.0"
|
||||
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.21.0.tgz#6fd2532ff5a6d877b6edb12f00d8ab7e8f308820"
|
||||
integrity sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ==
|
||||
dependencies:
|
||||
loose-envify "^1.1.0"
|
||||
object-assign "^4.1.1"
|
||||
|
||||
semver-compare@^1.0.0:
|
||||
version "1.0.0"
|
||||
@@ -4798,10 +4813,10 @@ style-value-types@5.0.0:
|
||||
hey-listen "^1.0.8"
|
||||
tslib "^2.1.0"
|
||||
|
||||
styled-jsx@5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-5.0.0.tgz#816b4b92e07b1786c6b7111821750e0ba4d26e77"
|
||||
integrity sha512-qUqsWoBquEdERe10EW8vLp3jT25s/ssG1/qX5gZ4wu15OZpmSMFI2v+fWlRhLfykA5rFtlJ1ME8A8pm/peV4WA==
|
||||
styled-jsx@5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-5.0.1.tgz#78fecbbad2bf95ce6cd981a08918ce4696f5fc80"
|
||||
integrity sha512-+PIZ/6Uk40mphiQJJI1202b+/dYeTVd9ZnMPR80pgiWbjIwvN2zIp4r9et0BgqBuShh48I0gttPlAXA7WVvBxw==
|
||||
|
||||
supports-color@^5.3.0:
|
||||
version "5.5.0"
|
||||
@@ -5007,13 +5022,6 @@ urix@^0.1.0:
|
||||
resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72"
|
||||
integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=
|
||||
|
||||
use-subscription@1.5.1:
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/use-subscription/-/use-subscription-1.5.1.tgz#73501107f02fad84c6dd57965beb0b75c68c42d1"
|
||||
integrity sha512-Xv2a1P/yReAjAbhylMfFplFKj9GssgTwN7RlcTxBujFQcloStWNDQdc4g4NRWH9xS4i/FDk04vQBptAXoF3VcA==
|
||||
dependencies:
|
||||
object-assign "^4.1.1"
|
||||
|
||||
use@^3.1.0:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f"
|
||||
|
||||
Reference in New Issue
Block a user