Giter VIP home page Giter VIP logo

material-ui-confirm's Introduction

Material-UI confirm GitHub license npm version Actions Status Coverage Status

Confirming user choice is a good thing to do, it should also be easy to do.

This package provides simple confirmation dialogs built on top of @mui/material and straightforward to use thanks to React Hooks.

Installation

npm install --save material-ui-confirm

Demo

Edit material-ui-confirm demo

Usage

Wrap your app inside the ConfirmProvider component.
Note: If you're using Material UI ThemeProvider, make sure ConfirmProvider is a child of it.

import React from "react";
import { ConfirmProvider } from "material-ui-confirm";

const App = () => {
  return <ConfirmProvider>{/* ... */}</ConfirmProvider>;
};

export default App;

Call the useConfirm hook wherever you need the confirm function.
Note: A component calling useConfirm must be a child of ConfirmProvider.

import React from "react";
import Button from "@mui/material/Button";
import { useConfirm } from "material-ui-confirm";

const Item = () => {
  const confirm = useConfirm();

  const handleClick = () => {
    confirm({ description: "This action is permanent!" })
      .then(() => {
        /* ... */
      })
      .catch(() => {
        /* ... */
      });
  };

  return <Button onClick={handleClick}>Click</Button>;
};

export default Item;

API

ConfirmProvider

This component is required in order to render a dialog in the component tree.

Props
Name Type Default Description
defaultOptions object {} Overrides the default options used by confirm.

useConfirm() => confirm

This hook returns the confirm function.

confirm([options]) => Promise

This function opens a confirmation dialog and returns a promise representing the user choice (resolved on confirmation and rejected on cancellation).

Options
Name Type Default Description
title ReactNode 'Are you sure?' Dialog title.
description ReactNode '' Dialog content, automatically wrapped in DialogContentText.
content ReactNode null Dialog content, same as description but not wrapped in DialogContentText. Supersedes description if present.
confirmationText ReactNode 'Ok' Confirmation button caption.
cancellationText ReactNode 'Cancel' Cancellation button caption.
dialogProps object {} Material-UI Dialog props.
dialogActionsProps object {} Material-UI DialogActions props.
confirmationButtonProps object {} Material-UI Button props for the confirmation button.
cancellationButtonProps object {} Material-UI Button props for the cancellation button.
titleProps object {} Material-UI DialogTitle props for the dialog title.
contentProps object {} Material-UI DialogContent props for the dialog content.
allowClose boolean true Whether natural close (escape or backdrop click) should close the dialog. When set to false force the user to either cancel or confirm explicitly.
confirmationKeyword string undefined If provided the confirmation button will be disabled by default and an additional textfield will be rendered. The confirmation button will only be enabled when the contents of the textfield match the value of confirmationKeyword
confirmationKeywordTextFieldProps object {} Material-UI TextField props for the confirmation keyword textfield.
acknowledgement string undefined If provided shows the acknowledge checkbox with this string as checkbox label and disables the confirm button while the checkbox is unchecked.
acknowledgementFormControlLabelProps object {} Material-UI FormControlLabel props for the form control label.
acknowledgementCheckboxProps object {} Material-UI Checkbox props for the acknowledge checkbox.
hideCancelButton boolean false Whether to hide the cancel button.
buttonOrder string[] ["cancel", "confirm"] Specify the order of confirm and cancel buttons.

Useful notes

Confirm by pressing Enter

You can get this behavior by adding the autoFocus property to the confirmation button. This way the button is focused as soon as the dialog opens and hitting Enter naturally triggers a click.

Locally
const MyComponent = () => {
  // ...

  const handleClick = () => {
    confirm({ confirmationButtonProps: { autoFocus: true } })
      .then(() => {
        /* ... */
      })
      .catch(() => {
        /* ... */
      });
  };

  // ...
};
Globally
const App = () => {
  return (
    <ConfirmProvider
      defaultOptions={{
        confirmationButtonProps: { autoFocus: true },
      }}
    >
      {/* ... */}
    </ConfirmProvider>
  );
};

material-ui-confirm's People

Contributors

adibhat108 avatar armanio avatar btmluiz avatar dependabot[bot] avatar gergely-adamku avatar imjordanxd avatar jonatanklosko avatar joshkel avatar liaokaime avatar mattfellows avatar muscularsloth avatar profhercules avatar tifosiblack avatar timmikeladze avatar ypahalajani avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

material-ui-confirm's Issues

Usage with Hooks

Can material-ui-confirm used in functional components?

Why is withConfirm needed? Can't there just be a global "confirm" function?

How to handle confirmed action result to stay and display an error?

Hi @jonatanklosko ,

Thanks for the library! Really often when the user confirms I do API requests and those can fail for any reason. I want to show the error to the user.

I could use a toaster/snackbar but it's not accessible.

So I would like to show an error block just above my text. I wanted to tweak the confirmationButtonProps.onClick to do my async request inside and depending on the result I would have tried modified the confirm content with an error block. Unfortunately my onClick is never called :(

Do you have an advice for this use case with your library?

Thank you,


EDIT: a solution otherwise would be to open a new modal to show the error. It makes things a bit weird, but when thinking about it "internal server error" should not happen often.

And also, let's say I have a list with options for each item (through a popover menu), in case I don't use a confirm to delete an item:

  1. showing the error among the list would be weird and would break the display
  2. showing the error above the list would require a scroll of maybe thousands of pixels, meaning the user would need to scroll down then to retry on the right item
  3. and for sure, impossible to show the error into the popover menu

So maybe it just makes sense to use a new modal to harmonize with and without an action that has useConfirm.


EDIT2: despite this issue, I need to make the "confirm button" being disabled and having a loader while doing the async request, otherwise it's not obvious there is a request that can takes a long time.

omit dialogProps open

When setting default dialogProps, the required open prop should be omitted in the expected type –– doesn't make much sense and of course you override it anyway.

package this library also as UMD

today there are 2 output files:

  • material-ui-confirm.cjs.js
  • material-ui-confirm.esm.js

Unfortunately none of them can be used as UMD in the browser
A broader use case - would be to use this library as external in webpack and other package tools out there...

Controlled input as content not updating state until dialog is closed

I have a confirmation dialog where I need the user to input an optional text value before confirming. My use of confirm looks something like this:

confirm( {content: <TextField defaultValue="" onChange=((e) => setValue(e.target.value)})
.then(() => APICall(value))
.catch(() => {})

And the issue is the value is not actually updated until the dialog is closed, so the value being used is always the previous one.

I'm not sure if there's something I'm doing wrong or maybe this tool is meant for simpler dialogs where it's only a description and an confirm/cancel button.

Thanks for your time.

[FEAT] Embed forms in confirm dialog

It would be amazing if this library supported embedding form inputs and other layout elements for purposes such as:

  • typing the name of a resource before deletion
  • entering a password to confirm account change

confirm is not a function

i installed this in react with typescript its says confirm is not a function

--> solved int the provider should be on top of the component

Changelog

Hi, would it be possible to maintain a changelog or release notes for this repo? Having to go through commits to see whats changed over the last few versions.

Thanks for the work!

Control key word for confirm

Is there a way to add an input to the Confirm Dialog to enter a control word?
After entering this word, the button will become active.

Thank you

Screenshot 2022-09-19 at 23 52 51

Options to add extra dialog action buttons?

Would it be possible to have the ability to add extra action buttons? I know that "cancel" will reject the promise and "confirm" will resolve, could bind any additional buttons to resolve/reject and the resolved/rejected promise could be a value indicating which action was pressed?
I mainly had the motivation of a dialog with options "Yes", "No" and "Cancel".

Opening dialog messes up theme

Hello, i'm trying to use this tool, but every time the confirm function is called, all of my website theme goes to default and i have to reload the website, any ideas what is going on?

EDIT: Cloning the repo and using the files directly works, i'm guessing it's an issue with the npm build using old material ui files (As far as i read this is an issue with material ui mui/material-ui#26452 )

Usage as a prompt, get input string from user

Can this be used/modified to show a prompt modal (with text input) instead of just confirm buttons?

So confirm.then((response) => {}) would receive the string the user entered in response.

[FEAT] Possible to add keypress listeners?

Hi there! First off, thanks for the amazing hook into the MUI's dialog component! I've been using this in a lot of my UI and have zero problems with it.

One thing I ended up doing on my own was wrapping the confirmation in a keypress listener, so that it would confirm the dialog if the user presses enter (or another key of my choice). I feel like this would be a great addition to this as it improves UX a bit. If you'd like, I can submit a PR and you can look it over and tell me what you think.

Anyways, thanks again for putting this together! Have a great day 😄

Invalid ConfirmProvider types

When trying to use ConfirmProvider, I'm getting the following error:

(alias) const ConfirmProvider: React.ComponentType<ConfirmProviderProps>
import ConfirmProvider
'ConfirmProvider' cannot be used as a JSX component.
  Its element type 'ReactElement<any, any> | Component<ConfirmProviderProps, any, any> | null' is not a valid JSX element.
    Type 'Component<ConfirmProviderProps, any, any>' is not assignable to type 'Element | ElementClass | null'.
      Type 'Component<ConfirmProviderProps, any, any>' is not assignable to type 'ElementClass'.
        The types returned by 'render()' are incompatible between these types.
          Type 'React.ReactNode' is not assignable to type 'import("<path>/node_modules/@types/react-dom/node_modules/@types/react/index").ReactNode'.
            Type '{}' is not assignable to type 'ReactNode'.
              Type '{}' is missing the following properties from type 'ReactPortal': key, children, type, props

I suspect that the React.ComponentType that is used in type declarations may be outdated?

Enable Prevent Dialog Close

Hi,

I've tried found a way how to prevent the dialog box to close upon "OK" button is clicked (waiting for API call done then will manually trigger the dialog to closed).

Is this feature available?

TypeScript definitions

Any plans to add TypeScript definitions?

I quickly created some that I use in my project:

declare module 'material-ui-confirm' {
    export const ConfirmProvider: React.ComponentClass;
    export const useConfirm: () => (options: {
        title?: string;
        description?: string;
        confirmationText?: string;
        cancellationText?: string;
        dialogProps?: Object;
    }) => Promise<any>;
}

Expose props for nested `MUI` components

Hi. Really great package!

Any chance you could expose the MUI props for the other components?

  • DialogTitle
  • DialogContent
  • DialogContentText
  • DialogActions

I need to restyle the title bar with a background-color and contrasting text color. I'd be adding default styling at provider and overriding it at call site based on type (confirm, don't confirm, etc...). I'd also like to customize the color of the text content and the padding of the rest (via defaults). Unfortunately, I don't think I can use global styling here.

Any help appreciated...!

Button props in hook should extends default props

Given

<ConfirmProvider
			defaultOptions={{
				confirmationButtonProps: {
					variant: 'contained',
					disableElevation: true,
				},
			}}
		>

And

confirm({
			title: 'Title',
			confirmationButtonProps: {
				disabled: true,
			},
		})

Expected:

Confirm button will have props:

{
  variant: 'contained',
  disableElevation: true,
  disabled: true,
}

Actual

Props get overwritten and compute to

{
  disabled: true,
}

Returns Boolean Interface

I recently found this projects and I'm loving how convenient it is to use! Thanks for create such a marvellous library.

I do have one suggestion, which is to provide some sort of API that returns a boolean instead of undefined. In other words, a function similar to window.confirm which would Promise.resolve(true) on confirm and Promise.resolve(false) on cancel or click away.

I'm imagining something like this:

import React from 'react';
import Button from '@mui/material/Button';
import { useConfirm } from 'material-ui-confirm';

const Item = () => {
  // the new proposed API
  const confirm = useConfirm().confirmBool;

  const handleClick = async () => {
    const consent = await confirm({ title: "Are you a duck?" });
    if (!consent) return;
    console.log("you're a duck");
  };

  return (
    <Button onClick={handleClick}>
      Click
    </Button>
  );
};

export default Item;

Would love to hear your thoughts

Test with Enzyme

Dialog works excellent. Thanks.
But if to test connected with redux component via enzyme, simulating a "button click" returns an error:
TypeError: confirm is not a function

Test:
const wrapper = shallow()
.find('ItemPage')
.dive();
wrapper
.find('[aria-label="delete"]')
.find([value="${id}"])
.simulate('click', {
currentTarget: {
value: id
}
});

Wrapping with e.g. shallow(<Container store={store} .../>) has no effect

Change the order of buttons

Can we change the order of buttons, so the confirmation button would come before the cancellation button? Note that I only want to change their order, both buttons should stay in the bottom right corner like they are now.

Default options does not update at runtime.

Hello, I am using i18n for React to change language of my app, but when the language changes confirmationText and cancellationText stay the same:
{ confirmationButtonProps: { autoFocus: true }, confirmationText: t("dialogs.yes"), cancellationText: t("dialogs.no"), }

How to pass additional parameters?

Hello,
Thanks you for your work on this HOC, I find it very useful and easy to use.
But I have a problem in my environment. I want to use it to validate action in a material-ui table (https://material-table.com/#/docs/features/actions). The onClick event passes 2 arguments: event and data about the row.
Here is an example which is working:
onClick: (e, rowData) => {console.log(e); console.log(rowData)}
I would like to use confirm for this action.
But when doing:
onClick: props.confirm((e, rowData) => {console.log(e); console.log(rowData)}, { description: "salut" })
the confirmation dialog opens correctly, the 'e' parameter is correctly logged (but I think it is the event from the OK button, not my action button), but I have undefined for rowData: it is not passed to my callback function.
Is it possible to get the onClick arguments to my callback function?

Thanks for your help.

Demo errors on cancel

Demo errors on cancel (albeit only in development) due to unhandled promise rejection. May be worth adding a .catch(() => console.log("User cancelled"))?

I see the same problem mentioned in the issues list so probably worth documenting.

Option to pass custom template

Currently it only uses Material UI basic dialog. If I want to use Form dialogu, there is no option to pass this template.

Take example of this pacakge, it accepts a custom template,

const Root = () => (
  <AlertProvider template={AlertTemplate} {...options}>
    <App />
  </AlertProvider>
)

Error: Invalid hook call

Thank u for awesome library,
I just ran into a problem during placing <ConfirmProvider /> under the Material UI's ThemeProvider, I believe it's sort of collision between providers but have no idea what exactly causes this error.
I appreciate your help in advance.

Full error message:

×
Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.
▶ 21 stack frames were collapsed.
(anonymous function)
src/index.js:95
  92 |     storage: window.localStorage,
  93 |   }).then(() => {
  94 |     client.onResetStore(async () => cache.writeData({ data: initData }));
> 95 |     setClient(client);
     | ^  96 |   });
  97 |   return () => {};
  98 | }, []);
View compiled
This screen is visible only in development. It will not appear if the app crashes in production.
Open your browser’s developer console to further inspect this error.

EDIT: I also add my providers to put more context

<ApolloProvider client={client}>
      <StylesProvider jss={jss}>
            <ThemeProvider theme={theme}>
                 <StyledThemeProvider theme={theme}>
                      <ConfirmProvider>
                            /* my app */
                      </ConfirmProvider>
                 </StyledThemeProvider>
            </ThemeProvider>
      </StylesProvider>
</ApolloProvider>

The button props for color not working properly.

I wanted to change the color for the cancel and confirm buttons but it did not work as I had hoped. Could you guide me on how best I can fix this issue? because I think am doing it wrong.

cancellationButtonProps: { color: "warning" },
confirmationButtonProps: { color: "error" },

The primary & secondary color prop values work but the other color props for the MUI Button aren't working.

I know this does not sound like an issue but I had no other medium I could use to get your help.

Option to not use `DialogContentText`

I have a slight variation from useConfirm's normal use case: I'd like to show two paragraphs instead of one. When I do this, React gives a validateDOMNesting warning, because the <p> elements that I'm using are part of the DialogContentText that material-ui-confirm uses.

I understand the desire to not complicate material-ui-confirm with a bunch of extra options, but what about an option to control the use of DialogContentText? I could imagine one of the following:

  • A text boolean option, defaulting to true; if true, it wraps description in <DialogContentText>, and if false, it uses it directly.
  • A Text component prop, defaulting to DialogContentText. Callers could override it if desired. (This may be less convenient, since for a lot of purposes, it would need to be an otherwise spurious div.)
  • A optional content ReactNode prop that, if present, completely replaces <DialogContentText>{description}</DialogContentText>.

This would also address this comment.

feature request: close the modal without cancel / confirm action

hello!

we've been using this lib but found that, when clicking in the backdrop to close the modal,

the promise is rejected: so it's like clicking the cancellationButton

we'd like to have a neutral option to close the modal as if nothing happened

(maybe will submit a PR if doesn't take too long to fix)

two times click "confirm" button cause an error

When I click confirm button two times, very fast, I get an error for the second click.

TypeError: resolve is not a function
(anonymous function)
node_modules/material-ui-confirm/dist/material-ui-confirm.esm.js:219
handleClose();
  217 | }, [reject, handleClose]);
  218 | var handleConfirm = useCallback(function () {
> 219 |   resolve();
      | ^  220 |   handleClose();
  221 | }, [resolve, handleClose]);

Is there a way to disable Confirm button after first click?

Material UI 5.0 Support?

Material UI 5.0 includes some package renaming from @material-ui/* to @mui/*.

Are there any plans to support Material UI 5.0 instead of the older versions?

Thank you!

Control to customise DialogActions section

Hey,
i am looking for a way to customise the DialogActions portion of the modal, as if suppose i want to switch the position of the 'Ok' and 'Cancel' button.... also suppose i want to add a third button in the bottom along with 'Ok' and 'Cancel button', Is there any way to do so??

How to use this as class component

useConfirm() is a react hook and cant be used in class component either we have to change class component to functional componant but that will be lengthy. What is the other way to useConfirm as Class component? It is not working on Render() also. I am new to React.

Closing the confirm should reject the promise

When the option allowClose is set to true (default value), the promise should be rejected (like if the user pressed the cancel button) when the confirm is closed (by pressing the Escape key for instance).

Currently, the promise keep its pending state.

Question - Do you support confirmation or cancelation onClick prop events?

Hi!

Pretty useful hook, thanks!

Do you support confirmation or cancelation onClick prop events?

No luck yet with:

  const handleOnClick = async () => {
    confirm({
      title: 'Title?',
      description: 'Description Description Description Description.',
      confirmationText: 'confirmation.Text',
      cancellationText: 'cancellation.Text',
      confirmationButtonProps: {
        onClick: () => { console.log('onClick'); },
      },
      cancellationButtonProps: {
        onClick: () => { console.log('onClick'); },
      },
    });
  };

Unable to apply dynamic 'disabled' styling to confirmationButtonProps

I have what is most likely an edge case issue here but wanted to raise your attention to this use-case.

I am using the confirm component to show a message and a small form consisting of a single field for the user to add a comment. I am using the built-in Buttons in DialogActions to submit the form, and passing the form content via content prop. If the user has not entered a comment, I would like the confirm button to be disabled, so I tried passing disabled in confirmationButtonProps like so

confirmationButtonProps: {
        disabled: formValues.comment.length === 0
}
content: <ConfirmationContent formProps={{...formProps}} />

however, this does not work. The disabled prop does not update the confirmation button when the user begins typing. As a workaround, I could instead add my own form submit buttons, however since the handleConfirm function is not exposed I am not able to actually resolve the promise.

I was wondering if it would be possible to expose the handleConfirm and handleCancellation functions to enable this type of functionality. Or, if there are any other better way to accomplish what I am trying to do?

Thanks.

Feature request: cancel without rejecting Promise

Hi, thanks for the great library.
It would be nice to have an option to not reject the promise on cancel, as cancellation is often a no-op and we could get rid of the confusing catch.
I think it would be sufficient to just store () => {} as "reject" value in resolveReject state.

Neutrally closing the dialog (e.g. when hitting Esc) causes code to hang

Affected version: 2.1.1

When you close a confirm dialog neutrally (i.e. hit ESC or click the backdrop), it causes the code that invoked confirm() to hang.

You can see an example of this at https://codesandbox.io/s/material-ui-confirm-demo-forked-67mfw?file=/src/Demo.js. Opening the confirm dialog causes the current timestamp to be logged to the console at a regular interval. If you click either of the buttons, the console logging is stopped appropriately. If hit ESC or click the backdrop, the console logging still continues, even when the dialog closes. If you open the confirm dialog again, there are now two processes logging the current timestamp to the console.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.