toddler.popup

Popup namespace that offers components and functions that focus on popup placement.

Use Container component from this namespace as close to mounted react element as possible.

All popup elements will look for Container component and render at that DOM element.

There are few preference position sequences available

(def default-preference
  [#{:bottom :left}
   #{:bottom :right}
   #{:top :left}
   #{:top :right}
   #{:bottom :center}
   #{:top :center}
   #{:left :center}
   #{:right :center}])


In addition to default-preferences other available preferences are:

  • central-preference
  • left-preference
  • right-preference
  • cross-preference

Following components and hooks should be used in most cases:

*area-element*

dynamic

Area element context. Area element is DOM element that will cause popup to appear on user event

*container*

dynamic

Is container context. Container is component where popups will be mounted using reacts createPortal function.

*offset*

dynamic

Offset context. How much in px is offset for popup from PopupArea element

*outside-action-channel*

dynamic

Context for outside action channel. This channel will receive events when scroll or click outside happened

*position*

dynamic

Position of popup. Value should be set of max two keywords

  • :top
  • :bottom
  • :left
  • :right
  • :center

adjust-scroll-width

(adjust-scroll-width data)(adjust-scroll-width {:keys [position], :as data} scroll-width)

Keep in mind that scroll can appear. This function will move computed candidate for scroll-width

Area

Component that will generate div element around children that will be provided as *area-element* context.

It is element that will listen for user events and open popup

best-candidate

(best-candidate candidates)

For given number of candidates, this function will find candidate that has least overflow, that is candidate that has most visibility

computation-props

(computation-props target el)

For given target (popup area) element and popup element function will return map with keys that are important for popup position computation:

  • :top, :left, :right :bottom keys
  • :popup-width, :popup-height
  • :half-popup-width, :half-popup-height
  • :vertical-center, horizontal-center
  • :window-width :window-height

compute-candidate

multimethod

Function will compute candidate for popup element bounding rect by specifying prefered position. I.E. for #{:bottom :left} position function will enrich input data with keys

  • :position/left
  • :position/right
  • :position/top
  • :position/bottom
  • :overflow/top
  • :overflow/bottom
  • :overflow/left
  • :overflow/right

compute-container-props

(compute-container-props target el)(compute-container-props target el preference)

For given popup area and popup element function will return candidate that is most suitable for showing popup

Container

Component that in most cases is instantiated only once. Somewhere near react mounted component.

This component is target for popups to mount. So Element function will look for this component that will provide *container* context and mount popup in Container.

default-preference

Sequence of prefered positions. First :bottom positions are tested, than :top positions and finally central

Element

Creates fixed positioned div element that is positioned based on preference to area context element.

Popup size will adjust to content that is inside of this element. Props:

  • :preference - position preference in form of sequence with set options. I.E. [#{:bottom :left} #{:top :left}]
  • :style - style that will override Element div
  • :offset - distance between Area and Element
  • :on-change - when popup position changes this will be called

ok-candidate?

(ok-candidate? {:keys [overflow/top overflow/bottom overflow/left overflow/right], :as candidate})

Returns true if candidate didn’t overflow. Than this position is OK

use-focusable-items

(use-focusable-items)(use-focusable-items direction)

Should be used with popups that can focus some option or elmenent. Like dropdowns or multiselects

Hook will return ref-fn and focus-option function.

ref-fn accepts option and binds that option element with ref to DOM element in internal state.

When focus-option function is called for some option it will use .scrollIntoView to focus that option, by pulling out ref from internal memory using input option

use-outside-action

(use-outside-action area handler)(use-outside-action area popup handler)(use-outside-action opened area popup handler)

Hook accepts area and optionally popup element and handler that will be called when outside click or scroll actions are made.

wrap-container

(wrap-container component)

Wrapper that will use Container component to render children if user is authorized