@render-props/viewport
v0.3.1
Published
State containers which provide an interface for listening and responding to window events in a scalable fashion.
Downloads
1,074
Maintainers
Readme
Viewport
State containers which provide an interface for listening and responding to window events in a scalable fashion.
Installation
yarn add @render-props/viewport
or npm i @render-props/viewport
Contents
Viewport
- Component which provides context from
ViewportOrientation
, andViewportScroll
- Component which provides context from
ViewportProvider
- A top-level
Viewport
component which stores the viewport state and provides it as context toViewportConsumer
components.
- A top-level
ViewportConsumer
- Receives context updates from
ViewportProvider
when the viewport state changes
- Receives context updates from
ViewportOrientation
- Provides context for
{width, height, aspect, orientation, screenOrientation}
while receiving{width, height, aspect}
fromViewportSize
parent. - Updates each time the window size or orientation changes.
- Provides context for
ViewportSize
- Provides context for
{width, height, aspect}
. - Updates each time the window size or orientation changes.
- Provides context for
ViewportQueries
- Provides context for
{inView, inViewX, inViewY, inFullView, inFullViewX, inFullViewY}
- Provides context for
ViewportScroll
- Provides context for
{scrollX, scrollY, scrollTo, distance, direction}
- Updates each time the scroll position changes
- Provides context for
Viewport
God component which provides context from ViewportOrientation
, and ViewportScroll
Usage
import Viewport from '@render-props/viewport'
const ViewportLogger = props => {
return (
<Viewport>
{({
width,
height,
aspect,
orientation,
screenOrientation,
scrollX,
scrollY,
distance,
direction,
scrollTo
}) => (
<>
<div>
width: {width}
</div>
<div>
scrollY: {scrollY}
</div>
<div>
aspect: {aspect}
</div>
</>
)}
</Viewport>
)
}
Props
This component takes no props
Render Props
Methods
scrollTo
(x <integer>, [y <integer>], [options <object{duration <ms>, timing <function>}>])
- scrolls to the provided
x
,y
coordinates in the window. You can optionally animate this by providing an options object with a duration. By default the timing function is linear, but you could for example use this bezier-easing library: https://github.com/gre/bezier-easingconst bezierCurve = BezierEasing(0, 0, 1, 0.5); scrollTo(0, 250, {timing: bezierCurve}) const cubicIn = x => x * x * x scrollTo(0, 250, {timing: cubicIn, duration: 400})
- scrolls to the provided
State
Note: these are only provided if withCoords
is true
.
scrollX {integer}
- the current horizontal scroll position in px
scrollY {integer}
- the current vertical scroll position in px
direction {object {x <integer>, y <integer>}}
- the direction the window was just scrolled
1
=right
forx
,down
fory
-1
=left
forx
,up
fory
0
= had no direction
- the direction the window was just scrolled
distance {object {x <integer>, y <integer>}}
- the distance between the latest recorded scroll activity in the window and the previous scroll activity
width {integer}
- the
clientWidth
of thedocumentElement
- the
height {integer}
- the
clientHeight
of thedocumentElement
- the
aspect {float}
- the aspect ratio
(width / height = aspect)
- the aspect ratio
orientation {landscape|square|portrait}
- returns
landscape
whenwidth > height
,square
whenwidth == height
, andportrait
whenwidth < height
- returns
screenOrientation {null|landscape-primary|landscape-secondary|portrait-primary|portrait-secondary}
null
: when orientation.type is unavailable'landscape-primary'
: when the device is landscape oriented, e.g. a laptop andwidth > height
'landscape-secondary'
: when the device is portrait oriented, e.g. a phone andwidth > height
'portrait-primary'
: when the device is portrait oriented, e.g. a phone andwidth < height
'portrait-secondary'
: when the device is landscape oriented, e.g. a laptop andwidth < height
ViewportProvider
A top-level Viewport
component which stores the viewport state
and provides it as context to ViewportConsumer
components.
It is in the only component in this package that is a not a render-prop component.
It takes valid react elements as children.
There are several benefits to using the ViewportProvider
/ViewportConsumer
components rather than Viewport
alone. There is only one event
listener of each type in the Provider model - so O(1) state is being
throttled and consumed vs. O(n).
Usage
import {ViewportProvider} from '@render-props/viewport'
function AppViewportProvider (AppWithViewportConsumers) {
return (
<ViewportProvider>
{AppWithViewportConsumers}
</ViewportProvider>
)
}
Props
withCoords {bool} {default: true}
: iffalse
, the component will providegetScroll
,getSize
, andgetAspect
functions as opposed to{scrollX, scrollY, width, height, aspect}
ViewportConsumer
Receives context updates from ViewportProvider
when the
viewport state changes. You can configure this component to only listen to
size or scroll events by using the observe
propert. See below for more details.
Usage
import {ViewportConsumer, observe} from '@render-props/viewport'
function SomeComponent (props) {
// This consumer listens to all changes in the viewport
return (
<ViewportConsumer>
{({
width,
height,
aspect,
orientation,
screenOrientation,
scrollX,
scrollY,
scrollTo
}) => (
<div>
width: {width}
</div>
)}
</ViewportConsumer>
)
}
function ScrollingComponent (props) {
// This consumer only listens to changes in viewport scroll position
return (
<ViewportConsumer observe='scroll'>
{({scrollX}) => (
<div>
scrollX: {scrollX}
</div>
)}
</ViewportConsumer>
)
}
function SizeComponent (props) {
// This consumer only listens to size changes in the viewport
return (
<ViewportConsumer observe='size'>
{({width, height}) => (
<div>
width: {width}
</div>
)}
</ViewportConsumer>
)
}
Props
observe {string|array<string>}
- Configures the consumer to only update on changes to size or scroll position.
By default this consumer listens to all updates.
import {ViewportConsumer} from '@render-props/viewport' /** * observe.scrollX: 0b0001, * observe.scrollY: 0b0010, * observe.scroll: 0b0011, * observe.width: 0b0100, * observe.height: 0b1000, * observe.size: 0b1100, * observe.any: 0b1111, */ // listens to scroll position changes <ViewportConsumer observe='scroll'/> // listens to width and scrollY changes <ViewportConsumer observe={['width', 'scrollY']}/> // listens to all changes <ViewportConsumer/>
- Configures the consumer to only update on changes to size or scroll position.
By default this consumer listens to all updates.
Also see Viewport props
Render Props
ViewportOrientation
- Provides context for
{width, height, aspect, orientation, screenOrientation}
while receiving{width, height, aspect}
fromViewportSize
parent. - Updates each time the window size or orientation changes.
Usage
import {ViewportOrientation} from '@render-props/viewport'
function ViewportOrientationState (props) {
return (
<ViewportOrientation>
{({
width,
height,
aspect,
orientation,
screenOrientation
}) => (
<div>
orientation: {orientation}
</div>
)}
</ViewportOrientation>
)
}
Props
withCoords {bool} {default: true}
: iffalse
, the component will providegetSize
, andgetAspect
functions as opposed to{width, height, aspect}
Render Props
State
width {integer}
- the
clientWidth
of thedocumentElement
- the
height {integer}
- the
clientHeight
of thedocumentElement
- the
aspect {float}
- the aspect ratio
(width / height = aspect)
- the aspect ratio
orientation {landscape|square|portrait}
- returns
landscape
whenwidth > height
,square
whenwidth == height
, andportrait
whenwidth < height
- returns
screenOrientation {null|landscape-primary|landscape-secondary|portrait-primary|portrait-secondary}
- returns
null
if orientation.type is unavailablelandscape-primary
: when the device is landscape oriented, e.g. a laptop andwidth > height
landscape-secondary
: when the device is portrait oriented, e.g. a phone andwidth > height
portrait-primary
: when the device is portrait oriented, e.g. a phone andwidth < height
portrait-secondary
: when the device is landscape oriented, e.g. a laptop andwidth < height
- returns
ViewportSize
- Provides context for
{width, height, aspect}
. - Updates each time the window size or orientation changes.
Usage
import {ViewportSize} from '@render-props/viewport'
function ViewportSizeState (props) {
return (
<ViewportSize>
{({width, height, aspect}) => (
<div>
width: {width}
</div>
)}
</ViewportSize>
)
}
Props
withCoords {bool} {default: true}
: iffalse
, the component will providegetSize
, andgetAspect
functions as opposed to{width, height, aspect}
Render Props
State
width {integer}
- the
clientWidth
of thedocumentElement
- the
height {integer}
- the
clientHeight
of thedocumentElement
- the
aspect {float}
- the aspect ratio
(width / height = aspect)
- the aspect ratio
ViewportQueries
Provides context for {inView, inViewX, inViewY, inFullView, inFullViewX, inFullViewY}
Usage
import {ViewportQueries} from '@render-props/viewport'
function ViewportQueriesState (props) {
return (
<ViewportQueries>
{({width, height, aspect}) => (
<div>
width: {width}
</div>
)}
</ViewportQueries>
)
}
Render Props
Methods
inView
(element <DOMNode>, leeway <number|object{top, right, bottom, left}>)
- returns
true
if@element
is partially or completely visible within the window bounds, give or take@leeway
- returns
inViewX
(element <DOMNode>, leeway <number|object{top, right, bottom, left}>)
- returns
true
if@element
is partially or completely visible horizontally within the window bounds, give or take@leeway
- returns
inViewY
(element <DOMNode>, leeway <number|object{top, right, bottom, left}>)
- returns
true
if@element
is partially or completely visible vertically within the window bounds, give or take@leeway
- returns
inFullView
(element <DOMNode>, leeway <number|object{top, right, bottom, left}>)
- returns
true
if@element
is completely visible within the window bounds, give or take@leeway
- returns
inFullViewX
(element <DOMNode>, leeway <number|object{top, right, bottom, left}>)
- returns
true
if@element
is completely visible horizontally within the window bounds, give or take@leeway
- returns
inFullViewY
(element <DOMNode>, leeway <number|object{top, right, bottom, left}>)
- returns
true
if@element
is completely visible vertically within the window bounds, give or take@leeway
- returns
ViewportScroll
- Provides context for
{scrollX, scrollY, scrollTo}
- Updates each time the scroll position changes
Usage
import {ViewportScroll} from '@render-props/viewport'
function ViewportScrollState (props) {
return (
<ViewportScroll>
{({scrollX, scrollY, scrollTo, direction, distance}) => (
<div>
scrollY: {scrollY}
</div>
)}
</ViewportScroll>
)
}
Props
withCoords {bool} {default: true}
: iffalse
, the component will provide agetScroll
function as opposed to{scrollX, scrollY, width, height, aspect}
Render Props
Methods
scrollTo
(x <integer>, [y <integer>], [options <object{duration <ms>, timing <function>}>])
- scrolls to the provided
x
,y
coordinates in the window. You can optionally animate this by providing an options object with a duration. By default the timing function is linear, but you could for example use this bezier-easing library: https://github.com/gre/bezier-easingconst bezierCurve = BezierEasing(0, 0, 1, 0.5); scrollTo(0, 250, {timing: bezierCurve}) const cubicIn = x => x * x * x scrollTo(0, 250, {timing: cubicIn, duration: 400})
- scrolls to the provided
State
Note: these are only provided if withCoords
is true
.
scrollX {integer}
- the current horizontal scroll position in px
scrollY {integer}
- the current vertical scroll position in px
direction {object {x <integer>, y <integer>}}
- the direction the window was just scrolled
1
=right
forx
,down
fory
-1
=left
forx
,up
fory
0
= had no direction
- the direction the window was just scrolled
distance {object {x <integer>, y <integer>}}
- the distance between the latest recorded scroll activity in the window and the previous scroll activity