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-modal-portal

v0.0.4

Published

Customizable, optionally styled modal dialog component

Downloads

10

Readme

react-modal-portal

NPM version Release XO code style

Components

The modal components are layout components which render their children into a modal container, either at a specific place in the DOM (portals) or in-place.

By default, modals are rendered to the end of the document's body.

Modal

The naked component (with no styles applied) is exported as Modal. The markup produced does apply some CSS classnames, and should render some markup similar to the following sample.

<div class="modal">
    <div class="backdrop"></div>
    <div class="window">
        <div class="title">
            <label for="x">
                <!-- title -->
            </label>
            <span tabIndex="9999" class="icon" role="button">
                &times;
            </span>
        </div>
        <div id="x" class="content">
            <!-- child content -->
        </div>
    </div>
</div>

StyledModal

This is the naked modal wrapped with styled-components and a default theme.

Some basic examples showing the default styles and bundled triggers are available at https://dominicbirch.github.io/react-modal-portal.

There are many ways to customize the appearance of the modal some suggestions which immediately sprint to mind are as follows.

Style it from scratch

To do this, just work with the naked Modal component and override using the class names it renders.

.modal {
    .backdrop {
        background-color: hotpink;
    }
}

The main advantage to doing this will be that there is minimal overhead, no need for styled-components, themes, or any of the default styles in your bundle.

This approach also gives you immediate control over how to chunk and serve your styles, whether that's in CSS or JS.

Provide a theme

If you are already using a styled-components theme, you will notice that the library adds a modal property to the default theme's abstraction; you can use this to adjust the basic settings of the default theme.

Even if you aren't using styled-components, you can pass it a theme object; either by adding a styled-components theme context to your app, or by passing one in to the modal's props.

You might decide to make some small changes like removing the whitespace to create a minimal layout container, then let the child content handle appearance for exmaple.

import React from "react";
import StyledModal, { defaultTheme } from "react-modal-portal";

export default () => 
    <StyledModal theme={{modal: { ...defaultTheme.modal, whitespace: 0 }}}>
        {/* your child content here */}
    </StyledModal>;

Higher-Order Components

The following may be used to augment the modal components as you see fit; they are intentionally kept separate rather than exporting lots of variations to offer more control with a smaller output.

Layouts

The library exports a Higher-Order Component factory, withLayout, which may be used to apply a given layout component to other components without repeatedly adding them to TSX/JSX with every usage. The HOC may be used with any component which accepts children.

The withLayout Higher-Order Component can be applied to class components as a decorator, as shown in the following example.

import React from "react";
import StyledModal from "react-modal-portal";

type Props = {
    onClose?: () => void;
    onChange?: (value: any) => void;
};

@withLayout(StyledModal, ({onClose}) => ({
    onClose,
    title: "Have you considered giving us more money?",
}))
export class Upsell extends React.Component<Props> {
    // ...
}

The named class export is replaced with a React.ComponentType<Props> where the defaultProps of Upsell are preserved, and the displayName is set as withStyledModal(Upsell).

Alternatively, it may also be applied without the decorator syntax above as follows.

export function Confirmation() {
    // ...
}

export const ConfirmationModal = withLayout(StyledModal, () => ({
    title: "Are you sure?",
}))(Confirmation);

Toggles

These functions can be used to reduce repetition of showing/hiding modals in response to clicking buttons, links.

toggled(componentType)

This is a simple Higher-Order Component or component decorator; use this when you want to augment a ModalLike component to include a toggle control, adding props to control the toggle used.

import { toggled, StyledModal } from "react-modal-portal";

export const ModalWithToggle = toggled(StyledModal);

withToggle(toggleOptions)(componentType)

This is a Higher-Order Component factory which can be used to create a decorator which creates a specific toggle for a ModalLike component, preserving the original ModalLike component's props.

Apply it as a decorator as follows:

import { withToggle, ModalProps } from "react-modal-portal";

@withToggle({
    kind: "button",
    label: "Show me the modal!",
})
export default class MyFancyModal extends React.Component<ModalProps> {
    // ...
}

Or alternatively,

import { withToggle, StyledModal } from "react-modal-portal";

export const ModalWithToggleButton = withToggle({ 
    kind: "button",
    label: "show",
    hideLabel: "hide",
})(StyledModal);

Hooks

All of the logical aspects of the modal components are exported as hooks; this should help if there's a need to create a different modal component with the same props/behavior.

  • useToggle - Returns a ToggleState for the given props.
  • useModalContainer - Returns a DOM reference for use as a portal target.
  • useBodyScrollLock - Used to control scrolling of background content.