Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[pickers] DatePicker click on outside triggers onAccept #10000

Open
2 tasks done
dabljues opened this issue Aug 11, 2023 · 11 comments
Open
2 tasks done

[pickers] DatePicker click on outside triggers onAccept #10000

dabljues opened this issue Aug 11, 2023 · 11 comments
Labels
component: pickers This is the name of the generic UI component, not the React module! enhancement This is not a bug, nor a new feature

Comments

@dabljues
Copy link

dabljues commented Aug 11, 2023

Duplicates

  • I have searched the existing issues

Latest version

  • I have tested the latest version

Steps to reproduce 🕹

Link to live example: https://codesandbox.io/s/busy-shtern-qh99sw?file=/src/App.tsx

Steps:

  1. Click on the date picker, dialog opens
  2. Select a value
  3. Click outside the picker dialog (not clicking Ok nor Cancel)
  4. Picker dialog closes

Current behavior 😯

On @mui/x-date-pickers version 6.0.3 (as it is on CodeSandbox), if I do this (click on the outside), the onAccept doesn't trigger.

You can see this on the CodeSandbox (the text below doesn't change, there's no "foo" in the console). And that's okay, that's what I want.

However, on the newest version (6.11.0), which I have locally, the click on the outside triggers the onAccept. I cannot select this version on CodeSandbox to show it.

Expected behavior 🤔

I want the click on the outside of the picker dialog not to trigger the onAccept. I know that this wasn't the case in the earlier version (at least in 6.0.3).

So basically, if the user changes their mind and closes the picker dialog by clicking on the outside (which some people prefer instead clicking Cancel), I want the onAccept not to trigger. So I don't change the state, write to the context, etc. Or, maybe there's some other event listener, different than onAccept that I can use?

P.S I think I cherry-picked the version that this got changed. Version 6.1.0 works as I want, version 6.2.0 doesn't (like the newest one).

Context 🔦

Explained above.

Your environment 🌎

npx @mui/envinfo
  Browser: Chromium
  System:
    OS: Windows 10 10.0.22621
  Binaries:
    Node: 20.3.1 - ~\scoop\apps\nodejs\current\node.EXE
    Yarn: 1.22.19 - ~\scoop\apps\yarn\current\bin\yarn.CMD
    npm: 9.6.7 - ~\scoop\apps\nodejs\current\npm.CMD
  Browsers:
    Chrome: Not Found
    Edge: Spartan (44.22621.1992.0), Chromium (115.0.1901.200)
  npmPackages:
    @emotion/react: ^11.11.1 => 11.11.1
    @emotion/styled: ^11.11.0 => 11.11.0
    @mui/base:  5.0.0-beta.10
    @mui/core-downloads-tracker:  5.14.4
    @mui/icons-material: ^5.11.16 => 5.14.3
    @mui/material: ^5.14.4 => 5.14.4
    @mui/private-theming:  5.14.4
    @mui/styled-engine:  5.13.2
    @mui/system:  5.14.4
    @mui/types:  7.2.4
    @mui/utils:  5.14.4
    @mui/x-date-pickers: ^6.11.0 => 6.11.0
    @types/react: ^18.2.8 => 18.2.20
    react: ^18.2.0 => 18.2.0
    react-dom: ^18.2.0 => 18.2.0
    typescript: ^5.1.3 => 5.1.6

Order ID or Support key 💳 (optional)

No response

@dabljues dabljues added the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Aug 11, 2023
@zannager zannager added the component: pickers This is the name of the generic UI component, not the React module! label Aug 11, 2023
@alexfauquette
Copy link
Member

Likely this behavior has been impacted by #8312

Before that PR, the lifecycle was not clearly defined.
Now it's documented (see subsection When the picker is manually closed).

When the user presses Escape or clicks outside the picker, onAccept is called with:

  • the current value, if the last view has been completed
  • the last accepted value, if the last view has not been completed

A solution could be to add additional information on the onAccpet to let you know why this call back get called, and then addapt the behavior as you want.

@flaviendelangle Might be time to add that information on all onAccept/onChange for consitency

@flaviendelangle
Copy link
Member

@flaviendelangle Might be time to add that information on all onAccept/onChange for consitency

Slightly related to #9985

I guess it would be a property like source: "shortcut" | "actionBar" | "dismiss" etc...

@dabljues
Copy link
Author

Now it's documented (see subsection When the picker is manually closed).

Oh, right, I didn't see this.

A solution could be to add additional information on the onAccpet to let you know why this call back get called, and then addapt the behavior as you want.

That would be great!

@alexfauquette
Copy link
Member

I guess it would be a property like source: "shortcut" | "actionBar" | "dismiss" etc...

Since we started with a context object for onChange: ctx = { shortcut: { ... } } I was thinking to go the same way:

{
  shortcut?: { id: string };
  actionBar?: { id: string };
  view?: { type: 'year' | 'month' | ....};
  other?: { type: 'keyboard-escape' | 'keyboard-enter' | 'click-outside'};
}

@alexfauquette alexfauquette added enhancement This is not a bug, nor a new feature and removed status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels Aug 14, 2023
@thedoctorde
Copy link

Any progress ?

@Ljupcho-Petrushevski
Copy link

I also need this behavior, since i have to implement a picker which won't make use of the onChange prop in most of the cases, but only onAccept in combination with slotProps={{ actionBar: { actions: ["cancel", "accept"] } }} and i expected that onAccept fires only when i click the "accept" button on the picker.

@alexfauquette
Copy link
Member

This issue can be split by multiple PR (on per kind of action)

@LukasTy LukasTy changed the title DatePicker click on outside triggers onAccept [pickers] DatePicker click on outside triggers onAccept Dec 11, 2023
@volodymyr-kryvoshapov
Copy link

volodymyr-kryvoshapov commented Jan 18, 2024

Guys. You really do not need this because it already implemented. My version is "@mui/x-date-pickers": "6.19.0"

You can achieve this with controlled open property:

const [open, setOpen] = React.useState(false);

<MobileDateTimePicker
    open={open}
    onClose={() => setOpen(false)}
    slotProps={{
        dialog: {
            onClose: (event: object, reason: string) => {
                setOpen(false);
            },
        },
        textField: {
            onClick: () => {
                setOpen(true);
            },
        },
    }}
/>

After you added onClose callback to dialog slotProps, it automatically stops accept and even close Dialog on escape press or backdrop click.

Additionally read documentation for onClose property in Dialog API. It also provide context props:

function(event: object, reason: string) => void

  • event The event source of the callback.
  • reason Can be: "escapeKeyDown", "backdropClick".

@AniteshT24
Copy link

Any update on this? @LukasTy

@jkz27
Copy link

jkz27 commented Jun 16, 2024

Any updates guys @flaviendelangle @alexfauquette thanks

@ramirez
Copy link

ramirez commented Jul 9, 2024

You can achieve this with controlled open property:

const [open, setOpen] = React.useState(false);

<MobileDateTimePicker
    open={open}
    onClose={() => setOpen(false)}
    slotProps={{
        dialog: {
            onClose: (event: object, reason: string) => {
                setOpen(false);
            },
        },
        textField: {
            onClick: () => {
                setOpen(true);
            },
        },
    }}
/>

After you added onClose callback to dialog slotProps, it automatically stops accept and even close Dialog on escape press or backdrop click.

This does not work for me. The dialog slot props are just ignored by the time picker. Am I missing something?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: pickers This is the name of the generic UI component, not the React module! enhancement This is not a bug, nor a new feature
Projects
None yet
Development

No branches or pull requests

10 participants