Skip to content

Commit 70f88f4

Browse files
authored
Fix hanging tests when using anchor prop (#3357)
* add test that verifies unit test hang * bail when parsing the `maxHeight` results in `NaN` * playground cleanup Testing using this playground example, so cleaned it up to be more modern using newer components, transition prop and so on. * use CSS instead of JS Let's make it a CSS problem instead of a JS problem. The `round(up, <valueToRound>, <roundingInterval>)` will behave similar to a `Math.ceil()` that we had in the JS implementation. See: https://developer.mozilla.org/en-US/docs/Web/CSS/round * Remove CSS solution for now I want to re-enable this in the future, but unfortunately for now we can't use it because Chrome only introduced support for this in the last 2 months. This reverts commit daac60d45ec3f02b324d0d8b18078a995e885733. * update changelog
1 parent d65829b commit 70f88f4

File tree

4 files changed

+61
-48
lines changed

4 files changed

+61
-48
lines changed

packages/@headlessui-react/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1212
- Fix prematurely added anchoring styles on `ListboxOptions` ([#3337](https://github.com/tailwindlabs/headlessui/pull/3337))
1313
- Ensure `unmount` on `Dialog` works in combination with the `transition` prop on `DialogBackdrop` and `DialogPanel` components ([#3352](https://github.com/tailwindlabs/headlessui/pull/3352))
1414
- Fix crash in `Combobox` component when in `virtual` mode when options are empty ([#3356](https://github.com/tailwindlabs/headlessui/pull/3356))
15+
- Fix hanging tests when using `anchor` prop ([#3357](https://github.com/tailwindlabs/headlessui/pull/3357))
1516

1617
## [2.1.1] - 2024-06-26
1718

packages/@headlessui-react/src/components/popover/popover.test.tsx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,26 @@ describe('Rendering', () => {
804804
assertActiveElement(getByText('restorable'))
805805
})
806806
)
807+
808+
it(
809+
'should be possible to use the `anchor` prop on the `PopoverPanel`',
810+
suppressConsoleLogs(async () => {
811+
render(
812+
<Popover>
813+
<PopoverButton>Trigger</PopoverButton>
814+
<PopoverPanel anchor="bottom">Panel open</PopoverPanel>
815+
</Popover>
816+
)
817+
818+
assertPopoverButton({ state: PopoverState.InvisibleUnmounted })
819+
assertPopoverPanel({ state: PopoverState.InvisibleUnmounted })
820+
821+
await click(getPopoverButton())
822+
823+
assertPopoverButton({ state: PopoverState.Visible })
824+
assertPopoverPanel({ state: PopoverState.Visible })
825+
})
826+
)
807827
})
808828

809829
describe('Multiple `Popover.Button` warnings', () => {

packages/@headlessui-react/src/internal/floating.tsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -375,9 +375,16 @@ function useFixScrollingPixel(element: HTMLElement | null) {
375375
if (!element) return
376376

377377
let observer = new MutationObserver(() => {
378-
let maxHeight = element.style.maxHeight
379-
if (parseFloat(maxHeight) !== parseInt(maxHeight)) {
380-
element.style.maxHeight = `${Math.ceil(parseFloat(maxHeight))}px`
378+
let maxHeight = window.getComputedStyle(element).maxHeight
379+
380+
let maxHeightFloat = parseFloat(maxHeight)
381+
if (isNaN(maxHeightFloat)) return
382+
383+
let maxHeightInt = parseInt(maxHeight)
384+
if (isNaN(maxHeightInt)) return
385+
386+
if (maxHeightFloat !== maxHeightInt) {
387+
element.style.maxHeight = `${Math.ceil(maxHeightFloat)}px`
381388
}
382389
})
383390

playgrounds/react/pages/listbox/listbox-with-pure-tailwind.tsx

Lines changed: 30 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Listbox, Transition } from '@headlessui/react'
1+
import { Label, Listbox, ListboxButton, ListboxOption, ListboxOptions } from '@headlessui/react'
22
import { useEffect, useState } from 'react'
33

44
let people = [
@@ -26,20 +26,12 @@ export default function Home() {
2626
<div className="flex h-full w-screen justify-center bg-gray-50 p-12">
2727
<div className="mx-auto w-full max-w-xs">
2828
<div className="space-y-1">
29-
<Listbox
30-
value={active}
31-
onChange={(value) => {
32-
console.log('value:', value)
33-
setActivePerson(value)
34-
}}
35-
>
36-
<Listbox.Label className="block text-sm font-medium leading-5 text-gray-700">
37-
Assigned to
38-
</Listbox.Label>
29+
<Listbox value={active} onChange={setActivePerson}>
30+
<Label className="block text-sm font-medium leading-5 text-gray-700">Assigned to</Label>
3931

4032
<div className="relative">
4133
<span className="inline-block w-full rounded-md shadow-sm">
42-
<Listbox.Button className="focus:shadow-outline-blue relative w-full cursor-default rounded-md border border-gray-300 bg-white py-2 pl-3 pr-10 text-left transition duration-150 ease-in-out focus:border-blue-300 focus:outline-none sm:text-sm sm:leading-5">
34+
<ListboxButton className="relative w-full cursor-default rounded-md border border-gray-300 bg-white py-2 pl-3 pr-10 text-left transition duration-150 ease-in-out sm:text-sm sm:leading-5">
4335
<span className="block truncate">{active}</span>
4436
<span className="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2">
4537
<svg
@@ -56,42 +48,35 @@ export default function Home() {
5648
/>
5749
</svg>
5850
</span>
59-
</Listbox.Button>
51+
</ListboxButton>
6052
</span>
6153

62-
<Transition
63-
enter="transition duration-500 ease-out"
64-
enterFrom="transform scale-95 opacity-0"
65-
enterTo="transform scale-100 opacity-100"
66-
leave="transition duration-500 ease-out"
67-
leaveFrom="transform scale-100 opacity-100"
68-
leaveTo="transform scale-95 opacity-0"
54+
<ListboxOptions
55+
anchor="bottom"
56+
transition
57+
className="w-[var(--button-width)] overflow-auto rounded-md border border-gray-300 bg-white py-1 text-base leading-6 shadow-lg transition duration-200 ease-out [--anchor-gap:theme(spacing.1)] [--anchor-max-height:theme(spacing.60)] focus:outline-none data-[closed]:scale-95 data-[closed]:opacity-0 sm:text-sm sm:leading-5"
6958
>
70-
<div className="absolute mt-1 w-full rounded-md bg-white shadow-lg">
71-
<Listbox.Options className="shadow-xs max-h-60 overflow-auto rounded-md py-1 text-base leading-6 focus:outline-none sm:text-sm sm:leading-5">
72-
{people.map((name) => (
73-
<Listbox.Option
74-
key={name}
75-
value={name}
76-
className="group relative cursor-default select-none py-2 pl-3 pr-9 text-gray-900 focus:outline-none data-[active]:bg-indigo-600 data-[active]:text-white"
77-
>
78-
<span className="block truncate font-normal group-data-[selected]:font-semibold">
79-
{name}
80-
</span>
81-
<span className="absolute inset-y-0 right-0 hidden items-center pr-4 text-indigo-600 group-data-[selected]:flex group-data-[active]:text-white">
82-
<svg className="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
83-
<path
84-
fillRule="evenodd"
85-
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
86-
clipRule="evenodd"
87-
/>
88-
</svg>
89-
</span>
90-
</Listbox.Option>
91-
))}
92-
</Listbox.Options>
93-
</div>
94-
</Transition>
59+
{people.map((name) => (
60+
<ListboxOption
61+
key={name}
62+
value={name}
63+
className="group relative cursor-default select-none py-2 pl-3 pr-9 text-gray-900 focus:outline-none data-[active]:bg-indigo-600 data-[active]:text-white"
64+
>
65+
<span className="block truncate font-normal group-data-[selected]:font-semibold">
66+
{name}
67+
</span>
68+
<span className="absolute inset-y-0 right-0 hidden items-center pr-4 text-indigo-600 group-data-[selected]:flex group-data-[active]:text-white">
69+
<svg className="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
70+
<path
71+
fillRule="evenodd"
72+
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
73+
clipRule="evenodd"
74+
/>
75+
</svg>
76+
</span>
77+
</ListboxOption>
78+
))}
79+
</ListboxOptions>
9580
</div>
9681
</Listbox>
9782
</div>

0 commit comments

Comments
 (0)