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 daf636d
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 35 deletions.
10 changes: 5 additions & 5 deletions packages/@headlessui-react/src/components/combobox/combobox.tsx
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 @@ -1534,7 +1535,7 @@ export type ComboboxOptionsProps<TTag extends ElementType = typeof DEFAULT_OPTIO
OptionsPropsWeControl,
PropsForFeatures<typeof OptionsRenderFeatures> & {
hold?: boolean
anchor?: boolean | AnchorProps
anchor?: AnchorProps
}
>

Expand All @@ -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
18 changes: 5 additions & 13 deletions packages/@headlessui-react/src/components/tooltip/tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
FloatingProvider,
useFloatingPanel,
useFloatingReference,
useResolvedAnchor,
type AnchorProps,
} from '../../internal/floating'
import { State, useOpenClosed } from '../../internal/open-closed'
Expand Down Expand Up @@ -415,22 +416,14 @@ export type TooltipPanelProps<TTag extends ElementType = typeof DEFAULT_PANEL_TA
TTag,
PanelRenderPropArg,
PanelPropsWeControl,
{ anchor?: boolean | AnchorProps } & PropsForFeatures<typeof PanelRenderFeatures>
{ anchor?: AnchorProps } & PropsForFeatures<typeof PanelRenderFeatures>
>

function PanelFn<TTag extends ElementType = typeof DEFAULT_PANEL_TAG>(
props: TooltipPanelProps<TTag>,
ref: Ref<HTMLElement>
) {
let {
anchor = {
to: 'top',
padding: 8,
gap: 8,
offset: -4,
} as AnchorProps,
...theirProps
} = props
let { anchor: rawAnchor, ...theirProps } = props
let data = useData('TooltipPanel')

let usesOpenClosedState = useOpenClosed()
Expand All @@ -443,9 +436,8 @@ function PanelFn<TTag extends ElementType = typeof DEFAULT_PANEL_TAG>(
})()

let internalPanelRef = useRef<HTMLElement | null>(null)
let [floatingRef, style] = useFloatingPanel(
visible && anchor !== false ? (anchor === true ? {} : anchor) : undefined
)
let anchor = useResolvedAnchor(rawAnchor ?? { to: 'top', padding: 8, gap: 8, offset: -4 })
let [floatingRef, style] = useFloatingPanel(visible ? anchor : undefined)
let panelRef = useSyncRefs(internalPanelRef, ref, floatingRef)

let ourProps = {
Expand Down

0 comments on commit daf636d

Please sign in to comment.