- Notifications
You must be signed in to change notification settings - Fork27
🚧 Create an invisible perimeter around an element and respond when its breached.
License
aweary/react-perimeter
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
Create an invisible padding around an element and respond when its breached.
react-perimeter exports a singlePerimeter component that will register amousemove listener and calculate whether the current mouse position is within a padding.
The padding will be calculated usinggetBoundingClientRect and thepadding prop, which lets you define "padding" for the perimeter.
<PerimeteronBreach={this.prefetch}padding={60}><buttononClick={this.fetch}>Load More</button></Perimeter>
Perimeter by default will wrap its children in aspan and use that to calculate the boundries. If you want to avoid the wrappingspan, or you want the padding to be calculated from another element, you can use a render callback.
<PerimeteronBreach={this.prefetch}padding={60}>{ref=>(<buttonref={ref}onClick={this.fetch}>Load More</button>)}</Perimeter>
The render callback is passed a ref callback which should be passed to theref prop of the element you want to use.
yarn add react-perimeter| Property | Type | Default | Description |
|---|---|---|---|
padding | number | 0 | The buffer around the element that defines the padding of the perimeter |
onBreach | () => void | undefined | A callback to be invoked when the perimeter is breached |
once | boolean | false | Whether the callback should only be invoked once (for example, when prefetching some data or chunks). If true all event listeners will be removed afteronBreach is called. |
mapListeners | EventListener => EventListener | undefined | If provided, each event listeners (resize,mousemove) will be passed in, and the returned function will be used instead. |
You may want to debounce or throttle themousemove andresize event listeners if you've profiled your application and determined that they are noticeably affecting your performance. You can do so using themapListeners prop, which takes a function that should accept an event listener and return a new function to be used instead.
<PerimetermapListeners={listener=>debounce(listener,20)}>
By letting you provide the mapped listener yourself,react-perimeter gives you full control over what debounce/throttle imeplementation you wish to use and its paramaters.
If you usereact-perimeter in multiple places in your application you may want to dedupe the internal event listeners.
react-perimiter integrates withreact-listener-provider to make deduping easy.Simplyyarn add react-listener-provider and wrap your application like this:
importReactListenerProviderfrom'react-listener-provider';<ReactListenerProvider><YourApp><Perimeter/></YourApp></ReactListenerProvider>
Any<Perimeter> component you use inside of<ReactListenerProvider> will automatically use the global event listener provided byreact-listener-provider instead of registering its own.
react-perimeter shines especially bright when used to prefetch or preload other components. Here is a small example that usesreact-loadable andreact-router to preload a route chunk when the cursor gets near a link:
importReactfrom'react'// Assume this is the component returned from `react-loadable`, not the page itselfimportOtherPagefrom'./routes/other-page'importPerimeterfrom'react-perimeter'import{Link}from'react-router'constApp=()=>(<div><h1>Home Page!</h1><p>Here's some content</p><Perimeterpadding={100}onBreach={OtherPage.preload}once={true}><Linkto="other">Other Page</Link></Perimeter></div>)
react-loadable provides an extremely useful staticpreload method that begins fetching the chunk for us. We pass this toonBreach so thatthe preloading begins as soon as the mouse is within100 pixels of theLink component. We also pass in theonce prop to tellreact-perimeterthat we only want to respond to the first breach. This means that, after the preload request has been issued, the listeners will be deregistered, removing any unneeded overhead.
We can go one step further and abstract this out into its own component,PreloadLink:
constPreloadLink=({ to, children, preload})=>(<Perimeterpadding={100}onBreach={preload.preload}once={true}><Linkto={to}>{children}</Link></Perimeter>)
<PreloadLinkto="about"preload={AboutPage}/>
About
🚧 Create an invisible perimeter around an element and respond when its breached.
Topics
Resources
License
Code of conduct
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.
Contributors6
Uh oh!
There was an error while loading.Please reload this page.