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-dialog-mui

v0.1.1

Published

This React library simplifies the usage of Material-UI dialogs, removing the need to manage states manually.

Downloads

26

Readme

react-dialog-mui

This React library simplifies the usage of Material-UI dialogs, removing the need to manage states manually. It offers convenient replicas of standard JavaScript dialog methods such as alert, confirm, and prompt, streamlining the implementation of common UX flows.

The library internally utilizes React Context to handle states, ensuring compatibility with most versions of React from version 17 onward.

Why?

The MUI Dialogs codebase is overly complex and lacks functionality. While the built-in JavaScript methods for alert, confirm, and prompt offer simplicity, they're not customizable and may fall short for complex scenarios.

My aim with this library is to create a user-friendly solution that meets both ease-of-use and complex use case requirements.

How to use?

npm install --save react-dialog-mui

yarn add react-dialog-mui

I've created some repos using Create React Application script. You can reference the sample repos here:

  • With typescript: https://github.com/synle/react-dialog-mui-cra-ts-sample
  • With javascript: https://github.com/synle/react-dialog-mui-cra-js-sample

Add the action dialog context to your root

To begin, wrap your app with ActionDialogsContext, a React context consumer that manages the dialog stack state.

// then wrap your app with with the ActionDialogContext
import { ActionDialogsContext } from 'react-dialog-mui';

function YourApp() {
  return (
    <ActionDialogsContext>
      <YourAppComponent />
    </ActionDialogsContext>
  );
}

Use the ActionDialog hooks

Alert

This alerts a simple message with an OK button, informing the user of an event. Useful for displaying messages.

image

import React from 'react';
import { useActionDialogs } from 'react-dialog-mui';

export function AlertExample() {
  const { alert } = useActionDialogs();

  const onSubmit = async () => {
    try {
      await alert({
        title: <>Query Result</>,
        message: <>The query has successfully executed, yielding 200 records in 15 seconds.</>,
        yesLabel: `Acknowledge`,
      });
    } catch (err) {}
  };

  return <button onClick={onSubmit}>My Action</button>;
}

Confirm

This prompts the user for a yes or no confirmation regarding an event.

image

import React, { useState } from 'react';
import { useActionDialogs } from 'react-dialog-mui';

export function ConfirmExample() {
  const { confirm } = useActionDialogs();
  const [deleted, setDeleted] = useState(false);

  const onSubmit = async () => {
    try {
      await confirm({
        title: <>Confirmation?</>,
        message: <>Do you want to delete this query?</>,
        yesLabel: `Delete`,
      });

      // when user selects yes
      setDeleted(true);
    } catch (err) {
      // when user selects no
      setDeleted(false);
    }
  };

  return (
    <>
      <button onClick={onSubmit}>Delete Query?</button>
      <div>
        Status:
        {deleted ? <>This query has been deleted</> : null}
      </div>
    </>
  );
}

Prompt

This is a basic text input for requesting user input in free-form text, ideal for short-and-single inputs.

image

import React, { useState } from 'react';
import { useActionDialogs } from 'react-dialog-mui';

export function PromptExample() {
  const { prompt } = useActionDialogs();
  const [name, setName] = useState('');

  const onSubmit = async () => {
    try {
      const newName = await prompt({
        title: 'Rename Query',
        message: 'New Query Name',
        value: name,
        saveLabel: 'Save',
      });

      // when user entered and submitted the value for new name
      setName(newName);
    } catch (err) {}
  };

  return (
    <>
      <button onClick={onSubmit}>Rename Query?</button>
      <div>
        <strong>New query name:</strong> {name}
      </div>
    </>
  );
}

Single Select Choice

This presents a list of options for the user to choose from, similar to a single-select dropdown. The user must select one option.

image

import React, { useState } from 'react';
import { useActionDialogs } from 'react-dialog-mui';

export function SingleSelectChoiceExample() {
  const { choiceSingle } = useActionDialogs();
  const [session, setSession] = useState('');

  const onSubmit = async () => {
    try {
      const newSession = await choiceSingle({
        title: 'Switch session', // the dialog title
        message: 'Select one of the following sessions:', // the question for the input
        options: [
          { label: 'Session 1', value: 'session_1' },
          { label: 'Session 2', value: 'session_2' },
          { label: 'Session 3', value: 'session_3' },
          { label: 'Session 4', value: 'session_4', disabled: true },
        ],
        value: session,
        required: true,
      });

      // when user selected a choice
      setSession(newSession);
    } catch (err) {
      setSession('');
    }
  };

  return (
    <>
      <button onClick={onSubmit}>Switch Session</button>
      <div>
        <strong>New selected session:</strong> {session}
      </div>
    </>
  );
}

Multi Select Choice

This presents a list of options for the user to choose from, similar to a checkbox list. The user can select more than options from the list.

image

import React, { useState } from 'react';
import { useActionDialogs } from 'react-dialog-mui';

export function MultiSelectChoiceExample() {
  const { choiceMultiple } = useActionDialogs();
  const [favContacts, setFavContacts] = useState<string[]>([]);

  const onSubmit = async () => {
    try {
      const newFavContacts = await choiceMultiple({
        title: 'Update Favorite Contacts',
        message: 'Select contacts to add to the favorite list:',
        options: [
          { label: 'John Doe', value: 'John Doe' },
          { label: 'Alice Smith', value: 'Alice Smith' },
          { label: 'Michael Johnson', value: 'Michael Johnson', disabled: true },
          { label: 'Emily Brown', value: 'Emily Brown' },
          { label: 'Daniel Wilson', value: 'Daniel Wilson' },
        ],
        value: favContacts,
        required: true,
      });

      // when user selected a choice
      setFavContacts(newFavContacts);
    } catch (err) {
      setFavContacts([]);
    }
  };

  return (
    <>
      <button onClick={onSubmit}>Update Favorite Contacts</button>
      <div>
        <strong>New selected favorite contacts:</strong> {JSON.stringify(favContacts)}
      </div>
    </>
  );
}

Modal

This displays custom modal content, suitable for complex use cases.

image

function ModalExample() {
  const { modal } = useActionDialogs();

  const onSubmit = async () => {
    try {
      await modal({
        title: 'Query Details',
        message: (
          <>
            <div>
              <strong>Name:</strong> Sample Mocked Query
            </div>
            <div>
              <strong>Status:</strong> Pending
            </div>
            <div>
              <strong>Created Date:</strong> {new Date().toLocaleDateString()}
            </div>
          </>
        ),
      });

      // when users close out of modal
    } catch (err) {}
  };

  return (
    <>
      <button onClick={onSubmit}>Show Details</button>
    </>
  );
}

Reference your own component

If you prefer not to use inline components, you can define your component separately and then include it in the react hook.

image

import { useActionDialogs } from 'react-dialog-mui';

function MyChildComponent() {
  return (
    <>
      <div>Hello world</div>
    </>
  );
}

export function ModalExampleWithChildComponent() {
  const { modal } = useActionDialogs();

  const onSubmit = async () => {
    try {
      await modal({
        title: 'Simple Modal',
        message: <MyChildComponent />,
        modalRef: modalRef,
        size: 'sm',
      });

      // when users close out of modal
    } catch (err) {}
  };

  return (
    <>
      <button onClick={onSubmit}>Show Modal</button>
    </>
  );
}
Dismiss the modal programmatically

Manual dismissal post-action, like form submission or interactions can be achieved via useActionDialogRef and dismiss(). Here's a sample code snippet.

Simplest example with Alert

This example shows how to set up modalRef and calling dismiss to dimiss the alert

import { useActionDialogs, useActionDialogRef } from 'react-dialog-mui';

export function AlertExampleWithManualDismiss() {
  const { alert } = useActionDialogs();
  const modalRef = useActionDialogRef();

  const onSubmit = async () => {
    try {
      await alert({
        title: <>Query Result</>,
        message: (
          <>
            <div>The query has successfully executed.</div>
            <button onClick={() => modalRef.current.dismiss()}>Close this modal and retry</button>
          </>
        ),
        modalRef,
      });
    } catch (err) {}
  };

  return <button onClick={onSubmit}>My Action</button>;
}
Dismiss via button click

This example features a modal with a dismiss button, allowing control from your component.

image

import React from 'react';
import { useActionDialogRef, useActionDialogs } from 'react-dialog-mui';

export function ModalExampleWithManualDismiss() {
  const { modal } = useActionDialogs();
  const modalRef = useActionDialogRef();

  const onSubmit = async () => {
    try {
      await modal({
        title: 'Manual Dismiss Modal',
        message: (
          <>
            <div>
              <button onClick={() => modalRef.current.dismiss()}>
                Manually dismiss this dialog
              </button>
            </div>
          </>
        ),
        modalRef: modalRef,
        size: 'sm',
      });

      // when users close out of modal
    } catch (err) {}
  };

  return (
    <>
      <button onClick={onSubmit}>Show Modal</button>
    </>
  );
}
Dismiss via form submission

This example features a modal with a form. Upon form submission, the modal closes automatically.

image

import React from 'react';
import { useActionDialogRef, useActionDialogs } from 'react-dialog-mui';

export function ModalExampleWithFormSubmit() {
  const { modal } = useActionDialogs();
  const modalRef = useActionDialogRef();

  const onSubmit = async () => {
    try {
      await modal({
        title: 'Login Modal',
        message: (
          <form
            onSubmit={(e) => {
              e.preventDefault();
              modalRef.current.dismiss();
            }}
            style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
            <input type='text' placeholder='Username' required />
            <input type='password' placeholder='Password' required />
            <div>
              <button type='submit'>Login</button>
            </div>
          </form>
        ),
        modalRef: modalRef,
        size: 'sm',
      });

      // when users close out of modal
    } catch (err) {}
  };

  return (
    <>
      <button onClick={onSubmit}>Show Modal</button>
    </>
  );
}

Additional Samples:

For more code samples, you can find them in the Storybook examples located here: https://github.com/synle/react-dialog-mui/tree/main/src/stories .

I published a blog post, you can refer to the link for more information about the motivation behind this library here: https://www.linkedin.com/article/edit/7182404170941972480/

Local Dev Storybook

I've set up the Storybook locally. You can interact with the live demo on your local machine. Use the following setup:

npm install
npm run dev

# then open http://localhost:6006/

Future Plans

  • [x] Set up CI/CD pipeline to release this as an official npm package.
  • [x] Enhance the dismiss dialog API for easy dismissal of custom dialog content.
  • [ ] Implement support for multi-select in the choice dialog.