-
Notifications
You must be signed in to change notification settings - Fork 10
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
Prevent dialog from closing #5
Comments
Hey! Thanks for trying it out 🥳 Hmm this should be possible with todays solution. Just use const ModalExample: () => {
const [isDirty, setDirty] = useState(false);
return (
<DialogContent
onPointerDownOutside={(e) => {
if (isDirty) {
e.preventDefault();
pushModal('Dynamic');
} else {
// Do something else?
}
}}
>
<button className="bg-black text-white p-2" onClick={() => setDirty((p) => !p)}>
{isDirty ? 'Dirty' : 'Not Dirty'}
</button>
</DialogContent>
); Skarminspelning.2024-04-10.kl.06.27.43.mov |
Oh great, thanks for your input! So implementing a prevent close function in onPointerDownOutside, along with onEscapeKeyDown and passing it to the DialogPrimitive.Close button should cover all the possible ways to exit of the dialog/sheet, so it's being managed outside of the library. Edit: Also I was trying to popAllModals() within the "exit" button in alert dialog so it closes every dialog opened, but the library doesn't notify the emitter with 'change' like in the popModal(). I think the emitter should notify all the dialog closed so the callback can be called for each. So then the useOnPushModal that I have defined in the dialog is not being called.
|
I will fix the event thingy. Regarding disable close. There's a lot of different ways to do this. I will play around and see what the best solution would be. |
Also could use this 🙌 |
@alexambrinos I managed to get around this by using the AlertDialog as a wrapping component. import { AlertDialog } from '@/components/ui/alert-dialog';
export const {
pushModal,
popModal,
...
} = createPushModal({
modals: {
...
AlertModal: {
//@ts-ignore
Wrapper: AlertDialog,
Component: AlertModal,
},
},
}); The modal doesn't close on interaction and you can still remove it by using popModal. TS isn't happy but oh well |
@digitdustin Great that you found something that works for you! If you always want to have the dialog not closable it's a great ideea. |
Hey, have not had time to look into this. Will try to find time this week! |
Important
export default function CreateDialog() {
const [isLoading, startTransition] = useTransition()
const onSubmit = (values) => {
startTransition(async () => {
// server action
})
}
return (
<Dynamic.Content
// to avoid this
onPointerDownOutside={(e) => {}}
onEscapeKeyDown={(e) => {}}
// new prop e.g:
closseable={isLoading} // and this disable the option to close the dialog and drawer, until the server action is finished.
>
{/* form */}
</Dynamic.Content>
)
} // per default
<Dialog open={} onOpenChange={}>
{/* content */}
</Dialog>
Warning You need to add this prop in both, otherwise you will get an error. // dialog.{jsx,tsx,js}
const DialogContent = forwardRef(
({ className, children, hiddenClose = false, ...props }, ref) => (
// ...
{!hiddenClose && (
<DialogPrimitive.Close className='absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity data-[state=open]:bg-accent data-[state=open]:text-muted-foreground hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none'>
<Cross2Icon className='size-4' />
<span className='sr-only'>Close</span>
</DialogPrimitive.Close>
)}
// ...
)
) // drawer.{jsx,tsx,js}
const DrawerContent = forwardRef(
({ className, children, hiddenClose = false, ...props }, ref) => (
// ...
{!hiddenClose && (
<div className='mx-auto mt-4 h-2 w-[100px] rounded-full bg-muted' />
)}
// ...
)
) // component.{jsx,tsx,js}
export default function CreateDialog() {
const [isLoading, startTransition] = useTransition()
const onSubmit = (values) => {
startTransition(async () => {
// server action
})
}
return (
<Dynamic.Content
hiddenClose={isLoading} // automatically hides when the form is submitted
>
{/* form */}
</Dynamic.Content>
)
} |
Hi, thanks for this amazing library! I was trying to convert my app to using this library for handling the modal state but inevitable I have hit a barrier.
I was trying to stack a dialog with an alert dialog from radix ui. I wanted to prevent closing the dialog when trying to close it with a dirty form inside it and show the alert dialog instead. But I can't do that since there's no access to the controlled state of the modal (specifically the onOpenChange of the Root)
If someone can find a way to implement this kind of flow without modifications to the library I would love to know. The only thing that comes to my mind would be to manage the "closable" state in the StateItem like it's being done with the closedAt property. And than pass a "setClosable" it in the Component so it can be changed within the modal.
The text was updated successfully, but these errors were encountered: