Skip to content

Commit

Permalink
simplify anchor handling per-component
Browse files Browse the repository at this point in the history
  • Loading branch information
RobinMalfait committed Apr 22, 2024
1 parent efc53b4 commit d4392d2
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import {
useFloatingPanel,
useFloatingPanelProps,
useFloatingReference,
useResolvedAnchor,
type AnchorProps,
} from '../../internal/floating'
import { FormFields } from '../../internal/form-fields'
Expand Down Expand Up @@ -1546,15 +1547,14 @@ function OptionsFn<TTag extends ElementType = typeof DEFAULT_OPTIONS_TAG>(
let {
id = `headlessui-combobox-options-${internalId}`,
hold = false,
anchor,
anchor: rawAnchor,
...theirProps
} = props
let data = useData('Combobox.Options')
let actions = useActions('Combobox.Options')
let anchor = useResolvedAnchor(rawAnchor)

let [floatingRef, style] = useFloatingPanel(
anchor === false ? undefined : anchor === true ? {} : anchor
)
let [floatingRef, style] = useFloatingPanel(anchor)
let getFloatingPanelProps = useFloatingPanelProps()
let optionsRef = useSyncRefs(data.optionsRef, ref, anchor ? floatingRef : null)

Expand Down
16 changes: 9 additions & 7 deletions packages/@headlessui-react/src/components/listbox/listbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import {
useFloatingPanelProps,
useFloatingReference,
useFloatingReferenceProps,
useResolvedAnchor,
type AnchorPropsWithSelection,
} from '../../internal/floating'
import { FormFields } from '../../internal/form-fields'
Expand Down Expand Up @@ -868,7 +869,7 @@ export type ListboxOptionsProps<TTag extends ElementType = typeof DEFAULT_OPTION
OptionsRenderPropArg,
OptionsPropsWeControl,
{
anchor?: boolean | AnchorPropsWithSelection
anchor?: AnchorPropsWithSelection
modal?: boolean
} & PropsForFeatures<typeof OptionsRenderFeatures>
>
Expand All @@ -878,7 +879,13 @@ function OptionsFn<TTag extends ElementType = typeof DEFAULT_OPTIONS_TAG>(
ref: Ref<HTMLElement>
) {
let internalId = useId()
let { id = `headlessui-listbox-options-${internalId}`, anchor, modal, ...theirProps } = props
let {
id = `headlessui-listbox-options-${internalId}`,
anchor: rawAnchor,
modal,
...theirProps
} = props
let anchor = useResolvedAnchor(rawAnchor)

// Always use `modal` when `anchor` is passed in
if (modal == null) {
Expand All @@ -903,8 +910,6 @@ function OptionsFn<TTag extends ElementType = typeof DEFAULT_OPTIONS_TAG>(
let initialOption = useRef<number | null>(null)

useEffect(() => {
if (typeof anchor === 'boolean') return

if (!anchor?.to?.includes('selection')) return

if (!visible) {
Expand Down Expand Up @@ -938,9 +943,6 @@ function OptionsFn<TTag extends ElementType = typeof DEFAULT_OPTIONS_TAG>(
let panelEnabled = didButtonMove ? false : visible

let anchorOptions = (() => {
if (anchor === false) return undefined
if (anchor === true) anchor = {}

if (anchor == null) return undefined
if (data.listRef.current.size <= 0) return { ...anchor, inner: undefined }

Expand Down
15 changes: 10 additions & 5 deletions packages/@headlessui-react/src/components/menu/menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import {
useFloatingPanelProps,
useFloatingReference,
useFloatingReferenceProps,
useResolvedAnchor,
type AnchorProps,
} from '../../internal/floating'
import { Modal, ModalFeatures, type ModalProps } from '../../internal/modal'
Expand Down Expand Up @@ -575,7 +576,7 @@ export type MenuItemsProps<TTag extends ElementType = typeof DEFAULT_ITEMS_TAG>
ItemsRenderPropArg,
ItemsPropsWeControl,
{
anchor?: boolean | AnchorProps
anchor?: AnchorProps
modal?: boolean

// ItemsRenderFeatures
Expand All @@ -589,11 +590,15 @@ function ItemsFn<TTag extends ElementType = typeof DEFAULT_ITEMS_TAG>(
ref: Ref<HTMLDivElement>
) {
let internalId = useId()
let { id = `headlessui-menu-items-${internalId}`, anchor, modal, ...theirProps } = props
let {
id = `headlessui-menu-items-${internalId}`,
anchor: rawAnchor,
modal,
...theirProps
} = props
let anchor = useResolvedAnchor(rawAnchor)
let [state, dispatch] = useMenuContext('Menu.Items')
let [floatingRef, style] = useFloatingPanel(
anchor === false ? undefined : anchor === true ? {} : anchor
)
let [floatingRef, style] = useFloatingPanel(anchor)
let getFloatingPanelProps = useFloatingPanelProps()
let itemsRef = useSyncRefs(state.itemsRef, ref, anchor ? floatingRef : null)
let ownerDocument = useOwnerDocument(state.itemsRef)
Expand Down
10 changes: 5 additions & 5 deletions packages/@headlessui-react/src/components/popover/popover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import {
useFloatingPanel,
useFloatingPanelProps,
useFloatingReference,
useResolvedAnchor,
type AnchorProps,
} from '../../internal/floating'
import { Hidden, HiddenFeatures } from '../../internal/hidden'
Expand Down Expand Up @@ -798,7 +799,7 @@ export type PopoverPanelProps<TTag extends ElementType = typeof DEFAULT_PANEL_TA
PanelPropsWeControl,
{
focus?: boolean
anchor?: boolean | AnchorProps
anchor?: AnchorProps
modal?: boolean

// ItemsRenderFeatures
Expand All @@ -815,7 +816,7 @@ function PanelFn<TTag extends ElementType = typeof DEFAULT_PANEL_TAG>(
let {
id = `headlessui-popover-panel-${internalId}`,
focus = false,
anchor,
anchor: rawAnchor,
modal,
...theirProps
} = props
Expand All @@ -827,9 +828,8 @@ function PanelFn<TTag extends ElementType = typeof DEFAULT_PANEL_TAG>(
let afterPanelSentinelId = `headlessui-focus-sentinel-after-${internalId}`

let internalPanelRef = useRef<HTMLDivElement | null>(null)
let [floatingRef, style] = useFloatingPanel(
anchor === false ? undefined : anchor === true ? {} : anchor
)
let anchor = useResolvedAnchor(rawAnchor)
let [floatingRef, style] = useFloatingPanel(anchor)
let getFloatingPanelProps = useFloatingPanelProps()

// Always use `modal` when `anchor` is passed in
Expand Down

0 comments on commit d4392d2

Please sign in to comment.