Skip to content

Commit

Permalink
feat(popper): add support for hide when detached
Browse files Browse the repository at this point in the history
  • Loading branch information
segunadebayo committed Sep 12, 2024
1 parent f079c60 commit 74d1848
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 2 deletions.
6 changes: 6 additions & 0 deletions .changeset/sour-donuts-smile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@zag-js/popper": minor
---

Add support for `hideWhenDetached` positioning option. This can be used in the `positioning` options for floating
components (select, popover, dialog, etc.)
14 changes: 12 additions & 2 deletions packages/utilities/popper/src/get-placement.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { AutoUpdateOptions, Middleware } from "@floating-ui/dom"
import { arrow, autoUpdate, computePosition, flip, limitShift, offset, shift, size } from "@floating-ui/dom"
import { arrow, autoUpdate, computePosition, flip, hide, limitShift, offset, shift, size } from "@floating-ui/dom"
import { getWindow, raf } from "@zag-js/dom-query"
import { compact, isNull, noop, runIfFn } from "@zag-js/utils"
import { getAnchorElement } from "./get-anchor"
Expand Down Expand Up @@ -44,7 +44,7 @@ function getOffsetMiddleware(arrowElement: HTMLElement | null, opts: Positioning
const arrowOffset = (arrowElement?.clientHeight || 0) / 2

const gutter = opts.offset?.mainAxis ?? opts.gutter
const mainAxis = typeof gutter === "number" ? gutter + arrowOffset : gutter ?? arrowOffset
const mainAxis = typeof gutter === "number" ? gutter + arrowOffset : (gutter ?? arrowOffset)

const { hasAlign } = getPlacementDetails(placement)
const shift = !hasAlign ? opts.shift : undefined
Expand Down Expand Up @@ -95,6 +95,11 @@ function getSizeMiddleware(opts: PositioningOptions) {
})
}

function hideWhenDetachedMiddleware(opts: PositioningOptions) {
if (!opts.hideWhenDetached) return
return hide({ strategy: "referenceHidden", boundary: opts.boundary?.() ?? "clippingAncestors" })
}

function getAutoUpdateOptions(opts?: boolean | AutoUpdateOptions): AutoUpdateOptions {
if (!opts) return {}
if (opts === true) {
Expand Down Expand Up @@ -122,6 +127,7 @@ function getPlacementImpl(referenceOrVirtual: MaybeRectElement, floating: MaybeE
shiftArrowMiddleware(arrowEl),
transformOriginMiddleware,
getSizeMiddleware(options),
hideWhenDetachedMiddleware(options),
rectMiddleware,
]

Expand Down Expand Up @@ -150,6 +156,10 @@ function getPlacementImpl(referenceOrVirtual: MaybeRectElement, floating: MaybeE
floating.style.setProperty("--x", `${x}px`)
floating.style.setProperty("--y", `${y}px`)

if (options.hideWhenDetached && pos.middlewareData.hide?.referenceHidden) {
floating.style.setProperty("visibility", "hidden")
}

const contentEl = floating.firstElementChild

if (contentEl) {
Expand Down
4 changes: 4 additions & 0 deletions packages/utilities/popper/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ export interface AnchorRect {
}

export interface PositioningOptions {
/**
* Whether the popover should be hidden when the reference element is detached
*/
hideWhenDetached?: boolean
/**
* The strategy to use for positioning
*/
Expand Down

0 comments on commit 74d1848

Please sign in to comment.