react-circular-reveal
Version:
Quickly and easily add Material Design's "Circular Reveal" animation in your web app.
370 lines (360 loc) • 21.5 kB
HTML
<html class="default no-js">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>react-circular-reveal</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="assets/css/main.css">
</head>
<body>
<header>
<div class="tsd-page-toolbar">
<div class="container">
<div class="table-wrap">
<div class="table-cell" id="tsd-search" data-index="assets/js/search.js" data-base=".">
<div class="field">
<label for="tsd-search-field" class="tsd-widget search no-caption">Search</label>
<input id="tsd-search-field" type="text" />
</div>
<ul class="results">
<li class="state loading">Preparing search index...</li>
<li class="state failure">The search index is not available</li>
</ul>
<a href="index.html" class="title">react-circular-reveal</a>
</div>
<div class="table-cell" id="tsd-widgets">
<div id="tsd-filter">
<a href="#" class="tsd-widget options no-caption" data-toggle="options">Options</a>
<div class="tsd-filter-group">
<div class="tsd-select" id="tsd-filter-visibility">
<span class="tsd-select-label">All</span>
<ul class="tsd-select-list">
<li data-value="public">Public</li>
<li data-value="protected">Public/Protected</li>
<li data-value="private" class="selected">All</li>
</ul>
</div>
<input type="checkbox" id="tsd-filter-inherited" checked />
<label class="tsd-widget" for="tsd-filter-inherited">Inherited</label>
<input type="checkbox" id="tsd-filter-externals" checked />
<label class="tsd-widget" for="tsd-filter-externals">Externals</label>
<input type="checkbox" id="tsd-filter-only-exported" />
<label class="tsd-widget" for="tsd-filter-only-exported">Only exported</label>
</div>
</div>
<a href="#" class="tsd-widget menu no-caption" data-toggle="menu">Menu</a>
</div>
</div>
</div>
</div>
<div class="tsd-page-title">
<div class="container">
<ul class="tsd-breadcrumb">
<li>
<a href="globals.html">Globals</a>
</li>
</ul>
<h1> react-circular-reveal</h1>
</div>
</div>
</header>
<div class="container container-main">
<div class="row">
<div class="col-8 col-content">
<div class="tsd-panel tsd-typography">
<p><a href="https://travis-ci.com/nosachamos/react-circular-reveal"><img src="https://travis-ci.com/nosachamos/react-circular-reveal.svg?branch=master" alt="Build Status"></a>
<a href="https://codecov.io/gh/nosachamos/react-circular-reveal"><img src="https://codecov.io/gh/nosachamos/react-circular-reveal/branch/master/graph/badge.svg" alt="codecov"></a></p>
<p><a href="https://github.com/prettier/prettier"><img src="https://img.shields.io/badge/styled_with-prettier-ff69b4.svg" alt="styled with prettier"></a>
<img src="https://img.shields.io/npm/v/react-circular-reveal.svg" alt="npm">
<img src="https://img.shields.io/snyk/vulnerabilities/github/nosachamos/react-circular-reveal.svg" alt="Snyk Vulnerabilities for GitHub Repo">
<img src="https://img.shields.io/github/license/nosachamos/react-circular-reveal.svg" alt="GitHub"></p>
<p><strong>react-circular-reveal</strong> allows you do quickly and easily add Material Design's "Circular Reveal" animation in your web app.</p>
<p align="center">
<img src="https://github.com/nosachamos/react-circular-reveal/raw/master/docs/_media/logo.png" alt="react-circular-reveal" style="max-width:100%;">
</p>
<br/>
<h1 id="installation">Installation</h1>
<pre><code class="language-sh">yarn add react-circular-reveal</code></pre>
<p>or</p>
<pre><code class="language-sh">npm install react-circular-reveal --save</code></pre>
<h1 id="usage">Usage</h1>
<p>The circular reveal panel manages two components: one that is displayed by default, and one that is "revealed" on top of
it when the circular reveal animation takes place. </p>
<pre><code class="language-jsx"><CircularRevealPanel
reveal={isOpened}
revealContent={
<div>
{/* When the reveal animation happens, I am displayed beautifully through a
circular reveal animation and, as long as I am not transparent, will cover
the div below */}
</div>
}
>
<div>
{/* I am displayed by default, and covered by the `revealContent` element when the
reveal animation takes place */}
</div>
</CircularRevealPanel></code></pre>
<h4 id="key-points-">Key points:</h4>
<ul>
<li><p>Set <code>reveal</code> prop to <code>true</code> to have the reveal content be displayed on top of the default content.</p>
</li>
<li><p>The reveal animation will by default open and close towards the current mouse location, which is automatically tracked fo you.
In the example above, you don't need to do anything to make it look like the content opened from the tip of the mouse cursor. Awesome!</p>
</li>
<li><p>Everything can be customized so you can be creative and build impressive user interfaces that are only normally seen in native applications.</p>
</li>
</ul>
<h2 id="example">Example</h2>
<pre><code class="language-jsx"><CircularRevealPanel
reveal={isOpened}
revealContent={
<div className={<span class="hljs-string">'revealed'</span>} onClick={() => setOpened(<span class="hljs-literal">false</span>)}>
<span class="xml"><span class="hljs-tag"><<span class="hljs-name">h2</span>></span>I am revealed with a circular animation.<span class="hljs-tag"></<span class="hljs-name">h2</span>></span></span>
<span class="xml"><span class="hljs-tag"><<span class="hljs-name">span</span>></span>(Click anywhere to close)<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>
<span class="xml"><span class="hljs-tag"><<span class="hljs-name">h1</span>></span>Awesome!<span class="hljs-tag"></<span class="hljs-name">h1</span>></span></span>
<span class="xml"><span class="hljs-tag"></<span class="hljs-name">div</span>></span></span>
}
>
<span class="xml"><span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">{</span>'<span class="hljs-attr">content</span>'} <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =></span> setOpened(true)}>
<span class="hljs-tag"><<span class="hljs-name">h1</span>></span>I am the main content<span class="hljs-tag"></<span class="hljs-name">h1</span>></span>
<span class="hljs-tag"><<span class="hljs-name">span</span>></span>(Click anywhere to trigger a circular reveal)<span class="hljs-tag"></<span class="hljs-name">span</span>></span>
<span class="hljs-tag"></<span class="hljs-name">div</span>></span></span>
<span class="xml"><span class="hljs-tag"></<span class="hljs-name">CircularRevealPanel</span>></span></span></code></pre>
<p>Results in:</p>
<p><img src="docs/_media/reveal.gif" alt="reveal animation"></p>
<h1 id="props">Props</h1>
<p>The <code>CircularRevealPanel</code> component accepts several props that can be used to setup and customize it's behavior.</p>
<h4 id="props-you-will-definitely-need">Props you will definitely need</h4>
<table>
<thead>
<tr>
<th>Prop</th>
<th>Type</th>
<th>Required</th>
<th>Default</th>
<th>Description</th>
</tr>
</thead>
<tbody><tr>
<td><code>revealContent</code></td>
<td><code>React Node</code></td>
<td>yes</td>
<td>N/A</td>
<td>Receives the content to be revealed through the circular reveal animation.</td>
</tr>
<tr>
<td><code>reveal</code></td>
<td><code>boolean</code></td>
<td>no</td>
<td><code>false</code></td>
<td>A value indicating whether to display the reveal content or not.</td>
</tr>
</tbody></table>
<h4 id="props-you-probably-won-t-need">Props you probably won't need</h4>
<table>
<thead>
<tr>
<th>Prop</th>
<th>Type</th>
<th>Required</th>
<th>Default</th>
<th>Description</th>
</tr>
</thead>
<tbody><tr>
<td><code>revealCurtainContent</code></td>
<td><code>React Node</code></td>
<td>no</td>
<td><code>undefined</code></td>
<td>Only needed for advanced customizations, this prop may be used to insert elements within the reveal curtain.</td>
</tr>
<tr>
<td><code>speed</code></td>
<td><code>string</code> or <code>function</code></td>
<td>no</td>
<td><code>normal</code></td>
<td>The valid string values are <code>very slow</code>, <code>slow</code>, <code>normal</code> (default), <code>fast</code>. Most likely these will suffice. For advanced customizations, see below.</td>
</tr>
<tr>
<td><code>contentMinWidth</code></td>
<td><code>number</code></td>
<td>no</td>
<td>500</td>
<td>The minimum width for the content to be revealed, in pixels. This prevents the content from appear to rearrange as the curtain expands.</td>
</tr>
</tbody></table>
<h1 id="events">Events</h1>
<p>The <code>CircularRevealPanel</code> component accepts an <code>onChange</code> event handler which is invoked when the opening and closing operations start and finish. It gives you access to the raw HTML elements used to </p>
<p>The event object argument contains three properties of interest:</p>
<ul>
<li>The<code>type</code> property which kind of event this is. It can be of the following: <code>CURTAIN_OPENING</code>, <code>CURTAIN_OPENED</code>, <code>CURTAIN_CLOSING</code>, <code>'CURTAIN_CLOSED</code>.</li>
<li>The <code>curtainElemRef</code> and <code>revealContentRef</code> the properties are references to the raw HTML div elements used as a reveal curtain and reveal content, respectively. Only needed for advanced customizations.</li>
</ul>
<p>Assume this following setup:</p>
<pre><code class="language-jsx"> <span class="hljs-keyword">const</span> handleOnChange = useCallback(<span class="hljs-function">(<span class="hljs-params">e: CurtainEvent</span>) =></span> {
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'EVENT TYPE: '</span> + e.type);
}, []);
<span class="xml"><span class="hljs-tag"><<span class="hljs-name">CircularRevealPanel</span>
<span class="hljs-attr">onChange</span>=<span class="hljs-string">{handleOnChange}</span>
<span class="hljs-attr">revealContent</span>=<span class="hljs-string">{</span>
<span class="hljs-attr">...</span>
}
></span>
...
<span class="hljs-tag"></<span class="hljs-name">CircularRevealPanel</span>></span></span></code></pre>
<p>In this case, opening and closing the reveal content would result in four console log print outs:</p>
<pre><code class="language-sh">EVENT TYPE: CURTAIN_OPENING
EVENT TYPE: CURTAIN_OPENED
EVENT TYPE: CURTAIN_CLOSING
EVENT TYPE: CURTAIN_CLOSED</code></pre>
<h1 id="advanced-customizations">Advanced Customizations</h1>
<h2 id="customizing-the-opening-closing-speed">Customizing the opening/closing <code>speed</code></h2>
<p>The speed with which to open or close the circular reveal animation. Can be a <code>string</code> or a <code>function</code>.</p>
<p>The valid string values are <code>very slow</code>, <code>slow</code>, <code>normal</code> (default), <code>fast</code>. Most likely these will suffice.</p>
<p>If you find however that you need to further customize it, you may pass in a function which will be invoked on every step of the reveal animation and must return the next size for the <em>reveal curtain</em> (the circular region that displays the reveal content). </p>
<p>This function is given two parameters - the current size of the reveal curtain, and whether the curtain is opening or closing.</p>
<p>For reference, this is the function that implements the <code>normal</code> speed:</p>
<pre><code class="language-jsx"><span class="hljs-keyword">const</span> resizeCurtainFunction = <span class="hljs-function">(<span class="hljs-params">size, opening</span>) =></span> {
<span class="hljs-keyword">return</span> opening ? size + <span class="hljs-built_in">Math</span>.max(size/<span class="hljs-number">3</span>, <span class="hljs-number">5</span>) : size - <span class="hljs-built_in">Math</span>.max(size/<span class="hljs-number">3</span>, <span class="hljs-number">5</span>);
};
<span class="xml"><span class="hljs-tag"><<span class="hljs-name">CircularRevealPanel</span>
<span class="hljs-attr">reveal</span>=<span class="hljs-string">{isOpened}</span>
<span class="hljs-attr">speed</span>=<span class="hljs-string">{resizeCurtainFunction}</span>
<span class="hljs-attr">revealContent</span>=<span class="hljs-string">{</span>
<span class="hljs-attr">...</span>
}
></span>
...
<span class="hljs-tag"></<span class="hljs-name">CircularRevealPanel</span>></span></span></code></pre>
<h2 id="overriding-styles">Overriding styles</h2>
<p>The styles of all three elements composing the <code>CircularRevealPanel</code> component can be overridden to further customize it.</p>
<p>To do so, add or override styles to the following classes:</p>
<ul>
<li><code>circular-reveal__overlay</code> - the class of the outermost container that holds both de default content as well as the reveal content. </li>
<li><code>circular-reveal__revealCurtain</code> - the class of the element that serves as our circular reveal curtain.</li>
<li><code>circular-reveal__revealContent</code> - the class of the element that holds the reveal content.</li>
</ul>
<p>Common use cases for overriding or extending such these styles include specifying a <code>z-index</code> and setting a <code>height</code> so that they will
cover the entire screen.</p>
<h1 id="demo-app">Demo app</h1>
<p>This project includes a demo app where this component can be seen in action.</p>
<p>To run the demo app locally, clone this repository, then open the terminal and navigate to the location where you closed it. Finally, run <code>npm start</code> from within the <code>demo=app</code> folder, then open the address <code>http://localhost:3000/</code> on your browser.</p>
<p><img src="docs/_media/reveal-demo-app.gif" alt="demo app"></p>
<h1 id="contributing">Contributing</h1>
<p>Contributions are very welcome!</p>
<p>We follow the "fork-and-pull" Git workflow.</p>
<ol>
<li><strong>Create a Fork and clone it</strong></li>
<li><strong>Modify the Code</strong></li>
<li><strong>Push your Changes</strong></li>
<li><strong>Create a Pull Request</strong></li>
</ol>
<h2 id="license">License</h2>
<p>MIT</p>
<hr>
<p>Created and maintained by <strong><a href="http://github.com/nosachamos"><code>Eduardo Born</code></a></strong> with ❤ and coffee</p>
</div>
</div>
<div class="col-4 col-menu menu-sticky-wrap menu-highlight">
<nav class="tsd-navigation primary">
<ul>
<li class="globals ">
<a href="globals.html"><em>Globals</em></a>
</li>
</ul>
</nav>
<nav class="tsd-navigation secondary menu-sticky">
<ul class="before-current">
<li class=" tsd-kind-class">
<a href="classes/curtainevent.html" class="tsd-kind-icon">Curtain<wbr>Event</a>
</li>
<li class=" tsd-kind-interface tsd-is-not-exported">
<a href="interfaces/props.html" class="tsd-kind-icon">Props</a>
</li>
<li class=" tsd-kind-type-alias">
<a href="globals.html#calculatecurtainsize" class="tsd-kind-icon">Calculate<wbr>Curtain<wbr>Size</a>
</li>
<li class=" tsd-kind-type-alias">
<a href="globals.html#eventtype" class="tsd-kind-icon">Event<wbr>Type</a>
</li>
<li class=" tsd-kind-type-alias">
<a href="globals.html#revealspeed" class="tsd-kind-icon">Reveal<wbr>Speed</a>
</li>
<li class=" tsd-kind-function">
<a href="globals.html#circularrevealpanel" class="tsd-kind-icon">Circular<wbr>Reveal<wbr>Panel</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<footer class="with-border-bottom">
<div class="container">
<h2>Legend</h2>
<div class="tsd-legend-group">
<ul class="tsd-legend">
<li class="tsd-kind-module"><span class="tsd-kind-icon">Module</span></li>
<li class="tsd-kind-object-literal"><span class="tsd-kind-icon">Object literal</span></li>
<li class="tsd-kind-variable"><span class="tsd-kind-icon">Variable</span></li>
<li class="tsd-kind-function"><span class="tsd-kind-icon">Function</span></li>
<li class="tsd-kind-function tsd-has-type-parameter"><span class="tsd-kind-icon">Function with type parameter</span></li>
<li class="tsd-kind-index-signature"><span class="tsd-kind-icon">Index signature</span></li>
<li class="tsd-kind-type-alias"><span class="tsd-kind-icon">Type alias</span></li>
</ul>
<ul class="tsd-legend">
<li class="tsd-kind-enum"><span class="tsd-kind-icon">Enumeration</span></li>
<li class="tsd-kind-enum-member"><span class="tsd-kind-icon">Enumeration member</span></li>
<li class="tsd-kind-property tsd-parent-kind-enum"><span class="tsd-kind-icon">Property</span></li>
<li class="tsd-kind-method tsd-parent-kind-enum"><span class="tsd-kind-icon">Method</span></li>
</ul>
<ul class="tsd-legend">
<li class="tsd-kind-interface"><span class="tsd-kind-icon">Interface</span></li>
<li class="tsd-kind-interface tsd-has-type-parameter"><span class="tsd-kind-icon">Interface with type parameter</span></li>
<li class="tsd-kind-constructor tsd-parent-kind-interface"><span class="tsd-kind-icon">Constructor</span></li>
<li class="tsd-kind-property tsd-parent-kind-interface"><span class="tsd-kind-icon">Property</span></li>
<li class="tsd-kind-method tsd-parent-kind-interface"><span class="tsd-kind-icon">Method</span></li>
<li class="tsd-kind-index-signature tsd-parent-kind-interface"><span class="tsd-kind-icon">Index signature</span></li>
</ul>
<ul class="tsd-legend">
<li class="tsd-kind-class"><span class="tsd-kind-icon">Class</span></li>
<li class="tsd-kind-class tsd-has-type-parameter"><span class="tsd-kind-icon">Class with type parameter</span></li>
<li class="tsd-kind-constructor tsd-parent-kind-class"><span class="tsd-kind-icon">Constructor</span></li>
<li class="tsd-kind-property tsd-parent-kind-class"><span class="tsd-kind-icon">Property</span></li>
<li class="tsd-kind-method tsd-parent-kind-class"><span class="tsd-kind-icon">Method</span></li>
<li class="tsd-kind-accessor tsd-parent-kind-class"><span class="tsd-kind-icon">Accessor</span></li>
<li class="tsd-kind-index-signature tsd-parent-kind-class"><span class="tsd-kind-icon">Index signature</span></li>
</ul>
<ul class="tsd-legend">
<li class="tsd-kind-constructor tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited constructor</span></li>
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited property</span></li>
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited method</span></li>
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited accessor</span></li>
</ul>
<ul class="tsd-legend">
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected property</span></li>
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected method</span></li>
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected accessor</span></li>
</ul>
<ul class="tsd-legend">
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private property</span></li>
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private method</span></li>
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private accessor</span></li>
</ul>
<ul class="tsd-legend">
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-static"><span class="tsd-kind-icon">Static property</span></li>
<li class="tsd-kind-call-signature tsd-parent-kind-class tsd-is-static"><span class="tsd-kind-icon">Static method</span></li>
</ul>
</div>
</div>
</footer>
<div class="container tsd-generator">
<p>Generated using <a href="http://typedoc.org/" target="_blank">TypeDoc</a></p>
</div>
<div class="overlay"></div>
<script src="assets/js/main.js"></script>
<script>if (location.protocol == 'file:') document.write('<script src="assets/js/search.js"><' + '/script>');</script>
</body>
</html>