Position

The Position component is a utility meant to help one control position of elements relative to other elements, for example, tooltips above a button.

Examples

Using the React component

import React, { useState } from 'react'
import Button from '@pluralsight/ps-design-system-button'
import Tooltip from '@pluralsight/ps-design-system-tooltip'
import { RightOf } from '@pluralsight/ps-design-system-position'
const Example: React.FC = props => {
const [hovered, setHovered] = useState(false)
const hide = () => setHovered(false)
const show = () => setHovered(true)
return (
<RightOf
show={
<Tooltip tailPosition={Tooltip.tailPositions.leftCenter}>
Tooltip
</Tooltip>
}
when={hovered}
>
<Button
appearance={Button.appearances.secondary}
onMouseEnter={show}
onMouseLeave={hide}
>
Hover me
</Button>
</RightOf>
)
}
export default Example

Portal override

Position always renders in a portal, defaulting to document.body. It is often desirable to provide your own node to render within. Use the inNode prop to pass an element reference.

import React, { forward, useLayoutEffect, useRef, useState } from 'react'
import Button from '@pluralsight/ps-design-system-button'
import { PlaceholderIcon } from '@pluralsight/ps-design-system-icon'
import Tooltip from '@pluralsight/ps-design-system-tooltip'
import { Above } from '@pluralsight/ps-design-system-position'
const Example: React.FC = props => {
const portal = useRef<HTMLDivElement>()
const [hasRendered, setHasRendered] = useState(false)
useLayoutEffect(() => {
setHasRendered(true)
}, [])
return (
<React.Fragment>
{hasRendered && (
<div className="example">
<Above
inNode={portal.current}
show={<Tooltip>Rendered in portal</Tooltip>}
>
<Target />
</Above>
</div>
)}
<div ref={portal} />
<style jsx>{`
.example {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 200px;
outline: 2px dashed lightgrey;
}
`}</style>
</React.Fragment>
)
}
const Target = forwardRef<HTMLButtonElement>((_props, ref) => (
<Button
appearance={Button.appearances.flat}
disabled
icon={<PlaceholderIcon />}
title="Target"
ref={ref}
/>
))
export default Example

Javascript Example

The most important bits of this utility are available in pure JavaScript.

import {
above,
aboveLeft,
aboveRight,
above,
belowLeft,
belowRight,
leftOf,
rightOf
} from '@pluralsight/ps-design-system-position'

Use the JavaScript function to get the positioning style desired.

Tooltip
import React, { useEffect, useRef, useState } from 'react'
import Button from '@pluralsight/ps-design-system-button'
import Tooltip from '@pluralsight/ps-design-system-tooltip'
import { rightOf } from '@pluralsight/ps-design-system-position'
const Example: React.FC = props => {
const button = useRef<HTMLButtonElement>()
const tooltip = useRef<HTMLDivElement>()
const [hovered, setHovered] = useState(false)
const hide = () => setHovered(false)
const show = () => setHovered(true)
const [style, setStyle] = useState({ position: 'absolute' })
useEffect(() => {
if (!button.current || !tooltip.current) return
const nextStyle = rightOf(button.current).styleFor(tooltip.current)
setStyle(nextStyle)
}, [hovered])
return (
<div>
<Button
appearance={Button.appearances.secondary}
onMouseEnter={show}
onMouseLeave={hide}
ref={button}
>
Hover me
</Button>
<Tooltip
ref={tooltip}
style={{ ...style, display: hovered ? 'block' : 'none' }}
visible={false}
>
Tooltip
</Tooltip>
</div>
)
}
export default Example

Positions

Usage & types

  • Version
  • Install
    npm install @pluralsight/ps-design-system-position
  • Import
    import { Above, AboveLeft, AboveRight, Below, BelowLeft, BelowRight, LeftOf, RightOf } from '@pluralsight/ps-design-system-position'
Name
Type
Description
Default
children
Required
React.ReactNode
target element something will be relative to
inNode
HTMLElement
specific node for portal rendering
document.body
show
Required
React.ReactNode
element placed in relation to target
target
Ref
reference to custom target
when
boolean
conditional rendering of positioned element
true