npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-showtime

v0.3.9

Published

Animate the entry/exit of React elements during mount/unmount with CSS transitions.

Downloads

74

Readme

React Showtime 🎟️ 🥁 🎭

Mount & unmount with CSS transitions

React Showtime makes it easy to apply CSS transitions to the appearance and disappearance of React elements. It automatically handles mounting and unmounting to allow time for transitions to occur.

Demo: https://react-showtime.dev/

👯 Choose between useShowtime hook and <Showtime /> component. 💃 Feels familiar: useShowtime is a near-drop-in replacement for conditional rendering with a state boolean. 💅 Specify showing styles however you like – inline, emotion, styled-components, classnames, you name it. 💨 Sensible API for defining hidden styles and custom transitions. 🎩 Included transitions: slideFade, slide, fade, rise, scale. 🎭 Symmetric or asymmetric show/hide transitions. 🕴 Zero dependencies. 3.4k min+gzip.

The essential insight of React Showtime is that the one-two sequence of React's useLayoutEffect and useEffect hooks is nicely suited to the one-two sequence of mounting a component with hidden CSS values and then applying showing CSS values to trigger the transition. As for hiding, transition event handlers trigger unmounting once the "hide" transition is complete.

What React Showtime is not

React Showtime is not for transitions that do not involve mounting/unmounting. It was created specifically as a shim for conditional rendering.

React Showtime is not for sophisticated animations, as it executes via CSS transition, not animation. Consider a more full-featured library like react-spring if you need keyframes or additional sophistication.

Getting Started

Installation

yarn add react-showtime
npm install react-showtime

tl;dr

  1. Choose between the useShowtime hook or the Showtime component. The component is better for list items or if you need to listen for events (onShowing, onHidden).
  2. Define your transition by describing the item's hidden styles with a CSS object literal. Or just pass the name of an included transition (slideFade, slide, fade, rise, scale).
  3. If using the hook, attach the supplied ref to your containing element and conditionally render your item with the supplied isMounted boolean.
  4. Call the hook's show() and hide() functions – or toggle the component's show prop – as needed.

Optionally adjust transition timing via duration, delay, easing.

You can also define asymmetric show/hide transitions (showTransition, hideTransition) and timing (showDuration, showDelay, showEasing, hideDuration, hideDelay, hideEasing).

Usage

Hook vs Component

As a rule of thumb, since you can't call hooks inside loops, use the hook when dealing with a singleton item that needs to conditionally appear or disappear (eg, a notification), and use the component when you've an indeterminate set of children that need to individually transition in and out of the DOM (eg, a list of messages).

useShowtime hook

The hook is designed to integrate with React's conditional rendering idiom. It returns an array/object containing a ref that must be attached to your element or component, an isMounted boolean that will conditionally render it, and show() and hide() functions for you to call as needed.

import React from "react";
import { useShowtime } from "react-showtime";

const HookExample = () => {
    const [ref, isMounted, show, hide] = useShowtime();

    // Or use object destructuring...
    // const {ref, isMounted, show, hide} = useShowtime();

    const toggle = () => (isMounted ? hide() : show());

    return (
        <div>
            <button onClick={toggle}>Toggle</button>
            {isMounted && <div ref={ref}>Hi there</div>}
        </div>
    );
};

Your element or component will start off showing by default. Pass { startHidden: true } to override that.

Pass { startWithTransition: true } to automatically execute the show transition when the item initially mounts. It will be ignored if startHidden is true.

Showtime component

Showtime takes a single child component. It uses useShowtime under the hood, cloning the child and adding the ref to it.

Toggle the show boolean prop to trigger show/hide.

import React, { useState } from "react";
import { Showtime } from "react-showtime";

const ComponentExample = () => {
    const [show, setShow] = useState(true);

    const toggle = () => setShow((current) => !current);

    return (
        <div>
            <button onClick={toggle}>Toggle</button>
            <Showtime show={show}>
                <div>Oh hi</div>
            </Showtime>
        </div>
    );
};

Pass startWithTransition={true} to automatically execute the show transition when the item initially mounts. It will be ignored if show is initially set to false.

Additional performance consideration

Since Showtime clones the child to attach its ref, it may be an expensive operation in some cases if the child component is substantially complicated. If so, provide a function that takes a ref and returns the child component instead, which may be more performant:

import React, { useState } from "react";
import { Showtime } from "react-showtime";

const ComponentExample = () => {
    const [show, setShow] = useState(true);

    const toggle = () => setShow((current) => !current);

    return (
        <div>
            <button onClick={toggle}>Toggle</button>
            <Showtime show={show}>
                {(ref) => <div ref={ref}>Oh hi</div>}
            </Showtime>
        </div>
    );
};

However, the direct child specification is recommended for most users.

Transitions

If you accept all defaults, you'll get a slideFade transition with a 250ms duration, 16ms delay, and "ease" easing:

// Hook
const [ref, isMounted, show, hide] = useShowtime();
// Component
<Showtime show={true}>...</Showtime>

Included transitions

React Showtime includes a set of pre-configured transitions: slideFade, slide, fade, rise, scale.

Choose one by passing its name as the hook's sole parameter or to the component's transition prop.

// Hook
const [ref, isMounted, show, hide] = useShowtime("slide");
// Component
<Showtime transition="fade" show={true}>
    ...
</Showtime>

The hook also accepts an object instead of a string, in which case pass { transition: ... }:

const [ref, isMounted, show, hide] = useShowtime({ transition: "slide" });

Timing

Adjust the transition's timing via duration, delay, and easing.

duration and delay accept integers (interpreted as milliseconds), floats (interpreted as seconds), or strings (eg, "1s" or "300ms".)

easing accepts any valid CSS transition-timing-function value.

// Hook
const [ref, isMounted, show, hide] = useShowtime({
    transition: "rise",
    duration: 1000,
    delay: 250,
    easing: "linear",
});
// Component
<Showtime
    show={true}
    transition="scale"
    duration={500}
    delay={50}
    easing="ease-out"
>

If you need different timings across show and hide transitions, use showDuration, showDelay, showEasing, and hideDuration, hideDelay, hideEasing.

Custom transitions

To define a custom transition, pass a CSS object literal describing the item's hidden state to the transition prop(erty).

Each value can be a string, number, or object. Strings and numbers will be passed through as CSS.

As an example, here's how you might define a revolve transition, where showing would mount the item then fade it in while spinning it around the y-axis. Hiding would do the reverse.

// Hook
const [ref, isMounted, show, hide] = useShowtime({
    transition: {
        transform: "rotate3d(0, 1, 0, 180deg)",
        opacity: 0,
    },
    ...
});
// Component
<Showtime
    transition={{
        transform: "rotate3d(0, 1, 0, 180deg)",
        opacity: 0,
    }}
    ...
>
Per-property timing

You can pass an object instead of a string or number as a CSS property's value. It should contain { value, duration, delay, easing } properties.

value is required and will be passed through as the CSS property's value.

The other properties are optional and will be applied to that property's transition timing, overriding any inherited timing values.

In this example, the right and top CSS properties will have a 350ms transition duration and the default "ease" easing, while opacity will take 400ms using "linear" easing.

const HookExample = () => {
    const [ref, isMounted, show, hide] = useShowtime({
        duration: 350,
        transition: {
            right: "100vw",
            top: "-100vh",
            opacity: {
                value: 0,
                duration: 400,
                easing: "linear",
            },
        },
    });

    // ...
};

Asymmetric transitions with showTransition and hideTransition

The showTransition and hideTransition properties allow you to use different transitions for showing and hiding. This is useful if, say, a notification should slide down from above, but fade away when dismissed.

Like transition, these properties accept a string (included transition) or object (custom transition). They override transition if that's also passed in.

const HookExample = () => {
    const [ref, isMounted, show, hide] = useShowtime({
        showTransition: "fade",
        hideTransition: {
            right: "100vw",
            top: "-100vh",
            opacity: 0,
        },
        hideDuration: 350,
    });

    // ...
};

Attaching the ref

The useShowtime hook provides a ref that must end up attached to the element you're showing/hiding. It uses the ref to directly assign CSS transition properties and hidden styles to the element, and to listen for transition events.

If you are transitioning an element directly, you can just pass the provided ref as a prop.

If you are transitioning a custom component, consider updating the component to use ref forwarding to pass the ref down to the component's outermost element.

If you are transitioning a component you cannot edit and that does not forward refs to its outermost element, attach the ref to a wrapper div.

Attaching multiple refs

There may be times when you need to attach your own ref to the element or component, along with React Showtime's ref. You can do this using a callback ref.

import React, { useRef } from "react";
import { useShowtime } from "react-showtime";

const MultipleRefsExample = () => {
    const myRef = useRef();
    const [showtimeRef, isMounted, show, hide] = useShowtime();

    const setRefs = (node) => {
        myRef.current = node;
        showtimeRef.current = node;
    };

    const toggle = () => (isMounted ? hide() : show());

    return (
        <>
            <button onClick={toggle}>Toggle</button>
            {isMounted && <div ref={setRefs}>Hi there</div>}
        </>
    );
};

Attaching your own ref to the Showtime component's child

If you pass a function child to the Showtime component (aka render prop), you can use a similar solution as the above to attach both your own ref and the ref Showtime supplies to the function child.

If you pass a normal JSX child to the Showtime component, the implementation is robust to any normal or callback ref you might attach yourself. Eg, in the following code, myRef will be attached as expected, along with the ref that Showtime attaches internally.

import React, { useRef } from "react";
import { Showtime } from "react-showtime";

const MultipleRefsExample = () => {
    const myRef = useRef();
    const [show, setShow] = useState(true);

    const toggle = () => setShow((current) => !current);

    return (
        <>
            <button onClick={toggle}>Toggle</button>
            <Showtime show={show}>
                <div ref={myRef}>Hi there</div>
            </Showtime>
        </>
    );
};

Events

The Showtime component accepts handlers for onHidden and onShowing. Other lifecycle events are being considered.

The useShowtime hook currently does not accept any event handlers.

API

All timing-related numbers are interpreted as milliseconds if integer, and seconds if float.

useShowtime hook

The useShowtime hook accepts a single parameter, which can be either of:

| Name | Type | Req'd | Default | Description | | --------------------- | ---------------------------- | ----- | ------------- | --------------------------------------------------------------------------------------------------------- | | startHidden | boolean | no | false | Hide the element initially | | startWithTransition | boolean | no | false | Execute show transition on initial mount. Ignored if startHidden is true. | | transition | string or CSS Properties | no | "slideFade" | Included transition or object defining custom transition (see below) | | showTransition | string or CSS Properties | no | "slideFade" | Included transition or object defining custom transition (see below) | | hideTransition | string or CSS Properties | no | "slideFade" | Included transition or object defining custom transition (see below) | | duration | number or string | no | 250 | Transition duration | | delay | number or string | no | 16 | Transition delay | | easing | string | no | "ease" | Transition timing function | | showDuration | number or string | no | | Transition duration | | showDelay | number or string | no | | Transition delay | | showEasing | string | no | | Transition timing function | | hideDuration | number or string | no | | Transition duration | | hideDelay | number or string | no | | Transition delay | | hideEasing | string | no | | Transition timing function |

Showtime component

| Name | Type | Req'd | Default | Description | | --------------------- | ---------------------------- | ----- | ------------- | --------------------------------------------------------------------------------------------------------- | | show | boolean | yes | | Toggle this to show/hide the element or component | | startWithTransition | boolean | no | false | Execute show transition on initial mount. Ignored if show initially set to false. | | transition | string or CSS Properties | no | "slideFade" | Included transition or object defining custom transition (see below) | | showTransition | string or CSS Properties | no | "slideFade" | Included transition or object defining custom transition (see below) | | hideTransition | string or CSS Properties | no | "slideFade" | Included transition or object defining custom transition (see below) | | duration | number or string | no | 250 | Transition duration | | delay | number or string | no | 16 | Transition delay | | easing | string | no | "ease" | Transition timing function | | showDuration | number or string | no | | Transition duration | | showDelay | number or string | no | | Transition delay | | showEasing | string | no | | Transition timing function | | hideDuration | number or string | no | | Transition duration | | hideDelay | number or string | no | | Transition delay | | hideEasing | string | no | | Transition timing function | | onHidden | function | no | | Called when hide transition complete. | | onShowing | function | no | | Called when show transition complete. |

Transition objects

CSS Properties

| Name | Type | Req'd | Default | Description | | ----------------------- | ------------------------------------- | ----- | ------- | --------------------------------------------------------------------------- | | [Any CSS property name] | string, number, or CSS Property | yes | | Use camelCase for names. String and number values passed directly to style. |

CSS Property

| Name | Type | Req'd | Default | Description | | ---------- | -------------------- | ----- | --------- | --------------------------------------------------------------------------------------------------------- | | value | string or number | yes | | Any CSS property name. | | duration | number or string | no | inherited | Transition duration | | delay | number or string | no | inherited | Transition delay | | easing | string | no | inherited | Transition timing function |

Development

React Showtime was originally bootstrapped with create-react-hook using this blog post as a guiding reference.

Be sure to reflect any API changes in test fixtures, the demo app in example/, the TypeScript types in index.d.ts, and this readme.

To get started:

  1. yarn start to watch for local changes to react-showtime,
  2. yarn start in example/ to watch for changes to the demo site and run a dev server.

This project uses the Git Flow branching workflow. Usage of the gitflow-cjs CLI tool is recommended for releases and hotfixes.