Skip to content

Commit

Permalink
refactor: placement naming
Browse files Browse the repository at this point in the history
  • Loading branch information
segunadebayo committed Mar 21, 2022
1 parent 02fff16 commit 8c86a38
Show file tree
Hide file tree
Showing 9 changed files with 49 additions and 43 deletions.
12 changes: 6 additions & 6 deletions packages/machines/menu/src/menu.machine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const machine = createMachine<MachineContext, MachineState>(
loop: false,
suspendPointer: false,
contextMenuPoint: null,
placementOptions: { placement: "bottom-start", gutter: 8 },
positioning: { placement: "bottom-start", gutter: 8 },
},

computed: {
Expand All @@ -40,8 +40,8 @@ export const machine = createMachine<MachineContext, MachineState>(
watch: {
isSubmenu(ctx) {
if (ctx.isSubmenu) {
ctx.placementOptions.placement = ctx.isRtl ? "left-start" : "right-start"
ctx.placementOptions.gutter = 0
ctx.positioning.placement = ctx.isRtl ? "left-start" : "right-start"
ctx.positioning.gutter = 0
}
},
},
Expand Down Expand Up @@ -315,11 +315,11 @@ export const machine = createMachine<MachineContext, MachineState>(
activities: {
computePlacement(ctx) {
if (ctx.disablePlacement) return
ctx.currentPlacement = ctx.placementOptions.placement
ctx.currentPlacement = ctx.positioning.placement
const arrow = dom.getArrowEl(ctx)
const cleanup = getPlacement(dom.getTriggerEl(ctx), dom.getPositionerEl(ctx), {
...ctx.placementOptions,
arrow: arrow ? { ...ctx.placementOptions.arrow, element: arrow } : undefined,
...ctx.positioning,
arrow: arrow ? { ...ctx.positioning.arrow, element: arrow } : undefined,
onPlacementComplete(placement) {
ctx.currentPlacement = placement
},
Expand Down
4 changes: 2 additions & 2 deletions packages/machines/menu/src/menu.types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Machine, StateMachine as S } from "@ui-machines/core"
import type { PlacementOptions, Placement } from "@ui-machines/popper"
import type { PositioningOptions, Placement } from "@ui-machines/popper"
import type { Point } from "@ui-machines/rect-utils"
import type { Context } from "@ui-machines/types"

Expand Down Expand Up @@ -63,7 +63,7 @@ export type MachineContext = Context<{
/**
* The options used to dynamically position the menu
*/
placementOptions: PlacementOptions
positioning: PositioningOptions
/**
* Whether to disable dynamic placement
*/
Expand Down
2 changes: 1 addition & 1 deletion packages/machines/popover/src/popover.connect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export function connect<T extends PropTypes = ReactPropTypes>(
const pointerdownNode = state.context.pointerdownNode

const isOpen = state.matches("open")
const arrow = state.context.placementOptions.arrow
const arrow = state.context.positioning.arrow

return {
isOpen,
Expand Down
6 changes: 3 additions & 3 deletions packages/machines/popover/src/popover.machine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export const machine = createMachine<MachineContext, MachineState>(
closeOnEsc: true,
autoFocus: true,
modal: false,
placementOptions: { placement: "bottom" },
positioning: { placement: "bottom" },
currentPlacement: undefined,
},

Expand Down Expand Up @@ -114,11 +114,11 @@ export const machine = createMachine<MachineContext, MachineState>(
{
activities: {
computePlacement(ctx) {
ctx.currentPlacement = ctx.placementOptions.placement
ctx.currentPlacement = ctx.positioning.placement
const anchorEl = ctx.isAnchorRendered ? dom.getAnchorEl(ctx) : dom.getTriggerEl(ctx)
const arrow = dom.getArrowEl(ctx)
const cleanup = getPlacement(anchorEl, dom.getPositionerEl(ctx), {
...ctx.placementOptions,
...ctx.positioning,
arrow: arrow ? { element: arrow } : undefined,
onPlacementComplete(placement) {
ctx.currentPlacement = placement
Expand Down
4 changes: 2 additions & 2 deletions packages/machines/popover/src/popover.types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { PlacementOptions, Placement } from "@ui-machines/popper"
import type { PositioningOptions, Placement } from "@ui-machines/popper"
import type { Context, MaybeElement } from "@ui-machines/types"

export type MachineContext = Context<{
Expand Down Expand Up @@ -62,7 +62,7 @@ export type MachineContext = Context<{
/**
* The user provided options used to position the popover content
*/
placementOptions: PlacementOptions
positioning: PositioningOptions
/**
* @internal The computed placement (maybe different from initial placement)
*/
Expand Down
2 changes: 1 addition & 1 deletion packages/machines/tooltip/src/tooltip.connect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export function connect<T extends PropTypes = ReactPropTypes>(

const triggerId = dom.getTriggerId(state.context)
const contentId = dom.getContentId(state.context)
const arrow = state.context.placementOptions.arrow
const arrow = state.context.positioning.arrow

return {
isVisible,
Expand Down
8 changes: 4 additions & 4 deletions packages/machines/tooltip/src/tooltip.machine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const machine = createMachine<MachineContext, MachineState>(
closeDelay: 500,
closeOnPointerDown: true,
interactive: true,
placementOptions: { placement: "bottom" },
positioning: { placement: "bottom" },
currentPlacement: undefined,
},

Expand Down Expand Up @@ -133,13 +133,13 @@ export const machine = createMachine<MachineContext, MachineState>(
{
activities: {
computePlacement(ctx) {
ctx.currentPlacement = ctx.placementOptions.placement
ctx.currentPlacement = ctx.positioning.placement
let cleanup: VoidFunction
raf(() => {
const arrow = dom.getArrowEl(ctx)
cleanup = getPlacement(dom.getTriggerEl(ctx), dom.getPositionerEl(ctx), {
...ctx.placementOptions,
arrow: arrow ? { ...ctx.placementOptions.arrow, element: arrow } : undefined,
...ctx.positioning,
arrow: arrow ? { ...ctx.positioning.arrow, element: arrow } : undefined,
onPlacementComplete(placement) {
ctx.currentPlacement = placement
},
Expand Down
4 changes: 2 additions & 2 deletions packages/machines/tooltip/src/tooltip.types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Placement, PlacementOptions } from "@ui-machines/popper"
import { Placement, PositioningOptions } from "@ui-machines/popper"

export type MachineContext = {
/**
Expand Down Expand Up @@ -50,7 +50,7 @@ export type MachineContext = {
/**
* The user provided options used to position the popover content
*/
placementOptions: PlacementOptions
positioning: PositioningOptions
/**
* @internal The computed placement of the tooltip.
*/
Expand Down
50 changes: 28 additions & 22 deletions packages/utilities/popper/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { cssVars, positionArrow, transformOrigin } from "./middleware"

export type { Placement }

export type PlacementOptions = {
export type PositioningOptions = {
arrow?: { padding?: number; element?: HTMLElement; size?: number; shadowColor?: string }
strategy?: "absolute" | "fixed"
placement?: Placement
Expand All @@ -29,7 +29,7 @@ export type PlacementOptions = {
onCleanup?: VoidFunction
}

const defaultOpts: PlacementOptions = {
const defaultOptions: PositioningOptions = {
strategy: "absolute",
placement: "bottom",
eventListeners: true,
Expand All @@ -39,38 +39,42 @@ const defaultOpts: PlacementOptions = {
sameWidth: false,
}

export function getPlacement(reference: HTMLElement | null, floating: HTMLElement | null, opts: PlacementOptions = {}) {
export function getPlacement(
reference: HTMLElement | null,
floating: HTMLElement | null,
options: PositioningOptions = {},
) {
if (reference == null || floating == null) {
return noop
}

opts = Object.assign({}, defaultOpts, opts)
options = Object.assign({}, defaultOptions, options)
const win = reference.ownerDocument.defaultView || window

const middleware: Middleware[] = [transformOrigin]

if (opts.flip) {
middleware.push(flip({ boundary: opts.boundary, padding: 8 }))
if (options.flip) {
middleware.push(flip({ boundary: options.boundary, padding: 8 }))
}

if (opts.gutter || opts.offset) {
const data = opts.gutter ? { mainAxis: opts.gutter } : opts.offset
if (options.gutter || options.offset) {
const data = options.gutter ? { mainAxis: options.gutter } : options.offset
middleware.push(offset(data))
}

middleware.push(shift({ boundary: opts.boundary }))
middleware.push(shift({ boundary: options.boundary }))

if (opts.arrow?.element) {
if (options.arrow?.element) {
middleware.push(
arrow({
element: opts.arrow.element,
padding: opts.arrow.padding ?? 8,
element: options.arrow.element,
padding: options.arrow.padding ?? 8,
}),
positionArrow({ element: opts.arrow?.element }),
positionArrow({ element: options.arrow?.element }),
)
}

if (opts.sameWidth) {
if (options.sameWidth) {
middleware.push(
size({
apply({ reference }) {
Expand All @@ -86,17 +90,18 @@ export function getPlacement(reference: HTMLElement | null, floating: HTMLElemen
function compute() {
if (reference == null || floating == null) return
computePosition(reference, floating, {
placement: opts.placement,
placement: options.placement,
middleware,
strategy: opts.strategy,
strategy: options.strategy,
}).then(({ x, y, placement, strategy }) => {
Object.assign(floating.style, { left: `${x}px`, top: `${y}px`, position: strategy })
opts.onPlacementComplete?.(placement)
options.onPlacementComplete?.(placement)
})
}

function addResizeListeners() {
const enabled = typeof opts.eventListeners === "boolean" ? opts.eventListeners : opts.eventListeners?.resize
const enabled =
typeof options.eventListeners === "boolean" ? options.eventListeners : options.eventListeners?.resize
if (!enabled) return

const unobserve = observeElementRect(reference!, compute)
Expand All @@ -109,7 +114,8 @@ export function getPlacement(reference: HTMLElement | null, floating: HTMLElemen
}

function addScrollListeners() {
const enabled = typeof opts.eventListeners === "boolean" ? opts.eventListeners : opts.eventListeners?.scroll
const enabled =
typeof options.eventListeners === "boolean" ? options.eventListeners : options.eventListeners?.scroll
if (!enabled || reference == null) return
const fns = getScrollParents(reference).map((el) => {
el.addEventListener("scroll", compute)
Expand All @@ -125,7 +131,7 @@ export function getPlacement(reference: HTMLElement | null, floating: HTMLElemen
compute()
const cleanups = [addResizeListeners(), addScrollListeners()]
return function cleanup() {
opts.onCleanup?.()
options.onCleanup?.()
cleanups.forEach((fn) => fn?.())
}
}
Expand All @@ -141,8 +147,8 @@ type ArrowStyleOptions = {
measured?: boolean
}

export function getArrowStyle(opts: ArrowStyleOptions = {}) {
const { size = 8, background, shadowColor, measured } = opts
export function getArrowStyle(options: ArrowStyleOptions = {}) {
const { size = 8, background, shadowColor, measured } = options
return {
position: "absolute",
[cssVars.arrowSize.variable]: `${size}px`,
Expand Down

0 comments on commit 8c86a38

Please sign in to comment.