DEV Community

Soichi Takamura
Soichi Takamura

Posted on • Edited on

react-kindness: A customizable screen guide for React

I just published a simple screen guide component of React. Please take a look.

👉 react-kindness Demo
👉 react-kindness README

The motivation of the development is thought that using SVG mask and pointer-events: none should be able to implement screen guide simple. Other libraries often place 4 absolutely-positioned dark divs around a focused element, which determines it cannot draw a circle spot in the overlay. SVG mask of course can.

Another implementation makes a target element to be position: relative; z-index: 9999999 !important; to let users "touch" the element and hide any other elements with an overlay div, which seems a cool solution at a first glance. However, I wonder whether we have to block user interactions during a screen guide. Rather, users may want to click an anchor link or click a bell icon to check recent notifications on the page, don't they?

react-kindness is a simple UI guide that doesn't block user interaction. Just shows a spot in an overlay, a message panel containing "prev" and "next" buttons and that's it.

Here is a minimum example of usage.

import {KindnessPanel, Kindness} from 'react-kindness';
import 'react-kindness/dist/index.css';

// ...
    <KindnessPanel
        enabled={this.state.show}
        onExit={() => this.setState({show: false})} />
Enter fullscreen mode Exit fullscreen mode

You probably want to switch on/off the guide, so keep the state within your component as this.state.show above. Please don't forget to disable it on a onExit event hook.

<Kindness>
    <input type="text" {...} />
</Kindness>

<Kindness message="Click here to submit your post!">
    <button type="submit">
        Submit
    </button>
</Kindness>
Enter fullscreen mode Exit fullscreen mode

Then wrap your elements with <Kindness /> which a spot will track. The other attributes like title and order are also available. Please refer to README for the documentation.

About blocking user interactions, if you feel like it, you can return false in onClickOutside. react-kindness will take care of disabling the user action for you.

    <KindnessPanel
        // ...
        onClickOutside={() => false} />
Enter fullscreen mode Exit fullscreen mode

And next, this is another thing I wanted to try, a "function as a component" pattern of React Component development. Using that, the panel content of react-kindness is fully customizable.

Internally, the panel content is implemented as <KindnessPanelContent /> that renders a message and buttons. Instead of using the default content, you can render arbitrary elements inside the panel.

import Button from '@material-ui/core/Button';

// ...

<KindnessPanel enabled={true}>
    {
        ({message, totalSize, currentIndex, goNext, goPrev}) => (
            <div>
                <h3>{message}</h3>
                <h4>{`You are seeing ${currentIndex + 1} of ${totalSize} in the guide.`}</h4>
                <Button action={goPrev}>Go previous</Button>
                <Button action={goNext}>Go next</Button>
            </div>
        )
    }
</KindnessPanel>
Enter fullscreen mode Exit fullscreen mode

Also, the styles of the panel and spot can be modified as you wish.

Finally, I'd like to say I appreciate a project Popper.js which react-kindness heavily depends on. Its functionalities of DOM positioning are comprehensive and sophisticated so that I could read and trace the code easily and utilize the functions that Popper.js exports for external developers like me. The architecture to modify positioning step by step in modifiers is just cool and extensible. If you face problems of DOM positioning, try Popper.js 👍

Top comments (1)

Collapse
 
ben profile image
Ben Halpern

Very nice 👌