# @render-props/viewport

> State containers which provide an interface for listening and responding to window events in a scalable fashion.

Latest version **0.3.1** (published 2019-03-20) · MIT license · 0 weekly downloads

## Install

```sh
npm install @render-props/viewport
pnpm add @render-props/viewport
yarn add @render-props/viewport
bun add @render-props/viewport
```

## Health

**Score 20/100 (F)** — status: abandoned.

Positive: esm support; no vulnerabilities.

Warnings: low downloads; no types; pre 1.0.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.3.1 |
| Published | 2019-03-20 |
| First published | 2018-02-06 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | ESM + CommonJS |
| Dependencies | 6 |
| Unpacked size | 66.3 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 36 |
| Author | Jared Lunde |
| Maintainers | jaredlunde |
| Keywords | react, render props, function as child, hoc, state container, viewport, window, window size, window scroll, window orientation, viewport size, viewport scroll, viewport orientation |

## Links

- npm: https://www.npmjs.com/package/@render-props/viewport
- Repository: https://github.com/jaredlunde/render-props/tree/master/packages/viewport
- npm.io page: https://npm.io/package/@render-props/viewport

## Dependencies (6)

- [@babel/runtime](https://npm.io/package/@babel/runtime.md) ^7.4.0
- [@render-props/rect](https://npm.io/package/@render-props/rect.md) ^0.1.21
- [@render-props/utils](https://npm.io/package/@render-props/utils.md) ^0.2.11
- [@render-props/events](https://npm.io/package/@render-props/events.md) ^0.1.12
- [@render-props/throttle](https://npm.io/package/@render-props/throttle.md) ^0.1.15
- [@render-props/scrollable](https://npm.io/package/@render-props/scrollable.md) ^0.1.19

## Alternatives

- [mobx-react](https://npm.io/package/mobx-react.md) — 2.8M weekly downloads
- [rc-tree](https://npm.io/package/rc-tree.md) — 2.6M weekly downloads
- [@react-oauth/google](https://npm.io/package/@react-oauth/google.md) — 1.3M weekly downloads
- [@wagmi/connectors](https://npm.io/package/@wagmi/connectors.md) — 877.0K weekly downloads
- [vee-validate](https://npm.io/package/vee-validate.md) — 836.4K weekly downloads

## Recent versions

- 0.3.1 (latest) — 2019-03-20
- 0.2.0-alpha.11 (next) — 2018-03-16
- 0.3.0 — 2019-02-25
- 0.2.18 — 2019-02-22
- 0.2.17 — 2019-02-22
- 0.2.16 — 2019-01-31
- 0.2.15 — 2019-01-12
- 0.2.14 — 2018-12-29
- 0.2.13 — 2018-09-11
- 0.2.12 — 2018-09-10
- 0.2.11 — 2018-08-21
- 0.2.10 — 2018-08-20
- 0.2.9 — 2018-08-18
- 0.2.8 — 2018-08-18
- 0.2.7 — 2018-08-18
- … 41 more at https://npm.io/package/@render-props/viewport/versions

## 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`**](#viewport)
  - Component which provides context from `ViewportOrientation`, and `ViewportScroll`
- [**`ViewportProvider`**](#viewportprovider)
  - A top-level `Viewport` component which stores the viewport state
    and provides it as context to `ViewportConsumer` components.
- [**`ViewportConsumer`**](#viewportconsumer)
  - Receives context updates from `ViewportProvider` when the viewport state changes
- [**`ViewportOrientation`**](#viewportorientation)
  - Provides context for `{width, height, aspect, orientation, screenOrientation}`
    while receiving `{width, height, aspect}` from `ViewportSize` parent.
  - Updates each time the window size or orientation changes.
- [**`ViewportSize`**](#viewportsize)
  - Provides context for `{width, height, aspect}`.
  - Updates each time the window size or orientation changes.
- [**`ViewportQueries`**](#viewportqueries)
  - Provides context for `{inView, inViewX, inViewY, inFullView, inFullViewX, inFullViewY}`
- [**`ViewportScroll`**](#viewportscroll)
  - Provides context for `{scrollX, scrollY, scrollTo, distance, direction}`
  - Updates each time the scroll position changes

____

# Viewport
God component which provides context from [`ViewportOrientation`](#viewportorientation), and [`ViewportScroll`](#viewportscroll)

## Usage
```js
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-easing
    ```js
    const 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})
    ```

#### 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` for `x`, `down` for `y`
    - `-1` = `left` for `x`, `up` for `y`
    - `0` = had no direction
- `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 the `documentElement`
- `height {integer}`
  - the `clientHeight` of the `documentElement`
- `aspect {float}`
  - the aspect ratio `(width / height = aspect)`
- `orientation {landscape|square|portrait}`
  - returns `landscape` when `width > height`, `square` when `width == height`,
    and `portrait` when `width < height`
- `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 and `width > height`
  - `'landscape-secondary'`: when the device is portrait oriented, e.g. a phone and `width > height`
  - `'portrait-primary'`: when the device is portrait oriented, e.g. a phone and `width < height`
  - `'portrait-secondary'`: when the device is landscape oriented, e.g. a laptop and `width < height`

____

# ViewportProvider
A top-level `Viewport` component which stores the viewport state
and provides it as context to [`ViewportConsumer`](#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
```js
import {ViewportProvider} from '@render-props/viewport'


function AppViewportProvider (AppWithViewportConsumers) {
  return (
    <ViewportProvider>
      {AppWithViewportConsumers}
    </ViewportProvider>
  )
}
```

____

## Props
- `withCoords {bool} {default: true}`: if `false`, the component will provide
  `getScroll`, `getSize`, and `getAspect` functions as opposed to
  `{scrollX, scrollY, width, height, aspect}`

____

# ViewportConsumer
Receives context updates from [`ViewportProvider`](#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
```js
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.
    ```js
      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/>
    ```

Also see [Viewport props](#props)

## Render Props
See [Viewport render props](#render-props)

____

# ViewportOrientation
- Provides context for `{width, height, aspect, orientation, screenOrientation}`
  while receiving `{width, height, aspect}` from [`ViewportSize`](#viewportsize)
  parent.
- Updates each time the window size or orientation changes.

## Usage
```js
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}`: if `false`, the component will provide
  `getSize`, and `getAspect` functions as opposed to `{width, height, aspect}`

## Render Props

#### State
- `width {integer}`
  - the `clientWidth` of the `documentElement`
- `height {integer}`
  - the `clientHeight` of the `documentElement`
- `aspect {float}`
  - the aspect ratio `(width / height = aspect)`
- `orientation {landscape|square|portrait}`
  - returns `landscape` when `width > height`, `square` when `width == height`,
    and `portrait` when `width < height`
- `screenOrientation {null|landscape-primary|landscape-secondary|portrait-primary|portrait-secondary}`
  - returns `null` if orientation.type is unavailable
    - `landscape-primary`: when the device is landscape oriented, e.g. a laptop and `width > height`
    - `landscape-secondary`: when the device is portrait oriented, e.g. a phone and `width > height`
    - `portrait-primary`: when the device is portrait oriented, e.g. a phone and `width < height`
    - `portrait-secondary`: when the device is landscape oriented, e.g. a laptop and `width < height`

____

# ViewportSize
- Provides context for `{width, height, aspect}`.
- Updates each time the window size or orientation changes.

## Usage
```js
import {ViewportSize} from '@render-props/viewport'

function ViewportSizeState (props) {
  return (
    <ViewportSize>
      {({width, height, aspect}) => (
        <div>
          width: {width}
        </div>
      )}
    </ViewportSize>
  )
}
```

____

## Props
- `withCoords {bool} {default: true}`: if `false`, the component will provide
  `getSize`, and `getAspect` functions as opposed to `{width, height, aspect}`

## Render Props

#### State
- `width {integer}`
  - the `clientWidth` of the `documentElement`
- `height {integer}`
  - the `clientHeight` of the `documentElement`
- `aspect {float}`
  - the aspect ratio `(width / height = aspect)`

____

# ViewportQueries
Provides context for `{inView, inViewX, inViewY, inFullView, inFullViewX, inFullViewY}`

## Usage
```js
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`
- `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`
- `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`
- `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`
- `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`
- `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`

____

# ViewportScroll
- Provides context for `{scrollX, scrollY, scrollTo}`
- Updates each time the scroll position changes

## Usage
```js
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}`: if `false`, the component will provide
  a `getScroll` 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-easing
    ```js
    const 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})
    ```

#### 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` for `x`, `down` for `y`
    - `-1` = `left` for `x`, `up` for `y`
    - `0` = had no direction
- `distance {object {x <integer>, y <integer>}}`
  - the distance between the latest recorded scroll activity in the window and
    the previous scroll activity

---
_Source: https://npm.io/package/@render-props/viewport · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
