feat!: move from react-toastify to sonner (#6682)

**BREAKING:** We now export toast from `sonner` instead of
`react-toastify`. If you send out toasts from your own projects, make
sure to use our `toast` export, or install `sonner`. React-toastify
toasts will no longer work anymore. The Toast APIs are mostly similar,
but there are some differences if you provide options to your toast

CSS styles have been changed from Toastify

```css
/* before */
.Toastify


/* current */
.payload-toast-container
.payload-toast-item
.payload-toast-close-button

/* individual toast items will also have these classes depending on the state */
.toast-info
.toast-warning
.toast-success
.toast-error
```


https://github.com/payloadcms/payload/assets/70709113/da3e732e-aafc-4008-9469-b10f4eb06b35

---------

Co-authored-by: Paul Popus <paul@nouance.io>
This commit is contained in:
Alessio Gravili
2024-06-11 14:12:59 -04:00
committed by GitHub
parent 10c6ffafc3
commit cb3355b30f
87 changed files with 747 additions and 353 deletions

View File

@@ -107,7 +107,7 @@ describe('Array', () => {
await page.locator('#field-arrayWithMinRows >> .array-field__add-row').click()
await page.click('#action-save', { delay: 100 })
await expect(page.locator('.Toastify')).toContainText(
await expect(page.locator('.payload-toast-container')).toContainText(
'The following field is invalid: arrayWithMinRows',
)
})
@@ -290,7 +290,7 @@ describe('Array', () => {
await targetInput.fill(bulkText)
await page.locator('#edit-array-fields .form-submit .edit-many__save').click()
await expect(page.locator('.Toastify__toast--success')).toContainText(
await expect(page.locator('.payload-toast-container .toast-success')).toContainText(
'Updated 3 Array Fields successfully.',
)
})

View File

@@ -182,7 +182,7 @@ describe('Block fields', () => {
test('should bypass min rows validation when no rows present and field is not required', async () => {
await page.goto(url.create)
await saveDocAndAssert(page)
await expect(page.locator('.Toastify')).toContainText('successfully')
await expect(page.locator('.payload-toast-container')).toContainText('successfully')
})
test('should fail min rows validation when rows are present', async () => {
@@ -208,7 +208,7 @@ describe('Block fields', () => {
await expect(firstRow).toHaveValue('first row')
await page.click('#action-save', { delay: 100 })
await expect(page.locator('.Toastify')).toContainText(
await expect(page.locator('.payload-toast-container')).toContainText(
'The following field is invalid: blocksWithMinRows',
)
})

View File

@@ -835,7 +835,9 @@ describe('lexicalBlocks', () => {
await saveDocAndAssert(page)
await expect(page.locator('.Toastify')).not.toContainText('Please correct invalid fields.')
await expect(page.locator('.payload-toast-container')).not.toContainText(
'Please correct invalid fields.',
)
}
// eslint-disable-next-line playwright/expect-expect
@@ -920,7 +922,9 @@ describe('lexicalBlocks', () => {
await page.click('#action-save', { delay: 100 })
await wait(300)
await expect(page.locator('.Toastify')).toContainText('The following field is invalid')
await expect(page.locator('.payload-toast-container')).toContainText(
'The following field is invalid',
)
await wait(300)
const requiredTooltip = conditionalArrayBlock

View File

@@ -138,7 +138,7 @@ describe('Number', () => {
test('should bypass min rows validation when no rows present and field is not required', async () => {
await page.goto(url.create)
await saveDocAndAssert(page)
await expect(page.locator('.Toastify')).toContainText('successfully')
await expect(page.locator('.payload-toast-container')).toContainText('successfully')
})
test('should fail min rows validation when rows are present', async () => {
@@ -151,7 +151,7 @@ describe('Number', () => {
await page.keyboard.press('Enter')
await page.click('#action-save', { delay: 100 })
await expect(page.locator('.Toastify')).toContainText(
await expect(page.locator('.payload-toast-container')).toContainText(
'The following field is invalid: withMinRows',
)
})

View File

@@ -86,13 +86,13 @@ describe('relationship', () => {
const textValue = 'hello'
await textField.fill(textValue)
await page.locator('[id^=doc-drawer_text-fields_1_] #action-save').click()
await expect(page.locator('.Toastify')).toContainText('successfully')
await expect(page.locator('.payload-toast-container')).toContainText('successfully')
await page.locator('[id^=close-drawer__doc-drawer_text-fields_1_]').click()
await expect(
page.locator('#field-relationship .relationship--single-value__text'),
).toContainText(textValue)
await page.locator('#action-save').click()
await expect(page.locator('.Toastify')).toContainText('successfully')
await expect(page.locator('.payload-toast-container')).toContainText('successfully')
})
test('should create nested inline relationships', async () => {
@@ -151,7 +151,7 @@ describe('relationship', () => {
await expect.poll(() => page.url(), { timeout: POLL_TOPASS_TIMEOUT }).toContain('create')
await page.locator('#action-save').click()
await expect(page.locator('.Toastify')).toContainText('successfully')
await expect(page.locator('.payload-toast-container')).toContainText('successfully')
})
test('should hide relationship add new button', async () => {
@@ -250,10 +250,10 @@ describe('relationship', () => {
await page.locator('.drawer__content #field-text').fill('something')
await page.locator('[id^=doc-drawer_text-fields_1_] #action-save').click()
await expect(page.locator('.Toastify')).toContainText('successfully')
await expect(page.locator('.payload-toast-container')).toContainText('successfully')
await page.locator('[id^=close-drawer__doc-drawer_text-fields_1_]').click()
await page.locator('#action-save').click()
await expect(page.locator('.Toastify')).toContainText('successfully')
await expect(page.locator('.payload-toast-container')).toContainText('successfully')
// Create a new doc for the `relationshipHasMany` field
await expect.poll(() => page.url(), { timeout: POLL_TOPASS_TIMEOUT }).not.toContain('create')
@@ -263,7 +263,7 @@ describe('relationship', () => {
// Save and close the drawer
await page.locator('[id^=doc-drawer_text-fields_1_] #action-save').click()
await expect(page.locator('.Toastify')).toContainText('successfully')
await expect(page.locator('.payload-toast-container')).toContainText('successfully')
await page.locator('[id^=close-drawer__doc-drawer_text-fields_1_]').click()
// Now open the drawer again to edit the `text` field _using the keyboard_
@@ -286,12 +286,12 @@ describe('relationship', () => {
// save drawer
await page.locator('[id^=doc-drawer_text-fields_1_] #action-save').click()
await expect(page.locator('.Toastify')).toContainText('successfully')
await expect(page.locator('.payload-toast-container')).toContainText('successfully')
// close drawer
await page.locator('[id^=close-drawer__doc-drawer_text-fields_1_]').click()
// save document and reload
await page.locator('#action-save').click()
await expect(page.locator('.Toastify')).toContainText('successfully')
await expect(page.locator('.payload-toast-container')).toContainText('successfully')
await page.reload()
// check if the value is saved
@@ -352,7 +352,7 @@ describe('relationship', () => {
await page.getByText('Seeded text document', { exact: true }).click()
await saveDocAndAssert(page)
await expect(page.locator('.Toastify')).toContainText('successfully')
await expect(page.locator('.payload-toast-container')).toContainText('successfully')
})
test('should fail min rows validation when rows are present', async () => {
@@ -373,7 +373,7 @@ describe('relationship', () => {
.click()
await page.click('#action-save', { delay: 100 })
await expect(page.locator('.Toastify')).toContainText(
await expect(page.locator('.payload-toast-container')).toContainText(
'The following field is invalid: relationshipWithMinRows',
)
})

View File

@@ -109,7 +109,7 @@ describe('Upload', () => {
page.locator('[id^=doc-drawer_uploads_1_] .file-field__upload .file-field__filename'),
).toHaveValue('payload.png')
await page.locator('[id^=doc-drawer_uploads_1_] #action-save').click()
await expect(page.locator('.Toastify')).toContainText('successfully')
await expect(page.locator('.payload-toast-container')).toContainText('successfully')
// Assert that the media field has the png upload
await expect(
@@ -140,7 +140,7 @@ describe('Upload', () => {
page.locator('[id^=doc-drawer_uploads_1_] .file-field__upload .file-field__filename'),
).toHaveValue('payload.png')
await page.locator('[id^=doc-drawer_uploads_1_] #action-save').click()
await expect(page.locator('.Toastify')).toContainText('successfully')
await expect(page.locator('.payload-toast-container')).toContainText('successfully')
await page.locator('.field-type.upload .file-details__remove').click()
})

View File

@@ -105,7 +105,7 @@ describe('fields', () => {
await page.click('#action-save', { delay: 200 })
// toast error
await expect(page.locator('.Toastify')).toContainText(
await expect(page.locator('.payload-toast-container')).toContainText(
'The following field is invalid: uniqueText',
)
@@ -126,7 +126,7 @@ describe('fields', () => {
await page.locator('#action-save').click()
// toast error
await expect(page.locator('.Toastify')).toContainText(
await expect(page.locator('.payload-toast-container')).toContainText(
'The following field is invalid: group.unique',
)
@@ -312,7 +312,7 @@ describe('fields', () => {
await titleInput.fill('Row 123')
await page.locator('#action-save').click()
await wait(200)
await expect(page.locator('.Toastify')).toContainText('successfully')
await expect(page.locator('.payload-toast-container')).toContainText('successfully')
// ensure the 'title' field is visible in the table header
await page.goto(url.list)
@@ -334,7 +334,7 @@ describe('fields', () => {
await titleInput.fill('Row 456')
await page.locator('#action-save').click()
await wait(200)
await expect(page.locator('.Toastify')).toContainText('successfully')
await expect(page.locator('.payload-toast-container')).toContainText('successfully')
// ensure there are not two ID fields in the table header
await page.goto(url.list)