There are nearly a dozen independent implementations of the same modal
spread throughout the admin panel and various plugins. These modals are
used to confirm or cancel an action, such as deleting a document, bulk
publishing, etc. Each of these instances is nearly identical, leading to
unnecessary development efforts when creating them, inconsistent UI, and
duplicative stylesheets.
Everything is now standardized behind a new `ConfirmationModal`
component. This modal comes with a standard API that is flexible enough
to replace nearly every instance. This component has also been exported
for reuse.
Here is a basic example of how to use it:
```tsx
'use client'
import { ConfirmationModal, useModal } from '@payloadcms/ui'
import React, { Fragment } from 'react'
const modalSlug = 'my-confirmation-modal'
export function MyComponent() {
const { openModal } = useModal()
return (
<Fragment>
<button
onClick={() => {
openModal(modalSlug)
}}
type="button"
>
Do something
</button>
<ConfirmationModal
heading="Are you sure?"
body="Confirm or cancel before proceeding."
modalSlug={modalSlug}
onConfirm={({ closeConfirmationModal, setConfirming }) => {
// do something
setConfirming(false)
closeConfirmationModal()
}}
/>
</Fragment>
)
}
```
68 lines
1.9 KiB
TypeScript
68 lines
1.9 KiB
TypeScript
'use client'
|
|
import { useModal } from '@faceless-ui/modal'
|
|
import React, { useCallback } from 'react'
|
|
import { toast } from 'sonner'
|
|
|
|
import type { OnConfirm } from '../ConfirmationModal/index.js'
|
|
|
|
import { useDocumentInfo } from '../../providers/DocumentInfo/index.js'
|
|
import { useTranslation } from '../../providers/Translation/index.js'
|
|
import { Button } from '../Button/index.js'
|
|
import { ConfirmationModal } from '../ConfirmationModal/index.js'
|
|
import { Translation } from '../Translation/index.js'
|
|
|
|
export type GenerateConfirmationProps = {
|
|
highlightField: (Boolean) => void
|
|
setKey: () => void
|
|
}
|
|
|
|
export function GenerateConfirmation(props: GenerateConfirmationProps) {
|
|
const { highlightField, setKey } = props
|
|
|
|
const { id } = useDocumentInfo()
|
|
const { toggleModal } = useModal()
|
|
const { t } = useTranslation()
|
|
|
|
const modalSlug = `generate-confirmation-${id}`
|
|
|
|
const handleGenerate: OnConfirm = useCallback(
|
|
({ closeConfirmationModal, setConfirming }) => {
|
|
setKey()
|
|
toast.success(t('authentication:newAPIKeyGenerated'))
|
|
highlightField(true)
|
|
setConfirming(false)
|
|
closeConfirmationModal()
|
|
},
|
|
[highlightField, setKey, t],
|
|
)
|
|
|
|
return (
|
|
<React.Fragment>
|
|
<Button
|
|
buttonStyle="secondary"
|
|
onClick={() => {
|
|
toggleModal(modalSlug)
|
|
}}
|
|
size="small"
|
|
>
|
|
{t('authentication:generateNewAPIKey')}
|
|
</Button>
|
|
<ConfirmationModal
|
|
body={
|
|
<Translation
|
|
elements={{
|
|
1: ({ children }) => <strong>{children}</strong>,
|
|
}}
|
|
i18nKey="authentication:generatingNewAPIKeyWillInvalidate"
|
|
t={t}
|
|
/>
|
|
}
|
|
confirmLabel={t('authentication:generate')}
|
|
heading={t('authentication:confirmGeneration')}
|
|
modalSlug={modalSlug}
|
|
onConfirm={handleGenerate}
|
|
/>
|
|
</React.Fragment>
|
|
)
|
|
}
|