Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/@headlessui-react/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fix prematurely added anchoring styles on `ListboxOptions` ([#3337](https://github.com/tailwindlabs/headlessui/pull/3337))
- Ensure `unmount` on `Dialog` works in combination with the `transition` prop on `DialogBackdrop` and `DialogPanel` components ([#3352](https://github.com/tailwindlabs/headlessui/pull/3352))
- Fix crash in `Combobox` component when in `virtual` mode when options are empty ([#3356](https://github.com/tailwindlabs/headlessui/pull/3356))
- Fix hanging tests when using `anchor` prop ([#3357](https://github.com/tailwindlabs/headlessui/pull/3357))

## [2.1.1] - 2024-06-26

Expand Down
20 changes: 20 additions & 0 deletions packages/@headlessui-react/src/components/popover/popover.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -804,6 +804,26 @@ describe('Rendering', () => {
assertActiveElement(getByText('restorable'))
})
)

it(
'should be possible to use the `anchor` prop on the `PopoverPanel`',
suppressConsoleLogs(async () => {
render(
<Popover>
<PopoverButton>Trigger</PopoverButton>
<PopoverPanel anchor="bottom">Panel open</PopoverPanel>
</Popover>
)

assertPopoverButton({ state: PopoverState.InvisibleUnmounted })
assertPopoverPanel({ state: PopoverState.InvisibleUnmounted })

await click(getPopoverButton())

assertPopoverButton({ state: PopoverState.Visible })
assertPopoverPanel({ state: PopoverState.Visible })
})
)
})

describe('Multiple `Popover.Button` warnings', () => {
Expand Down
13 changes: 10 additions & 3 deletions packages/@headlessui-react/src/internal/floating.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -375,9 +375,16 @@ function useFixScrollingPixel(element: HTMLElement | null) {
if (!element) return

let observer = new MutationObserver(() => {
let maxHeight = element.style.maxHeight
if (parseFloat(maxHeight) !== parseInt(maxHeight)) {
element.style.maxHeight = `${Math.ceil(parseFloat(maxHeight))}px`
let maxHeight = window.getComputedStyle(element).maxHeight
Copy link
Member Author

@RobinMalfait RobinMalfait Jul 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Used getComputedStyle to resolve the calculated min(var(--anchor-max-height, 100vh), ${availableHeight}px) value


let maxHeightFloat = parseFloat(maxHeight)
if (isNaN(maxHeightFloat)) return

let maxHeightInt = parseInt(maxHeight)
if (isNaN(maxHeightInt)) return

if (maxHeightFloat !== maxHeightInt) {
element.style.maxHeight = `${Math.ceil(maxHeightFloat)}px`
}
})

Expand Down
75 changes: 30 additions & 45 deletions playgrounds/react/pages/listbox/listbox-with-pure-tailwind.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Listbox, Transition } from '@headlessui/react'
import { Label, Listbox, ListboxButton, ListboxOption, ListboxOptions } from '@headlessui/react'
import { useEffect, useState } from 'react'

let people = [
Expand Down Expand Up @@ -26,20 +26,12 @@ export default function Home() {
<div className="flex h-full w-screen justify-center bg-gray-50 p-12">
<div className="mx-auto w-full max-w-xs">
<div className="space-y-1">
<Listbox
value={active}
onChange={(value) => {
console.log('value:', value)
setActivePerson(value)
}}
>
<Listbox.Label className="block text-sm font-medium leading-5 text-gray-700">
Assigned to
</Listbox.Label>
<Listbox value={active} onChange={setActivePerson}>
<Label className="block text-sm font-medium leading-5 text-gray-700">Assigned to</Label>

<div className="relative">
<span className="inline-block w-full rounded-md shadow-sm">
<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">
<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">
<span className="block truncate">{active}</span>
<span className="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2">
<svg
Expand All @@ -56,42 +48,35 @@ export default function Home() {
/>
</svg>
</span>
</Listbox.Button>
</ListboxButton>
</span>

<Transition
enter="transition duration-500 ease-out"
enterFrom="transform scale-95 opacity-0"
enterTo="transform scale-100 opacity-100"
leave="transition duration-500 ease-out"
leaveFrom="transform scale-100 opacity-100"
leaveTo="transform scale-95 opacity-0"
<ListboxOptions
anchor="bottom"
transition
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"
>
<div className="absolute mt-1 w-full rounded-md bg-white shadow-lg">
<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">
{people.map((name) => (
<Listbox.Option
key={name}
value={name}
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"
>
<span className="block truncate font-normal group-data-[selected]:font-semibold">
{name}
</span>
<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">
<svg className="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
<path
fillRule="evenodd"
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"
clipRule="evenodd"
/>
</svg>
</span>
</Listbox.Option>
))}
</Listbox.Options>
</div>
</Transition>
{people.map((name) => (
<ListboxOption
key={name}
value={name}
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"
>
<span className="block truncate font-normal group-data-[selected]:font-semibold">
{name}
</span>
<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">
<svg className="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
<path
fillRule="evenodd"
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"
clipRule="evenodd"
/>
</svg>
</span>
</ListboxOption>
))}
</ListboxOptions>
</div>
</Listbox>
</div>
Expand Down